본문 바로가기

[Wargame Write-up]/HellBoundHackers

[HellBoundHackers] [Application Cracking] Application Cracking 10

Application Cracking 10번째 문제이다.


이제부터 난이도 Hard가 계속되는데, 뭔가 기대된다.




Form과 실패 시 표시되는 메시지박스이다.


        



실패 메시지를 찾아오면, 다음과 같은 루틴을 볼 수 있다.


40307E에 목표로 하는 문자열이 들어 있다. 입력값에 대한 어떤 연산의 결과가 이 문자열과 같은지 비교 후, 그에 따라

분기하게 된다.




입력값으로 연산하는 부분이다.


9번 문제처럼 입력값에서 8번째 문자까지만 연산에 활용되고 있는 것을 알 수 있다.


8글자를 반씩 쪼개, 앞의 4글자는 첫 번째 key(0x13579abc), 뒤의 4글자는 2번째 key(0xfedcba98)로 XOR 연산을 한 후,


MOV 연산을 통해 이어 붙인다. (401148~40114D)




이후에는 9번 문제에서 봤던 긴 루틴을 실행한다.


실행 전후의 차이점을 확인해, 이 루틴의 기능을 파악하도록 하자.




실행 전의 ASCII 영역이다. a 9개를 입력했을 때의 XOR 결과가 다음과 같이 들어있다.




다음은 긴 루틴 이후의 결과 화면이다. 결과값을 4바이트씩 끊어서, Little Endian 방식으로 각 바이트를 문자화시킨다.


예를 들어, 0x72를 "72"로 바꾸는 작업을 하는 것이고, 0xDD, 0xFB, 0x36, 0x72 순으로 들어 있는 것을 뒤집어서 72, 36, FB, DD 순으로 String 형태로 넣는다.




이제, 목표 문자열에 대한 입력값을 찾기 위해 XOR 연산 부분을 재조명해야 한다.


'a'(0x61) 9개를 입력했을 때의 연산 결과가 7236FBDD9FBDDBF9였다.


아래를 보면, 위에서 분석한 대로 결과가 나오는 것을 알 수 있다. 앞의 0x, 뒤의 L만 빼버리고 이어 붙이면 Ollydbg에서 봤던


결과가 된다.




간단하게 이렇게 코딩할 수 있다. (앞에서 목표 문자열을 가린 관계로, 여기서도 *로 마스킹하였다.)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def main():
    key = [0x13579abc0xfedcba98]
    goal = "****************"
    decrypted_hex_string = ""
    decrypted = ""
 
    for i in range(2):
        decrypted_hex_string += hex(int(goal[i*8:i*8+8], 16) ^ key[i]).replace("0x""").replace("L""")
 
    decrypted_hex_string = decrypted_hex_string.upper()
 
    for i in range(0len(decrypted_hex_string), 2):
        decrypted += chr(int(decrypted_hex_string[i:i+2], 16))
 
    print "\nDecrypted: " + decrypted
 
 
if __name__ == '__main__':
    main()
cs



결과는 다음과 같이 나온다.




인증키를 확인하기 위해, 입력해 보자.




입력값과 인증키가 같다고 한다. 


사실, 메시지 분기점 이후, lstrcat 함수로 성공 메시지 text를 구성하게 되는데, 403104 주소(입력값이 들어가는 주소)의 문자열이 쓰이는 것을 보고, 입력값=인증키 관계를 파악할 수도 있다.