#About


Author : abex


Korean :

StolenByte를 구하시오

Ex) 75156A0068352040


English :

Find the StolenByte

Ex) 75156A0068352040




#Contents


패킹 진행 과정에서, 원본 코드 중 일부를 별도의 영역에서 실행하게하여 OEP의 위치를 다른 위치로 가장하는

기법을 통해 StolenByte를 이해 후, 올바른 언패킹을 진행하는 것이 목적이다




#Solution


[그림 1] - 패킹 확인


바이너리 분석을 위해 디버거로 열었을 때, PUSHAD 명령을 통해 레지스터 값을 모두 스택에

적재함을 확인할 수 있고 이를 통해 패킹 여부를 유추할 수 있다


[그림 2] - UPX 패킹


PEiD를 통해 UPX로 패킹되어 있음을 확인할 수 있었고 언패킹은 아래와 같이 진행을 했다


[그림 3]  - UPX 언패킹


[그림 4] - 올바르지 않은 언패킹


언패킹을 진행 후 디버거로 열었을 때, 첫 번째로 실행되는 MessageBoxA 함수에 전달할 인자가 부족함을 알 수 있었고

함수를 실행했을 때, 올바르지 않은 형태의 메시지박스를 확인할 수 있었다


이를 통해 부족한 인자들이 곧 문제와 연관있음을 알 수 있었고 검색을 통해 StolenByte를 이해할 수 있었다


StolenByte


 패킹된 바이너리를 언패킹할 때의 과정을 방해하기 위한 방법으로, 프로그램의 일부 바이트를 별도의

영역에서 실행되게 하여 OEP를 다른 위치로 가장하고 덤프를 쉽게 하지 못하도록 구현한 기법이다


 패커가 패킹을 진행할 때, 원본 코드 중 일부를 다른 곳으로 이동 시킨 코드로써, 주로 엔트리 포인트 위의 몇 줄의 코드이다


  올바른 프로그램을 얻기 위해서는 패킹 과정에서 떼어진 StolenByte를 함께 복원해야 덤프가 성공적으로 이루어진다


[그림 5]


프로그램 복원을 위한 StolenByte를 찾기 위해, 위에서 주어진 StolenByte의 정보를 바탕으로, 엔트리 포인트로

점프하는 주소(00407387)를 찾아 갔더니 POPAD 이후 스택에 적재되는 세개의 값을 확인할 수 있었다


[그림 6] - MessageBoxA 함수의 인자


OEP로 점프하는 구간에 브레이크포인트를 걸고 실행시켰더니 [그림 4]의 MessageBoxA 함수 호출에 필요한

인자들이 스택에 PUSH 됨을 알 수 있고, 이를 통해 PUSH 되는 인자들이 StolenByte 임을 확인할 수 있다


[그림 7] - StolenByte 복구 위치 확인


StolenByte를 확인하고 [그림 6]의 브레이크포인트에서 F8을 통해 JMP 명령을 실행시키게 되면  No Operation을 의미하는

 NOP코드를 12개 확인할 수 있으며, 해당 12개의 NOP 코드값이 원래 StolenByte가 있던 위치이다


[그림 8] - StolenByte 


맨 위의 NOP 코드부터 Ctrl+E를 통해 [그림 7]에서 알 수 있었던 StolenByte의 OP코드를 넣어주었더니

위와 같이 MessageBoxA 함수 호출에 필요한 인자가 모두 스택에 적재됨을 알 수 있다


[그림 9] - Use OllyDump Plugin


제대로 된 언패킹을 위해 올리덤프를 사용해, 위 그림과 같이 OEP를 100C가아닌,

아래와 같이 NOP를 수정한 코드의 시작점인 1000으로 수정해 준 뒤, 덤프를 진행해야 한다


[그림 10] - Modify OEP


[그림 11] - Completed Unpacking



'Wargame' 카테고리의 다른 글

CodeEngn Basic 11  (0) 2017.10.08
CodeEngn Basic 10  (2) 2017.10.02
CodeEngn Basic 8  (0) 2017.09.25
CodeEngn Basic 7  (0) 2017.09.24
CodeEngn Basic 6  (0) 2017.09.13

#About


Author : Rekenmachine


Korean :

OEP를 구하시오

Ex) 00400000


English :

Find the OEP

Ex) 00400000




#Contents


프로그램의 실제 시작 주소를 의미하는 Original Entry Point를 구하는 것이 목적이다

 



#Solution


[그림 1] - 실행 화면


08.exe를 실행했을 때 계산기의 기능을 할 것 같은 UI가 나오며, 기본적인 계산의 기능을 제공함을 확인했다


[그림 2] - UPX 패킹


PEiD를 통해 해당 바이너리는 UPX 방식으로 패킹되어 있음을 알 수 있었고 아래와 같이 언패킹을 진행했다


[그림 3] - UPX 언패킹


[그림 4] - OEP 확인


언패킹을 진행 후 Ollydbg로 열면 실제 프로그램 시작 주소인 OEP를 확인할 수 있다


또는


[그림 5] - PUSHAD


레지스터를 전부 스택에 백업하는 명령어인 PUSHAD를 통해 패킹이 되어 있음을 확인할 수 있고 UPX의 경우,

프로그램 마지막 부분의 코드에 OEP로 점프하는 구문이 존재하며 아래와 같이 확인할 수 있다


[그림 6] - JMP to OEP


'Wargame' 카테고리의 다른 글

CodeEngn Basic 10  (2) 2017.10.02
CodeEngn Basic 9  (0) 2017.09.26
CodeEngn Basic 7  (0) 2017.09.24
CodeEngn Basic 6  (0) 2017.09.13
CodeEngn Basic 5  (0) 2017.09.08

#About


Author : Abex


Korean :

컴퓨터 C 드라이브의 이름이 CodeEngn 일경우 시리얼이 생성될때 CodeEngn은 "어떤것"으로 변경되는가


English :

Assuming the drive name of C is CodeEngn, what does CodeEngn transform into in the process of the serial construction




#Contents


해당 문제는 C드라이브의 볼륨명을 참조 해, 여러 변환을 통해 최종적으로 변경되는 시리얼 키 값을 구하는 것이 목표이다




#Solution


[그림 1] - 실행 화면


해당 문제 역시 시리얼 키를 구한 뒤 검증을 거치는 로직으로 프로그램이 짜여있고

분석해야 할 사항은 로직의 세부분석을 통해 지문에 주어진 문제와 연관짓는 것이다


[그림 2] -  초기 화면


올리디버거로 07.exe 파일을 열었을 때 초기화면이며, 해당 프로그램에 사용된 함수와 텍스트 값을 아래와 같이 추출했다


[그림 3] - 함수 리스트


[그림 4] - 텍스트 리스트


함수 리스트를 보면 GetVolumeInformationA라는 함수를 볼 수 있고 이름에서 부터 볼륨 정보를 가져옴을 유추할 수 있다


[그림 5] - 값 참조 리스트


[그림 5]는 GetVolumeInformationA 함수에서 값을 참조하는 목록이며 VolumeNameBuffer를 통해

볼륨네임 즉, 드라이브 명을 가져옴을 알 수 있으며 문제와 관련있음 또한 알 수 있다


[그림 6] - Break Point at GetVolumeInformationA


해당 함수의 동작을 알아보기 위해 브레이크 포인트를 건 후, 변화를 살펴보니 아래와 같이 

메모리 주소 0040225C에 C드라이브 볼륨명을 PUSH 함을 알 수 있다


[그림 7] - C 드라이브 명


[그림 8] - C드라이브 이름 값 참조


[그림 9] - 볼륨명 변환 코드


lstrcatA 함수를 거치고 나면 "4562-ABEX"와 C드라이브 볼륨명인 CodeEngn이 합쳐지게 되며 

004010AD~004010CD 부분의 코드가 의미하는 바를 해석하면, DL에 2를 넣고 메모리주소 40225C~40225F

부분의 값을 참조해 +1 연산 시키는 구문이며 총 2회를 반복 후 004010AF로 점프하는 구문이다


40225C부터 40225F에 어떤 값이 담겨 있는지 확인을 해보았더니 아래와 같이 볼륨명이 할당되어 있음을 알 수 있었다


[그림 10] - 메모리 할당 값 확인


따라서 메모리주소 40225C~40225F는 "Code"라는 문자를 의미하며 +1연산을 진행하면

Dpef가 되고 +1 연산을 한번 더 하게 되면 아래와 같이 Eqfg가 됨을 알 수 있다


[그림 11] - +1 연산 2회 반복


[그림 12] - 입력 값 검증


[그림 11]처럼 Code가 Eqfg로 바뀐 후 코드를 실행하다보면 L2C-5781과 EqfgEngn4562-ABEX와 합쳐진 뒤 String1이 되며

lstrcmpiA 함수를 통해 String1과 사용자의 임의의 시리얼 입력 값이었던 "Loddy"와 비교 후

리턴 값이 0 즉, String1과 String2가 일치하다면 00401117로 분기 후 Yep, you entered a correct serial!이라는 값을 출력한다


따라서 사용자 시리얼 입력 값은 임의의 값이었던 Loddy가 아닌, L2C-5781EqfgEngn4562-ABEX가 되야하며

아래와 같이 해당 값을 시리얼로 입력해주었을때 올바른 메시지가 나옴을 확인할 수 있다


[그림 13] - 인증


'Wargame' 카테고리의 다른 글

CodeEngn Basic 9  (0) 2017.09.26
CodeEngn Basic 8  (0) 2017.09.25
CodeEngn Basic 6  (0) 2017.09.13
CodeEngn Basic 5  (0) 2017.09.08
CodeEngn Basic 4  (0) 2017.09.05

+ Recent posts