Write-up/dreamhack.io

[Dreamhack.io] easy-crackme1

새달아 2022. 8. 16. 14:34

dreamhack.io의 Wargame easy-crackme1 문제이다. 해당문제는 내가 리버싱을 시작하면서 가장 먼저 풀었던 문제인데, 이제와서야 write-up을 쓴다...

https://dreamhack.io/lecture/courses/24

 

쉬운 crackme를 통한 디버거 사용법 - 1

쉬운 crackme를 통해 디버거 사용법을 배웁니다.

dreamhack.io

 

# 문제분석

프로그램을 실행시키면 input: 이라는 문구가 뜬다. 임의로 1이라는 값을 두 개 넣었더니 wrong! 문구가 뜬 후, 프로그램이 종료된다. 아마, input 이후에 들어오는 값에 대해 입력값 검증을 하는 프로그램일 것으로 추측된다. 일차적인 목표는 key값을 검증하는 함수를 찾아서 그 내용을 살펴보는 것!

 

# 문제풀이

해당 부분은 문자열 찾기를 이용하여 찾은 메인함수 영역이다.

0x140001221 주소에서 call로 함수가 실행되는데, 이 함수는 문자열을 사용자로부터 받아오는 함수이다.

[rsp+20], [rsp+24] 를 해당 함수가 call 되기 전에 확장시켜놓았으며, 함수가 ret된 이후에는 edx, ecx에 값을 전달하는 것을 볼 수 있다. 아마 받아온 값을 edx, ecx에 새로 담아서 그 다음 함수에 인자로 전달하는 것으로 보인다.(확인했더니 진짜 그렇다...!)

 

조금 지나면... test eax, eax 가 보이고, 해당 분기에서 correct! 혹은 wrong!이 출력될지 결정된다. 그렇다면 <easy-crackme1.140001180> 함수가 입력값을 검증하는 함수인 것으로 보인다.

 

여기서 대충 보고 알 수 있는 것들...

  • 사용자 입력값을 2개 받아왔다.
  • 점프 해야하는 곳과 안해야 하는 곳이 있네.

자세히 뜯어보자...는 주석에 모두 달아놓았다!

여기서 알고 넘어가면 좋은 내용들을 몇 개 보자면...

 

xor 연산

해당 연산에서는 서로가 같으면 0, 서로가 다르면 1로 값이 세팅된다.

본 문제에서는 xor edx, edx 로 사용되었는데, 왜 사용되었을까???

 

=> edx 초기화때문에...!

만약 edx에 0x1111이라는 값이 들어있다고 치자.

조금 밑으로 내려가면 div dword ptr ss:[rsp+28] 이 보일 것이다. 해당 부분에서 [rsp+28]에 들어가 있는 나눗셈의 나머지 값은 edx에 저장된다. 나머지 값이 3이라고 가정한다면, 이후에 이 나머지 값을 참조할 때 0x3을 참조해야 한다.

그러나 만약에 edx를 0으로 초기화 시켜주지 않으면 edx에 값이 씌워질 때, 0x1103으로 덧씌워지면서 아예 다른 값이 나오게 된다...!

 

div  연산

div 연산은 부호 없는 나눗셈이며, div [소스] 의 형식으로 사용한다. 해당 연산은 eax값을 소스의 값으로 나누어서 몫은 eax에 저장하고, 나머지는 edx에 저장한다. 그렇기에 원하는 값을 정확하게 얻으려면 div 연산 이전에 edx를 0으로 초기화시켜줘야 한다.

 

아무튼... 위 함수에서의 모든 조건을 정리하자면... (사용자 입력값 2개를 a와 b라고 가정.)

a의 값은 0x2000보다 작거나 같아야 한다.
b의 값은 0x2000보다 작거나 같아야 한다.
a * b가 0x6AE9BC랑 같아야 한다.
a // b가 0x4랑 같아야 한다.
a ^ b가 0x12FC랑 같아야 한다.

 

해당 내용을 계산해주면...

for a in range(8192):
	for b in range(8192):
    	if a * b == 7006652:
        	if a // b == 4:
            	if a ^ b == 4860:
                	print(a, b)

 

 

5678 1234

쨘! flag 획득 성공~