Wargame/dreamhack

dreamhack rev-basic-3

esyeonge 2021. 5. 19. 18:14
문제
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!

 

성공 구문을 찾아보자!

 

Correct가 있음을 볼 수 있다. 해당 위치로 가서 분기점을 찾아보자.

 

성공과 실패를 가르는 분기점이 위의 선택된 주소에 나타난 것을 볼 수 있다.

eax 값이 0일 경우에, wrong으로 가게 된다.

eax 값은 test 명령어 위의 call 명령어로 불러지는 함수에서 정해질 테니 00007FF7458D116E에 BP를 걸어두고 실행해보자.

 

함수에 들어가면 위와 같은 명령어들이 보인다.

(1) rcx에 00007FF7458D3000 dump 주소값을 넣는다.

 

(2) rax에 dump rcx+rax 주소에 해당 되는 값을 넣는다.

이 경우에는 rax가 0이므로 rcx인 00007FF7458D3000의 값인 I가 들어가게 된다.

 

(3) Stack에서 000000A3932FF7B0 주소 값을 찾아 rcx에 넣는다.

이땐 아무 값이 없기 때문에 0이 들어간다.

 

(4) RDX에 입력했던 값인 hihihi를 넣는다. hihihi는 rsp+20에 저장되어 있다.

 

(5) ecx에 덤프의 rdx+rcx 주소에 있는 값(== 내가 입력한 값)의 제일 앞의 1바이트를 가져온다.

이 경우에는 h이다.

 

(6) rcx 값과 스택에서 rsp 주소에 해당되는 값을 xor 수행한다.

 

(7) edx에 스택에서 rsp 주소에 해당되는 값을 넣는다.

 

(8) ecx에 dump에서 rcx+rdx*2한 주소에 있는 값을 넣는다.

 

(9) I(=비교 대상이 되는 값)와 h(입력한 값)를 비교한다. 같으면 이 과정을 반복하고 같지 않으면 return 한다.

 

그럼 우리는 ds:[00007FF7458D3000]에 있는 값이 우리가 비교할 값임을 알 수 있다.

이때 우리가 유의해야 하는 것은 (6)에서 수행하는 xor 값이 1씩 늘어난다는 것과

(8)에서 수행하는 값이 *2를 통해 2배가 된다는 것이다.

 

 

출력값 = (입력값 * ss:[rsp]) + rdx*2를 수행하는 것으로 볼 수 있다.

우리는 출력값을 알고 있기 때문에 입력값을 역산으로 구할 수 있다.

입력값 = {출력값 - (rdx*2)} xor ss:[rsp]

 

하나하나 살펴보자.

I는 ss:[rsp]값도 1이고, rdx*2의 값도 0이기 때문에그대로 입력해도 된다.

 

`(96)의 경우에는 rdx*2 값이 2, ss:[rsp]의 값이 1이다.

그럼 (96 - 2) xor 1 = 95가 된다.

즉, `일 때는 95에 해당되는 문자열인 _를 입력하면 되는 것이다.

 

g(103)의 경우에는 rdx*2 값이 4, ss:[rsp]의 값이 2이다.

그럼 (103 - 4) xor 2 = 99 xor 2 = 0110 0011 xor 0010 = 0110 0001 = 97이 된다.

즉, g일 때는 97에 해당되는 문자열인 a를 입력하면 되는 것이다.

 

이걸 코드로 짜면 쉽게 계산할 수 있을 것 같다!

 

위와 같이 코드를 작성하고, 실행을 했더니

 

정답으로 보이는 문자열이 출력된다!

 

입력해보니 정답이다!