wargame / / 2020. 8. 28. 20:00

Reversing.kr Replace

 

 

 

 

 

 

[그림 1.] 프로그램 실행 모습

 

프로그램을 실행 하게 되면 숫자만 입력받을 수 있는 Text 칸이 나오고 체크버튼이 있다.

 

 

[그림 2.] PEID 모습

PEID에 입력하면 C++로 제작된 GUI프로그램이라고 한다.

 

 

아무 숫자나 입력해서 실행 시켜보면

 

[그림 3.] 작동 중지 메시지

작동이 중지 되었다고 뜬다. 

 

IDA를 켜서 흐름 분석을  잠깐 해보자면 

 

Win API 특성상 저 텍스트에 대한 이벤트는 DialogFunc함수 내에 있을 수 있다고 추측 가능하다.

 

[그림 4.] DialogFunc 함수 내의 GetDigitemint 발견

 

인자를 받아서 GetDIgItemInt 함수를 호출한뒤 [4084D0]이라는 포인터 메모리에 GetDIgItemInt 함수의 반환 값 eax를 저장 하고있다. 그리고 40466F함수를 호출한다.

 

 

[그림 5.] 40466F함수 내부 모습

 

[406016]에 619060EB를 넣고 현재 주소의 + 5 위치를 호출한다.

 

[그림 6.] $+5의 위치는?

 

call $+5의 의미는 404684+5를 호출하라는 뜻이다.

 

404689를 호출하게 되어있다. 

 

404689를 수행하고 쭉쭉 흐름을 보다보면

 

 

[그림 7.] 잘못된 주소에 대한 접근?

loc_40469F에서 첫줄에

 

[40466F]에 상수 값을  넣는걸 확인 할 수 있다.

 

분명 40466F는 함수주소인데 상수값을 넣어서 아마 이부분에서 크래시가 나는게 아닐까 추측하였다.

 

그리고 Correct!를 띄우는 부분이 그래프에서 떨어져 나가있다.

 

이 부분까지 확인하고 디버깅을 진행 해 보았다.

 

 

 

GetDIgItemInt에 bp를 걸고 진행 하였다. 입력 값은 1234를 넘겨줬다.

 

[그림 8.] GetDIgItemInt함수 실행
[그림 9.] EAX 확인

[그림 8.]과 [그림 9.]를 확인 해 보면 GetDIgItemInt를 실행해서 EAX로 4D2를 반환 하고있다.

(* 4D2는 1234의 16진수 값이다.)

 

그리고 [4084D0]에 우리의 input값인 EAX(4D2)를 넣고있다. 

 

그리고 4066F함수를 호출한다. 그리고 40467A로 들어가게 되는데 따라 들어가보면

 

 

[그림 10.] 40467A 내부

포인터 [406016] 619060EB를 넣는다.

 

그리고 404689를 호출한다. (바로 밑으로 진행)

 

[4084D0]++를 두번 한다.

(esp 위치가 404689에 있으므로)

 

그리고 404674로 뛰게 된다.

 

[그림 11.] 404674 내부

404674를 보면 [4084D0]에 601605C7를 더하고 있다.

 

그다음 40467E ~ 404683에서는 

 

EAX++ 진행 -> EAX에는 아직 4D2가 있다. ++ 를 했으니 EAX에는 4D3이 된다.

add bl, ch 

 

EBX는 00000001 ECX는 0C14E342 

즉 01 + E3 한 값을 EBX에 저장한다. (add a1, a2는 a1 = a1 +a2) -> EBX에 E4가 저장된다.

pushad popad를 한다. (특정 행동을 하지않는데 왜 넣었다가 바로 빼는지 모르겠음)

 

그리고 404689로 (바로 밑) 뛴다.

 

마찬가지로 [4084D0]에 있는 값++ 두번

 

그다음 40106A에서 eax를 0으로 초기화 시켜주고 404690으로 뛴다.

[그림 12.] 404690 내부

 

그리고 [4084D0]의 값 (input값 + 4 + 601605C7)을 eax에 저장한다.

 

 

후에 다시 404689로 뛰어서 [4084D0]안에 존재하는 값을++해준다.

 

그리고 40469F로 복귀한다.

 

그리고 여기서 중요한데

 

mov dword ptr ds:[40466F], C39000C6을 통해서 함수주소 포인터안에 어떠한 hex값을 넣어서 자체적으로 코드를 수정을 시도한다.

 

(자세한 설명은 밑 링크로)

https://ggn0.tistory.com/101

 

Self-modifying code [자체 수정 코드]

이번에 리버싱을 하면서 Self-modifying이라는 새로운 신기한 기술을 하나 배웠다. Self-modifying은 자체 수정 코드로써 실행 도중에 자신의 기계어 명령 코드를 주입시켜 코드를 바꾸는 걸 말한다. Self

ggn0.tistory.com

 

그리고 난 뒤 수정된 코드가 있는 40466F로 점프한다.

 

[그림 13.] 수정 된 코드

코드는 우리가 위에서 저장한 [eax]안의 주소에 에 90(nop)을 씌우고 있었다.

 

이 부분에서 크래시가 나는데 우리가 저장한 eax는 존재하지않는 메모리 주소이기 때문이다.

(input값: 4D2 + 4 + 601605C7)

 

한마디로 우리가 input값을 넣어서 프로그램 코드중 하나를 nop으로 덮어 쓸수 있다는 것이다.

 

만약 덮어 쓸 수 있는 주소 값(정상적인 값)을 덮어 씌웠다면 흐름은 

 

4046AE로 뛴 후 

 

[그림 14.] 4046AE

이제는 의미가 없어진 코드들을 실행 한 후 401071로 뛴다.

 

[그림 15.] 401071

401071로 가보면 Correct을 출력하는 함수를 점프하는 점프문이 있다. 

 

이 코드를 아까 nop으로 덮어씌우면 정상적으로 Correct를 출력할 것이다.

 

(input값 + 4 + 601605C7) = 401071이 돼야 하니까 계산을 해보면

 

[그림 16.] 계산
 [그림 17.] 계산2

2687109798을 입력해보면 정답!

 

[그림 18.] 정답

 

'wargame' 카테고리의 다른 글

python challenge - level 4  (0) 2019.01.28
python challenge - level3  (0) 2019.01.27
python challenge - level 2  (0) 2019.01.27
python challenge - level 1  (0) 2019.01.27
vortex.labs.overthewire.org@vortex1  (0) 2016.06.01
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유