1. EPROCESS의 ActiveProcessLinks Linked List를 이용해서 Traverse.
( 왠만한 루트킷들은 이 값을 조작하므로 별로 소용없을지도 모르지만,
ZwQuerySystemInformation()을 후킹하여 결과값을 조작하는 식으로 숨기는 경우는
이 방법으로 손쉽게 찾아낼 수 있습니다. )
2. ZwOpenProcess() Brute-Force Detection
유효 PID인 0L부터 0xFFFFL까지 4의 배수들을 모두 Open해서 성공적으로 열어지는 프로세스를
감지합니다. 단, 프로세스가 종료되었으나 핸들이 닫히지 않은 경우에도 Open되므로 추가적인
확인이 필요합니다.
3. PspCidTable Traverse
Windows NT에는 PspCidTable이라는 Unexported Symbol이 존재하는데, 프로세스와 스레드에
대한 개체 포인터들을 저장하고 있는 핸들 테이블의 일종입니다. 이를 트레버싱하여 숨겨진
프로세스를 찾을 수도 있습니다.
( 개체 포인터만 저장되어있으므로, 포인터-0x18 한 값이 가리키는 OBJECT_HEADER 헤더의
Type 필드가 PsProcessType인지 검사해줄 필요가 있습니다. )
4. Process Handle Table Link Traverse
EPROCESS에는 HandleTable 필드가 존재하고 이 안에는 링크드 리스트가 존재합니다.
이 리스트를 이용해서 트레버싱하면 모든 EPROCESS를 찾을 수 있습니다.
5. CSRSS.EXE의 Handle Table Traversing
CSRSS.EXE 프로세스는 프로세스 시작을 커널에 통지하고 그 뒷처리를 하는 역할을 하기도 합니다.
(BaseSetProcessCreateNotify라는 Unexported/Undocumented Symbol을 이용합니다.
이 심볼 포인터를 후킹함으로써 User Mode에서 폴링(Polling) 과정 없이 프로세스 시작을
감지하는 방법을 구현한 적이 있습니다. http://blog.naver.com/startgoora/130026875156 )
때문에 CSRSS.EXE에는 모든 프로세스에 대한 핸들이 저장되어있습니다.
* 참고적으로 이를 반대로 이용하여 NtOpenProcess()를 거치지 않고 프로세스를 여는 방법중의 하나로 NtQuerySystemInformation()으로 모든 핸들을 얻어온 후 NtDuplicateObject()를 사용하여 핸들을 복사할 수 있습니다.
6. Memory Scanning
Process 개체 이전에 붙는 OBJECT_HEADER로 Scan하는 방법입니다.
http://vbdream.tistory.com/entry/Kernel-탐구-숨겨진-EPROCESS를-찾는-방법-1-Memory-Scanning
에서 PoC(Proof-of-Concept) 코드로 올린 바가 있습니다.
7. ETHREAD로 부터 프로세스 개체 얻기
ETHREAD::ThreadsProcess 필드를 응용하면 EPROCESS의 Pointer를 취득할 수 있습니다.
PspCidTable이나 링크드 리스트를 이용해서 ETHREAD를 구할 수 있습니다.
그리고 EPROCESS의 UniqueProcessId가 조작되어도 ETHREAD::Cid를 이용하면
원래 PID를 구할 수도 있습니다.
8. PsSetCreateProcessNotifyRoutine()
프로세스 생성과 종료에 대한 콜백을 등록할 수 있습니다.
드라이버 로드시에 모든 프로세스를 얻어놓고 이 콜백에 의존하여 리스트를 빼거나 추가함으로써
순수한 프로세스 리스트를 얻을 수가 있겠죠.
(비슷한 것으로 PsSetCreateThreadNotifyRoutine와 PsSetLoadImageNotifyRoutine가 있습니다.)
9. CSRSS.EXE::BaseSetProcessCreateNotify Hook
위에서도 잠깐 언급하였으며 http://blog.naver.com/startgoora/130026875156 를 참고하세요.
이 방법은 프로세스 시작만 감지할 수 있다는 단점이 있습니다.
( 뭐... CSRSS.EXE의 ZwClose를 후킹하면 될지도 모른다는 생각이 드는군요. :-) )
출처 : http://blog.naver.com/startgoora
( 왠만한 루트킷들은 이 값을 조작하므로 별로 소용없을지도 모르지만,
ZwQuerySystemInformation()을 후킹하여 결과값을 조작하는 식으로 숨기는 경우는
이 방법으로 손쉽게 찾아낼 수 있습니다. )
2. ZwOpenProcess() Brute-Force Detection
유효 PID인 0L부터 0xFFFFL까지 4의 배수들을 모두 Open해서 성공적으로 열어지는 프로세스를
감지합니다. 단, 프로세스가 종료되었으나 핸들이 닫히지 않은 경우에도 Open되므로 추가적인
확인이 필요합니다.
3. PspCidTable Traverse
Windows NT에는 PspCidTable이라는 Unexported Symbol이 존재하는데, 프로세스와 스레드에
대한 개체 포인터들을 저장하고 있는 핸들 테이블의 일종입니다. 이를 트레버싱하여 숨겨진
프로세스를 찾을 수도 있습니다.
( 개체 포인터만 저장되어있으므로, 포인터-0x18 한 값이 가리키는 OBJECT_HEADER 헤더의
Type 필드가 PsProcessType인지 검사해줄 필요가 있습니다. )
4. Process Handle Table Link Traverse
EPROCESS에는 HandleTable 필드가 존재하고 이 안에는 링크드 리스트가 존재합니다.
이 리스트를 이용해서 트레버싱하면 모든 EPROCESS를 찾을 수 있습니다.
5. CSRSS.EXE의 Handle Table Traversing
CSRSS.EXE 프로세스는 프로세스 시작을 커널에 통지하고 그 뒷처리를 하는 역할을 하기도 합니다.
(BaseSetProcessCreateNotify라는 Unexported/Undocumented Symbol을 이용합니다.
이 심볼 포인터를 후킹함으로써 User Mode에서 폴링(Polling) 과정 없이 프로세스 시작을
감지하는 방법을 구현한 적이 있습니다. http://blog.naver.com/startgoora/130026875156 )
때문에 CSRSS.EXE에는 모든 프로세스에 대한 핸들이 저장되어있습니다.
* 참고적으로 이를 반대로 이용하여 NtOpenProcess()를 거치지 않고 프로세스를 여는 방법중의 하나로 NtQuerySystemInformation()으로 모든 핸들을 얻어온 후 NtDuplicateObject()를 사용하여 핸들을 복사할 수 있습니다.
6. Memory Scanning
Process 개체 이전에 붙는 OBJECT_HEADER로 Scan하는 방법입니다.
http://vbdream.tistory.com/entry/Kernel-탐구-숨겨진-EPROCESS를-찾는-방법-1-Memory-Scanning
에서 PoC(Proof-of-Concept) 코드로 올린 바가 있습니다.
7. ETHREAD로 부터 프로세스 개체 얻기
ETHREAD::ThreadsProcess 필드를 응용하면 EPROCESS의 Pointer를 취득할 수 있습니다.
PspCidTable이나 링크드 리스트를 이용해서 ETHREAD를 구할 수 있습니다.
그리고 EPROCESS의 UniqueProcessId가 조작되어도 ETHREAD::Cid를 이용하면
원래 PID를 구할 수도 있습니다.
8. PsSetCreateProcessNotifyRoutine()
프로세스 생성과 종료에 대한 콜백을 등록할 수 있습니다.
드라이버 로드시에 모든 프로세스를 얻어놓고 이 콜백에 의존하여 리스트를 빼거나 추가함으로써
순수한 프로세스 리스트를 얻을 수가 있겠죠.
(비슷한 것으로 PsSetCreateThreadNotifyRoutine와 PsSetLoadImageNotifyRoutine가 있습니다.)
9. CSRSS.EXE::BaseSetProcessCreateNotify Hook
위에서도 잠깐 언급하였으며 http://blog.naver.com/startgoora/130026875156 를 참고하세요.
이 방법은 프로세스 시작만 감지할 수 있다는 단점이 있습니다.
( 뭐... CSRSS.EXE의 ZwClose를 후킹하면 될지도 모른다는 생각이 드는군요. :-) )
출처 : http://blog.naver.com/startgoora
728x90
댓글