보안 공부하는 꼬깔이

- ImagePrc

 

ImagePrc를 클릭해 문제를 다운받자.

 

[ Exeinfo Pe ]

패킷여부 : Not packed

제작언어 : C++

 

 

문제 파일을 실행 시켜보면 흰 백그라운드의 창하나와 CHECK 버튼으로 구성된 창이 하나 뜬다.

흰 백그라운드의 창에는 마우스로 클릭하고 움직이면 사진과 같이 줄이 그어진다.

 

Check 버튼을 클릭하면 해당 시도가 틀렸을때 나오는 문구가 출력된다.

제출자가 원하는 그림을 그려서 제출하는 문제인가...?

 

해당 프로그램에서 사용되는 라이브러리 목록이다.

그래픽과 GUI에 관련된 작업들을 할때 사용하는 라이브러리들이 무수히 존재한다.

이번 문제에서도 역시 실패 했을때 출력되는 문구인 "Wrong" 을 찾아 분석을 시작해보자

 

Wrong 을 출력하는 어샘코드 부분이다.

004013AA 주소의 분기문으로 인해 "Wrong" 이 출력되는 코드로 분기하는 모양이다.

그렇다면 분기문을 만나기전 비교를 하는 구문이 있을것이다.

위 사진을 보면 실제로 레지스터에서 어떠한 작업이 이루어지고 그것을 CMP 레지스터로 비교하는 부분이 존재한다.

 

더욱 위로 올라오면 FindResourceA, LoadResource , LockResource 등의 함수들이 사용되는 것을 확인 할 수 있다.

해당부분은 이러한 함수들로인해 리소스를 찾고 그 리소스가 존재하면 Load를 하게끔 코드가 구성되어있다.

 

FindResourceA 함수를 call 하는 부분에 브레이크 포인트(F2)를 걸고 프로그램을 시작한 뒤 FindResourceA 함수를 사용하고 난 뒤 결과값을 확인했더니 리소스가 저장되어 있는 주소의 위치가 0x47E048 주소 라는것을 알게 되었다. 

그리고 해당 리소스를 LOAD해서 EAX에 저장시킨다.

 

리소스를 찾고 로드하는 함수들의 과정이 끝나면 해당 코드가 수행된다.

ESI 레지스터에는 사용자가 그린 그림의 영역 주소가 저장되고 EAX에는 리소스 영역의 주소가 저장된다.

결국 해당 코드는 사용자가 입력한 그림과 리소스 여역의 그림을 픽셀 단위로 0x15F90 번 만큼 반복하면서 검사를 진행한다.

검사도중 일치하지 않는 부분이 발견되면 그 즉시 "Wrong!" 문구가 출력되는 쪽으로 분기를 시켜버린다.

반대로 검사하는 모든 리소스가 일치하여 반복문이 끝나면 특정한 영역을 CALL 하게 된다.

 

그렇다면 어떤식으로 프로그램에 저장되어 있는 리소스를 알 수 있을까?

 

프로그램안에 이미지에 해당하는 데이터가 존재하면 그것을 MainFest에 저장하게 된다.

실제로 PEview를 통해 imageprc.exe 파일의 ManiFest를 확인해보니 리소스가 존재했다.

그리고 해당 리소스를 확인했을떄 256의 색을 FF이하로 표현을 하며 비트맵 방식을 사용하는 BMP 이미지 파일로 유추를 하였다.

 

해당 리소스를 resource_hacker 툴을 사용해 파싱한 후 해당 내용을 Notepad++ 에 복사 후 저장했다.

현재 리소스에는 해더가 존재하지 않기 때문에 우리가 임의로 BMP 해더를 넣어주어야 한다.

 

그리고 리소스의 본래 사이즈를 코드상에서 알아내었다. 가로의 크기는 0x96(200) 세로의 크기는 0xC8(150) 이다

 

그림판에서 가로 200, 세로 150의 크기를 가진 임의의 파일을 하나 만들고 해당 파일을 HXD 툴을 이용해 파싱한 리소스에 BMP 해더를 붙여 저장하게 되면 어떤 문구가 적힌 BMP 파일이 출력되는데 해당파일이 우리가 입력한 그림과 비교를 하던 리소스 파일이며 이 문제의 정답이다.

 

 

ImagePrc clear!