Haboob Blue CTF 2023
HABOOB BLUE CTF
Difficulty:
HARD
Windows 10 Notifications
I discovered this information within the browser history. The user accessed Telegram, so we need to examine the messages. To do this, navigate to the Windows Notification artifacts.
Upon investigation, we found the following information:
In the path \Users\<username>\AppData\Local\Microsoft\Windows\Notifications
, you can locate the database appdb.dat
(before Windows Anniversary) or wpndatabase.db
(after Windows Anniversary).
Within this SQLite database, there is a Notification table containing all the notifications in XML format. These notifications may contain interesting data.
Reference: Windows Forensics - HackTricks
Secret Notification
Hey Pinky,
Let’s do the same thing we do every night,… try to take over the world! Since your birthday is 14/11/1995, isn’t it, Pinky!!
So, we will execute the plan in November this year at the festival using the three keys.
By the way, I noticed that you have connected to my PC and encrypted one of the keys there. Did you save it on your machine?
Narf, Yours in world domination…
Note: The entire notification serves as a hint, indicating a connection to the RDP And for the encrypted file.
RDP
In our investigation, we discovered that Pinky is connected to the Windows box. To analyze this remote connection, we need to examine Remote Desktop Protocol (RDP) and other tools such as AnyDesk.
Flag1 Investigation
Our discovery is based on the presence of this connection in both the browser history and TeamViewer logs. Additionally, it is recommended to analyze the RDP “bitmap cache” located in the following path :
C:\Users<USER>\AppData\Local\Microsoft\Terminal Server Client\Cache\
Analyze RDP
To extract images from the RDP Bitmap Cache, we can utilize the bmc-tool.py
. This tool proves useful in extracting valuable information.
Reference: Blind Forensics with the RDP Bitmap Cache
Collect the Pieces
We utilized RDPieces to rebuild the images.
Unfortunately, the libraries used were subpar.
No looking back, let’s do it manually.
1st Flag: Haboob{y0u_r_m4a5ter_in_b1tm4p5}
Suspected Container
Flag2 Investigation
During our investigation, we discovered a container file that appears suspicious and is encrypted as autopsy module show us. The file is located in the path /img_PinkyPC.e01/Users/Desktop
.
It contains the following directory structure:
- [current folder]
- [parent folder]
Container
- desktop.ini
- firstOneFromBrain.txt
Encrypted volumes will always get the high entropy score. I used autopsy key search to search for Truecrypt and Veracrypt couldn’t found Truecrypt and only found Veracrypt By looking into appsearch.exe globalitems we can found there was search for ‘veracrypt’ that help us to know the type of encryption was used
Bruteforce
We generated a custom wordlist using the Cupp tool
, incorporating information obtained from the first message. Subsequently, we utilized hashcat
to crack the generated wordlist.
- Cupp tool information was obtained from HackGPT.
Command for hashcat: hashcat -w 4 -m 13721 Container pinky.txt
Password Cracked: yknip_954
Mount the image
- Mount the image using VeraCrypt
Zip File Exploration
Discovery
After mounting the disk, an encrypted zip file was found.
SAM Dump Attempt
Attempts to dump the Security Account Manager (SAM) for the password, tried to used cracked passowrd to unzip the zip folder but no lock.
Red Teaming Mindset
Despite unsuccessful attempts to unzip the file, a red teaming mindset was employed.
Chrome Credentials Investigation
Two login attempts in Chrome were identified, leading to the use of Mimikatz
1
- Reference: [Reading DPAPI Encrypted Secrets with Mimikatz and C++](https://www.ired.team/offensive-security/credential-access-and-credential-dumping/reading-dpapi-encrypted-secrets-with-mimikatz-and-c++)
Master Key Retrieval
To proceed, the master key was needed. The Security Identifier (SID) was downloaded from appdata\Roaming\Microsoft\Protect
using the cracked user password.
Dump Attempt
Attempts to dump passwords of two users using the obtained master key were unsuccessful.
SQLite Exploration
Considering alternative approaches (https://ctftime.org/writeup/33938), SQLite was explored based on research and a similar scenario.
SQLite and DPAPI
Exploration of SQLite revealed the calling of DPAPI, providing promising insights. (https://nandynarwhals.org/sieberrsec-ctf-3.0-digginginthedump/)
Blob Extraction
Advancing to the next level, the blob from Mimikatz was utilized.
Python Script Modification
Extensive debugging led to the realization that the provided Python script needed modification. (decrypt_chrome_password.py) - Reference: Decode Chrome 80 Cookies
Password Decoding
After fixing the Python script, the password was successfully decoded:
1
2
3
`
Pinky1020@1234+=+=+=++
`
Important Commands:
Command 1:
1
2
3
4
cat 'AppData/Local/Google/Chrome/User Data/Local State' | jq -r .os_crypt.encrypted_key | base64 -d | xxd```
This command decodes the encrypted key from the 'Local State' file in the Chrome directory using jq, base64, and xxd.
1
2
3
4
5
6
7
8
9
cat DPAP_extractor.py
import json, base64
x = json.load(open('AppData/Local/Google/Chrome/User Data/Local State', 'rb'))['os_script']['encrypted_key']
x = base64.b64decode(x)
open("blob", 'wb').write(x[5:])
flag
Haboob{Bru73_F0rc3d_7h3_c0N741n3R}
JS
Flag3 Investigation
Tool - Autopsy
During the investigation, a suspicious JavaScript file was found in recently accessed files.
- Data Sources » PinkyPC.e01_1Host
- File Path: /img_PinkyPC.e01/Users/Pinky/AppData/Local/Google/Chrome/User Data/Default/Extensions/x9mhkkegcca9sldgd9medpiccmgmlc
Directory Structure:
- [current folder]
- [parent folder]
- images
- background.js
- manifest.json
- popup.html
The code was obfuscated, so it was deobfuscated to reveal the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
chrome.runtime.onInstalled.addListener(function () {
console.log('Clipboard Manager');
});
function base64Encode(C) {
return btoa(C);
}
function base64Decode(C) {
return atob(C);
}
chrome.runtime.onMessage.addListener(function (C, k, K) {
if (C.action === 'copy') {
const s = base64Encode(C.text);
if (s === base64Encode('bG9s')) {
// List of decimal values assigned to variables d1, d2, ..., d35
const d1 = 41.5, d2 = 35.5, d3 = 35 * 2, d4 = 52.5, d5 = 49, d6 = 25, d7 = 28.5, d8 = 52.5, d9 = 50.5,
d10 = 25, d11 = 43, d12 = 44.5, d13 = 39, d14 = 25, d15 = 43, d16 = 58.5, d17 = 37, d18 = 35.5,
d19 = 53.5, d20 = 59.5, d21 = 49, d22 = 54, d23 = 28.5, d24 = 60.5, d25 = 38.5, d26 = 25.5,
d27 = 44.5, d28 = 61, d29 = 49.5, d30 = 53, d31 = 42.5, d32 = 61, d33 = 49.5, d34 = 55, d35 = 24;
const V = [d1 * 2, d2 * 2, d3 * 2, d4 * 2],
r = [d5 * 2, d6 * 2, d7 * 2],
n = [d8 * 2, d9 * 2, d10 * 2],
M = [d11 * 2, d12 * 2, d13 * 2],
P = [d14 * 2, d15 * 2, d16 * 2, d17 * 2],
U = [d18 * 2, d19 * 2, d20 * 2],
A = [d21 * 2, d22 * 2, d23 * 2],
a = [d24 * 2, d25 * 2, d26 * 2],
z = [d27 * 2, d28 * 2, d29 * 2],
v = [d30 * 2, d31 * 2, d32 * 2],
q = [d33 * 2, d34 * 2, d35 * 2];
let J = '';
for (let i = 0; i < V.length; i++) {
J += String.fromCharCode(V[i]);
}
const Y = document.createElement('textarea');
Y.value = base64Decode(J);
document.body.appendChild(Y);
Y.select();
document.execCommand('copy');
document.body.removeChild(Y);
}
}
});
so i wrote python script to solve it :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import re
from decimal import Decimal
d31 = 42.5
d15 = 43
d13 = 39
d6 = 25
d35 = 24
d24 = 60.5
d18 = 35.5
d8 = 52.5
d2 = 35.5
d25 = 38.5
d1 = 41.5
d16 = 58.5
d9 = 50.5
d21 = 49
d5 = 49
d11 = 43
d32 = 61
d10 = 25
d12 = 44.5
d20 = 59.5
d28 = 61
d4 = 52.5
d14 = 25
d7 = 28.5
d3 = 35
d27 = 44.5
d19 = 53.5
d33 = 49.5
d26 = 25.5
d34 = 55
d23 = 28.5
d29 = 49.5
d22 = 54
d30 = 53
d17 = 37
list = [d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16,d17, d18, d19, d20, d21, d22, d23, d24,
d25, d26, d27, d28, d29, d30, d31, d32, d33, d34, d35]
for i in list:
x = i * 2
z = int(float(x))
y = int(Decimal(z))
h = chr(y)
print (h,end="")
Flag Decoding Process
Undefined Variable
It was noticed that d17
was not defined.
So we defined ‘d17’ as 1 to test, after running the script, the output was SGFib29ie2VYN2VuJGkwbl9yM3YzcjUzcn0
.
Base64 Decoding
The output was decoded using Base64, revealing Haboob{eX7en..l..}
.
Decimal Value Discovery
ASCII Table Conversion: Utilizing the ASCII table, it was confirmed that every number corresponds to a character value, aiding in finding the complete flag
A Python script was written to find the decimal value of d17
. The script provided the initial digits of the flag. To obtain the full flag, it was necessary to define d17
with the correct value. A bruteforce approach on d17
revealed that the correct value was 37. With the correct value for d17
, the output was base64-decoded again, resulting in Haboob{eX7en$i0n_r3v3r53r}
.
and i got the flag :D
Final Flag:
Haboob{eX7en$i0n_r3v3r53r}