【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

下期预告


<<:  [Day9] ORM Injection

>>:  Day10:今天来讲一下microsoft defender for endpoint的装置执行动作

服务反应每慢一秒,转换率就会掉 12%

很多时候在讨论使用者友善,其实最简单粗暴,也最有感的改善之一就是让操作动作变快,也就是让用户更快得到...

ipfs-swarm.key生成代码

#!/bin/bash set -eu function main() { echo -e "/ke...

[LeetCode30] Day27 - 42. Trapping Rain Water

题目 有一个array,size为n,储存的值皆>=0,值代表那格的海拔高度,这样会形成很多凹...

Day16 CSS排版之神flex

今天要介绍十分好用的一个属性display:flex。 有了这个东西以後,不用再担心会排版排到想摔电...

【Side Project】 (老板)订单清单-未完成餐点提示

原本程序的部分打算到上一篇就结束了, 不过有小夥伴问到如何在更改状态的同时<span>中...