Chromium 进程降权和提权模拟示例c++

 一、背景知识概念参考微软链接:

强制完整性控制 - Win32 应用程序 |Microsoft 学习

授权) (模拟级别 - Win32 apps | Microsoft Learn

DuplicateTokenEx 函数 (securitybaseapi.h) - Win32 apps | Microsoft Learn

特权常量 (Winnt.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). 

sid和字符串互转函数参考:

ConvertSidToStringSid

convertStringSidToSid

ConvertSidToStringSidA 函数 (sddl.h) - Win32 apps | Microsoft Learn

二、代码:

#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博客 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值