Введение в реверсинг с нуля, используя IDA PRO. Часть 44.

Дата публикации 2 май 2018 | Редактировалось 2 май 2018
Конечно, нам нужно решить упражнение PRACTICA_44, но мы будем решать его в следующих частях. Сейчас мы увидим дополнительную информацию, которую мы можем получить используя WINDBG внутри IDA. Мы будем использовать предыдущий случай PRACTICA 41B, про который мы знаем, что это переполнение кучи.

Мы перейдём от отладчика IDA к WINDBG и убедимся, что он находится в режиме USER через DEBUGGER OPTIONS.

1.png

Мы меняем GFLAGS для того, чтобы процесс имел включенный PAGE HEAP в режиме FULL.

2.png

И я запускаю скрипт SCRIPT2.

3.png

Но на этот раз, когда программа останавливается, я присоединяю IDA к анализу PRACTICA41B загруженного в ЗАГРУЗЧИК и конечно в режиме отладки USER WINDBG.

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

4.png

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

5.png

Хорошо. WINDBG имеет много полезных команд для исследования кучи. Я думаю, что для работы с кучами, этот интерфейс является наиболее полными.

6.png

Эта команда очень полезна. Она просто работает полностью с включенным режимом PAGE HEAP FULL. И мне сообщается размер выделенного блока, который использует программа или занят (не свободный) и сообщает мне историю мест, где это произошло, когда этот блок был выделен.

Если бы мы выполнили ту же команду в блоке, который был освобожден или свободен, команда покажет нам историю тех мест где был освобождён блок.

Распределение приходит из адреса.
002411AC PRACTICA41B+ 0x000011AC

7.png

И выше, в списке истории, программа похоже вызывает функцию MALLOC. Затем идет внутренний вызов RTLALLOCATEHEAP и т.д.

Ниже, в списке истории у нас есть такой вызов

0024109D PRACTICA41B+0x0000109D

8.png

Команда помечает адреса возврата вызовов куда входила программа, чтобы выделить блоки.

9.png

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

10.png

На веб-страницы MICROSOFT мы видим информацию о заголовке, в данном случае, информацию о кучи в режиме FULL PAGE. Заголовок начинается с байтов ABCDBBBB и заканчивается байтами DCABBBBB. Давайте посмотрим, увидим ли мы это непосредственно перед началом, где мы писали.

11.png

С помощью команды DT WINDBG, за которой следует _DPH_BLOCK_INFORMATION, команда будет выдавать нам информацию о полях заголовка.

Если мы пойдем по адресу, который указывает STACK TRACE.

12.png

13.png

Немного ниже сохраняется история распределения. Это соответствует тому, что нам дала команда.

¡heap –p –a xxx

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

Я выключаю режим PAGE GUARD FULL.

32.png

Я запускаю скрипт снова и когда программа остановится, я присоединяю снова IDA с анализом и локальным отладчиком WINDBG, как и раньше.

Логически, мы не имеет ту же информацию и программа падает, когда она переходит к выполнению.
Давайте посмотрим нашу кучу.

14.png

Статистики кучи такая.

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

15.png

И регистр EBP не меняется и поскольку мы знаем программу, мы будем делать чит, смотря на значение буфера, которое мы передали в функцию GETS_S, которое является началом выделенного блока потому. Теперь программа копирует его. Он передается в качестве агумента (очевидно мы можем это сделать, потому что это простая программа и для учебы, в противном случае, мы должны включить PAGE GUARD и делать то что мы видели раньше)

16.png

Переменная BUF продолжает указывать на начало кучи. Поэтому мы можем пойти туда.

17.png

18.png

BLOCK
LIST ENTRY поломан. Мы знаем это.

Очевидно, поскольку все поломано, мы постараемся присоединиться прежде чем куча сломается, чтобы увидить информацию о блоке. Хорошо. Я не могу запустить его непосредственно в IDA, потому что он запускается в режиме отладки в куче. Поэтому я буду помещать байты EB FE, чтобы программа зациклилась и когда я запущу его, я буду присоединиться к нему.

19.png

Я буду изменять байты 74 18 условного перехода на байты EB FE. После изменения я выбираю EDIT → PATCH PROGRAM APPLY PATCH TO INPUT FILE.

Сейчас я запускаю скрипт. Как только он зациклится, я останавливаюсь здесь. Но поскольку я уже прошел через MALLOC я уже могу увидеть кучу.

20.png

После выделения, в регистре EAX остается адрес блока.

21.png

Давайте посмотрим, что скажет нам команда.

22.png

USER как всегда является частью где Вы можете писать, а ENTRY это где начинается заголовок. Посмотрим на них.

23.png

Команда показывает только одну кучу, и вот где она. Давайте посмотрим её содержимое.

WINDBG>!heap -a 007a0000
Index Address Name Debugging options enabled
1: 007a0000
Segment at 007a0000 to 008a0000 (0004b000 bytes committed)
Flags: 00000002
ForceFlags: 00000000
Granularity: 8 bytes
Segment Reserve: 00100000
Segment Commit: 00002000
DeCommit Block Thres: 00000800
DeCommit Total Thres: 00002000
Total Free Size: 0000031b
Max. Allocation Size: 7ffdefff
Lock Variable at: 007a0138
Next TagIndex: 0000
Maximum TagIndex: 0000
Tag Entries: 00000000
PsuedoTag Entries: 00000000
Virtual Alloc List: 007a00a0
Uncommitted ranges: 007a0090
007eb000: 000b5000 (741376 bytes)
FreeList[ 00 ] at 007a00c4: 007e8ec0 . 007e4e90
007e4e88: 00028 . 00010 [100] - free
007a6750: 00028 . 00010 [100] - free
007a6158: 00050 . 00010 [100] - free
007e2d30: 00028 . 00018 [100] - free
007e2c58: 00210 . 00018 [100] - free
007e8eb8: 00078 . 01878 [100] - free

Segment00 at 007a0000:
Flags: 00000000
Base: 007a0000
First Entry: 007a0588
Last Entry: 008a0000
Total Pages: 00000100
Total UnCommit: 000000b5
Largest UnCommit:00000000
UnCommitted Ranges: (1)

Heap entries for Segment00 in Heap 007a0000
address: psize . size flags state (requested size)
007a0000: 00000 . 00588 [101] - busy (587)
007a0588: 00588 . 00240 [101] - busy (23f)
007a07c8: 00240 . 00020 [101] - busy (18)
007a07e8: 00020 . 01dd8 [101] - busy (1dce)
007a25c0: 01dd8 . 02d00 [101] - busy (2cf8)
007a52c0: 02d00 . 00048 [101] - busy (3c)
007a5308: 00048 . 00038 [101] - busy (30)
007a5340: 00038 . 00080 [101] - busy (78)
007a53c0: 00080 . 00080 [101] - busy (78)
007a5440: 00080 . 00048 [101] - busy (3c)
007a5488: 00048 . 00228 [101] - busy (220)
007a56b0: 00228 . 00050 [101] - busy (42)
007a5700: 00050 . 00080 [101] - busy (78)
007a5780: 00080 . 00018 [101] - busy (10)
007a5798: 00018 . 00050 [101] - busy (46)
007a57e8: 00050 . 00080 [101] - busy (78)
007a5868: 00080 . 00018 [101] - busy (10)
007a5880: 00018 . 00018 [101] - busy (10)
007a5898: 00018 . 00020 [101] - busy (14)
007a58b8: 00020 . 00070 [101] - busy (64)
007a5928: 00070 . 00208 [101] - busy (200)
007a5b30: 00208 . 00208 [101] - busy (200)
007a5d38: 00208 . 00030 [101] - busy (24)
007a5d68: 00030 . 00030 [101] - busy (24)
007a5d98: 00030 . 00038 [101] - busy (30)
007a5dd0: 00038 . 00028 [101] - busy (20)
007a5df8: 00028 . 00028 [101] - busy (20)
007a5e20: 00028 . 00028 [101] - busy (20)
007a5e48: 00028 . 00028 [101] - busy (20)
007a5e70: 00028 . 00018 [101] - busy (10)
007a5e88: 00018 . 00080 [101] - busy (78)
007a5f08: 00080 . 00080 [101] - busy (78)
007a5f88: 00080 . 00018 [101] - busy (10)
007a5fa0: 00018 . 00020 [101] - busy (14)
007a5fc0: 00020 . 00020 [101] - busy (10)
007a5fe0: 00020 . 00078 [101] - busy (6c)
007a6058: 00078 . 00080 [101] - busy (78)
007a60d8: 00080 . 00018 [101] - busy (10)
007a60f0: 00018 . 00018 [101] - busy (10)
007a6108: 00018 . 00050 [101] - busy (42)
007a6158: 00050 . 00010 [100]
007a6168: 00010 . 00058 [101] - busy (4a)
007a61c0: 00058 . 00080 [101] - busy (78)
007a6240: 00080 . 00020 [101] - busy (10)
007a6260: 00020 . 00018 [101] - busy (10)
007a6278: 00018 . 00080 [101] - busy (78)
007a62f8: 00080 . 00020 [101] - busy (10)
007a6318: 00020 . 00018 [101] - busy (10)
007a6330: 00018 . 00018 [101] - busy (10)
007a6348: 00018 . 00070 [101] - busy (68)
007a63b8: 00070 . 00080 [101] - busy (78)
007a6438: 00080 . 00018 [101] - busy (10)
007a6450: 00018 . 00070 [101] - busy (68)
007a64c0: 00070 . 00078 [101] - busy (70)
007a6538: 00078 . 00080 [101] - busy (78)
007a65b8: 00080 . 00020 [101] - busy (10)
007a65d8: 00020 . 00018 [101] - busy (10)
007a65f0: 00018 . 00020 [101] - busy (10)
007a6610: 00020 . 00078 [101] - busy (6a)
007a6688: 00078 . 00088 [101] - busy (7c)
007a6710: 00088 . 00018 [101] - busy (10)
007a6728: 00018 . 00028 [101] - busy (20)
007a6750: 00028 . 00010 [100]
007a6760: 00010 . 00080 [101] - busy (78)
007a67e0: 00080 . 00080 [101] - busy (78)
007a6860: 00080 . 03d20 [101] - busy (3d1f)
007aa580: 03d20 . 378b0 [101] - busy (378a8) Internal
007e1e30: 378b0 . 00080 [101] - busy (78)
007e1eb0: 00080 . 00020 [101] - busy (17)
007e1ed0: 00020 . 00400 [101] - busy (3f8) Internal
007e22d0: 00400 . 00400 [101] - busy (3f8) Internal
007e26d0: 00400 . 00080 [101] - busy (78)
007e2750: 00080 . 00080 [101] - busy (78)
007e27d0: 00080 . 00028 [101] - busy (20)
007e27f8: 00028 . 00028 [101] - busy (20)
007e2820: 00028 . 00070 [101] - busy (66)
007e2890: 00070 . 00080 [101] - busy (78)
007e2910: 00080 . 00028 [101] - busy (20)
007e2938: 00028 . 00028 [101] - busy (20)
007e2960: 00028 . 00070 [101] - busy (68)
007e29d0: 00070 . 00078 [101] - busy (6a)
007e2a48: 00078 . 00210 [101] - busy (208)
007e2c58: 00210 . 00018 [100]
007e2c70: 00018 . 00070 [101] - busy (66)
007e2ce0: 00070 . 00028 [101] - busy (20)
007e2d08: 00028 . 00028 [101] - busy (20)
007e2d30: 00028 . 00018 [100]
007e2d48: 00018 . 00078 [101] - busy (6c)
007e2dc0: 00078 . 02000 [101] - busy (1ff8) Internal
007e4dc0: 02000 . 00028 [101] - busy (20)
007e4de8: 00028 . 00028 [101] - busy (20)
007e4e10: 00028 . 00028 [101] - busy (20)
007e4e38: 00028 . 00028 [101] - busy (20)
007e4e60: 00028 . 00028 [101] - busy (20)
007e4e88: 00028 . 00010 [100]
007e4e98: 00010 . 00078 [101] - busy (6a)
007e4f10: 00078 . 00408 [101] - busy (400)
007e5318: 00408 . 00028 [101] - busy (20)
007e5340: 00028 . 00800 [101] - busy (7f8) Internal
007e5b40: 00800 . 006d0 [101] - busy (6c8)
007e6210: 006d0 . 00c08 [101] - busy (c00)
007e6e18: 00c08 . 00800 [101] - busy (7f8) Internal
007e7618: 00800 . 00228 [101] - busy (220)
007e7840: 00228 . 00228 [101] - busy (220)
007e7a68: 00228 . 00490 [101] - busy (483)
007e7ef8: 00490 . 00218 [101] - busy (209)
007e8110: 00218 . 00058 [101] - busy (4a)
007e8168: 00058 . 00808 [101] - busy (800)
007e8970: 00808 . 00088 [101] - busy (80)
007e89f8: 00088 . 00448 [101] - busy (440)
007e8e40: 00448 . 00078 [101] - busy (6c)
007e8eb8: 00078 . 01878 [100]
007ea730: 01878 . 00100 [101] - busy (f4)
007ea830: 00100 . 00038 [101] - busy (2e)
007ea868: 00038 . 00030 [101] - busy (28)
007ea898: 00030 . 00040 [101] - busy (37)
007ea8d8: 00040 . 00048 [101] - busy (3c)
007ea920: 00048 . 00040 [101] - busy (31)
007ea960: 00040 . 00030 [101] - busy (24)
007ea990: 00030 . 00040 [101] - busy (32)
007ea9d0: 00040 . 00038 [101] - busy (2e)
007eaa08: 00038 . 00038 [101] - busy (2c)
007eaa40: 00038 . 00030 [101] - busy (28)
007eaa70: 00030 . 00030 [101] - busy (21)
007eaaa0: 00030 . 00020 [101] - busy (15)
007eaac0: 00020 . 00038 [101] - busy (2b)
007eaaf8: 00038 . 00030 [101] - busy (22)
007eab28: 00030 . 00038 [101] - busy (2e)
007eab60: 00038 . 00048 [101] - busy (39)
007eaba8: 00048 . 00020 [101] - busy (17)
007eabc8: 00020 . 00040 [101] - busy (36)
007eac08: 00040 . 00050 [101] - busy (47)
007eac58: 00050 . 00050 [101] - busy (48)
007eaca8: 00050 . 00020 [101] - busy (12)
007eacc8: 00020 . 00020 [101] - busy (18)
007eace8: 00020 . 00030 [101] - busy (24)
007ead18: 00030 . 00038 [101] - busy (29)
007ead50: 00038 . 00098 [101] - busy (8b)
007eade8: 00098 . 00020 [101] - busy (17)
007eae08: 00020 . 00020 [101] - busy (11)
007eae28: 00020 . 00020 [101] - busy (18)
007eae48: 00020 . 00020 [101] - busy (17)
007eae68: 00020 . 00030 [101] - busy (21)
007eae98: 00030 . 00020 [101] - busy (13)
007eaeb8: 00020 . 00020 [101] - busy (14)
007eaed8: 00020 . 00020 [101] - busy (16)
007eaef8: 00020 . 00030 [101] - busy (28)
007eaf28: 00030 . 00030 [101] - busy (27)
007eaf58: 00030 . 00060 [101] - busy (52)
007eafb8: 00060 . 00028 [101] - busy (12)
007eafe0: 00028 . 00020 [111] - busy (1d)
007eb000: 000b5000 - uncommitted bytes.

Если мы посмотрим в список, там будет блок. Если мы найдем его по адресу заголовка, то программа сообщит нам его размер.

24.png

25.png

Он больше не показывает нам историю, хотя, если размер, общий размер равен 0xF, потому что, чтобы найти общее количество, программа умножает на 8, что даёт нам.
hex(0xf *0x8)
'0x78'

Это полный размер с заголовком и концевиком и т.д.

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

26.png

Проблема заключается в том, что они закодированы (XOR) константой. Где мы можем найти константу чтобы раскодировать(UNXOR) их.

27.png

Мы видим, что поле смещению 0x50 структуры кучи называется ENCODING

WINDBG>dd 007a0000+ 0x50 L2
007a0050 4ede14ce 000068d6

Это те DWORDS, которые зашифровывают информацию.

28.png

Если мы сделаем то же самое в заголовке разделив его на два DWORDS.

dd 007E8E40 L2

У меня есть два DWORDS, которые мне нужны, чтобы зашифровать две записи.

WINDBG>dd 007a0000+ 0x50 L2
007a0050 4ede14ce 000068d6

WINDBG>dd 007E8E40 L2
007e8e40 40df14c1 0c00685f

Я зашифровываю

WINDBG>? 4EDE14CE ^ 40DF14C1
Evaluate expression: 234946575 = 0E01000F

WINDBG>? 68D6 ^ 0C00685F
Evaluate expression: 201326729 = 0C000089


Мы можем создать небольшую таблицу. Очевидно, мы сломаем программу и не сможем запустить её больше, но один раз это можно сделать.

29.png

Я заменяю значения, чтобы зашифровать.

30.png

31.png

Поскольку, в этом случае размер равен 0xF, мы должны умножить его на 8, чтобы найти общие размер и это даёт мне 0x78. То же самое у меня получилось в начале где включен заголовок и концевик.

Хорошо. Мы медленно наблюдаем и знакомимся с блоками кучи. В следующий раз, мы увидим, что MONA расскажет нам об этом. Поможет она нам или нет.

=======================================================

Автор текста: Рикардо Нарваха - Ricardo Narvaja (@ricnar456)
Перевод на английский: IvinsonCLS (@IvinsonCLS)
Перевод на русский с испанского+английского: Яша_Добрый_Хакер(Ростовский фанат Нарвахи).
Перевод специально для форума системного и низкоуровневого программирования — WASM.IN
02.05.2018
Версия 1.0

1 5.171
yashechka

yashechka
Ростовский фанат Нарвахи

Регистрация:
2 янв 2012
Публикаций:
90