본문 바로가기

My Study/Programming&Theory

Bluepill Sample Code Test

음.. 지금 bluepill 코드를 vmware에서 테스트 해보는데 0x7f_d BSOD 때문에 상당히 애를 먹었네요.

뭐 결국 디버깅은 하지 못하고 DbgPrint로 찍어가면서 해도 충분할 것 같습니다. 아무튼 어찌어찌 진행을 하긴 하네요.


프로젝트 들어가기전에 bluepill 코드 테스트 하고 시작하렵니다 ㅎㅎ


VMX는 프로세서에서 지원하는 가상화 기술입니다. 이 기술은 하나의 하드웨어에서 여러 소프트웨어 환경을 지원하는 기술이죠. 이에 관해 자세한 설명은 내공이 상당하신 maple 님이 저같은 초보자도 쉽게 이해할 수 있게끔 좋은 문서를 써놓은게 있습니다.


virtualizationtechnology_maple.pdf


마플형님 감사드립니다. ㅎㅎ 문제되면 내릴께요 ㅠ_ㅠ ! ㅋㅋ


아무튼 가상화 관련 기술은 위 문서를 참조하시면 이해가 쏙쏙~ 되실 것 입니다.


전 단순히 CPUID Instruction 을 활용한 코드 테스트를 해보겠습니다. 그전에 약간만 설명하면..

bluepill 코드를 실행시키면 드라이버를 로드한 OS는 Guest OS가 되게됩니다. 그러면 Guest OS와 하드웨어간 통신하는 대부분의 내용을 중간에서 모니터링 및 조작을 할 수가 있습니다. 우리가 흔히 알고있는 Windows Kernel은 Ring 0 에서 돌아가는데 이 bluepill 루트킷은 Ring 0 보다 더욱 낮은.. OS를 벗어난 영역에서 수행되기 때문에 OS 단에서는 이 루트킷을 무력화 한다는 평소 Ring 0 루트킷을 잡는 것과는 색다른 방법을 사용해야 할 것 입니다.



위 그림을 보면 Windows Kernel에서 작동하는 보안 모듈은 VMM에서 작동하는 루트킷의 행위를 함부로 탐지를 못할 것 입니다.


"64-ia-32-architectures-software-developer-vol-3c-part-3-manual" 문서에 Intel VMX 관련 기술이 자세하게 나와있습니다.

그 중 한 부분을 보겠습니다. 일반적으로 VMX가 돌아가면 Guest OS는 VMX non-root mode로 돌아가는데 VMX root mode로 VM Exit가 발생하는 부분입니다.


먼저 VM Exit가 발생하는데 있어서 무조건적으로 발생하는 경우입니다.


일반 명령어 : CPUID, GETSEC, INVD, XSETBV

VMX 명령어 : INVEPT, INVVPID, VMCALL, VMCLEAR, VMLAUNCH, VMPTRLD, VMPTRST, VMREAD, VMRESUM, VMWRITE, VMXOFF, VMXON


위  명령어들이 VM non-root mode 시 수행이되면 VM Exit 가 발생하면서 VM root mode로 바뀌게 됩니다. 조금 있다가 봐볼 CPUID 명령어도 무조건적으로 VM Exit가 일어나는 명령어이군요.


그 다음은 조건적으로 발생하는 경우입니다. ( 비트 설정 및 몇 가지 작업 )

CLTS, HLT, IN, INS/INSB/INSW/INSD, OUT, OUTS/OUTSB/OUTSW/OUTSD, INVLPG, INVPCID, LGDT, LIDT, LLDT, LTR, SGDT, SIDT, SLDT, STR, LMSW, MONITOR, MOV from CR3, MOV from CR8, MOV to CR0, MOV to CR3, MOV to CR4, MOV to CR8, MOV DR, MWAIT, PAUSE, RDMSR, RDPMC, RDRAND, RDTSC, RDTSCP, RSM, WBINVD, WRMSR


엄청나게 많군요.


VM Exit 가 발생하면 VMLAUNCH 전에 VMCS ( 0x00006C16 ) 에 등록시켜두었던 Host EIP 위치로 제어가 옮겨지게 되겠죠.


그 후 Exit ReasonExit Qualification 을 적절히 활용해 루틴을 작성해 주면 됩니다.


이제 원래 목적인 CPUID 를 조작해보겠습니다.


Intel 문서에서 일부만 가져왔습니다.


Exit Reason - 10 이 CPUID가 발생할 때의 값입니다. 


아래는 코드입니다.


정말 단순하게 생겼습니다.


CPUID 명령어가 발생하면 VM Exit 가 발생하게 되고 ExitReason을 구해 10일 경우 들어오고 그 때 

CPUID의 수행 후 정보를 받을 코드 값이 0 인 경우 그 값을 바꿔버리는 것 입니다. 뭐... 그냥 Hooking과 같은 거라고 생각하면 되겠죠.


CPUID 0은 CPU 제조업체 ID를 가져오는 것입니다. 이제 마무리 테스트 동영상을 봐보고 끝내겠습니다.

(  마우스 휠로 브라우져 크기를 조절해서 보세요 ^^ )




이제 이 기술을 활용해 2학기 졸업작품 프로젝트를 간단하게 진행해볼까 하는데 

Windows anti rootkit by bluepill project

라는 주제가 될 것 같습니다.


다른걸 또 공부해야할 탠데.. 산 책들은 언제 다 볼지 ㅠ