HackTheBox: Seized

Miyuki is now after a newly formed ransomware division which works for Longhir. This division's goal is to target any critical infrastructure and cause financial losses to their opponents. They never restore the encrypted files, even if the victim pays the ransom. This case is the number one priority for the team at the moment. Miyuki has seized the hard-drive of one of the members and it is believed that inside of which there may be credentials for the Ransomware's Dashboard. Given the AppData folder, can you retrieve the wanted credentials?

Information

Challenge: Seized

Category:
Forensics

Difficulty:
Medium

Files : Seized.zip 227 MB

Environment: Remnux VM

My Recommendations

Download it from hackthebox and verify it with:

sha256sum /path/to/Seized.zip

SHA256SUM: c7b53d9fe75e0f8fb11a46f417caca042693ab19c36140af2e555163a61812c7

Walkthrough

1. Filesystem Analysis

First, let’s check the folders present in the AppData folder:

				
					mv Users/User/AppData .
ls AppData/*
				
			

Nothing out of the ordinary. The folder Google suggests that Chrome is installed, which may be where the credentials are stored.

				
					grep -r -s -l -i 'dashboard' AppData
#returns multiple files in AppData/Local/Google/Chrome
				
			

Chrome saved passwords are stored in a file named ‘Local State‘. To decrypt the passwords, we also need the file ‘Login Data’. We can find and copy them to a tempdir.

				
					mkdir tempdir
find AppData/Local/Google \( -name 'Local State' -o -name 'Login Data' \) -exec cp "{}" tempdir/ \;
#checking we are on the right track
jq . tempdir/'Local State'
				
			

Seems like the file contains credentials for a dashboard and belongs to user ‘ransomoperator’. Decrypting Chrome passwords is no easy task. We will need access to ‘CryptUnprotectData‘, which is normally unavailable. To do that, we need to extract the masterkey stored in the Protect directory. 

				
					ls -la AppData/Roaming/Microsoft/Protect/*

				
			

The MasterKey file is annotated in pink, and the user SID in yellow. These are essential to the next steps.

Copying the files to the tempdir and moving on to decryption:

				
					cp -r AppData/Roaming/Microsoft/Protect tempdir/
				
			

2. MasterKey Decryption

JohnTheRipper jumbo version has a code to extract hashes from MasterKey files: DPAPImk2john.py. We need to run it and save the hash before bruteforcing it.

				
					DPAPImk2john.py -S S-1-5-21-3702016591-3723034727-1691771208-1002 -mk tempdir/Protect/S-1-5-21-3702016591-3723034727-1691771208-1002/865be7a6-863c-4d73-ac9f-233f8734089d -c local> mkhash
john --wordlist=/usr/share/wordlists/rockyou.txt mkhash 
				
			

Easy peasy and so… predictable 🤦‍♀️ 🤦‍♀️ 🤦‍♀️. Now that we found the user’s password, we can use impacket’s dpapi.py and get the actual Master Key.

				
					dpapi.py masterkey -file tempdir/Protect/S-1-5-21-3702016591-3723034727-1691771208-1002/865be7a6-863c-4d73-ac9f-233f8734089d -sid S-1-5-21-3702016591-3723034727-1691771208-1002 -password ransom
				
			

With the Decrypted Master Key we are now capable of decrypting the Chrome passwords.

3. Chrome Passwords Decryption

It took a while to put together something that would work on a Linux VM. Here is the final code.

				
					import os
import json
import sqlite3
import base64
from impacket.dpapi import DPAPI_BLOB
from binascii import unhexlify
from Cryptodome.Cipher import AES

local_state = 'tempdir/Local State'
login_data = 'tempdir/Login Data'
masterkey = unhexlify("138f089556f32b87e53c5337c47f5f34746162db7fe9ef47f13a92c74897bf67e890bcf9c6a1d1f4cc5454f13fcecc1f9f910afb8e2441d8d3dbc3997794c630")

def get_encrypted_key(localstate):
    with open(localstate, 'r') as f:
        encrypted_key = json.load(f)['os_crypt']['encrypted_key']
        encrypted_key = base64.b64decode(encrypted_key)
    f.close()
    return encrypted_key

def get_credentials(logindata):
    conn = sqlite3.connect(logindata)
    cursor = conn.cursor()
    cursor.execute('SELECT action_url, username_value, password_value FROM logins')
    rows = cursor.fetchall()
    url = rows[0][0]
    username = rows[0][1]
    encrypted_value = rows[0][2]
    return url, username, encrypted_value

def decrypt_creds(key, value):
    if value.startswith(b'v10'):
        nonce = value[3:3+12]
        ciphertext = value[3+12:-16]
        tag = value[-16:]
        cipher = AES.new(key, AES.MODE_GCM, nonce)
        password = cipher.decrypt_and_verify(ciphertext, tag)
    else:
        password = DPAPI_BLOB.decrypt(value)
    return password

encrypted_key = get_encrypted_key(local_state)
enc_key_blob = DPAPI_BLOB(encrypted_key[5:])
localstate_key = enc_key_blob.decrypt(masterkey)
url, username, encrypted_value = get_credentials(login_data)
password = decrypt_creds(localstate_key, encrypted_value)
print(" \n "  + " URL: " + url + " \n " + " Username: " + username + "\n " + " Decrypted Password: " + password.decode("utf-8"))

				
			

 

Flag: HTB{Br0ws3rs_C4nt_s4v3_y0u_n0w}

TLDR

–  With grep, we find that the credentials are stored in Chrome.
– Using john, we can generate a hash from the Protect directory and crack it with rockyou.txt
Impacket calculates the Decrypted Master Key, necessary for decrypting Chrome Login Data.
– The credentials can be retrieved with a ‘custom’ python script.

Recent Posts

Follow Us

Featured Video

Guide

Discover more from forensicskween

Subscribe now to keep reading and get access to the full archive.

Continue reading

Exit mobile version
%%footer%%