#About
Author : Basse 2002
Korean :
Key를 구한 후 입력하게 되면 성공메시지를 볼 수 있다
이때 성공메시지 대신 Key 값이 MessageBox에 출력 되도록 하려면 파일을 HexEdit로 오픈 한 다음
0x???? ~ 0x???? 영역에 Key 값을 overwrite 하면 된다.
문제 : Key값과 + 주소영역을 찾으시오
Ex) 77777777????????
English :
You will see a success message after finding the key.
If you would want the Key itself to replace the success message in the MessageBox,
open up a Hex Editor and overwrite the key value in the offset range 0x???? ~ 0x????.
Q : find the key value and the offset range and write the solution in this format : key????????
(first ???? for the start and the next 4 ?s for the end).
#Contents
해당 문제는 안티리버싱 기법 중 하나인 더미코드의 이해와 Hex Editor에서의 바이너리를 이해하는 것을 목표로 한다
#Solution
[그림 1] - 실행화면
12.exe를 실행하게 되면 위와 같은 UI를 확인 가능하며, 임의의 값을 넣고 Check를 누르면 아무 반응이 없음을 알 수 있었다
분석을 위해 디버거로 열었을 때, 아래와 같은 에러 메시지를 확인할 수 있었다.
[그림 2] - 에러메시지
메시지의 내용과 문제를 연관지어 생각해보면, 12.exe 파일은 PE 구조중 코드 영역이 비어 있음을 알 수 있고 이를
이용해 코드영역에 overwrite 해야할 값은 Key 값이 위치하는 주소값이라는 가설을 세울 수 있다(혼자 일단 세워봄 ㅎ)
[그림 3] - Key 값
[그림 2]의 과정을 넘어, 디버거로 열고 조금만 내리다 보면 Congratulation, you fond the right key(이하 성공메시지)라는
문구를 확인할 수 있으며, 위 문구가 적힌 코드 위에서 아스키 문자로 적혀있는 키 값을 확인할 수 있다.
문제의 지문에서도 알 수 있듯, Key 값을 구해 입력하게 되면 성공메시지가 뜨는 것을 알 수 있으니, Key 값을 메시지로 출력시키기 위해서는
어떻게 할 수 있을까 생각하다가 메모리에 성공메시지가 담겨있는 주소가 아닌, 키 값이 담긴 주소로 바꿔 주면 가능할 것 같아
아래와 같이 코드를 수정해주었다 ( 0040106B 주소 또한 키 값을 출력하는 코드로 강제로 분기 하게 바꿔줌 )
[그림 4] - 코드 수정
수정을 진행 후, 임의의 값을 넣고 Check를 누르자 아래와 같이 키 값이 출력됨을 알 수 있다
[그림 5] - 키 값 출력
또한 이러한 방법이 아닌, Hex Editor로 수정도 가능함을 알게 되었다
1. 아래와 같이 강제로 성공 메시지를 출력하는 구문으로 분기하게 끔 만들어 준다
강제로 분기하게 만드는 방법은, 여러개의 코드가 될 수 있음
[그림 6] - 분기문 수정
2. [그림 6]과 같이 코드를 수정 후 패치 한 다음, 아래와 같이 성공메시지가 저장되어 있는 주소인 0040353B를 HexEditor에서 찾는다
[그림 7] - 성공 메시지가 저장 되어 있는 메모리 주소
3. 위 0040353B 부분을, 키 값이 적혀 있는 메모리 주소인 00403000으로 아래와 같이 바꿔준다
[그림 8] - 메모리 주소 값 변경
4. 위와 같이 수정해 준 뒤, 저장하고 프로그램을 실행하면 아래와 같이 키 값이 메시지창에 출력됨을 확인할 수 있다
[그림 9] - 메시지 창에 키 값 출력
그래서 여기까지가 제일 처음 문제 풀며 삽질 했던 것이며, 지금 부터 풀이를 진행 하겠습니다 ㅋ.ㅋ ... 고멘ㅎ
#Solution
[그림 10] - 실행화면
12.exe를 디버거상에 올렸을 때 화면이며, 어떻게 짜여진 프로그램인지 알기 위해 해당 프로그램에서 사용 된 함수들을 추출해 보았더니 아래와 같았다
[그림 11] - 함수 목록
해당 프로그램에 사용 된 함수들은 위와 같고, 문제 풀이에 가장 관련 있는 함수는 "GetDlgItemInt"다
해당 함수는, 컨트롤로부터 입력된 정수 값을 읽어들여 리턴하는 함수이며 아래와 같이 정의되어 있다
UNIT GetDlgItemInt(HWND hDlg, int nID, BOOL *IpTranslated, BOOL bSigned);
컨트롤로부터 정수형 값을 읽어들일 때는 항상 에러가 발생할 소지가 있으며, 그 예시로는 입력된 정수를 읽어들일 때
숫자 이외의 문자가 있거나 숫자가 너무 클 경우이다. 이 경우 GetDlgItemInt는 세 번째 인수로 지정된 BOOL형 포인터에
에러가 있었는지 없었는지를 대입하며, 에러 검사를 할 필요 없을 경우엔 NULL 값을 전달한다
(출처 : ymn2047.tistory.com/category/API)
[그림 12] - BreakPoint > DialogBoxParamA
0040101D부분에 bp를 걸고 실행했을 때, 아래의 DialogBox를 볼 수 있다
[그림 13] - DialogBox
Key 부분에 임의의 값을 넣고 체크해 봤지만 값을 검증하지 않는 듯 아무런 반응이 없었고, 다시 bp를 아래 사진과 같이 GetDlgItemInt에 걸고 진행을 했다
[그림 14] - BreakPoint > GetDlgItemInt
위와 같이 GetDlgItemInt 함수에 bp를 걸고 실행 시켰을 때에는 [그림 13]의 과정과 달리 아래 그림과 같이 임의의 값인 256을 넣고 체크한 뒤,
F8(Step Over)를 눌러 코드를 한줄 진행하게 되면, [그림 16]과 같이, GetDlgItemInt 함수의 리턴 값으로 EAX에 0x100으로 반환 됨을 알 수 있다
[그림 15] - 임의의 값 입력
[그림 16] - EAX = 0x100
[그림 17] - 반복 루틴 진행
위 그림은 GetDlgItemInt의 반환 값으로 0x100이 반환되고 난 후 바로 아래 코드들의 주석이다
00401068에서 ESI 값에서 4바이트를 읽어들인 후, 0과 비교를 하며 ESI 값은 바로 위 코드에 적힌 아스키 값이다
0040106B에서는 위의 ESI 값이 0이 아니라면 00401071로 분기해서 다음 4바이트를 읽어들이는 루틴이 반복 진행되며 이 반복되는 코드들은
성공메시지를 띄우기 위한 구문으로 넘어가는 JMP 0040107D가 실행되지 않는, 리버싱을 어렵게 하기위한 더미코드라고 볼 수 있다.
[그림 17]의 반복루틴은 더미코드기 때문에 문제해결과는 상관이 없기에, 0040107D로 넘어가 코드를 확인하면,
리턴값이 담기는 레지스터인 EAX에 담긴 값과 7A2896BF와 비교하며, 비교한 값이 같다면 성공메시지를 출력한다
따라서 7A2896BF를 의미하는 10진수 값을 Key 값으로 넣으면 성공메시지를 확인할 수 있으며 10진수 값은 2049480383이다
[그림 18] - 값 입력
[그림 18-1] - 성공 메시지 출력
문제에서 요구하는 것은 성공메시지를 출력하는 것이 아닌 키 값 출력을 요구하므로
해당 메시지가 저장되어 있는 곳으로 가서 키 값으로 바꿔주면 될 것이고, 그 과정은 아래와 같다
[그림 19] - Success Message on Hex Value
[그림 20] - Change Hex Value
[그림 21] - 2049480383
[그림 22] - 변경 된 값 출력
'Wargame' 카테고리의 다른 글
CodeEngn Basic 14 (0) | 2017.10.11 |
---|---|
CodeEngn Basic 13 (0) | 2017.10.11 |
CodeEngn Basic 11 (0) | 2017.10.08 |
CodeEngn Basic 10 (2) | 2017.10.02 |
CodeEngn Basic 9 (0) | 2017.09.26 |