iT邦幫忙

2021 iThome 鐵人賽

DAY 9
1
Security

打通任督二脈奇幻之旅 - 用 30 天探索 Windows 底層運作原理系列 第 9

【Day 09】- 今天來創造 Ghost Process(基於斷鏈隱藏 Process 的手法)

Agenda

  • 資安宣言
  • 測試環境與工具
  • 學習目標
  • 技術原理與程式碼
  • References
  • 下期預告

資安宣言


撰寫本系列文章目的在於提升資訊安全之實務能力,
並透過實作體悟到資訊安全領域的重要性,
本系列所有文章之內容皆有一定技術水平,
不得從事非法行為、惡意攻擊等非法活動,
「一切不合法規之行為皆受法律所約束」,
為了避免造成公司、廠商或玩家之間困擾,
所有實作不會拿已上市產品、Online Game 等等來作範例學習,
且部分具有深度、價值之內容,將會提升一定閱讀門檻(不對該技術做分析、解說),
請勿透過本系列文章所學,從事任何非法活動,請不要以身試法!!!


測試環境與工具

學習目標

  • 1.了解 EProcess 中的 ActiveProcessLinks
  • 2.修改 ActiveProcessLinks 達到隱藏 Process 的效果

技術原理與程式碼

首先開始前要先說一下,
小弟我目前還屬於菜鳥階段,正不斷努力學習中,
若有發現錯誤或不妥之處還請不吝賜教。
歡迎大家多多留言,互相交流交流。

那就開始今天的主題吧~~
/images/emoticon/emoticon08.gif

今天要來講講 EProcess 中的 ActiveProcessLinks,
首先當然是先打開強大的工具:WinDbg

  1. 使用 Administrator 權限打開 WinDbg
  2. 選 Kernel Debug...
    • (需要打開測試模式,依照提示的指示進行操作)
  3. 選 Local 按確定
    • (需要打開測試模式,依照提示的指示進行操作)
  4. 輸入 !process 0 0 notepad.exe
    • 查看 notepad.exe
    lkd> !process 0 0 notepad.exe
    PROCESS ffffe30718e4c080
        SessionId: 1  Cid: 0a58    Peb: 329620000  ParentCid: 1054
        DirBase: 1becc000  ObjectTable: ffffcf018b67e900  HandleCount: 263.
        Image: notepad.exe
    
  5. 輸入 dt _eprocess ffffe30718e4c080
    • 查看 notepad.exe 的 eprocess
    lkd> dt _eprocess ffffe30718e4c080
    nt!_EPROCESS
       +0x000 Pcb              : _KPROCESS
       +0x2d8 ProcessLock      : _EX_PUSH_LOCK
       +0x2e0 UniqueProcessId  : 0x00000000`00000a58 Void
      >+0x2e8 ActiveProcessLinks : _LIST_ENTRY [ 0xffffe307`1787b368 - 0xffffe307`186f98a8 ]
       +0x2f8 RundownProtect   : _EX_RUNDOWN_REF
    
       --- --- --- ---
       --- --- --- ---
       --- --- --- ---
    
       +0x448 ImageFilePointer : 0xffffe307`17e50080 _FILE_OBJECT
    -->+0x450 ImageFileName    : [15]  "notepad.exe"
       +0x45f PriorityClass    : 0x2 ''
       +0x460 SecurityPort     : (null) 
    

此時此刻,
我們可以在 EProcess 中看到 +0x2e8 處有個 ActiveProcessLinks,
它是 _LIST_ENTRY 結構的表,這張表是雙向鏈表,
只要是執行中的 Process 都可以列舉這張表來找到,
可以輸入 dt _LIST_ENTRY 看一下它的樣貌:

lkd> dt _LIST_ENTRY
nt!_LIST_ENTRY
   +0x000 Flink   : Ptr64 _LIST_ENTRY
   +0x008 Blink   : Ptr64 _LIST_ENTRY

所以,
Flink 指向 0xffffe307`1787b368
Blink 指向 0xffffe307`186f98a8

Flink 是指向下一個 EProcess 的 ActiveProcessLinks,
Blink 是指向前一個 EProcess 的 ActiveProcessLinks,

我們手動來看看這個 notepad.exe 的下一個 Process 是誰,
輸入:da 0xffffe307`1787b368-0x2e8+0x450

-0x2e8 是因為 ActiveProcessLinks 是在 EProcess +0x2e8 的位置,
扣除後就會回到 EProcess 正確的位址。

+0x450 是因為 ImageFileName 距離 EProcess +0x450 的位置,
加上後就會走到 ImageFileName 這個位置。

所以就會看到:

lkd> da 0xffffe307`1787b368-0x2e8+0x450
ffffe307`1787b4d0  "audiodg.exe"

這樣就手動列舉出 notepad.exe 的下一個 Process 是 audiodg.exe,
那 notepad.exe 前一個呢?同樣道理。

所以有想到要如何隱藏 Process 了嗎?
做壞事我想最快 XD
/images/emoticon/emoticon01.gif

我整理了資訊如下:

Process Name EProcess ActiveProcessLinks Flink Blink
svchost.exe 0xffffe307186F95C0 0xffffe307186f98a8 0xffffe30718e4c368 0xffffe307167958a8
notepad.exe 0xffffe30718e4c080 0xffffe30718e4c368 0xffffe3071787b368 0xffffe307186f98a8
audiodg.exe 0xffffe3071787b080 0xffffe3071787b368 0xffffe307187076e8 0xffffe30718e4c368

ActiveProcessLinks = EProcess + 0x2e8
Flink = 下一個 EProcess 的 ActiveProcessLinks
Blink = 上一個 EProcess 的 ActiveProcessLinks

所以知道怎麼做了嗎?
流程大概是這樣:

  1. 找到要隱藏的 Process 的 EProcess Address
    • 方法一:列舉 EProcess 然後透過 +0x450 處的 ImageFileName 來判斷
    • 方法二:直接 Call API 傳遞 PID 拿 EProcess Address
  2. 下一個 EProcess 的 ActiveProcessLinks 的 Blink 指向上一個 EProcess 的 ActiveProcessLinks
  3. 上一個 EProcess 的 ActiveProcessLinks 的 Flink 指向下一個 EProcess 的 ActiveProcessLinks

完成後就會像這樣:

Process Name EProcess ActiveProcessLinks Flink Blink
svchost.exe 0xffffe307186F95C0 0xffffe307186f98a8 0xffffe3071787b368 0xffffe307167958a8
notepad.exe 0xffffe30718e4c080 0xffffe30718e4c368 0xffffe3071787b368 0xffffe307186f98a8
audiodg.exe 0xffffe3071787b080 0xffffe3071787b368 0xffffe307187076e8 0xffffe307186f98a8

程式碼怎麼寫呢?請看 hidden Project 的 PsMonitor.c
我放一份在這:

VOID UnlinkProcessFromList(PLIST_ENTRY Current)
{ // https://github.com/landhb/HideProcess/blob/master/driver/hideprocess.c
	PLIST_ENTRY Previous, Next;

	Previous = (Current->Blink);    
	Next = (Current->Flink);

	// Loop over self (connect previous with next)
	Previous->Flink = Next;
	Next->Blink = Previous;

	// Re-write the current LIST_ENTRY to point to itself (avoiding BSOD)
	Current->Blink = (PLIST_ENTRY)&Current->Flink;
	Current->Flink = (PLIST_ENTRY)&Current->Flink;
}

隱藏前:

隱藏後:

/images/emoticon/emoticon07.gif
注意!已經有按照 PID 排序 XD

注意!注意!
使用這項技術會觸發 PatchGuard!!!
Kernel_Patch_Protection

觸發後長什麼樣子?

圖片來源:poc-published-for-new-microsoft-patchguard-kpp-bypass

讀者:所以有辦法繞過嗎?
我:有!開啟測試模式 XDDDDD
讀者:我是說有在一般環境下運作的方法嗎?(不開測試模式)
我:有!剛剛上面那ㄍ連結好像是今年的ㄛ :D

多多思考,多多研究,多多爬文,多多交流
就會知道如何 Bypass PatchGuard!!!!!
這部份就不說了。

/images/emoticon/emoticon39.gif

好了,這篇就講到這結束了,
大家若有發現哪裡寫得不好或錯誤的地方,都留個言討論一下吧 XD
那我們下期見 o( ̄▽ ̄)ブ

References

下期預告


上一篇
【Day 08】- 見鬼了(っ °Д °;)っ我明明沒有啟動這支程式…
下一篇
【Day 10】- 藏起來的 Process 真的看不見摸不著?(講解找出斷鏈後的 Process 方法)
系列文
打通任督二脈奇幻之旅 - 用 30 天探索 Windows 底層運作原理15

尚未有邦友留言

立即登入留言