본문 바로가기

2. Reversing (리버싱)/1) Write UP

[2020.06.16] Reversing.kr | Position 문제

http://reversing.kr의 Position 문제를 풀어보도록 하자.

문제를 클릭하면 Position.zip 파일이 다운받아진다.

Position.exe 파일을 열면 다음과 같은 프로그램이 실행된다.

ReadMe.txt 파일을 보면 시리얼 번호가 76876-77776일때 name을 찾고 password를 찾는 문제임을 알 수 있다.

비밀번호는 ***p 이다.

문자열을 검색해 Correct!로 이동한다.

Position.00011740 함수를 호출하고 결과에 따라 Correct와 Wrong으로 분기되는 것을 볼 수 있다.

리턴값이 1이어야 Correct가 된다.

Position.00011740 함수 내부로 들어가 살펴보자.

Position.00011740 함수에서는 Name을 입력받은 후 조건을 검사한다.

1. [ECX-C] 값과 4를 비교한 후 같으면 Position.000117D9로 점프한다.

2. 점프하면 첫번째 루프에서 name에 입력한 4글자가 알파벳 소문자인지 확인한다.

3. 두번째 루프에서는 name의 각각의 글자 중에 서로 같은 글자가 있는지 확인한다.

4. 세번째 루프에서는 Serial의 글자수가 총 11글자이고, Serial의 5번째 문자가 ' - ' 인지 확인한다.

정리하면 다음의 3가지 조건을 검사한다.

1. Name의 길이가 4인가?

2. Name이 a~z까지의 소문자로 구성되어 있는가?

3. Name의 구성 문자중 중복이 있는가?

그 이후로는 name을 이용해 serial을 만드는 루틴이 나온다.

(ida pro 유료버전이 없기 때문에 다른 사람 문제에서 가져왔다...)

아래 사진 출처 : https://gyeongje.tistory.com/249

GetAt(char* a1, int a2) 함수는 문자열 a1의 a2번째 인덱스의 값을 반환한다.

if문으로 10번을 검증하는 루틴이 있다.

시리얼 값 중에서 ' - '를 제외하면 10자리이기 때문에 이부분에서 password를 이용해 Serial을 만든다는 것을 알 수 있다.

password값 1,2번째 값을 통해 serial 값 ' - ' 앞부분 5자리를 만들고,

password값 4,5 번째 값을 통해 serial 값 ' - ' 뒷부분 5자리를 만든다.

GetAt(&v61, 0)에서 v61은 password이므로 한자리씩 가져와서 shift연산, and 연산을 통해 입력한 시리얼 값과 비교한다.

if(v13==v12)에서 v12는 입력한 시리얼값의 첫번째 인덱스, v13은 password를 연산해 나온 시리얼 값의 첫번째 인덱스이다.

이런 식으로 10자리가 모두 맞아야 1을 리턴해 Corret!를 볼 수 있다.

Name값은 4자리이기 때문에 Brute Force를 통해 확인하였다.

Name 값은 3개가 나오는데 1개만 답으로 인정된다.