安全矩阵

 找回密码
 立即注册
搜索
查看: 2245|回复: 0

实战 | BypassUAC的研究和思路

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-10-28 15:34:17 | 显示全部楼层 |阅读模式
原文链接:实战 | BypassUAC的研究和思路

基础知识
用户帐户控制(User Account Control)是Windows Vista(及更高版本操作系统)中一组新的基础结构技术,可以帮助阻止恶意程序(有时也称为“恶意软件”)损坏系统,同时也可以帮助组织部署更易于管理的平台。
使用UAC,应用程序和任务总是在非管理员帐户的安全上下文中运行,但管理员专门给系统授予管理员级别的访问权限时除外。UAC会阻止未经授权应用程序的自动安装,防止无意中对系统设置进行更改。
用户帐户控制(UAC)是新版Windows的核心安全功能,也是其最常被人误解的众多安全功能当中的一种。

而在这些程序里面,有的需要授权、有的不需要,是因为UAC是分授权等级的
首先请按Win+R,输入gpedit.msc,打开组策略。
然后我们在左侧窗口找到“计算机配置–Windows设置–安全设置–本地策略–安全选项”,再在右侧窗口找到“用户帐户控制:管理员批准模式中管理员的提升权限提示的行为”,双击该条目,打开设置窗口,如下图:

不提示直接提升:关闭UAC,需要权限时直接提升权限。
在安全桌面上提示凭据:需要权限时在安全桌面上输入管理员密码提升权限。
在安全桌面上同意提示:需要权限时在安全桌面上选择“允许”提升权限。
提示凭据:需要权限时在普通窗口中输入管理员密码提升权限。
同意提示:需要权限时在普通窗口中选择“允许”提升权限。
非 Windows 二进制文件的同意提示:(默认设置)当非 Microsoft 应用程序的某个操作需要提升权限时,选择“允许”提升权限。
因为普通应用执行权限有限,某些操作必然会要求更高的管理员权限。此时,通常就需要一个权限提升的操作。程序可以向系统请求提权,系统会将此请求通过提一个提示框,请用户确认。
如果当前用户的用户组权限不是管理员,提权操作是要求输入管理员密码的,这点和在Linux中的相应操作类似。
•程序只能在运行前要求提权。如果已经在运行了,那么将失去申请提权的能力•权限提升仅对此次进程有效
提升权限的操作大致有两个:
•自动提权请求•手动提权请求
手动提权就是“以管理员身份运行”,自动提权请求就是程序本身就一运行就开始申请权限,如:注册表编辑器
在开发的过程中,程序员若要开发一个程序,可以在编译器配置,写入一个配置文件,用于向系统标识该应用程序是必须要管理员权限运行的。
visual studio里面的uac
在visual studio里面有一个manifest文件,这个文件本质上是一个xml文件,用于标识当前应用程序的配置属性。其中这几个级别明细如下
•aslnvoker 默认权限•highestAvailable 最高权限•requireAdministrator 必须是管理员权限

将编译选项调整为requireAdministrator,则当用户运行程序后,将获得管理员权限会话,不需要绕过UAC。
挖掘白名单的uac程序有一些系统程序是会直接获取管理员权限同时不弹出UAC弹窗,这类程序被称为白名单程序。这些程序拥有autoElevate属性的值为True,会在启动时就静默提升权限。
那么我们要寻找的uac程序需要符合以下几个要求:
  1. 1. 程序的manifest标识的配置属性 autoElevate 为true
  2. 2. 程序不弹出UAC弹窗
  3. 3. 从注册表里查询Shell\Open\command键值对
复制代码

首先是寻找autoElevate为true的程序,这里就写一个py脚本去批量跑一下,这里就找system32目录下面的
  1. import os
  2. from subprocess import *

  3. path = 'c:\windows\system32'
  4. files = os.listdir(path)
  5. print(files)
  6. def GetFileList(path, fileList):
  7.     newDir = path
  8.     if os.path.isfile(path):
  9.         if path[-4:] == '.exe':
  10.             fileList.append(path)
  11.     elif os.path.isdir(path):
  12.         try:
  13.             for s in os.listdir(path):
  14.                 newDir=os.path.join(path,s)
  15.                 GetFileList(newDir, fileList)
  16.         except Exception as e:
  17.             pass
  18.     return fileList
  19. files = GetFileList(path, [])
  20. print(files)
  21. for eachFile in files:
  22.     if eachFile[-4:] == '.exe':
  23.         command = r'.\sigcheck64.exe -m {} | findstr auto'.format(eachFile)
  24.         print(command)
  25.         p1 = Popen(command, shell=True, stdin=PIPE, stdout=PIPE)
  26.         if '<autoElevate>true</autoElevate>' in p1.stdout.read().decode('gb2312'):
  27.             copy_command = r'copy {} .\success'.format(eachFile)
  28.             Popen(copy_command, shell=True, stdin=PIPE, stdout=PIPE)
  29.             print('[+] {}'.format(eachFile))
  30.             with open('success.txt', 'at') as f:
  31.                 f.writelines('{}\n'.format(eachFile))
复制代码



整理之后exe如下所示
  1. c:\windows\system32\bthudtask.exe
  2. c:\windows\system32\changepk.exe
  3. c:\windows\system32\ComputerDefaults.exe
  4. c:\windows\system32\dccw.exe
  5. c:\windows\system32\dcomcnfg.exe
  6. c:\windows\system32\DeviceEject.exe
  7. c:\windows\system32\DeviceProperties.exe
  8. c:\windows\system32\djoin.exe
  9. c:\windows\system32\easinvoker.exe
  10. c:\windows\system32\EASPolicyManagerBrokerHost.exe
  11. c:\windows\system32\eudcedit.exe
  12. c:\windows\system32\eventvwr.exe
  13. c:\windows\system32\fodhelper.exe
  14. c:\windows\system32\fsquirt.exe
  15. c:\windows\system32\FXSUNATD.exe
  16. c:\windows\system32\immersivetpmvscmgrsvr.exe
  17. c:\windows\system32\iscsicli.exe
  18. c:\windows\system32\iscsicpl.exe
  19. c:\windows\system32\lpksetup.exe
  20. c:\windows\system32\MSchedExe.exe
  21. c:\windows\system32\msconfig.exe
  22. c:\windows\system32\msra.exe
  23. c:\windows\system32\MultiDigiMon.exe
  24. c:\windows\system32\newdev.exe
  25. c:\windows\system32\odbcad32.exe
  26. c:\windows\system32\PasswordOnWakeSettingFlyout.exe
  27. c:\windows\system32\pwcreator.exe
  28. c:\windows\system32\rdpshell.exe
  29. c:\windows\system32\recdisc.exe
  30. c:\windows\system32\rrinstaller.exe
  31. c:\windows\system32\shrpubw.exe
  32. c:\windows\system32\slui.exe
  33. c:\windows\system32\Sysprep\sysprep.exe
  34. c:\windows\system32\SystemPropertiesAdvanced.exe
  35. c:\windows\system32\SystemPropertiesComputerName.exe
  36. c:\windows\system32\SystemPropertiesDataExecutionPrevention.exe
  37. c:\windows\system32\SystemPropertiesHardware.exe
  38. c:\windows\system32\SystemPropertiesPerformance.exe
  39. c:\windows\system32\SystemPropertiesProtection.exe
  40. c:\windows\system32\SystemPropertiesRemote.exe
  41. c:\windows\system32\SystemSettingsAdminFlows.exe
  42. c:\windows\system32\SystemSettingsRemoveDevice.exe
  43. c:\windows\system32\Taskmgr.exe
  44. c:\windows\system32\tcmsetup.exe
  45. c:\windows\system32\TpmInit.exe
  46. c:\windows\system32\WindowsUpdateElevatedInstaller.exe
  47. c:\windows\system32\WSReset.exe
  48. c:\windows\system32\wusa.exe
复制代码

然后再去寻找不弹uac框的程序,这里我就从上往下开始尝试,找到的是ComputerDefaults.exe 这个exe

运行之后直接就会出现默认应用这个界面

uac程序特性探究通常以shell\open\command命名的键值对存储的是可执行文件的路径,如果exe程序运行的时候找到该键值对,就会运行该键值对的程序,而因为exe运行的时候是静默提升了权限,所以运行的该键值对的程序就已经过了uac。所以我们把恶意的exe路径写入该键值对,那么就能够过uac执行我们的恶意exe。
这里使用proc监听ComputerDefaults.exe

发现他会去查询HKCU\Software\Classes\ms-settings\Shell\Open\command里面的值

那么我们创建一个HKCU\Software\Classes\ms-settings\Shell\Open\command路径,再对ComputerDefaults.exe进行监听尝试

然后发现他还会去查询HKCU\Software\Classes\ms-settings\Shell\Open\command\DelegateExecute,而且Result显示的是NAME NOT FOUND,那么可以认为首先去查询HKCU\Software\Classes\ms-settings\Shell\Open\command路径下的注册表,再去查询HKCU\Software\Classes\ms-settings\Shell\Open\command\DelegateExecute是否存在

那么这里我创建一个DelegateExecute的键值对,然后把默认键值对指向我的一个程序进行尝试

当我运行c:\windows\system32\ComputerDefaults.exe的时候,发现不再弹出的是默认进程的界面,而是打开了我自己的程序
​​

那么这里就可以大胆的猜测一下,首先运行ComputerDefaults.exe这个程序之前,会查询HKCU:\Software\Classes\ms-settings\shell\open\command这个目录是否存在,若存在继续寻找同目录下是否有DelegateExecute这个键值对,若两者都存在则执行HKCU:\Software\Classes\ms-settings\shell\open\command指向的exe路径
为了验证猜想,这里我将exe路径改为cmd,若猜测成立则可以获得管理员权限的cmd

whoami /priv查看一下果然成功

bypass的实现经过上面的探究过后,我们整理下思路,首先要创建注册表,并添加DelegateExecute这个键值对,并修改command的指向exe路径即可bypassuac,那么这里用到一下几个函数
RegCreateKeyExA
首先是创建注册表项,对应的是之前创建HKCU\Software\Classes\ms-settings\Shell\Open\command这个路径的操作,这个路径默认情况下是不存在的
  1. LSTATUS RegCreateKeyExA(
  2.   [in]            HKEY                        hKey,
  3.   [in]            LPCSTR                      lpSubKey,
  4.                   DWORD                       Reserved,
  5.   [in, optional]  LPSTR                       lpClass,
  6.   [in]            DWORD                       dwOptions,
  7.   [in]            REGSAM                      samDesired,
  8.   [in, optional]  const LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  9.   [out]           PHKEY                       phkResult,
  10.   [out, optional] LPDWORD                     lpdwDisposition
  11. );
复制代码

hkey:句柄
lpSubKey:此函数打开或创建的子项的名称
Reserved:保留参数,必须为0
lpClass:该键的用户定义类类型。可以忽略此参数。此参数可以为NULL
dwOptions:有几个值,使用的时候具体查询
samDesired:指定要创建的密钥的访问权限的掩码
lpSecurityAttributes:指向SECURITY_ATTRIBUTES结构的指针
phkResult:指向接收打开或创建的键的句柄的变量的指针
lpdwDisposition:指向处置值变量的指针
RegSetValueExA
再就是修改注册表项,指向我们的恶意exe路径
  1. LSTATUS RegSetValueExA(
  2.   [in]           HKEY       hKey,
  3.   [in, optional] LPCSTR     lpValueName,
  4.                  DWORD      Reserved,
  5.   [in]           DWORD      dwType,
  6.   [in]           const BYTE *lpData,
  7.   [in]           DWORD      cbData
  8. );
复制代码

hkey:句柄
lpValueName:要设置的值的名称
Reserved:保留参数,必须为0
dwType:lpData参数指向的数据类型
lpData:要存储的数据
cbData:lpData参数指向的信息的大小,以字节为单位
RegDeleteTreeA
执行exe过后我们为了隐蔽最好是删除这个路径,那么就需要用到这个api
  1. LSTATUS RegDeleteTreeA(
  2.   [in]           HKEY   hKey,
  3.   [in, optional] LPCSTR lpSubKey
  4. );
复制代码

hkey:句柄
lpSubKey:密钥的名称
这里测试一下,先把路径写成cmd.exe
char filePath[] = "C:\\Windows\\System32\\cmd.exe";
实现效果如下

这里cmd的实现成功了,那么直接使用cs的马上线能不能够直接bypassuac呢,实验一下,这里把路径改为cs马的路径

实现效果如下

这里为了验证已经bypass了uac,我后面手动自己点了一下cs的木马,第一个就是我们通过我们写的程序上线的,第二个就是直接点击上线的,看一下区别
仔细看的话这里bypass过的右上角有一个*

首先看一下第一个对话

再看下第二个对话,很明显这里已经bypass过了uac

思考我们所使用的几个api,如RegCreateKeyExA、RegSetKeyExA都是直接修改注册表的操作,这种操作应该被归类为敏感操作,那么这里会不会被杀软拦截呢,去测试一下
windows defender正常上线

获取到的权限也是bypassuac后的权限

再看一下360,这里我试了两个方法,第一种方法是直接对artifact.exe做一下免杀,然后执行bypassuac.exe可以正常上线并bypassuac,但是如果使用注入shellcode到其他的exe就不能够获得uac权限

如图所示,这里我思考了一下,因为如果注入shellcode到其他程序,注册表指向的还是这个注入shellcode到其他程序的exe,所以后面那种方法是不能够bypassuac的

工具已经打包至github:
https://github.com/Drunkmars/BypassUAC
切勿用于非法用途!


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-4-19 22:26 , Processed in 0.016495 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表