Я пытаюсь использовать данную программу и не могу понять, что я делаю неправильно.Короче говоря, мне удается внедрить код для перезаписи 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, но это все.Ребята, что происходит?