Userland registry hijacking
0x00 前言
之前我在研究"Use SCT to Bypass Application Whitelisting Protection"的时候曾有过一个想法:在执行 regsvr32 命令注册 COM 组件的过程中,在注册表 HKEY_CLASSES_ROOT\CLSID\下会同步创建 COM 组件的键值,并且 classid 的子项 InprocServer32 下会包含 scrobj.dll 的绝对路径,那么如果修改了子项 InprocServer32 的键值,能否实现对某些操作的劫持?
然而实际修改 HKCR\CLSID\下的键值需要管理员权限,因此没有对这个想法深入研究。直到最近,Matt Nelson@enigma0x3 的博客给了我新的思路,只需要普通用户权限就可以实现对高权限系统注册表键值的劫持,让我对 userland registry hijacking 有了新的认识。
0x01 简介
本文将对 userland registry hijacking 的原理进行介绍,实例分析在 Userland Persistence 和 BypassUAC 两方面的具体应用,借助 Process Monitor,介绍一种寻找 BypassUAC 的方法。
0x02 Userland registry hijacking 原理
1、键值同步
修改 HKCU:\Software\Classes\下的键值中默认名称的数据,可以同时修改 HKCR:\下对应键值默认名称的数据(前提是 HKCR:\已存在此注册表项)
例如:编辑 HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command 的默认值为 c:\test\admin.exe
注:默认 HKEY_CURRENT_USER\Software\Classes\下不存在 mscfile\shell\open\command,需要自己创建,定位到 HKEY_CLASSES_ROOT\mscfile\shell\open\command 下,发现默认值被自动修改为 c:\test\admin.exe
注:在 HKCU:\Software\Classes\CLSID 下新建一个 HKCR:\CLSID 不存在的键值,并不会更新 HKCR:\CLSID 的数据
新建 HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command\1,默认名称的数据设为 1,然而 HKEY_CLASSES_ROOT\mscfile\shell\open\command 并不会新建子项 1
2、权限
- 修改 HKCU 下的键值只需要普通用户权限
- 修改 HKCR 下的键值需要管理员权限
综上,只需要以普通用户的权限编辑 HKCU:\Software\Classes\下的键值就可以同步修改对应管理员权限 HKCR 下的键值。
根据以上介绍的原理,可具体应用在 Userland Persistence 和 BypassUAC 两方面:
0x03 Userland Persistence With Scheduled Tasks
如果劫持系统某个计划任务对应的注册表键值,修改其中要启动的 dll 绝对路径,那么仅需普通用户权限就能实现一个后门,具体操作如下:
1、查看计划任务同注册表的对应关系
系统中的计划任务同注册表 HKCU:\Software\Classes\CLSID\下的键值存在对应关系,可借助 Matt Nelson@enigma0x3
分享的脚本直接查看
下载地址:https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Get-ScheduledTaskComHandler.ps1
注:通过计划任务面板查看的信息不完全,计划任务面板的打开方式为:我的电脑-右键-管理,找到计划任务,如图
ps 脚本获取的部分对应关系如图
可获得每个计划任务对应注册表键值的位置和启动的 dll
2、修改对应键值中的 dll 位置
找到对应关系后,需要定位具体的注册表键值位置,即 HKEY_CURRENT_USER\Software\Classes\CLSID{CLSID},通常情况 HKCU 下该键值不存在,需要手动建立,默认值设为需要运行的测试 dll 的绝对路径,键值创建后 HKCR 下的键值会同步更新,计划任务启动的 dll 随之被修改。
实例:
1、查看计划任务同注册表的对应关系
运行 Get-ScheduledTaskComHandler 找到可被劫持的 dll,挑选一个通用的计划任务——UserTask,详细信息如下:
TaskName : UserTask
CLSID : {58fb76b9-ac85-4e55-ac04-427593b1d060}
Dll : C:\Windows\system32\dimsjob.dll
Logon : True
IsUserContext : True
注:此操作需要查找 HKCR 下的键值,所以需要管理员权限才可以获得
2、修改对应键值中的 dll 位置
在 HKEY_CURRENT_USER\Software\Classes\CLSID\下新建项{58fb76b9-ac85-4e55-ac04-427593b1d060}
接着新建项 InprocServer32
值设定为 c:\test\MessageBox32.dll
注:注册表项{58fb76b9-ac85-4e55-ac04-427593b1d060}通用,不同系统下键值名称相同
MessageBox32.dll 下载地址为:https://github.com/enigma0x3/MessageBox
实际测试发现 https://github.com/enigma0x3/MessageBox/tree/master/bin 的 dll 在 win7 下失效,使用源代码重新编译生成新的 dll 可以使用
此时查看 HKEY_CLASSES_ROOT\CLSID{58fb76b9-ac85-4e55-ac04-427593b1d060}\InprocServer32,默认值被修改为 c:\test\MessageBox32.dll,如图
注销用户,重新登录,MessageBox32.dll 被加载,弹框
但是在 Scheduled Task 面板的日志中会提示 DLL 中出错(0x800401F9),如图
猜测是导出函数的问题导致 dll 加载报错,使用 dumpbin 查看计划任务 UserTask 对应的原 dll 的导出函数,执行:
dumpbin /exports C:\Windows\system32\dimsjob.dll
注: UserTask 对应的原 dll 的绝对路径为 C:\Windows\system32\dimsjob.dll
获得 dimsjob.dll 的导出函数表,如图
所以需要为 dll 添加新的导出函数:
- DllCanUnloadNow
- DllGetClassObject
- DllRegisterServer
- DllUnregisterServer
注:具体为 dll 添加导出函数的方法在《Code Execution of Regsvr32.exe》做了详细介绍,此处略过
添加成功后,dumpbin 查看结果如图
替换旧的 MessageBox32.dll,注销用户,重新登录,新的 MessageBox32.dll 被加载,弹框
查看 Scheduled Task 面板的日志,问题解决,操作成功完成,如图
以上操作可通过 powershell 自动实现,修改 UserTask 的代码如下:
function Invoke-ScheduledTaskComHandlerUserTask
{
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
Param (
[Parameter(Mandatory = $True)]
[ValidateNotNullOrEmpty()]
[String]
$Command,
[Switch]
$Force
)
$ScheduledTaskCommandPath = "HKCU:\Software\Classes\CLSID\{58fb76b9-ac85-4e55-ac04-427593b1d060}\InprocServer32"
if ($Force -or ((Get-ItemProperty -Path $ScheduledTaskCommandPath -Name '(default)' -ErrorAction SilentlyContinue) -eq $null)){
New-Item $ScheduledTaskCommandPath -Force |
New-ItemProperty -Name '(Default)' -Value $Command -PropertyType string -Force | Out-Null
}else{
Write-Verbose "Key already exists, consider using -Force"
exit
}
if (Test-Path $ScheduledTaskCommandPath) {
Write-Verbose "Created registry entries to hijack the UserTask"
}else{
Write-Warning "Failed to create registry key, exiting"
exit
}
}
Invoke-ScheduledTaskComHandlerUserTask -Command "C:\test\testmsg.dll" -Verbose
测试系统: Win7 x86
在运行后,当用户重新登录后,加载 dll,实际演示如图
依次执行 DLL_PROCESS_ATTACH() 和 DllGetClassObject(),由于 DllGetClassObject() 仅作弹框,所以之后会显示 taskhost.exe 报错
注: 此处仅作演示,暂不介绍具体解决方法
至此,成功劫持计划任务 UserTask,在系统启动时加载 testmsg.dll
0x04 UACBypass
计划任务同注册表 HKCR:\下的键值存在对应关系,同样一些高权限的程序也会调用 HKCR:\下的键值,这就为 Bypass UAC 带来了可能。
同样的原理,通过修改 HKEY_CURRENT_USER\Software\Classes\下的键值同步修改 HKCR:\下的键值,如果高权限的程序在运行过程中调用此处被修改过的键值,自然就实现了 Bypass UAC,以高权限启动我们设定的程序。
此处的难点在于找到这个高权限的程序
方法: 借助 Process Monitor,可以查看程序运行过程中的注册表、文件、网络、进程间的调用关系
接下来使用 Process Monitor 复现一下 Matt Nelson@enigma0x3 发现的过程
1、找到高权限的 exe
Matt Nelson@enigma0x3 的方法为使用 sigcheck 查看 exe 的 manifest
参数如下:
sigcheck.exe -m c:\windows\system32\eventvwr.exe
返回结果如图
从 level="highestAvailable"得知 eventvwr.exe 的权限为高权限
注:提供一个更加直观的判断方法:
查看文件图标,如果带有 UAC 标志,那么一定是高权限的程序,如图
2、使用 Process Monitor 查看进程调用关系
启动 Process Monitor
运行 eventvwr.exe
Process Monitor 选择 Tools-Process Tree,找到 eventvwr.exe,右键-Go To Event,如图
仔细查看进程调用关系,如图
找到如下信息:
- eventvwr.exe 的权限为 high
- eventvwr.exe 首先查询键值 HKCU\Software\Classes\mscfile\shell\open\command,查询结果为 NAME NOT FOUND
- eventvwr.exe 接着查询键值 HKCR\mscfile\shell\open\command,结果为 SUCCESS
3、修改测试
如果修改键值 HKCU\Software\Classes\mscfile\shell\open\command,使其查询结果为 SUCCESS,会如何呢?
下面首先修改键值 HKCU\Software\Classes\mscfile\shell\open\command,值为 calc.exe
再次运行 eventvwr.exe,发现启动了 calc.exe
使用 Process Monitor 查看进程调用关系,如图
此时对键值 HKCU\Software\Classes\mscfile\shell\open\command 的查询结果为 SUCCESS
至此,成功通过修改 HKCU\Software\Classes\mscfile\shell\open\command,实现 BypassUAC,获得了高权限
calc.exe 的权限为 high,如图
4、更多结论
修改 HKCU\Software\Classes\mscfile\shell\open\command 后,会劫持所有.msc 文件的运行,如 gpedit.msc,如图
按照这个方法,我对 system32 下的所有高权限 exe 进行了测试,尚未发现根据同样的方法利用 command 键值实现的 UACBypass,但是其他键值仍值得测试。
0x05 防御
Win10 系统已对该处做了修复,低版本 Windows 系统尚未修复,防御建议:
- set the UAC level to “Always Notify”
- remove the current user from the Local Administrators group
- alert on new registry entries in HKCU\Software\Classes\
引用自 https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/
0x06 小结
计划任务中可被用作 persistence 的 dll 有很多,在防御上建议对此进行监控。 通过 Process Monitor 寻找 BypassUAC 的方法值得继续研究,一定会有新的发现。
相关学习资料:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论