Reversing/Kernel

[ Window Device Driver ] 5. Process Hide - DKOM(디컴) : ActiveProcessLinks

DKOM?

  • Direct Kernel Object Manipulation
  • 직접 커널 객체 조작
  • 커널 오브젝트 - 프로세스, 드라이버, 파일등에 대한 정보를 조작하는 기법
  • 함수 테이블이나 Native API 등에 대한 hooking등을 거치지 않고 커널 오브젝트를 직접적으로 조작한다.
  • 프로세스 리스트를 받아오는 원리가 EPROCESS 구조체에 들어있는 멤버들에 의존적임
    • 따라서 객체 멤버를 조작하는 방식으로 다른 부분에 영향을 미치지 않고 조작가능
  • 오브젝트의 구조와 그 구조체 속 멤버등의 전체 구조, 역할 등을 완벽하게 파악하고 이해해야함.
  • 업데이트시 커널 버전에 따른 변화와 그 영향을 인지하고 있어야함.

PEB - Process Environment Block

  • User Mode 에서 프로세스 정보를 가짐
  • 각 프로세스마다 PEB가 존재하고, 각 쓰레드별로 TEB를 가짐
  • 커널에 있는 정보를 가져와 유저모드 메모리에 프로세스 구조체를 저장한다. → 간접적인 접근
    • 유저모드에서 프로세스 정보를 조회할 때 마다 커널에 접근해야 한다면 상대적으로 시간이 오래 걸리게 되니, 유저모드 메모리에 해당 데이터를 복사해와 저장한 개념.

EPROCESS

  • Kernel Mode의 프로세스 정보를 가지고 있는 구조체
  • 원본 데이터에 직접적으로 접근하여 정보 가져옴

원리

  • EPROCESS 구조체 내의 이중 연결리스트로 프로세스 리스트가 구현됨
  • LIST_ENTRY 구조체
    • FLINK : 앞 구조체를 가리킴
    • BLINK : 뒤 구조체를 가리킴
  • 변조하고자 하는 프로세스 앞 프로세스의 BLINK뒤 프로세스의 FLINK를 조작하여 서로 연결해주면 가운데 프로세스가 없는것 처럼 여겨지게 된다.

디버깅

  • windbg에서 프로세스 이름으로 정보 찾고 EPROCESS 구조체 내용물 확인
     
    • !process 1774 로 notepad.exe 정보 확인
    • dt_EPROCESS ffff9b8f9b6da0c0로 EPROCESS 구조 확인
       
      • ActiveProcessLinks 멤버에 LIST_ENTRY가 있고, FLINK와 BLINK 정보가 확인된다.
    • notepad.exe 전후 프로세스인 msedge.exe 와 TextInputHost.exe 정보 확인
       
      • msedge.exe : ffff9b8f9b37a080
        • PID : 0xcfc ( → notepad.exe)
        • 주소 + 0x448 = FFFF9B8F'9B37A4C8
      • TextInputHost.exe :
        • PID : 0x1c74 ( ← notepad.exe)
        • 주소 + 0x448 = FFFF9B8F`9B6BB4C8
      • notepad.exe 의 ActiveProcessLinks 속 멤버에서 앞 뒤 프로세스에 유효하게 접근할 수 있음.
        • 두 프로세스 모두 ActiveProcessLinks 멤버로 0xffff9b8f`9b6da508을 가지고 있는데, 이는 notepad.exe 의 ActiveProcesssLinks(+0x448) 주소값임.
        • msedge.exe 가 두번째 멤버가 됨. (BLINK)
        • TextInputHost.exe 가 첫 번째 멤버가 됨.(FLINK)

목표

  • 작업관리자에서 유저모드 어플리케이션 notepad.exe 를 숨기자.
  • 숨기고자 하는 PID 입력해서 넘기고 숨겨보기
  • EProcess의 ActiveProcesssLinks를 고정 오프셋이 아닌, 다른 함수의 실행 결과로 가져올 수 있으면 제일 좋음
    • EProcess.UniqueProcessId + 8로 추정
    • EProcess.UniqueProcessId는 SYSTEM_PROCESS_INFORMATION의 멤버이기도 함.
    • SYSTEM_PROCESS_INFORMATION.UniqueProcessId + 8 위치 값을 가져와 출력해서 ActiveProcessLinks 와 동일한지 비교해보자.
  • 프로세스별 ActiveProcessLinks 오프셋에 접근
    • +0이 FLINK로, 해당 위치를 따라가 대상 프로세스의 BLINK(+0x8)를 BLINK에 있는 값으로 바꿔줘야함
    • +8이 BLINK로 , 해당 위치를 따라가 대상 프로세스의 FLINK(+0x8)을 FLINK에 있는 값으로 바꿔줘야함.
    • 원본 process의 flink와 blink는 커널 오류 방지를 위해 서로가 서로를 가리키게 해줌.

실습

  • PID 입력하여 ActiveProcessLinks 오프셋에 접근하도록 드라이버에 요청하는 유저모드 프로그램 작성
    • SYSTEM_PROCESS_INFORMATION→UniqueProcessId 로는 제대로 접근 불가
    • +0x440이면 FFFF9B8F9B6DA500 가 나와야함.
  • EPROCESS 찾아오는 함수 필요
    • PsLookupProcessByProcessId() 함수
      • pid를 인자로 EPROCESS 객체 반환
      • MmGetSystemRoutineAddress() 함수 사용해 ntoskrnl에서 가져오자.
  • 찾아온 EPROCESS 객체에서 UniqueProcessId의 오프셋을 찾아야함.
    • PsGetProcessId() 함수
    • EPROCESS를 인자로 받아 0x440 위치에 있는 UniqueProcessId를 반환하는 함수
    • 어셈블리에 오프셋 바이트가 박혀있음 → 함수 주소 직접 참조해서 오프셋 바이트 읽어올 수 있어보임.
    • 함수 시작주소 + 3바이트부터 2바이트 읽어오면 오프셋 나옴
    • MmGetSystemRoutineAddress() 함수 사용해 ntoskrnl에서 시작주소 가져오자.
      • 1088 = 0x440
      • 오프셋 성공적으로 가져왔다.
    • 가져온 오프셋과 EPROCESS 구조체 시작주소 더하면 PID 위치에 접근할 수 있다.
      • 3bc = 956 으로 PID 제대로 갖고온게 확인된다.
      • 구해온 오프셋에 8바이트 더하면 ActiveProcessLinks 에 접근할 수 있다.
    • 근데 왜 이렇게 했었지..? 그냥 EPROCESS→ActiveProcessLinks로 갖고올수 있었을텐데
    • 아무튼 진행, FLINK와 BLINK에 제대로 접근 되는것 확인됨.
    • Flink를 따라가 BLINK(+0x8)를 BLINK에 있는 값으로 변경
    • Blink를 따라가 FLINK(+0x0)을 FLINK에 있는 값으로 변경
  • 드라이버 DKOM 코드 실행
    • 전 후 프로세스들의 FLINK,BLINK가 가리키는 주소 체크
      • svchost.exe
      • TextInputHost.exe
      • ~F144C8이 notepad.exe의 ActiveProcessLinks 주소
        • ffff9b8f9af14080+448 = FFFF9B8F9AF144C8
    • 실행 후
      메모장 사라짐
      • svchost.exe
        • ActiveProcessLinks : FFFF9B8F9AE664C8
      • TextInputHost.exe
        • ActiveProcessLinks : FFFF9B8F99C444C8
      • FFFF9B8F9AF144C8 이 아닌 각기 서로의 ActiveProcessLinks를 가리키는게 확인됨 .

ProcessHide 완료


Github

https://github.com/synod2/Kernel_Hooking/tree/main/Window Device Driver/MyDriver5

 

GitHub - synod2/Kernel_Hooking: windows Kernel Hooking

windows Kernel Hooking. Contribute to synod2/Kernel_Hooking development by creating an account on GitHub.

github.com


참고 문서

https://ko.wikipedia.org/wiki/직접_커널_객체_조작 - 위키백과 DKOM

 

직접 커널 객체 조작 - 위키백과, 우리 모두의 백과사전

직접 커널 객체 조작 (DKOM : Direct Kernel Object Manipulation)은 써드 파티 프로세스, 드라이버, 파일에 대한 잠재적인 손상 및 중계 연결을 작업 관리자와 이벤트 스케줄러로부터 숨기는데 사용되는

ko.wikipedia.org

https://1828.tistory.com/entry/Rootkit-DKOM-Direct-Kernel-Object-Manipulation을-이용한-프로세스-은닉 - DKOM

 

[Rootkit] DKOM (Direct Kernel Object Manipulation)을 이용한 프로세스 은닉

Windows Kernel Table이나 Native API를 Hooking하지 않고, Windows Kernel에 의해 관리되는 Kernel Object를 직접적으로 건드리는 기법 EPROCESS 구조체 안에 LIST_ENTRY의 구조체 멤버에서 FLINK와 BLINK를 수정..

1828.tistory.com

https://ghdwn0217.tistory.com/64 - PEB,EPROCESS,KPROCESS

 

EPROCESS,PEB,KPROCESS

프로세스가 처음 실행될 때 커널 메모리에 해당 프로세스의 정보를 지닌 구조체를 생성한다. 때문에 모든 프로세스는 각각의 Eprocess 구조체를 가진다. 또한, 프로세스에서 실행하고 있는 Thread

ghdwn0217.tistory.com

https://www.geoffchappell.com/studies/windows/km/ntoskrnl/inc/ntos/ps/eprocess/index.htm EPROCESS 구조체

 

EPROCESS

Geoff Chappell, Software Analyst

www.geoffchappell.com