[dreamhack] rev-basic-3 문제풀이
[Reversing] rev-basic-3 문제풀이

문제를 확인해보자.

 

 

Correct를 출력하는 FLAG 값을 찾는 문제이다.

문제 파일을 x64dbg 프로그램으로 열어보자.

 


correct를 출력하는 flag 값을 찾아야하기 때문에 문자열 참조 찾기를 통해 correct 문자열을 찾아보자.

 

 

사용자가 FLAG를 입력하고 chall3.7FF6CBF01000 함수에서 입력 값 비교를 한 뒤, 

Correct/Wrong 메시지를 출력한다. 해당 함수를 따라가보자.

 

 

음 상당히 난해하다. 어셈블리어를 이제는 봐야한다.

눈을 감는다고 해결되지 않는다.

한숨을 크게 들이쉬고 시작해보자.

 

먼저 [cmp rax, 18] 을 통해 사용자 입력 값을 0x18번 비교한다.

FLAG의 문자열 길이는 0x18=24 로 확인할 수 있다.

 

사용자 입력 값 비교는 [lea ecx, qword ptr ds:[rcx+rdx*2]] 에서 수행한다.

ecx는 사용자 입력 값을 저장하고, rcx는 메모리에 올라와있는 값을 가져온다.

[lea rcx, qword ptr ds:[7FF6C4AD3000]] 구문을 보면 7FF6C4AD3000 주소에

rcx의 값이 저장되어 있으니 해당 주소를 따라가보자.

 

 

메모리에 저장되어 있는 비교 문자열의 길이는 24이므로 값을 확인해보자.

16진수 값 : 49 60 67 74 63 67 42 66 80 78 69 69 7B 99 6D 88  68 94 9F 8D 4D A5 9D 45

10진수 값 : I`gtcgBf.xii{.m.h...M¥.E

 

어셈블리어 코드를 보면 rcx에 올라간 문자열과 사용자의 입력 값을 그대로 비교하는 것이 아니라

사용자의 입력 값을 연산하여 rcx의 값과 비교하기 때문에 연산과정을 역연산하여

FLAG를 도출해야 한다.

 

사용자의 입력 값이 연산되는 식은 다음과 같다.

- str : 메모리에 저장된 비교 문자열

- input : 사용자가 입력한 문자열

- i : 문자열 카운트를 위한 정수형 변수

연산식 : (input[i]^i)+(i*2)=str[i]

 

해당 연산을 통해 메모리에 저장된 문자열과 비교를 하기 때문에

사용자가 입력해야할 값을 추측하기 위해서는 input[i]의 값을 역연산 해야 한다.

 

1. (input[i]^i)+(i*2)=str[i]  // 기본 연산식

2. (input[i]^i)=str[i]-(i*2)  // 양변에 -(i*2) 추가

3. input[i]=(str[i]-(i*2))^i // 양변에 ^i 추가 => 역연산 식

 

해당 연산을 비교 문자열 길이인 i=24로 놓고 파이썬으로 코드를 작성해보자.

 

str='49','60','67','74','63','67','42','66','80','78','69','69','7B','99','6D','88','68','94','9F','8D','4D','A5','9D','45'
res=''

for i in range(24):
    res+=chr((int(str[i],16)-(i*2))^i)

print(res)

 

코드를 실행하면 다음과 같은 결과가 나온다.

 

 

여기서 글자 수를 세보면 23글자이다. 

 

 

문자열을 다시 출력했더니 공백 문자가 포함되어 24자 인 것으로 확인된다.

이 문자열을 프로그램에 입력해보자.

 

문제풀이 끗