我正在学习计算机安全的基础知识,并且我正在尝试执行一些我写过的shellcode。我按照这里给出的步骤进行了
http://dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf
http://webcache.googleusercontent.com/search?q=cache:O3uJcNhsksAJ:dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf+own+shellcode&cd=1&hl=nl&ct=clnk&gl=nl
$ cat pause.s
xor %eax,%eax
mov $29,%al
int $0x80
$ as -o pause.o pause.s
$ ld -o pause pause.o
ld: warning: cannot find entry symbol _start; defaulting to <<some address here>>
$ ./pause
^C
$ objdump -d ./pause
pause: file format elf64-x86_64
Disassembly of section .text:
08048054 <.text>:
8048054: 31 c0 xor %eax,%eax
8048056: b0 1d mov $0x1d,%al
8048058: cd 80 int $0x8
$
由于我的暂停程序正常工作,我只是将objdump输出复制到c文件中。
test.c的:
int main()
{
char s[] = "\x31\xc0\xb0\x1d\xcd\x80";
(*(void(*)())s)();
}
但这会产生段错误。现在,这只能归功于Arch Linux(?)的安全措施。那我怎么能让它发挥作用呢?
答案 0 :(得分:7)
生活在页面s
未映射到执行权限。因为你在x86_64上,你肯定在硬件上有NX支持。默认情况下,这些天代码和数据存在于非常独立的页面中,数据没有执行权限。
您可以使用mmap()
或mprotect()
解决此问题,以分配或更改网页以获得PROT_EXEC
权限。
答案 1 :(得分:0)
您还可以使用#define来定义shellcode。这样预处理器就会将代码直接插入到主
中 #define SHELLCODE "\x31\xc0\xb0\x1d\xcd\x80"
int main()
{
(*(void(*)())SHELLCODE)();
}
由于安全措施,较旧的编写shellcode样式不适用于较新的系统。 您可能还必须在关闭堆栈保护的情况下进行编译:
gcc -z execstack -fno-stack-protector shellcode.c -o shellcode
这是一个完整的工作示例,它使用我在3.2.0.3内核x86_64上测试的退出系统调用:
#include<stdio.h>
#define SHELLCODE "\x48\xc7\xc0\x3c\x00\x00\x00\x48\xc7\xc7\xe7\x03\x00\x00\x0f\05"
main()
{
int (*function)();
// cast shellcode as a function
function = (int(*)())SHELLCODE;
// execute shellcode function
(int)(*function)();
return 0;
}
shellcode使用64位寄存器,因此无法在32位机器上运行。 要验证代码是否有效,可以使用strace进行测试:
strace shellcode
execve("./shellcode", ["shellcode"], [/* 38 vars */]) = 0
....
munmap(0x7ffff7fd5000, 144436) = 0
_exit(999) <---- we passed 999 to exit, our shellcode works!