PPL Attack

win10配置双机调试: [Win10双机调试(Windbg+VMware+Win10LTSC) - DarkBright - 博客园 (cnblogs.com)](https://www.cnblogs.com/DarkBright/p/10843698.html#:~:text=打开 Windbg ,设置挂接选项: 设置完毕点击OK之后,虚拟系统选择,Debug 选项启动,Windbg成功中断: 双机调试配置成功,可以在命令窗口输入命令控制虚拟机里面的Win10系统 0x04 Windbg的简单使用:)

PPL保护介绍

Windows 的 PPL(Protected Process Light,受保护的进程 Light)是一种安全机制,用于保护关键系统进程和受信任的程序免受恶意软件的篡改和攻击。它通过限制对受保护进程的访问来实现这一点,即使是管理员用户也无法随意修改或终止这些进程。

mimikatzsekurlsa::logonpasswords 指令用于从 Windows 操作系统的内存中提取明文密码、哈希值、PIN 码和 Kerberos 票据等凭据信息。它主要针对 LSASS(Local Security Authority Subsystem Service)进程,该进程负责在 Windows 系统中管理本地安全策略和用户身份验证。sekurlsa::logonpasswords` 通过访问 LSASS 进程的内存空间,从中提取存储的凭据信息。

但是我们可以发现,即使我们已经提权了,有了SeDebugPrivilege,但是依旧报了一个0xc0000005的错误,这就是访问了不可访问的内存导致的一个错误

![1728789129090](PPL Attack/1728789129090.png)

那么该意识到不对劲了,上一节我们刚说过,有了SeDebugPrivilege,访问系统进程应该是没问题了吧(除了我们之前做的会话Session隔离,但是那个是关于线程注入的),但是为什么这下又不行了呢??

没错,这就是开了PPL导致的,即使拥有了SeDebugPrivilege,但是仍然不能对其操作

进程的保护级别已添加到 EPROCESS 内核结构中,并且更具体地存储在其 Protection 成员中。该 Protection 成员是一个 PS_PROTECTION 结构,其中又包含_PS_PROTECTED_TYPE_PS_PROTECTED_SIGNER 这俩结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
typedef struct _PS_PROTECTION {
union {
UCHAR Level;
struct {
UCHAR Type : 3;
UCHAR Audit : 1; // Reserved
UCHAR Signer : 4;
};
};
} PS_PROTECTION, * PPS_PROTECTION;

typedef enum _PS_PROTECTED_TYPE
{
PsProtectedTypeNone = 0,
PsProtectedTypeProtectedLight = 1,
PsProtectedTypeProtected = 2
} PS_PROTECTED_TYPE, * PPS_PROTECTED_TYPE;


typedef enum _PS_PROTECTED_SIGNER
{
PsProtectedSignerNone = 0, // 0
PsProtectedSignerAuthenticode, // 1
PsProtectedSignerCodeGen, // 2
PsProtectedSignerAntimalware, // 3
PsProtectedSignerLsa, // 4
PsProtectedSignerWindows, // 5
PsProtectedSignerWinTcb, // 6
PsProtectedSignerWinSystem, // 7
PsProtectedSignerApp, // 8
PsProtectedSignerMax // 9
} PS_PROTECTED_SIGNER, * PPS_PROTECTED_SIGNER;

PsProtectedTypeProtectedLight (值为 1)

  • 描述:表示该进程是轻量级受保护进程(Protected Light Process,简称 PPL)。这种类型的进程受到某些限制,以防止未授权的访问,但不如完整的受保护进程严格。
  • 适用场景:通常用于某些系统进程或服务,它们需要一定程度的保护,通常是在处理敏感数据或执行关键任务时。

sPsProtectedTypeProtected (值为 2)

  • 描述:表示该进程是完全受保护的进程(Protected Process)。这类进程受到更严格的保护机制,以防止未授权访问和修改。
  • 适用场景:主要用于重要的系统进程(如安全进程),这些进程需要防止恶意软件或其他未经授权的程序的干扰。比如,Windows 的某些安全功能和防病毒程序可能会以这种方式运行。

下面这个表格是对应的级别

![1728893208713](PPL Attack/1728893208713.png)

用Windbg可以对比加了保护和没有保护的进程

这是没有加PPL保护的进程:

![1728805271682](PPL Attack/1728805271682.png)

这是加了PPL保护的进程:

![1728805305057](PPL Attack/1728805305057.png)

实践测试下PPL保护

例如我们在Process Explore可以发现有一个进程叫MpDefenderCoreService.exe,这个进程开了PPL保护

![1728789244531](PPL Attack/1728789244531.png)

我们写了一个代码测试一下,看看能不能操作PPL保护的程序

![1728789371008](PPL Attack/1728789371008.png)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <windows.h>

int main() {
// 1. Get the target process ID (PID). Replace with your target process's PID.
DWORD targetProcessId = 6068; // REPLACE WITH ACTUAL PID

// 2. Open a handle to the target process. Requires appropriate privileges.
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcessId);
if (hProcess == NULL) {
std::cerr << "Failed to open process. Error: " << GetLastError() << std::endl;
return 1;
}

// 3. Allocate memory in the target process.
LPVOID baseAddress = VirtualAllocEx(hProcess, NULL, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (baseAddress == NULL) {
std::cerr << "Failed to allocate memory. Error: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return 1;
}

// 4. The code to inject. This is a simple example; replace with your actual code.
char code[] = {
0x90, 0x90, 0x90, 0x90, // NOP instructions (no operation)
0xCC // INT 3 (breakpoint instruction)
};
SIZE_T bytesWritten;

// 5. Write the code to the allocated memory.
if (!WriteProcessMemory(hProcess, baseAddress, code, sizeof(code), &bytesWritten)) {
std::cerr << "Failed to write memory. Error: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, baseAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}

// 6. (Optional) Create a remote thread to execute the injected code. This step is crucial for actually running the injected code. Requires additional API calls. See example below.

// 7. Clean up.
VirtualFreeEx(hProcess, baseAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
std::cout << "Code injection (partially) completed." << std::endl;
return 0;
}

可以看到的是,目前我们已经拥有了SeDebugPrivilege

![1728789425655](PPL Attack/1728789425655.png)

BUT!!!果然有了PPL,我们就不能够打开了

![1728789481808](PPL Attack/1728789481808.png)

遍历出所有受PPL保护的进程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "header.h"
#define DebugPrint(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,__VA_ARGS__)
#define PROCESS_QUERY_INFORMATION 0x0400
bool FindProcessProtect(PEPROCESS m_eprocess)
{
PS_PROTECTION* ps_protection = (PS_PROTECTION*)((SIZE_T)m_eprocess + 0x6fa);
PCHAR FileName = (PCHAR)((SIZE_T)m_eprocess + 0x450);
if (ps_protection->u.Type == PsProtectedTypeProtectedLight)
{
DebugPrint("进程%s具有PPL保护",FileName);
switch (ps_protection->u.Signer)
{


case PsProtectedSignerNone:
{
DebugPrint(" PsProtectedSignerNone\n");
break;
}
case PsProtectedSignerAuthenticode:
{
DebugPrint(" PsProtectedSignerAuthenticode\n");
break;
}
case PsProtectedSignerCodeGen:
{
DebugPrint(" PsProtectedSignerCodeGen\n");
break;
}
case PsProtectedSignerAntimalware:
{
DebugPrint(" PsProtectedSignerAntimalware\n");
break;
}
case PsProtectedSignerLsa:
{
DebugPrint(" PsProtectedSignerLsa\n");
break;
}
case PsProtectedSignerWindows:
{
DebugPrint(" PsProtectedSignerWindows\n");
break;
}
case PsProtectedSignerWinTcb:
{
DebugPrint(" PsProtectedSignerWinTcb\n");
break;
}
case PsProtectedSignerWinSystem:
{
DebugPrint(" PsProtectedSignerWinSystem\n");
break;
}
case PsProtectedSignerApp:
{
DebugPrint(" PsProtectedSignerApp\n");
break;
}
case PsProtectedSignerMax:
{
DebugPrint(" PsProtectedSignerMax\n");
break;
}
}
}
else if (ps_protection->u.Type == PsProtectedTypeProtected)
{
DebugPrint("进程%s具有PP保护\n", FileName);



}

return true;

}




VOID Traverse_EPROCESS()
{
PEPROCESS m_EPROCESS = PsGetCurrentProcess();
PEPROCESS original_EPROCESS = m_EPROCESS;

//获取到EPROCESS链表
_LIST_ENTRY ActiveProcessLinks = *(_LIST_ENTRY*)((SIZE_T)m_EPROCESS + 0x2F0);
m_EPROCESS = (PEPROCESS)((SIZE_T)ActiveProcessLinks.Flink - 0x2f0);


while (1)
{
if (m_EPROCESS == original_EPROCESS)
{
break;
}

if (FindProcessProtect(m_EPROCESS) == false)
{
//获取到进程名:
PCHAR Process_Name = (PCHAR)((SIZE_T)m_EPROCESS + 0x450);
DebugPrint("%s具有保护", Process_Name);
}
//获取到EPROCESS链表
ActiveProcessLinks = *(_LIST_ENTRY*)((SIZE_T)m_EPROCESS + 0x2F0);
m_EPROCESS = (PEPROCESS)((SIZE_T)ActiveProcessLinks.Flink - 0x2f0);
}

}

结果长这样:

![1728829223517](PPL Attack/1728829223517.png)

启用LSA保护

在默认情况下,Lsass是没有PPL保护的,但是我们如果开启LSA保护的花,那么Lsass就会有PPL保护

在三环层面具体就是去修改注册表
注册表路径为:HKLM\SYSTEM\CurrentControlSet\Control\Lsa
然后添加一个 DWORD 值:RunAsPPL ,并把值从0改为1即可开启 LSA

如图所示:
![1728895402213](PPL Attack/1728895402213.png)

然后重启一下电脑,再次打开,可以发现此时lsass.exe已经有了PPL的标志
![1728895496670](PPL Attack/1728895496670.png)

开启LSA保护之后,也就是Lsass有了PPL保护之后,我们发现现在要去Lsass拿东西已经被禁止掉了,归根结底就是因为权限不够

![1728895200390](PPL Attack/1728895200390.png)

如何强制关闭LSA

查阅资料后发现:

PPL 机制在内核函数 NtOpenProcess 进行实现,当我们访问进程时最终都会调用该函数;NtOpenProcess 位于 ntoskrnl.exe

我们在RtlTestProtectedAccess这个API下断点

![1728896887101](PPL Attack/1728896887101.png)

可以看到NtOpenProcess就是调用RtlTestProtectedAccess来判断PPL是否满足条件,再决定是否API调用成功

![1728897061052](PPL Attack/1728897061052.png)

因此,我们猜测直接修改EPROCESS结构里面的PPL结构,就是破掉LSA的关键

找到EPROCESS的 _PS_PROTECTION,修改成0

![1728897914165](PPL Attack/1728897914165.png)

再用Process Explorer去查看,发现PPL保护已经没了

![1728898078942](PPL Attack/1728898078942.png)

发现mimikatz又可以正常用了!

![1728898322270](PPL Attack/1728898322270.png)

日后学习

AntiAntiVirusNotes/WeakDefender.md at master · xf555er/AntiAntiVirusNotes (github.com)

与Win Defender对抗