XXX-xxxx.sys 句柄相关
该帖仅供图一乐(学习),无不良引导。(已厚码)
Object回调部分:
伪代码:
1.1 IsNtProc
判断该进程 TOKEN 的 LUID.LowPart 是否为999 、997、996,SESSIONID为0的进程符合条件,伪代码如下:
1.2 SetProcHandleAtt_HaveWhitelist
如果有白名单表,那么特殊处理,进到这个函数:
伪代码:
1.2.1 GetPtNotAtt
获取这个句柄不应该有的权限。伪代码如下:
1.2.2 CheckWhiteAtt
获取这个句柄允许的权限(通过白名单字符串匹配)伪代码如下:(Context.Type选择权限)
1.2.3 CheckNameHaveStrByPid
这个函数就是匹配 进程路径和白名单字符串,如果是匹配返回1。
1
2
3
4
5
6
7
8
9
10
|
struct _ProcInformation
/
/
GetProcInfoPointerByPidEx 返回的结构体大致如下
{
ULONG64 SessionId;
ULONG64 ThreadCount;
ULONG64 CreateTime;
ULONG64 Uk;
WCHAR ExeName[
260
];
ULONG32 FatherPid;
WCHAR FileName[
260
];
};
|
动态调试拿到“白名单”
对应匹配顺序、权限1、权限2,请看下图(关键信息已打码)
匹配顺序从上到下:(权限指的是可保留的权限)补充:
类型
2:SESSIONID = 0进程打开受保护进程句柄
3:父进程打开受保护进程句柄 或 受保护进程打开自己的句柄
回调的Context结构如下:
1
2
3
4
5
6
7
8
|
typedef struct _ProcObjCallBackContext{
ULONG32
Type
;
/
/
Type
=
1
选择权限
1
Type
=
2
选择权限
2
(可是权限
1
权限
2
设置成了一样的值,所以这个没啥用)
ULONG32 Uk1;
/
/
未知
ULONG64 OpenPcb;
/
/
句柄的PEPROCESS (受保护进程的PEPROCESS)
ULONG64 ObjectType;
/
/
句柄类型
ULONG64 Uk2;
/
/
未知
ULONG64 PHandleTableEntry_Att;
/
/
属性指针
}ProcObjCallBackContext,
*
PProcObjCallBackContext;
|
Context.Type 选择 权限 1 还是 2,但其实都一样。
线程扫描句柄降权部分:
一个线程,会不断的扫描进程,使用 ExEnumHandleTable 对进程句柄进行处理。
2.1 GetAtt2
对句柄权限的处理同句柄回调部分。
换言之,通过了句柄回调的句柄,也就不会再对它进行降权了。
一些手法:
“白名单”中有两条是相同的(匹配路径的字符串相同,但是类型和可保留权限不同)。
一条类型为 1 : 可保留 0x83a 句柄权限。
一条类型为 2 : 可保留 0x33 句柄权限。
1
2
3
4
|
类型
1
:普通进程打开受保护进程句柄
2
:SESSIONID
=
0
进程打开受保护进程句柄
3
:父进程打开受保护进程句柄 或 受保护进程打开自己的句柄
|
于是就有了这非常逆天的一幕:
(管理员权限拿到 0x83a 权限的句柄 可读写)
只需要 进程路径满足“白名单”即可拿到读写权限句柄。
(当然了也可以用SESSIONID = 0 且 进程路径符合“白名单” 的进程,可以拿到 0x33 权限的句柄)
更多【XXX-xxxx.sys 句柄相关】相关视频教程:www.yxfzedu.com