Chromium 进程降权和提权模拟示例c++
一、背景知识概念参考微软链接:
强制完整性控制 - 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);
}} // namespaceint 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博客