WARGAME/reversing

[dreamhack] patch

lucykorea414 2023. 9. 22. 16:33
728x90

 

실행파일 실행

먼저 실행파일을 실행해보면 다음과 같은 화면이 뜹니다.

이때, 플래그 값이 어떤 줄들에 의해 지워진 걸로 보이네요!!

문제 설명에 나와있듯이 flag를 가리게 하는 어떤 루틴이 있는걸로 보입니다.

 

 

 

정적분석

IDA 로 한번 정적 분석을 해보겠습니다.

보면 WinMain 이라는 메인함수가 제일 먼저 호출되고 있습니다.

지금 실행시켜도 알겠지만 이 친구는 WinAPI 를 사용한 GUI 실행파일입니다.

 

따라서 이 점을 참고하고 디컴파일된 코드를 보겠습니다.

여기서 함수들을 분석을 할건데, 저는 WinAPI에 대해서 잘 모르기 때문에 마이크로소프트의 공식문서를 활용하여 분석을 해보도록 하겠습니다.

 

여기서 LoadStringW 이라는 함수에 대해서 자세히 알아보자면, 지정된 모듈과 연결된 실행 파일에서 문자열 리소스를 로드하고 문자열을 종료 null 문자가 있는 버퍼에 복사하거나 문자열 리소스 자체에 대한 읽기 전용 포인터를 반환하는 함수입니다.

 

따라서 문자열 리소스를 읽고, 12~14행에 v11 이라는 변수에 사이즈, 스타일 그리고 창 프로시저의 주소를 지정하게 되는데(v11.lpfnWndProc) 여기서 sub_1400032F0 이라는 콜백 함수 포인터가 지정되는 모습을 볼 수 있습니다.

 

이후, 23행에서 RegisterClassExW 를 통해 v11변수를 윈도우 클래스로 등록을 하게 되는 것입니다.

따라서, 주요 동작이 sub_1400032F0 함수에 있을것이므로 이 함수를 살펴보겠습니다.

 

함수를 살펴보면 switch 구문을 확인할 수 있습니다.

총 3가지 case가 있는데, 이 중 0xFu에 해당 하는 부분에서13행에 Begin Paint가 있고 35행에 EndPaint 가 있습니다.

그럼 이 중간에 플래그값이 그려지고 플래그를 덮는 동작도 수행될거라고 예상할 수 있겠죠?

 

28행에 있는 sub_140002C40 함수가 호출되는 것으로 보아 이 함수가 뭔가 그림을 그리는 함수라고 추축할 수 있을 것 같습니다. 그럼 분석의 편의를 위해 이 함수의 이름을 dec_paint 함수라고 이름을 바꾸고 내부의 코드를 확인해보겠습니다.

 

dec_paint 함수 내부를 보게 되면 다음과 같이 계속 어떤 함수를 호출하는 형태가 보입니다.

이때 이거는 반복적으로 무엇을 그리는 형태라고 추측할 수 있습니다.

첫 부분에 계속 반복적으로 등장하는 sub_140002B80 함수를 분석해보면 다음과 같습니다.

 

GdipCreatePen1 이라고 되어있는 함수는 그림을 그릴 펜 함수를 호출하고 GdipDrawLineI 함수를 이용해서 화면에 줄을 그리는 것을 알 수 있습니다.

 

 

 

이제 아까 dec_paint 함수 밑에 나와있던 sub_1400017A0 함수를 분석해봅시다.

dec_paint에 있는 sub_1400017A0 함수
sub_1400017A0 함수 분석

 

sub_1400017A0 함수는 sub_140002B80 함수와는 다르게 펜을 생성한 후 여러개의 선을 그리고 있는 것을 볼 수 있습니다. 따라서 이 함수가 플래그 글자를 그리는 함수라고 추측할 수 있습니다. 그럼 이 함수의 이름을 draw_flag 라고 바꾸고 디버깅을 해보겠습니다.

 

 

 

 

동적분석

처음 여러 선을 그리는 함수에 bp를 걸고 실행해보겠습니다.

 

 

화면이 떴고 이제 F8로 하나하나씩 그려나가 보겠습니다.

한줄 실행을 했는데 선이 그려졌습니다.

그럼 이 함수 호출이 끝날때까지 실행을 해보면 어떨까요?

예상대로 플래그 글자를 가리는 선들이 그려지게 됩니다.

그럼 이 함수가 실행되지 않게 우리는 이 실행파일을 패치(patch) 해야합니다.

먼저, 패치 하기 전에 분석의 용이함을 위해 sub_140002B 함수를 hide_flag 라고 바꿔줍시다.

(함수명이 자동적으로 77~~ 어쩌구로 바뀐거는 그냥 base 주소가 변경되었기 때문인데 그냥 무시 가능)

 

 

 

 

바이너리 패치

IDA 에서 Edit - Patch Program 라는 메뉴를 클릭하여 패치를 진행해보겠습니다. 이중에서, 어셈블리 인스트럭션을 패치 하기 위해서는 assemble 기능입니다.

 

선을 그리는 함수가 hide_flag 함수를 함수창에서 찾아서 봐도 되고 g 를 눌러 hide_flag 을 입력하고 함수로 가도 됩니다.

 

그리고 첫번째 인스트럭션에 커서를 올리고 Edit - Patch Program - Assemble... 을 누르면 인스트럭션을 입력할 수 있는 창이 뜹니다. 우리는 이 함수가 실행되는 것을 막아야하기 때문에 그냥 실행되자마자 리턴이 될 수 있게 ret 을 입력합니다.

 

OK 를 누르면 함수의 형태가 깨지면서 인스트럭션이 retn 으로 변경된 것을 확인할 수 있습니다. (IDA 가 기존에 정의해 둔 함수의 형태에서 인스트럭션이 변경되었기 때문에 UI에 변화가 생겼지만 크게 신경쓰지 않아도 됨)

 

이때 패치한 내용을 실제 바이너리에 적용하기 위해서는 Edit - Path Program - Apply patches to input file... 메뉴를 클릭하고 ok를 누릅니다!! 그럼 바로 적용이 됩니다~~

 

 

플래그값 찾기

이제 패치된 실행파일을 다시 실행해보면 다음과 같이 실행됩니다.

굳뜨!!!

 

 

 

 

 

참고:

https://junk-s.tistory.com/48

https://learn.microsoft.com/en-us/windows/win32/api/

https://learn.dreamhack.io/217#1

728x90

'WARGAME > reversing' 카테고리의 다른 글

[코드엔진/CodeEngn] Basic RCE L19  (1) 2023.11.13
[dreamhack] rev-basic-3  (0) 2023.09.22
[dreamhack] rev-basic-1  (0) 2023.09.15
[dreamhack] rev-basic-0  (0) 2023.09.15
[Crackme] #1  (0) 2023.09.11