IMyoungho 2019. 4. 29. 00:45

이번 문제는 Poet이다. 생각보다 쉬웠다.




 NX만 걸려있었고 RELRO는 Partial이었다.

힙, 스택, 데이터 영역에 실행권한이 없었고

got overwrite는 가능하다는 걸 알 수 있었다.




문제를 실행시켜보도록 하겠다.

뭔가 값을 입력받고나서 저자가 누구인지 물어본다.

총 2번의 입력을 사용자로부터 받고 있었고

출력된 문자열을 보니 1000000점을 

획득해야한다는 것을 알 수 있었다.




이번에는 IDA를 이용해서 코드를 보도록 하겠다.

main함수를 보니 총 4가지의 함수가 돌고 있었고

각각의 함수를 살펴보기로 했다. 또한 dowrd 6024E0이라는

변수는 1000000이여야 while문을 탈출하고 reward 함수를

호출하는 것으로 보아 점수에 해당하는 변수임을 알 수 있었다.





첫 번째로 호출되는 get_poem 함수는 poem변수에

입력을 받고 아까 위에서 봤던 점수를 뜻하는 dword_6024E0을

0으로 초기화 시키고 있었다.





두 번째로 호출되는 함수인 get_author을 보면

딱히 별 건없고 unk_6024A0에 gets로 입력을 받고 있었다.






세 번째로 호출되는 rate_poem함수를 보면 특정 문자열을

입력했을 시 100점씩 점수가 오른다는 것을 알 수 있었다.





마지막으로 호출되는 reward 함수는 while문을 탈출해야만

실행되는데 내용은 flag를 보여주도록 되어있었다.




지금까지 진행한 것으로 생각해보았을 때 알 수 있던 것은

점수를 10000000을 맞아야 한다는 것과 이 점수를 저장하는

변수가 존재한다는 것이고 이 변수는 고정주소를 가진 bss영역에

존재하고 있는 전역변수로 선언되었다 라는 것이다. 또한

두 번째로 호출된 함수 get_author에서 입력을 받는 변수인

unk_6024A0 또한 bss영역에 속하는 변수임을 알 수 있었다.

그렇다면 우리는 이 점들을 이용해서 문제를 풀어야한다.




우리의 목적은 결과적으로 점수이기 때문에

사용자가 함수에서 원하는 문자열을 입력하였을 때

100점을 얻게되는 부분을 우선적으로 확인해보았다.

rate_poem 함수에서 strcmp하는 조건문 다음에

조건과 일치할 시 점수가 100점 상승하는 부분인데

rip+0x201bAE에 존재하는 값을 100점을 올리는 것으로 보아

이 부분이 dword_6024E0라는 것을 알 수 있었고 그 주소는

rip + 0x201bAE는 0x6024E0이라는 것을 알 수 있었다.



이전에 실행했던 get_author함수에서 우리는 두 번째 입력이

가능했는데 그 부분의 변수 또한 전역변수에 값을 입력하는

gets함수가 존재했었다. 그러므로 그 부분을 다시 확인해보았다.




이 함수에서 호출되는 gets에 "aaaa"를 입력하였는데

이 값이 저장되는 변수인 전역변수 unk_6024A0이

주소 0x6024A0라는 것을 알 수 있었다. 그러므로

우리는 여기서 호출되는 gets가 BOF를 일으킬 수 있음을

이용하여 점수를 의미하는 변수 dword_6024E0 값을

1000000으로 만들어주면 된다는 것을 알 수 있었다.

두 변수간의 거리는 64개임을 확인하였고  그 다음 부분을

덮어쓰게되면 우리는 점수를 조작할 수 있을 것이다.



그럼 이제 Payload를 구성해보도록 하겠다.

나는 sleep로 100점을 얻고 시작하고 싶어서

이런식으로 진행하였다.ㅎㅎ 999900인 상태에서

rate_poem이 호출되면 sleep을 입력했으므로

100을 더해줘 1000000이 될 것이다ㅎㅎ 이런식으로

Payload를 구성해서 진행하게되면~




while문을 탈출하여 reward 함수가 실행되면서

FLAG를 볼 수 있게 된다~

반응형