Невозможно ввести правильный указатель инструкции во время эксплойта - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь использовать данную программу и не могу понять, что я делаю неправильно.Короче говоря, мне удается внедрить код для перезаписи RIP.Это означает, что я должен иметь возможность перенаправить выполнение кода, но проблема в том, что я получаю SIGSEGV.Нужно ли разрабатывать инъецированный стек особым образом, чтобы не получать SIGSEGV?

Мой план игры состоит в том, чтобы использовать функцию mainloop и изменить обратный адрес.Стек для функции mainloop имеет следующие значения:

0000| 0x7fffffffdff0 --> 0xa7400ffffe010 
0008| 0x7fffffffdff8 --> 0xf423f55758260 
0016| 0x7fffffffe000 --> 0x7fffffffe010 --> 0x5555555550b0 (<__libc_csu_init>:  push   r15)
0024| 0x7fffffffe008 --> 0x5555555550a4 (<main+66>: mov    eax,0x0)

Таким образом, обратный адрес хранится в 0x7fffffffe008, и мне удалось перезаписать это значение адресом, указывающим на код, который я хочувыполнить.В этом случае адрес 0x555555554e6e.

Обратный след программы выглядит следующим образом:

#6  0x0000555555554fab in mainloop ()
#7  0x00005555555550a4 in main ()
#8  0x00007ffff7e1109b in __libc_start_main (main=0x555555555062 <main>, argc=0x1, argv=0x7fffffffe0f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
stack_end=0x7fffffffe0e8) at ../csu/libc-start.c:308
#9  0x000055555555486a in _start () 

Как видите, когда я выйду из mainloop, я вернусь к main, и когда я выхожу из main, я перехожу к куче libc-функций, чтобы программа выходила чисто (?).

Так что же происходит, когда я запускаю свой код эксплойта?Это:

0000| 0x7ffe1b3d4150 --> 0x424142001b3d4170 
0008| 0x7ffe1b3d4158 ("ABABABABABABABABnNUUUU")
0016| 0x7ffe1b3d4160 ("ABABABABnNUUUU")
0024| 0x7ffe1b3d4168 --> 0x555555554e6e ('nNUUUU')
0032| 0x7ffe1b3d4170 --> 0x55a34784000a 
0040| 0x7ffe1b3d4178 --> 0x7f7c156c409b (<__libc_start_main+235>:      mov    edi,eax)
0048| 0x7ffe1b3d4180 --> 0x0 
0056| 0x7ffe1b3d4188 --> 0x7ffe1b3d4258 --> 0x7ffe1b3d5474 ("./device")

То, что вы видите, это стек.Я добавил несколько байтов, чтобы вы могли получить больше контекста.Но я думаю, что мне удалось выбрать правильный размер наполнителя для моего подвига.Мне удалось изменить значение в байте 24.

Но моя PEDA / GDB, похоже, не считает это значение указателем инструкции, что странно.Кажется, это рассматривается как C-струна (?).Обратная трассировка выглядит следующим образом:

#6  0x000055a347849fab in mainloop ()
#7  0x0000555555554e6e in ?? ()
#8  0x000055a34784000a in ?? ()
#9  0x00007f7c156c409b in __libc_start_main (main=0x55a34784a062 <main>, argc=0x1, argv=0x7ffe1b3d4258, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
stack_end=0x7ffe1b3d4248) at ../csu/libc-start.c:308
#10 0x000055a34784986a in _start () 

И когда я выхожу mainloop, я получаю в PEDA / GDB следующее:

Stopped reason: SIGSEGV
0x0000555555554e6e in ?? ()

И если я запускаю команду i f вGDB я получаю:

Stack level 0, frame at 0x7ffe1b3d4178:
 rip = 0x555555554e6e; saved rip = 0x55a34784000a
 called by frame at 0x7ffe1b3d4180
 Arglist at 0x7ffe1b3d4168, args: 
  Locals at 0x7ffe1b3d4168, Previous frame's sp is 0x7ffe1b3d4178
 Saved registers:
  rip at 0x7ffe1b3d4170 

По адресу 0x0000555555554e6e программа выполняет следующий ASM:

0x0000555555554e6e <+172>:  lea    rdi,[rip+0x20126b]        #    0x5555557560e0 <flag2>

Так что, похоже, у меня есть правильный RIP, но это все.Ребята, что происходит?

1 Ответ

0 голосов
/ 19 февраля 2019

GDB (по умолчанию) отключает ASLR при запуске программы из GDB.В исполняемом файле PIE статический код / ​​адреса данных рандомизированы.Внедрение обратного адреса работает, только если вы знаете правильный абсолютный адрес.

Но, очевидно, вы иногда запускаете свою программу вне GDB, где адреса не всегда одинаковы .Это, очевидно, приводит к segfault, и ваш вопрос не показывает разборку с фактическим 0x0000555555554e6e в фактическом процессе, который segfailed, вопреки тому, что вы утверждали / предполагали.

(GCC делает PIE исполняемыми файламипо умолчанию в Linux это недавно: если вы следовали старому учебнику, он мог бы предположить, что сам исполняемый файл зависел от позиции, и только библиотеки + стек будут иметь ASLR. 32-битные абсолютные адреса больше не разрешены вx86-64 Linux? )

См. Отключение рандомизации адресов памяти для общесистемного или межпроцессного способа отключения ASLR или создания исполняемых файлов без PIE.

...