현재 대학에서 듣고 있는 역공학 수업에서 레포트 과제를 받았다.
수업시간에 abex' crackme와 지뢰찾기 게임을 IDA와 immunity dedugger를 왔다갔다 하면서 역분석 하는 것을 보여주셨었는데, 그것을 참고하여 교수님이 주신 두 문제를 역분석하여 풀어내는 과제이다.
그중에서 이번에 풀어볼 문제는 저번 글에 이어서 두번째 문제인 Crackme2에 해당한다.
이전글 바로가기
이 문제를 cmd 창에서 실행 시켜 보았을 때, Crackme1과 동일하게 Password를 입력받고, Password 가 맞는지 판단하여 결과를 출력해주는 것을 알 수 있다.
앞에서와 동일한 과정으로, IDA를 통해서 흐름 그래프를 살펴보면, Password를 입력 받고, 조건에 따라 다음과정으로 분기하여(초록 화살표의 의미) “>> No Password” 혹은 “>> Success!!”를 출력하게 되는 흐름은 앞과 동일하다.
그러나, 두 코드의 흐름그래프를 비교해보았을 때, 다른점이 파란색으로 네모표시를 해둔 ’43h‘ 부분이다. 이전의 Crackme1에서는 ’xor eax, 8’ 이었지만 현재 문제에서는 ‘xor eax, 43h’ 임을 알 수 있다. 이 점에 주목하여 의사코드를 살펴보자.
19번째 줄이 ‘xor eax, 43h’ 부분이다.
Crackme1과 동일한 Password 저장과 비교 과정을 가지지만, 다른 점하나가 19번째 줄에서 xor 연산을 하는 과정인데, 이것을 고려하여 연산을 하는 poc를 짜야한다.
앞과 동일하게 unk_403040 에 비밀번호가 저장이 되어있으므로, 배열의 원소를 가져오면,
[0x30, 0x2B, 0x2C, 0x30, 0x2B, 0x23, 0x1A, 0x27, 0x39, 0x2B, 0x2A, 0x23, 0x22, 0x2B, 0x6E, 0x7E, 0x0C, 0x19, 0x34, 0x39, 0x14, 0x3E, 0x3A, 0x3D] 이고, 이를 리스트로 나열하고, 리스트의 각 요소에 대해 XOR 연산을 수행하고, 그 결과를 문자로 변환하여 하나의 문자열로 연결하여 출력하는 코드를 python으로 작성하면,
enc_flags = [0x30, 0x2B, 0x2C, 0x30, 0x2B, 0x23, 0x1A, 0x27, 0x39, 0x2B, 0x2A, 0x23, 0x22, 0x2B, 0x6E, 0x7E, 0x0C, 0x19, 0x34, 0x39, 0x14, 0x3E, 0x3A, 0x3D]
print("".join([chr(c ^ 0x43 ^ i) for (i, c) in enumerate(enc_flags)]))
코드를 실행시켜보면 Password를 얻을 수 있다.
Success!! 라는 문구를 통해 Password가 일치한다는 것을 알 수 있다.
Crackme1과 많이 유사해서 금방 쉽게 풀었던 문제인 것 같다.
다만, 코드 작성과정에서 전과는 다른 연산과정을 가지는 값들을 문자열로 변경하려니 코드가 (내기준) 복잡해지고 다양한 함수가 쓰였는데, 이번 문제 역시 나의 파이썬 실력에 대해서 반성하게 만드는 계기가 되었다.