Shellcode基础
基本原理
- shellcode通常是一小段用于利用软件漏洞的机器代码,目的是为了获得目标机器的shell
- 本地shellcode常用于提权,攻击者利用高权限程序中的漏洞获得与目标进程相同的权限
- 远程shellcode通过TCP/IP套接字为攻击者提供shell访问(反弹shell、绑定shell、套接字重用shell)
- shellcode可分段执行,由一段短的shellcode去加载一段复杂的shellcode
编写
C语言
- C编写简单shellcode
1 |
|
- 执行效果如下,可以看到已经拿到shell

- C语言使用内联汇编方式调用shellcode,使用的shellcode为汇编生成的opcode(先看汇编那一节)
1 |
|
1 | # -z execstack用于禁用NX保护机制 |
汇编
- 21个字节实现
execve("/bin/sh")的Linux 32位程序(2种都可以)
1 | ; shell1 |
1 | ;shell2 |
push的理解
/bin/sh用16进制表示为2f62696e2f7368- 由于是小端序,因此
/sh=0x68 0x73 0x2f,由于不足4个字节,用'/' (0x2f)补足即"//sh" = 0x68732f2f - 同理,
"/bin" = 0x6e69622f - 压栈顺序:h >> s >> / >> / >> n >> i >> b >> /
xor的理解
- shellcode中不能包含NULL,因为NULL会将字符串操作函数阶段,这样执行的shellcode就会被截断
xor ecx, ecx用于替换mov ecx, 0x00
寄存器的理解
mov ebx, esp:将栈顶指针赋给ebxmov eax, 0xb:0xb = 11,execve的系统调用号为11xor ecx(edx), ecx(edx):清空ecx和edx寄存器
软中断
由于一般shellcode有长度限制而且我们不知道系统函数地址,无法直接调用
- 触发中断(int 0x80或者syscall)进行系统调用
system("/bin/sh")底层是调用execve("/bin/sh",0,0)
1 | # 编译 |

因此shellcode为"\x68\x2f\x73\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb8\x0b\x00\x00\x00\xcd\x80"
shell2的shellcode为"\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
gdb详细信息如下

- Linux 64位 shellcode30字节
1 | global _start |
- 编译并链接
1 | # 注意现在是64位了 |

python
- 使用pwntools生成shellcode
1 | from pwn import * |
