[Reversing.kr] Position
#REVERSINGReversing.kr의 Position 문제풀이
Reversing.kr의 Position 문제인데
프로그램을 시작하자 mfcu100.dll 오류가 발생했다. 해당 오류는 이 블로그에서 해결했다.
오류를 해결한 후의 프로그램 화면과 ReadMe는 아래와 같은데 전에 풀었던 Easy Keygen 문제와 유사하지만 난이도는 꽤 올라갔다.
시리얼 값이 76876-77776일때의 이름을 찾으면 된다.
ReversingKr KeygenMe
Find the Name when the Serial is 76876-77776
This problem has several answers.
Password is ***p
마지막 줄에서 알 수 있듯이 정답의 끝 문자는 p라고 한다.
IDA의 그래프를 보면 sub_401740 함수의 결과에 따라 성공과 실패로 나뉘는 것을 확인할 수 있다.
sub_401740 함수에서 가장 먼저 등장하는 의미있는 부분은 name의 길이 체크이다.
위는 name의 길이가 4
인지 확인하는 부분이고 4가 아닐 경우 실패 분기로 넘어간다.
그 다음 의미있는 부분은 name의 문자들이 알파벳 소문자로 이루어져 있는지 확인하는 부분이다.
name의 길이가 4이므로 4번의 반복을 하면서 문자들이 알파벳 소문자인지 확인한다.
그리고 나오는 의미있는 부분은 이제 시리얼 값 검증이다.
우선 시리얼의 길이가 11
인지를 확인하고 5번째 문자가 -
인지 확인한다.
여기까지는 어셈블리만 보고 충분히 의도를 파악할 수 있었다. 이제부터 등장하는 로직은 IDA의 디컴파일 기능이 있어야 정말 편하다.
디컴파일된 소스도 꽤 긴데 이걸 어셈블리만 보고 파악하기는 정말 고될 거 같다.
아래는 디컴파일된 소스의 일부분이다. (전체 소스는 사진 한 장에 안 담긴다.)
위에 처럼 코드 한줄 한줄 주석을 달면 의도를 충분히 파악할 수 있다.
중간중간 등장하는 mfc100u 관련 함수를 정리하면 다음과 같다. 참고로 내 감이여서 정확하지는 않다. 근데 맞는 거 같다.
- mfc100u_7006 : name 이나 serial의 문자 길이를 구하는 함수
- mfc100u_4478 : 인덱스를 함수 인자로 줘서 name 이나 serial에서 인덱스에 해당하는 문자 하나 반환
- mfc100u_4511 :
itow_s
함수에서 사용될 버퍼 만들기
- mfc100u_11494 : 위 함수로 만든 버퍼 비우기(?)
디컴파일된 소스를 하나하나 적으면 아래와 같은 결론이 나온다.
name[0] 과 name[1] 로 시리얼 앞부분을 만들고, name[2] 과 name[3] 로 시리얼 뒷부분을 만든다.
저기에 맞는 name을 찾으면 되는데 이때 쓰는 방식이 브루트 포스(brute force)
이다. 흔히 무차별 대입으로 조합 가능한 모든 값을 다 넣어서 답을 구하는 것이다.
아래는 Brute force의 C++ 소스이다.
위 코드를 돌리면 총 4가지의 답이 나온다.
bump
cqmp
ftmp
gpmp
위 4가지 중 Reversing.kr에서인정하는 Flag는 bump
하나이다.
어렵지는 않았지만 좀 귀찮은게 많았던 문제이었다.