1nzag

[reversing.kr]Direct3D FPS Writeup

wargame/reversing.kr

솔직히 이번문제는 엄청난 게싱으로 푼거 같다.


바이너리를 열었더니 FPS 게임이 나왔고, 몬스터를 총으로 쏴서 잡을 수 있었다. 왠지 몬스터를 다 잡으면 플래그가 나올것 같았다.

근데 게임이 너어무 느려서 이대로 몬스터를 다 잡다간 정신이 나갈거 같아서 그냥 정적분석을 했다.


일단 바이너리가 너무 커서 바이너리에 의미있는 스트링이 있는지 확인하였다.

다행히 바이너리에서 검색된 문자열은 얼마 없었고, 의미있는 문자열이 나왔다. 이 문자열을 참조하는 코드를 확인해보았다.

뭔가 보니 위의 count 값을 result가 넘을시 게임이 클리어 되는 것을 보아 result 는 잡은 몬스터의 수와 관련이 있는 것 같다. 그리고 클리어 할 시에 arr_byte 의 스트링을 출력하는데 막상 해당 문자열을 보면 의미있는 문장이 나오지 않기 때문에 암호화 되어있는 것으로 예측했다.


위의 count 값이나 status 배열을 참조하는 코드를 찾아보았다.

status를 참조하는 코드를 찾아봤더니 다음과 같은 루틴이 있었다. arr_byte 에 byte 의 일부분을 xor 하는 것으로 보아 byte 배열 값을 가져오면 플래그 값을 복호화 하여 찾아올수 있다는 것을 알 수 있었다. 

문제는 byte 배열의 어느 인덱스를 찾아오느냐였다. 

인덱스와 관련된 sub_1323440 함수 부분에 들어가봤더니 값은 1의 배수 형태로 리턴을 한다는 것을 알 수 있었다. 아마도 내가 잡은 몬스터나 아니면 몬스터의 번호를 리턴하는것 같다. 0x84 의 크기로 몬스터의 객체가 배열에 저장되어있고, 객체에 몬스터의 HP 정보가 저장되어있는것으로 보인다.

그리고 몬스터의 HP 가 0이 되면 잡은 몬스터의 index 와 관련된 부분의 주소부분에 해당된 암호화된 플래그값을 복호화 하는 것 같다.

어쨌든 중요한건 byte 배열의 값이니, 디버거를 붙인 후에 byte 에 있는 값을 무작정 덤프했다.

몬스터가 몇마리나 있는지는 모르지만 arr_byte 가 있는 부분으로부터 적당히 0x100 개 만큼 값을 덤프하고 byte 배열부분은 해당 arr_byte의 값을 커버할 수 있는 0x100 * 4 * 0x84 만큼을 덤프 한 뒤 복호화 루틴에 돌렸다.


from pwn import *



data = open("dump", "rb").read()

key = open("key", "rb").read()



res = ""

for i in range(len(key)):

res += chr(ord(key[i]) ^ ord(data[(i * 0x84) * 4]))



print hexdump(res)

 될까 했는데 정말 플래그가 떠버렸다 ;;


이걸로 reversing.kr의 쉬운문제는(대략 600명 이상 푼 문제) mp3 문제 빼고는 다 푼것같다. 대체로 난이도가 쉬운편이거나 직감이 잘 떨어져서 빠르게 문제를 푼것 같다. 

mp3문제는 바이너리가 너무 크고 익숙하지도 않고 뭔가 감도 잘 오지 않아서 나중에 여유로우면 풀어야 겠다 ;;


나머지 문제들은 ctf 문제를 풀면서 간간히 같이 풀어야겠다.

'wargame > reversing.kr' 카테고리의 다른 글

[reversing.kr]Position Writeup  (0) 2018.08.02
[reversing.kr] ransomware writeup  (0) 2018.08.02