메로나

[HackCTF] Offset (150) write-up 본문

Wargame & CTF/Pwnable

[HackCTF] Offset (150) write-up

m3r0n4 2020. 8. 11. 22:01

추천받은 오마이걸 효정... 아름다우십니다

어떤 보호기법이 걸려있는지 보자.

카나리를 제외한 모든 보호기법이 걸려있다. ASLR이 활성화되어 있기 때문에 프로그램을 실행할 때 마다 함수의 주솟값이 임의로 바뀌게 된다.

메인 함수를 Hex-Ray로 보면, gets함수로 s에 불러오고 싶은 함수의 이름을 받아오고, select_func 함수를 이용해 그 함수를 불러오는 것 같다. select_func 함수를 Hex-Ray로 보면, 

v3에 처음엔 two를 넣고, dest에 처음 받아온 s를 31바이트 복사해온 다음 dest가 one이라면 one함수를 불러온다.

dest와 v3의 offset이 2A - C = 30인데 dest에는 총 31바이트를 받아올 수 있으므로 v3의 마지막 1바이트를 임의로 조작할 수 있다. 다시 프로그램으로 돌아가 심볼을 한번 본다면,

누가 봐도 flag를 받아오는 함수가 존재한다. 과연 마지막 1바이트를 조작하는것으로 two에서 print_flag 함수로 바꿀 수 있을까?

결론은 있다. 

two
print_flag

two 함수의 시작주소는 0x000006AD이고, print_flag 함수의 시작주소는 0x000006D8이다. PIE로 인해 함수의 주솟값이 늘 바뀌더라도 함수 간 오프셋은 일정하다. two 함수의 마지막 1바이트를 바꾸는것만으로 two 함수를 print_flag 함수로 바꿀 수 있기 때문에 최종적으로 print_flag 함수를 불러올 수 있게 된다.

익스플로잇 코드는

Dummy(30) + offset(\xD8)

이다. 이를 이용해 코드를 작성해 보면 아래와 같다.

실행 해 보면,

플래그를 읽어 올 수 있게 되었다.