2016 HDCON crackme(500)

Reversing/리버싱 문제풀이

2016. 10. 25. 22:18



프로그램이 너무 복잡하다.

내가 분석한결과는 위에처럼 함수가 구성되어있다.

무언가를 print를 해주는 비슷한 함수가 2개 있고,

input을 받는 함수, 그리고 너무커서 분석도 잘안되는 nodap함수, main함수 이렇게 크게 나눠진다.





함수마다 대충 구조가 위에 처럼 생겨먹었다

일단 위의 그래프는 신경안쓰고 생각을 해봤다.

crackme문제이기 때문에 입력이 맞으면 플래그를 출력해줄것이라고 예상을 했다.


입력을 하는 함수안에 분명히 힌트가 있을 것이고

답은 괄호안에있다고 했는데 print함수 2개에는 괄호가 없다.

따라서 input함수에서 제대로 정답을 맞추면 nodap함수에서 플래그를 출력해준다고 예상을했다.





user_input함수 안을 보면 위와 같이 특정변수들이 아스키값에대해서 비교연산을 계속 하고 있는것을 확인했다.








그래서 살펴보니 user의 입력이 저장되는 buf(v51)부터 v75까지 각각 이러한 아스키값비교를 1~3번씩 하는 것을 확인했다.

그래서 각 자리의 글자를 알아내고 모든 경우의수를 뽑아보면 답이 나오지 않을까 싶어서 c코드를 긁어서 파싱하는 코드를 짯다.




각 글자별로 리스트를 뽑아보니 위와같은 결과가 나왔다.

대충 봐도 확실한 글자는 몇개 보인다.

나는 Your_Passw0rd 문자열을 고정시켜놓고

BFS를 하는 재귀코드를 대충짜서 출력을 시켜보았다.





제일 말이 맞는것이 show_Me_The_Your_Passw0rd 이다.

( 대회때는 피곤하고 정신이없어서 sHow_Me_The_Your_Passw0rd 로 계속 인증해서 못풀었다;;)




위의 키를 입력하면 플래그가 나온담







def parse_key() :
    code = open('ccode.txt', 'r').read().split('\n')
    key = [ [] for i in range(51,76) ]
    for line in code :
	if 'v' in line and 'if' in line :
            idx = line.index('v')
            num = int(line[idx+1:idx+3])
            if 51 <= num <= 75 :
		tmp = line.split('(')[1].split(')')[0].split()
		if tmp[1] != '==' and tmp[1] != '!=' :
                    continue
		key[num-51].append(chr(int(tmp[2])))
    return key

def make_key(index=0, _str='') :
    if len(key) == index :
        if 'Your_Passw0rd' in _str :
            print _str
        return
    for i in key[index] :
        make_key(index+1, _str + i)

if __name__ == '__main__' :
    key = parse_key()
    make_key()