본문 바로가기

리버싱/리버싱기초

PE파일 데이터 암호화

실행파일을 메모리에 올려주는 작업을 PE로더라한다. 검증작업을 걸쳐서 실행파일이 맞으면 메모리에 올려준다. 예를들어 MZ라는 단어가 있어야만 실행이 된다. 실행파일을 보면 보통 최소 4키로바이트이다. 우리는 이런 이유가 클러스터 크기가 4KB이기 때문에 그렇다고 생각하지만 실행파일은 실제 4KB에 가깝다. 왜냐하면 실행에 관련된 필요한 정보 같은 것이 담겨있기 때문이다. 그래서 한 때 실행파일을 최소로 줄이는 대회가 있었다. 그 때 97B로 그 크기를 줄일 수 있었다고 한다. 


PE파일이 메모리에 로딩되면 거의 그대로 올라간다. 하지만 바뀌는 것이 존재한다. 파일의 오프셋-> 메모리에 올라오는 주소가 바뀌게 되는데 실행파일의 이러한 alignment는 대게 0x1000이다. 악성행위자는 이런 남는 공간을 이용해 패킹을 한다.


이게 가능한 이유는 


1) 엔트리포인트를 내맘대로 수정할 수 있고 (프로그램 구동과정을 바꿀 수 있다.)


2) 그러면 섹션 헤더까지 수정이 가능하기 때문이다.


보통 코드 부분은 쓰기 권한이 없다. 왜냐하면 코드를 고치는 경우는 거의 없기 때문이다. 근데 이곳에 쓰기 권한을 주면 내맘대로 코드 진행을 바꿀 수 있다. 그러면 히든 영역을 두어 이부분을 먼저 실행시켜 원래 있던 코드를 다른 내용으로 바꿀 수 있을 것이다. 또는 원래 정성작인 코드였는데 악성행위를 하도록 바꿀 수 도 있다. 


악성코드의 대부분이 UPS라고(그 구조는 이미 알려짐)으로 패킹되어 있다. 이러한 패킹은 소프트웨어를 보호하기 위해 사용될 수 있지만 소프트웨어로 패킹하여 파일을 보호하는 것은 이미 2010부터 불가능하다고 알려졌다. 그래서 나타난 것이 TPM이란 모듈이다. 내가 내돈 주고샀는데 내가 모르는 영역이 존재하고 이 영역에 키를 넣어서 나를 제어한다. 그리고 이 키를 가지고 사업자들과 짜고 DRM 같은 것을 걸어놓는다. 하지만 이는 현재 잘 쓰이지 않는데 그 이유는 소비자단체의 반발이 심했고 나도 모르게 내 개인정보가 빠져나갈 수 있기 때문이다. 


알고 있을지 모르지만 윈도우 8버전에 TMP가 존재했고 2.0버전이 나오면서 독일정부는 공공단체에서 윈도우8을 안쓰기로 법안이 통과되었다. 그 이유는 나도 몰래 내 정보가 빠져나갈 수 있기 때문이다. 이게 나타난 이유는 키를 모르면 패킹을 깰 수 없다고 알려졌기 때문이다. 


현재 PE파일을 측정하는 것은 안티파이러스밖에 없는데 서로 선점할려고 하기 때문에 문제가 발생한다. 


여담이지만 윈도우 비스타 이전에는 익스플로잇이 쉬어서 인터넷을 하지 않더라도 바이러스가 걸리곤 했다. 하지만 이후에는 그걸 카운터메저하는 검증단계가 들어가 이전방법으로 익스플로잇을 하면 거의 안되도록 보호조치가 되었다.(훨씬 어려워짐) 그래서 요즘은 하드웨어에 관련된 곳을 공격하기 시작했다(ap.라우터...)


pe파일의 처음부분에 32비트 실행코드가 존재하는 주소를 가리키는데 그 위에는 도스 실행코드가 존재한다. 그 곳에 이 파일이 도스에서 실행될 경우 실행이 안됨을 설명하기 위해 주로 쓰인다.(16비트 코드) 실행코드를 숨기는 방법이 여러가지가 존재한다. 물론 코드를 인코딩하고 아래부분에 디코딩 코드를 작성할 수 도 있고 섹션을 하나만들어 그곳을 실행가능하도록 바꾸고 엔트리 포인트를 바꿀 수 도 있다. 이 이후의 내용은 코드 대신 데이터영역을 알아볼 수 없도록 간단히 패킹을 하는 방법에 대해 설명한다. 






파일 : 


Tiny_PE.zip






분석 도구 : 



LordPE.zip


PEview0.9.8.zip




위의 파일을 처음 다운받고 실행시키면 다음과 같은 메세지창이 출력된다. 우리는 IDA 를 이용해 이 프로그램에서 사용되는 문자열이 무엇인지 알 수 있다. 





위처럼 프로그램에서 사용되는 문자열은 PE파일을 역공학하여 확인이 가능하다. 이 문자열은 리버싱하는 사람에게 중요한 지표가 될 수 있으므로 XOR로 간단히 암호화하여 내용을 이해할 수 없도록 하자.


DeRox를 이용해 이 프로그램의 어셈블 코드를 확인한다.




PEeditor을 이용해 이 프로그램의 시작위치를 확인하면 401000(Entry Point + Image Base)에서 시작됨을 알 수 있다.



이제 데이터를 XOR 패킹하는 파이썬 코드를 이용해 데이터영역을 암호화하자.



이 파일의 원래 데이터영역은 다음과 같다.





데이터 영역을 XOR 연산하기 위해 WinHex 프로그램을 실행시킨다. 

블록처리한 후 상단 메뉴의 Edit->Modify Data를 선택한다. 





작업 후 실행하면 다음과 같이 데이터를 알아 볼 수 없게 된다.



DeRox를 통해 사용되지 않는 코드 영역에 다음과 같은 코드를 입력하여 패킹된 영역을 풀어주자


 주소

 명령어 

 설명

 00401021

 MOV EAX, 00402000

 EAX에 00402000(데이터영역) 주소 값을 넣음

 00401026

 MOV BL,BYTE PTR SS:[EAX] 

 BL에 EAX 주소에 위치하는 데이터 1 바이트를 넣음

 00401029

 XOR BL,50

 0x50으로 XOR연산

 0040102C

 MOV BYTE PTR SS:[EAX],BL

 다시 EAX 주소에 XOR연산한 값을 넣음

 0040102F

 INC EAX

 EAX 주소를 1증가

 00401030

 CMP EAX, 00402030

 EAX주소가 00402030(패킹 하고 싶은 데이터 영역 끝)이 되었는지 확인

 00401035

 JE SHORT 00401000

 언패킹이 끝났으면 다시 시작위치로 점프

 00401037

 JMP SHORT 00401026 

 아직 언패킹이 끝나지 않았으면 계속 XOR연산

 00401039

 NOP  

 0040103A

 NOP

 




코드 삽입이 완료되었다면 실행 파일을 저장한다.


마우스 우클릭 -> Copy to executable -> All modifications -> Copy all 을 하면 아래와 같은 창이 뜨게 될 것이다.



마우스 우클릭 -> Save file -> 저장


이제 실행파일의 엔트리 포인트 주소를 바꿔주자. 이뿐만 아니라 쓰기권한을 주어야한다. 위의 경우 데이터영역을 패킹한 것이므로 굳이 권한은 변경할 필요가 없지만 코드 영역은 쓰기작업이 불가능하기 때문에 권한을 변경해주어야만 한다.


LoadPE 프로그램으로 이 파일을 실행시킨다. PE Editor 버튼을 클릭한 후 엔트리 포인트의 주소를 1021로 변경해준다.



데이터 영역에 쓰기 권한이 있는지 확인한다. Sections 버튼을 클릭한 후 

데이터영역 마우스 우클릭 -> edit section header -> ...버튼 클릭 -> Writeable 체크 확인




이후 프로그램을 다시 실행시키면 정상적으로 실행됨을 확인할 수 있다.





지금은 데이터 영역을 패킹했지만 이는 주로 코드영역을 패치하기 사용될 것이다. 하지만 이 방법은 XOR을 아무리 하더라도 패킹부분 코드만 확인하면 그 내용을 쉽게 알면 알수있다. 오리지날 엔트리 포인트(OEP)만 찾으면 메모리가 정상적으로 다 변환되어 있을 것이기 때문이다. 그래서 요즘 쓰는 방법은 한번에 언패킹을 하지 않고 천천히 코드를 푸는 방법을 사용한다. 또한 안티디버거 코드를 엄청 삽입한다.


예를 들어 파일 딜레이가 어느 정도 존재할 경우 실행안되고 프로세스 목록 중 온리디버그가 있으면 실행이 안될 수 있다. 이것은 동적 분석을 막는 방법인데 이런 것은 이미 10년전부터 해온 상황이다. 


이러한 방법에 대한 대책 중 괜찮은 논문이 존재한다. 엔트로피를 이용한 방법인데 압축이나 암호는 내 앞바이트 또는 뒤바이트와 편차가 크다. 하지만 실행파일은 내용이 어셈코드이므로 편차가 강하지 않다. 오리지날 엔트리 포인트를 어떻게 하면 잘 찾을 수 있을까? 또한 어떤 타이밍에 브레이크포인트를 걸까? 압축을 풀다보면 계속 엔트로피가 줄어들 것이다. 이 체크루틴을 브랜치가 일어날때만 확인한다. (조건, 비조건 분기문 모두) 그리고 그것이 가장 저점일 때 메모리 덤프를 계속 뜨면 오리지날 코드를 찾아낼 수 있다. 알려지지 않은 패킹 파일을 실험했는데 85퍼센트를 풀 수 있었다고 한다.