一、背景知识概念参考微软链接:
强制完整性控制 - Win32 应用程序 |Microsoft 学习
授权) (模拟级别 - Win32 apps | Microsoft Learn
DuplicateTokenEx 函数 (securitybaseapi.h) - Win32 apps | Microsoft Learn
本文主要演示 low, medium, high, and system 四种权限创建和使用例子:
Windows defines four integrity levels: low, medium, high, and system
integrity levels定义如下:
C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\winnt.h
#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
#define SECURITY_MANDATORY_LOW_RID (0x00001000L)
#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
#define SECURITY_MANDATORY_MEDIUM_PLUS_RID (SECURITY_MANDATORY_MEDIUM_RID + 0x100)
#define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
或者字符串也一样:
// INTEGRITY_LEVEL_SYSTEM: "S-1-16-16384" System Mandatory Level
// INTEGRITY_LEVEL_HIGH: "S-1-16-12288" High Mandatory Level
// INTEGRITY_LEVEL_MEDIUM: "S-1-16-8192" Medium Mandatory Level
// INTEGRITY_LEVEL_MEDIUM_LOW: "S-1-16-6144"
// INTEGRITY_LEVEL_LOW: "S-1-16-4096" Low Mandatory Level
// INTEGRITY_LEVEL_BELOW_LOW: "S-1-16-2048"
// INTEGRITY_LEVEL_UNTRUSTED: "S-1-16-0" Untrusted Mandatory Level
Low (SID: S-1-16-4096),
Medium (SID: S-1-16-8192),
High (SID: S-1-16-12288)
System (SID: S-1-16-16384).
二、代码:
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <windows.h>
#include <iostream>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/process/launch.h"
#include "base/process/process.h"
#include "base/threading/thread.h"
#include "base/win/access_token.h"
#include "base/win/scoped_handle.h"
#include "base/win/sid.h"
#include "build/build_config.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
namespace {
// Copies the process token making it a primary impersonation token.
// The returned handle will have |desired_access| rights.
bool CopyProcessToken(DWORD desired_access,
base::win::ScopedHandle* token_out) {
HANDLE temp_handle;
if (!::OpenProcessToken(::GetCurrentProcess(),
TOKEN_DUPLICATE | desired_access, &temp_handle)) {
LOG(ERROR) << "Failed to open process token";
return false;
}
base::win::ScopedHandle process_token(temp_handle);
if (!::DuplicateTokenEx(process_token.Get(), desired_access, nullptr,
SecurityImpersonation, TokenPrimary, &temp_handle)) {
LOG(ERROR) << "Failed to duplicate the process token";
return false;
}
token_out->Set(temp_handle);
return true;
}
void RunAccessTokenTest(DWORD integrity_level) {
base::win::ScopedHandle privileged_token;
CopyProcessToken(MAXIMUM_ALLOWED, &privileged_token);
absl::optional<base::win::AccessToken> token =
base::win::AccessToken::FromToken(std::move(privileged_token));
token->SetIntegrityLevel(integrity_level);
DWORD level = token->IntegrityLevel();
if (level == integrity_level) {
LOG(INFO) << "IntegrityLevel: " << level;
} else {
LOG(ERROR) << "failed IntegrityLevel: " << level;
}
base::LaunchOptions options;
options.as_user = token->get();
static const base::CommandLine::CharType* argvTmp[] = {
FILE_PATH_LITERAL("C:/Windows/System32/Notepad.exe")};
base::CommandLine command_line(1, argvTmp);
LOG(INFO) << "Browser: " << command_line.GetCommandLineString();
base::Process child_process = base::LaunchProcess(command_line, options);
}
} // namespace
int main(int argc, const char* argv[]) {
// SYSTEM HIGH MEDIUM LOW UNTRUSTED
// Note: These levels map to SIDs under the hood.
// INTEGRITY_LEVEL_SYSTEM: "S-1-16-16384" System Mandatory Level
// INTEGRITY_LEVEL_HIGH: "S-1-16-12288" High Mandatory Level
// INTEGRITY_LEVEL_MEDIUM: "S-1-16-8192" Medium Mandatory Level
// INTEGRITY_LEVEL_MEDIUM_LOW: "S-1-16-6144"
// INTEGRITY_LEVEL_LOW: "S-1-16-4096" Low Mandatory Level
// INTEGRITY_LEVEL_BELOW_LOW: "S-1-16-2048"
// INTEGRITY_LEVEL_UNTRUSTED: "S-1-16-0" Untrusted Mandatory Level
// DWORD integrity_level PSID 定义如下
// #define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
// #define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
// #define SECURITY_MANDATORY_LOW_RID (0x00001000L)
// #define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
// #define SECURITY_MANDATORY_MEDIUM_PLUS_RID (SECURITY_MANDATORY_MEDIUM_RID
// + 0x100) #define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
// #define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
// #define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
base::CommandLine::Init(argc, argv);
RunAccessTokenTest(SECURITY_MANDATORY_SYSTEM_RID); // system权限进程
RunAccessTokenTest(SECURITY_MANDATORY_HIGH_RID); // high权限进程
RunAccessTokenTest(SECURITY_MANDATORY_MEDIUM_RID); // medium权限进程
RunAccessTokenTest(SECURITY_MANDATORY_LOW_RID); // low权限进程
return 0;
}
三、编译之后运行效果如图:
可以看到已经按照预定完整性级别创建了进程。
system级别创建失败 是因为02-test.exe进程级别是high的,按照规则不可以模拟出大于原始进程完整性级别。强制完整性控制 - Win32 应用程序 |Microsoft 学习
四、总结:
核心也是利用DuplicateTokenEx复制进程token完整性级别,在设置到token中【SetTokenInformation】
SetIntegrityLevel函数定义如下:
template <typename T>
bool Set(const ScopedHandle& token,
TOKEN_INFORMATION_CLASS info_class,
T& value) {
return !!::SetTokenInformation(token.get(), info_class, &value,
sizeof(value));
}
bool AccessToken::SetIntegrityLevel(DWORD integrity_level) {
absl::optional<base::win::Sid> sid = Sid::FromIntegrityLevel(integrity_level);
if (!sid) {
::SetLastError(ERROR_INVALID_SID);
return false;
}
TOKEN_MANDATORY_LABEL label = {};
label.Label.Attributes = SE_GROUP_INTEGRITY;
label.Label.Sid = sid->GetPSID();
return Set(token_, TokenIntegrityLevel, label);
}
base\win\access_token.cc
base\win\sid.cc
也可以参考windows 进程降权和提权代码示例(2)-CSDN博客
标签:MANDATORY,降权,示例,16,c++,token,base,SECURITY,include From: https://blog.csdn.net/jangdong/article/details/143609895