2021-2 STUDY/Reversing Study

Week03_Dreamhack rev-basic-4, rev-basic-5, rev-basic-6

안지현 2021. 10. 2. 19:14

Dreamhack rev-basic-4

 

먼저 x64dbg를 이용하여 주어진 문제 파일을 열어보았다.

 

 

위와 같이 "input: " 부분이 출력되는 구간을 찾았고, 이 부분이 메인 함수와 관련 있을 것이라 생각했기 때문에 breakpoint를 걸어주었다. 

 

 

F7 키를 이용하여 breakpoint를 걸었던 call 함수 내부로 들어가 보니 위와 같은 코드를 확인할 수 있었다.

여기서 test eax, eax를 통해 eax가 0인지 아닌지 판단하는 부분을 찾아볼 수 있는데,

이때 eax 값이 0이면 Wrong을 출력하고, 아니면 Correct를 출력한다는 것을 예상할 수 있다.

 

 

위 부분에서 계속 진행을 하다가 "input: " 부분에 아무 문자나 입력한 후 엔터를 눌러주었더니 위와 같은 코드로 이동했다.

 

 

위 부분의 코드를 하나씩 살펴보면,

00007FF760361031 주소 부분에서 sar eax, 4의 의미는 eax=eax>>4, 즉 eax에 있는 입력 값을 오른쪽으로 4비트 shift 해주는 것을 의미한다.

또한, 00007FF760361041 주소 부분에서 shl ecx,4의 의미는 ecx=ecx<<4, 즉 ecx에 있는 입력 값을 왼쪽으로 4비트 shift 해주는 것을 의미한다.

다음으로 00007FF760361044 주소 부분에서 and ecx,F0을 해주고 있기 때문에 5-8번째 비트 값만 남도록 설정되므로 최종 값은 ecx eax 즉, 원래는 eax ecx 형태였던 것이 뒤바뀐 순서로 나오게 된다.

이를 덤프의 7FF760363000에 있는 값과 비교해주고 있기 때문에 이 주소로 이동해보았다.

 

 

해당 주소로 가보니 위와 같은 값들을 확인할 수 있었다.

따라서 아까 위의 코드에서 봤던 연산을 반대로 수행해주면 값을 알아낼 수 있을 것이다.

즉, 0x24는 0010 0100이다. 이때 0010은 ecx의 값, 0100은 eax의 값이 된다.

ecx는 왼쪽으로 4bit shift 해주었기 때문에 하위 4비트,였을 것이고, eax는 오른쪽으로 4bit shift 해주었기 때문에 상위 4비트였을 것이다.

따라서 원래의 입력값은 0100 0010 = 0x42가 되고, 0x42를 아스키코드 값으로 변환해주면 B가 된다.

 

이와 같은 방법으로 위 덤프에 있는 값들을 모두 수행해주면 "Br1ll1ant_bit_dr1bble_<<_>>"라는 값이 나온다.

 

 

따라서 위와 같이 답을 입력해주면 Correct 문구가 잘 출력되는 것을 확인할 수 있다.

 

Dreamhack rev-basic-5

 

 

이 문제도 역시 x64dbg를 사용했고, 위와 같이 메인 함수 부분이라고 생각되는 부분에 breakpoint를 걸어주었다.

 

 

F7키를 사용하여 함수 내부로 들어가 보니 마찬가지로 사용자의 입력 값에 따라 test를 해주어 Correct와 Wrong 문구를 출력해주는 분기문을 확인할 수 있었다.

 

 

위와 같이 "input : " 부분에 아무 값을 입력했더니 위와 같은 코드로 넘어가는 것을 볼 수 있었고, 이후에 F8키로 계속 코드를 진행시켜보았다.

 

 

이때 위 부분의 코드를 자세히 살펴보자.

00007FF6BC4E1031 주소 부분에서 eax에 입력된 값을 넣어주고,

00007FF6BC4E1034 주소 부분에서 inc ecx, 즉 ecx 값을 1씩 증가시켜준다.

00007FF6BC4E1042 주소 부분에서는 eax와 ecx 값을 더해준 값을 eax에 저장한다.

그리고 나서 덤프의 00007FF6BC4E3000에 있는 값과 비교해주고 있다/

 

00007FF6BC4E3000에 있는 값을 확인해 보기 위해 이 주소로 이동했다.

 

 

해당 주소에는 위와 같은 값이 저장되어 있었다.

 

즉, 0과 가장 마지막으로 입력한 문자의 hex 값을 더한 값이 4C가 되기 때문에 가장 마지막 입력값의 hex 값은 4C이다.

다음으로 4C와 마지막에서 두번째 입력한 문자의 hex 값을 더한 값이 98이 되어야 하기 때문에 마지막에서 두번째 입력값은 98-4C=4C, 즉 이를 아스키코드값으로 변환하면 L이 된다. 

 

이와 같은 방법으로 모두 연산을 진행해주면 "All_l1fe_3nds_w1th_NULL"라는 문자열이 나온다.

 

 

위와 같이 Correct가 잘 출력되는 것을 확인할 수 있다.

 

Dreamhack rev-basic-6

 

 

이 문제도 역시 메인 함수를 찾아 breakpoint를 걸어 주었다.

 

 

breakpoint를 걸어준 부분의 함수 내부로 들어가 보니 위와 같이 "Input : " 값을 받아 값을 비교해준 후 Correct와 Wrong 문구를 출력해주는 부분이 있었다.

 

 

마찬가지로 한 단계씩 코드를 진행해 보며 확인해 보았고, 

00007FF7D787116E 주소 부분에서 F7키를 눌러 내부로 들어가보았다.

 

 

이도 마찬가지로 한 단계씩 코드를 진행시켜 보았고, 다음 코드를 확인해보자.

 

 

00007FF7D7871024 주소 부분에서는 rax에 0을 넣어주었다.

00007FF7D7871028 주소 부분에서는 rcx에 사용자의 입력 값을 넣어주었다.

00007FF7D787102D 주소 부분에서는 eax에 rcx 값과 rax 값을 더해준 값을 넣어주었다.

여기서 첫번째 반복문의 경우에는 rax 값이 0이므로 입력값의 가장 첫번째 문자가 들어가게 된다.

00007FF7D7871031 주소 부분에서는 rcx에 7FF7D7873020이라는 주소를 넣어주었다.

 

 

이때 00007FF7D7871038 주소 부분에서는 eax에 rcx 값과 rax 값을 더한 주소에 해당되는 값을 넣어준다.

즉, 위에서 내가 입력했던 값이 asdf였고, 가장 첫번째 문자인 a는 0x61이므로 7FF7D7873020 + 61 = 7FF7D7873081 주소에 해당되는 값인 EF가 eax에 들어가게 된다.

 

00007FF7D787103C 주소 부분에서는 rcx에 반복문을 돈 횟수를 넣어준 후, rdx에 7FF7D7873000의 주소를 넣어준다.

 

 

덤프를 통해 확인해보면 00007FF7D7873000에 있는 값은 위와 같다.

 

00007FF7D7871047 주소 부분에서는 ecx에 rdx 값과 rcx 값을 더해준 값을 넣어준다.

00007FF7D787104B 주소 부분에서는 eax와 ecx 값을 비교해준 후 같으면 반복문을 다시 돌고, 아니면 Wrong 문구를 출력한다.

 

 

즉, 7FF7D7873020와 입력값 중 첫 번째 문자의 hex 값을 더해준 주소에 해당되는 값이 00007FF7D7873000에 있는 값과 같아야 하므로 덤프에서 그 값을 찾아주면 00007FF7D7873072에 있는 것을 확인할 수 있다.

따라서 첫 번째 입력값은 00007FF7D7873072-00007FF7D7873020=0x52이므로 이를 아스키코드로 변환하면 R이 된다.

 

위와 같은 과정을 반복해주면 "Replac3_the_w0rld"라는 값을 얻을 수 있다.

 

 

따라서 이 값을 입력해보면 위와 같이 Correct가 잘 출력되는 것을 확인할 수 있다.