[문제]
[풀이]
바이너리를 실행해보면 1000000점수를 획득해야 flag를 출력할 것으로 보인다.
RELRO가 Partial인 것으로 보아 GOT Overwrite가 가능하고, shellcode 삽입은 불가하다.
main 함수를 확인해보면 get_poem, get_author, rate_poem 함수를 호출한 후, 점수가 1000000이면 reward 함수를 호출하면서 무한루프를 탈출한다.
각각의 함수들을 살펴보면 get_poem, get_author함수에서는 단순히 gets함수로 시와 작가를 입력받고 있다. 여기서 gets 함수 때문에 BOF를 발생시킬 수 있을 것으로 보인다.
rate_poem 함수를 통해 입력 값을 검증하고 있는데, strcmp 함수 속에 있는 local_10이 poem 값인 것으로 보아 poem 입력 부분만 신경쓰면 점수를 획득할 수 있다. 입력 값들을 비교하여 맞다면 100점을 추가해주는 형태로 코드가 설계되어 있다.
마지막으로 reward 함수를 확인해보면, 점수가 1000000이면 flag.txt를 읽어와서 출력해주도록 되어 있다.
그렇다면 점수를 어떻게 1000000으로 만들어주느냐가 관건인데, 비교 문자열을 만 번이나 입력해주는 것은 무리일 것이고 점수가 저장되는 부분을 찾아 1000000으로 만들어주면 exploit할 수 있을 것으로 보인다.
이에 gdb를 실행하여 입력값에 sleep을 입력해 실행해보았다.
poem에 sleep, author에 aaaa를 입력한 후 문자열 비교까지 진행한 캡쳐이다. rax에 0x64(100)이 저장되어 있고, 이는 100점을 획득했음을 의미한다. sleep 문자열이 저장된 곳을 찾아보면 다음과 같다.
필요 부분만 잘라서 확인해보면 poem 시작부분에 sleep이, poem+1024에 author가 저장되어 있음을 확인할 수 있다.
100점이라는 점수는 poem+1088에 저장되는 것을 알 수 있다.
그렇다면, poem에는 길이를 신경쓰지 않고 dummy를 채우고 상대적으로 점수가 저장된 곳과 가까운 author 부분에 둘 사이의 offset만큼의 dummy를 채우고 poem+1088에 1000000을 넣어주면 exploit할 수 있을 것으로 보인다.
author와 점수가 저장되는 부분의 offset은 0x40(64)이다.
'Wargame > HackCTF' 카테고리의 다른 글
[HackCTF] Random_key (1) | 2021.08.23 |
---|---|
[HackCTF] 1996 (0) | 2021.08.23 |
[HackCTF] yes_or_no (0) | 2021.08.15 |
[HackCTF] BOF_PIE (0) | 2021.07.26 |
[HackCTF] Offset (0) | 2021.07.25 |