Salaheldin

March 14, 2019

Recover Alabaster’s Password

Main Challenge @ The 2018 SANS Holiday Hack Challenge [ Kringlecon ]

CTF Writeup

📍 Forensic_artifacts.zip which contain a memory dump from Alabaster computer and his encrypted password database.

kc18_elves_elf_21.png

Now that we don’t have to worry about new infections, I could sure use your L337 security skills for one last thing.

As I mentioned, I made the mistake of analyzing the malware on my host computer and the ransomware encrypted my password database.

Take this zip with a memory dump and my encrypted password database, and see if you can recover my passwords.

One of the passwords will unlock our access to the vault so we can get in before the hackers.

icon-idea

Memory Strings

Pulling strings from a memory dump using the linux strings command requires you specify the -e option with the specific format required by the OS and processor.

Of course, you could also use powerdump.

https://github.com/chrisjd20/power_dump

Public / Private Key Encryption

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?


solution-icon.png

01- Download Forensic_artifacts.zip and unzip it :

https://www.holidayhackchallenge.com/2018/challenges/forensic_artifacts.zip

02- Download powerdump tool :

https://github.com/chrisjd20/power_dump

03- Let’s follow the hint given by elf and try to see if there is a non-minified version of the wannacookie.min.ps1 ,

Assuming that min used to point to minified version than a non-minified version would be wannacookie.ps1.

04- Let’s try to grab the file :

Method1 :

We can use the code in file source-1.ps1 which used to download wannacookie.min.ps1 but change $f to the name of the file we need wannacookie.ps1 after we encoded in HEX without spaces 77616e6e61636f6f6b69652e707331

A. Create a copy of source-1.ps1 and rename it to source-1b.ps1 then edit the value of $f , The code after editing will look like this :

21-img-11.jpg

B. Run the modified code in PowerShell and export the result to wannacookie.ps1 :

.\source-1b.ps1 | out-file wannacookie.ps1

It will take some time wait until finish.

You can use tool like DNS Query Sniffer to see dns connection in live action

https://www.nirsoft.net/utils/dns_query_sniffer.html

21-img-10.jpg


Method2 :

Let’s examine the malware code in file wannacookie.min.ps1 to find any other interesting codes and see how it’s download the files :

A. You notice this interesting code for requesting html file :

$html_c = @{‘GET /’ = $(g_o_dns (A2H “source.min.html”));

Which is grabbing file source.min.html using g_o_dns function after converting the name using A2H function.

B. Open the file wannacookie.min.ps1 in PowerShell ISE and create a breakpoint before the main function to get all functions loaded and ready to test our code.

C. Run the script then when stop at breakpoint write the code snippet in bottom console and press enter to export the result to wannacookie.ps1 :

$(g_o_dns (A2H “wannacookie.ps1”)) | out-file wannacookie.ps1

It will take some time wait until finish.

Stop the debugger from upper menu debug > stop debugger


05- Let’s take a look at the new file code wannacookie.ps1 , now we have clear view at the functions meaning:

  • File Encryption /Decryption function e_d_file > Enc_Dec-File
  • Hashing function using Sha1 sh1 > sha1
  • Encrypt function using PublicKey p_k_e > Pub_Key_Enc
  • Encrypt and Decrypt function e_n_d > enc_dec
  • Get using DNS function g_o_dns > get_over_dns
  • Split function s_2_c > split_to_chunks
  • Send key function snd_k > send_key
  • The Main function wanc > wannacookie


06- Let’s see how the malware work:

  • First it’s check the killswitch domain
  • Check the local host at port 8080 if it’s not used 127.0.0.1:8080
  • Grab the public key over the DNS $pub_key
  • Generate a random key $Byte_key
  • Convert the random key $Byte_key from bytes to HEX > $Hex_key
  • Create a hash for the random key $Hex_key > $Key_Hash
  • Encrypt the random key $Byte_key using public key $pub_key $Pub_key_encrypted_Key > $Pub_key_encrypted_Key
  • Send the encrypted random key $Pub_key_encrypted_Key to the server and retrieve the cookie id > $cookie_id
  • Get date and time $date_time
  • Get list of files with extension .elfdb in
  • {Desktop, Documents, Videos, Pictures, Music folders} > $future_cookies
  • Encrypt all the elfdb files in $future_cookies with the random key $Byte_key
  • Clear the values in $Hex_key , $Byte_key
  • Set $lurl to http://127.0.0.1:8080/
  • Get main html named source.min.html > $htmlcontents
  • Set html content - close request to <p>Bye!</p>
  • Starts a PowerShell background job with maximized windows size which provides a simple, programmatically controlled HTTP protocol listener $listener using localhost 127.0.0.1 on port 8080
  • Load source.min.html into maximized browser windows
  • After that depends on http get request received :
  • Request GET / get the main html file > source.min.html
  • Request GET /decrypt decrypt the files using key after validation with hashing
  • Request GET /close close window after displaying word Bye!
  • Request GET /cookie_is_paid check with the server to see if the ransom was paid using $cookie_id


07- Let’s first garb the file source.min.html and also try un-minified version source.html :

$(g_o_dns (A2H “source.min.html”)) | out-file source.min.html

It will take some time wait until finish , it’s about 6800 requests !

$(g_o_dns (A2H “source.html”)) | out-file source.html

it will take some time wait until finish , it’s about 6800 requests !

It’s seems the html code doesn’t have any useful information just confirm the sequence of how malware works, This how the source.html file source code after download :

21-img-8.jpg


08- Let’s grab the public key from server :

Using encoded hex 7365727665722E637274 > server.crt

$(g_o_dns (A2H “server.crt”)) | out-file server.crt

PEM certificates usually have extensions such as .pem, .crt, .cer, and .key. They are Base64 encoded ASCII files


09- Because the key encryption function is using public key then the decryption will need a private key as shown here :

21-img-6.jpg

let’s try grab it using server.key :

$(g_o_dns (A2H “server.key”)) | out-file server.key

This Unencrypted private key in PEM file .key , The KEY extension is used both for public and private PKCS#8 keys which prefixed with a “—– BEGIN …” line.


10- We need also to calculate the length of the different keys available in the malware code for easier filtration after memory dump analysis :

  • First create a breakpoints after each key variable we need to it’s length and comments the lines we don’t need.
  • Then we will use $variable.length command to know the lengths as following :
$Pub_key_encrypted_Key.length
  • Now run the script and type the command to get the length after each variable :
$Pub_key_encrypted_Key > 512

$pub_key > 865 we can got from there server in previous step

$Key_Hash > 40 we don’t need it because the hashing is irreversible process

$Byte_key > 16 we don’t need it because it’s cleared after usage

$Hex_key > 32 we don’t need it because it’s cleared after usage


11- Now we are ready to try finding a way to decrypt the file alabaster_passwords.elfdb.wannacookie , let’s start with analyzing the memory dump powershell.exe_181109_104716.dmp :

1/ We will use powerdump tool to retrieves powershell blocks and variables from memory , run the tool on the memory dump file and make sure the dump file in same directory as power_dump.py file for easier commands,

2/ Let’s fire up the tool using the following command :

python power_dump.py

21-img-7.jpg

3/ Select option 1 to load a powershell memory dump >Write ls to list files > Write ld dump-filename to load our powershell memory dump file

ld powershell.exe_181109_104716.dmp

4/ Go back using b > Select option 1 to process this dump

It will take some time wait until finish.

5/ Select option 4 to search/dump stored PS variables

There is 10947 possible variables stored in memory , we need to reduce this number so let’s do some filtration, we are looking for $Pub_key_encrypted_Key which is in hex because it’s outputted using B2H converter at end of Pub_Key_Enc function :

matches “^[a-fA-F0-9]+$”

And it’s length = 512 :

len == 512

So now there is 1 Possible variable , you can see it by print command

print

Let’s go a head and dump those :

dump

it’s dumped to file named variable_values.txt , copy the file to other location rename it to Pub_key_encrypted_Key.txt

6/ Aslo we can look for $Key_Hash to prove our key after we decrypt it , we know it’s in Hex and length = 40 , clear the filters first :

clear

Then Hex filter :

matches “^[a-fA-F0-9]+$”

And it’s length = 40 :

len == 40

So now there is 1 Possible variable , you can see it by print command

print

Let’s go a head and dump those :

dump

it’s dumped to file named variable_values.txt , copy the file to other location and rename it to sha1.txt

So we have $Pub_key_encrypted_Key , $Key_Hash , server public key, server private key


12-Let’s reverse malware process
First we will need to decrypt $Pub_key_encrypted_Key with $private_key to get $Byte_key then decrypt the file with $Byte_key to get alabaster_passwords.elfdb , let’s begin :

a) First we need a certificate type that can work with The X.509 certificate import method , it’s support several certificate types : Base64-encoded or DER-encoded X.509 certificates, PFX/PKCS12 certificates, and signer certificates such as Authenticode.

You can find more about Asymmetric Encryption/Decryption here

https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2

We need to have a cert with a private key in supported format , let’s convert our pem files ( .crt, .key ) to pfx certificate type using openssl :

  • Install openssl
    Openssl installation tutorial : https://www.youtube.com/watch?v=892_4UQy_L8
  • Browser to certificate and private key folder then run the following command to check the private key :
    openssl rsa -in server.key -check
    if you encounter any error with crt or key file try to download the files again.
21-img-5.jpg

  • Check the certificate :
    openssl x509 -in server.crt -text -noout
  • Convert add the private key to the certificate and convert to pfx without a password
    openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt
  • Check the certificate pfx file :
    openssl pkcs12 -info -in server.pfx


b) We need to create function to decrypt the file encryption key using the private key, let’s call it Pub_Key_Dec function :

function Pub_Key_Dec($encKey){ $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2 $cert.Import( “C:\Users\IEUser\Downloads\wannacookie\server.pfx” ) $decKey = $cert.PrivateKey.Decrypt($encKey, $true) return $(B2H $decKey) }

Then we add the following lines to the main function to import $Pub_key_encrypted_Key from Pub_key_encrypted_Key.txt file :

$Pub_key_encrypted_Key = Get-Content -Path “C:\Users\IEUser\Downloads\wannacookie\Pub_key_encrypted_Key.txt”

And Convert it from HEX to Bytes to be able to use it in Pub_Key_Dec function :

$Pub_key_encrypted_Key = $(H2B $Pub_key_encrypted_Key);


c) Now let’s run our code and add breakpoint after our added code lines:

$Byte_key = Pub_Key_Dec($Pub_key_encrypted_Key); $Byte_key;

Now we have our key $Byte_key to decrypt the files :

fbcfc121915d99cc20a3d3d5d84f8308

21-img-4.jpg

You can check if it’s correct key by running it against sha1 hash we found from power dump

21-img-3.jpg


13- Let’s decrypt the file alabaster_passwords.elfdb.wannacookie using enc_dec function:

  • First we point to the encrypted file :
$enc_file = @(“C:\Users\IEUser\Downloads\wannacookie\alabaster_passwords.elfdb.wannacookie”);
  • And Convert the key from HEX to Bytes to be usable in enc_dec function :
$Byte_key = $(H2B $Byte_key);
  • Then we run the function with false state to decrypt the file:
enc_dec $Byte_key $enc_file $false;
  • Run the function and add breakpoint after our added code lines:

21-img-2.jpg

Now we have the Alabaster’s password vault unencrypted the file with name alabaster_passwords.elfdb


14- Let’s take a look at Alabaster’s password vault , since the file using .elfdb and we know he is obsessed with SQLite database storage :

  • if you open the file with text editor you will confirm it’s SQLite format by first line .

21-img-1.jpg

  • Now er know the database format is SQLite , let’s view it usingDB Browser for SQLite or any similar software : https://sqlitebrowser.org/

    File > open database readonly > Select alabaster_passwords.elfdb > Select Browse Data

21-img-12.jpg

We have the password !

ED#ED#EED#EF#G#F#G#ABA#BA#B

kc18_elves_elf_21.png

I’m seriously impressed by your security skills.