有很多工具需要启用SeDebugPrivilege才能正常使用,比如mimikatz就有个很经典的 privilege::debug.如果没有这个权限,administrator用openprocess可能都会报错,所以需要提升,管理员组拥有该权限但默认禁用,普通用户不拥有该权限,也就是说仅仅只有管理员账户能启用该权限。这个权限提供了强大的能力以至于可以忽视安全上下文行动。

我们会用到AdjustTokenPrivileges和LookupPrivilegeValueA,以及Token PRIVILEGES结构树

Token PRIVILEGES结构树

typedef struct _TOKEN_PRIVILEGES {
DWORD PrivilegeCount;
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;

PrirvilegeCount 表示Privileges数组中有多少个元素 Privileges 指向LUID_AND_ATTRIBUTES结构,该结构用于具体表示某个权限的开启或关闭

typedef struct _LUID_AND_ATTRIBUTES {
LUID Luid;
DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;`

Luid 选择一个LUID值,该值对应一个权限 Attributes 选择指定LUID的权限的开放或关闭,其详细参数如下

SE_PRIVILEGE_ENABLED The privilege is enabled.
SE_PRIVILEGE_ENABLED_BY_DEFAULT The privilege is enabled by default.
SE_PRIVILEGE_REMOVED Used to remove a privilege. For details, see AdjustTokenPrivileges.
SE_PRIVILEGE_USED_FOR_ACCESS The privilege was used to gain access to an object or service. This flag is used to identify the relevant privileges in a set passed by a client application that may contain unnecessary privileges.

下面我们来展示如何利用windows 编程获取该权限。

这只是一个函数demo,修改当前进程的权限。

BOOL GetDebugPriv() {
HANDLE Token;
TOKEN_PRIVILEGES tp;
LUID Luid;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &Token)) { //TOKEN_ADJUST_PRIVILEGES代表要修改令牌权限
std::cout << "OpenProcessToken ERROR" << GetLastError() << std::endl;
return false;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid)) {
std::cout << "LookupPrivilegeValue ERROR" << GetLastError() << std::endl;
return false;
}
tp.Privileges[0].Luid = Luid;
if (!AdjustTokenPrivileges(Token, FALSE, &tp, sizeof(tp), NULL, NULL) ){
std::cout << "AdjustTokenPrivileges ERROR" << GetLastError() << std::endl;
return false;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) { //ERROR_NOT_ALL_ASSIGNED的出现原因是,用户权限本身就没有sedebugprivilege
return false;
}
else {
return true;
}
}

如果觉得我的文章对您有用,请随意打赏。您的支持将