CTF & Wargame/Reversing

abex's crackme #2 알고리즘

GiJi 2021. 2. 21. 02:22

문제에서 제공한 실행 파일을 실행하면서 생긴 메시지 창으로 통해 알고리즘을 유추해보겠다.

[그림1]

Name과 Serial을 모두 입력하지 않으면 Name을 적어도 4 글자 이상 입력하라는 메시지가 나온다.

이 부분을 통해 실행 파일의 알고리즘을 조금 유추해 볼 수 있다.

"사용자가 입력한 Name의 길이를 알아낸다

-> Name의 길이가 4보다 작은 지 같거나 큰지를 비교한다

-> 이후 조건문에 따라 JMP 한다."

[그림2]

Name과 Serial을 임의의 것으로 입력할 경우, serial 값이 틀리면 serial 값이 틀렸다는 메시지가 출력되고 맞게되면 맞았다는 메시지가 출력될 것이다.

"사용자가 입력한 Serial과 알맞은 Serial을 비교하는 과정이 있을 것이다."

 

[첫번째 분기문] 입력한 Name의 길이가 4 이상인지 아닌지가 기준

[그림3]

vbaLenVar() 함수 : Name의 길이 파악

vbaVarTstLt() 함수 : Name의 길이가 4 이상인지 아닌지 파악

->4보다 작으면 FFFFFF를 리턴하고 그렇지 않으면 0을 리턴하게 된다.

TEST 명령어는 AND 연산을 하기 때문에 AX 값이 0이면 ZF(ZeroFlag)가 1이 되어 JE 명령어를 수행하게 된다.

만약 Name이 4보다 작게 되면 EAX는 FFFFFF이 되어 ZF가 0이 되고 JE 명령어를 수행하지 않고 통과해 [그림4] 부분으로 이동하게 된다.

[그림4]

입력한 Name의 길이가 4 미만일 경우, 40302C로 이동해 "Please enter at least 4 chars as name" 메시지를 띄우게 된다.

 

[그림5]

입력한 Name의 길이가 4 이상일 때, 4030F9로 이동한다.

이 부분에서는 Name의 길이 조건을 다시 한번 더 점검한다. 이때 글자 수가 4 미만이면 403130에서 다시 점프하게 된다.

 

[두번째 분기문] EAX 값에 따라 루프 반복 여부 결정

[그림6]

4032A0에서 403197로 점프하게 되고 이때 EAX 값이 0이 아닌 1이기 때문에 Serial 값을 비교하는 부분이 아닌 Serial 값을 생성한는 부분으로 이동하게 된다. 

 

입력한 Name에 대한 Serial 값을 생성할 때 사용되는 함수들에 대해 설명하겠다.

 

1. vbaStrVarVal() : EAX 레지스터에 Name의 N번째 문자의 포인터 저장

 

2. rtcAnsiValuBstr() : 첫 번째 함수를 통해 저장된 EAX 주소의 hex 값을 다시 EAX에 넣어준다. -> 문자의 ASCII 값 리턴

 

3. vbaVarAdd() : 문자의 ASCII 값과 16진수 64(10진수로 100)를 더한다.

 

4. rtcHexVarFromVar() : 3번째 함수에서 더해준 값을 16진수로 나타내고 그 16진수를 String으로 변환

 

5. vbaVarCat() : 기존 문자열 뒤에 방금 생성한 16진수 string 2개를 붙여준다.

 

1에서 5번까지의 루프를 4번 반복하여 EAX의 값이 0이 되어 루프를 빠져나갈 수 있게 된다.

 

[Serial을 생성하는 코드를 통해 알 수 있는 것]

Name을 4글자 이상 입력하게 한 이유:

Serial을 생성하는 루프를 모두 4번 반복하고 Serial은 사용자가 입력한 Name을 기반으로 만들어진다.

또한 루프를 4번만 반복하기 때문에 Name에서 4번째 이상의 문자는 Serial을 생성하는 데 아무런 영향을 미치지 못한다.

 

Serial 계산 방법:

[Name에서 한 문자의 ASCII] + 100

-> 16진수화 -> String 변환

->이전 String에 추가

 

ex) abcd에 대한 Serial 생성

hex(ord(‘a’)+0x64) >>0xC5

hex(ord(‘a’)+0x64) >>0xC6

hex(ord(‘a’)+0x64) >>0xC7

hex(ord(‘a’)+0x64) >>0xC8

 

[세번째 분기문] Serial 값 비교_ Wrong! vs Congratulations!

[그림6]

vbaVarTsEq() 함수: 입력한 Serial 값과 생성한 Serial 값 비교

 

[그림7]

Serial 값을 비교하는 함수의 인자는 EDX와 EAX이다. 각각은 스택 내의 주소인 [EBP-44]와 [EBP-34]에 저장되어 있다.

또한 각각은 계산된 Serial 값과 입력한 Serial 값을 의미한다.

 

[그림8]

해당 주소로 스택 창에서 이동해보면 [그림8]과 같이 입력한 Name "abcd"에 대해 계산된 Serial 값과 입력한 Serial 값이 저장되어 있는 것을 볼 수 있다. 이때 계산된 Serial 값이 EBP-44에 저장되어 있지 않고 8만큼 차이가 난 EBP-3C에 저장되어 있다. 각 변수들은 16바이트씩 공간을 차지하기 때문에 변수의 실제 데이터가 저장된 주소와 변수의 시작 주소 간에 8만큼 차이가 생기게 된다.

 

[그림9]

입력한 Serial 값과 계산된 Serial 값이 같으면 [그림9]에 나온 코드로 이동해 성공 메시지를 출력하게 된다.

 

[그림10]

입력한 Serial 값과 계산된 Serial 값이 다르면 틀렸다는 메시지를 출력하게 하는 [그림10]에 나온 코드 부분으로 이동하게 된다.