The Cogs of Blackmail
Flag: HACKDAY{dllCeption-be9746fa-d0f7-4761-a5ba-0e461a162877}
Challenge
Ce challenge tourne sur un docker et n'est pas disponible
Solution
Ce challenge contient une DLL .NET
. Celle-ci contient des données chiffrées en AES-CBC
, ces donnĂ©es sont en fait une autre DLL .NET contenant la mĂȘme chose. Et ceci, 150 fois.
La clé, l'IV et les données chiffrées sont statiques dans la DLL, on va donc faire un petit programme .NET permettant de récupérer ces valeurs et les déchiffrer. Ici, j'utilise dnlib pour le faire.
using System;
using System.Reflection;
using dnlib.DotNet;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
class Program
{
static void Main(string[] args)
{
string dllPath = args[0]; // La DLL contenant la DLL chiffrée
string outPath = args[1]; // LĂ oĂč on sauvegarde ce qu'on a dĂ©chiffrĂ©
var module = ModuleDefMD.Load(dllPath); // Chargement de la DLL avec dnlib
Aes aes = Aes.Create(); // Cipher AES
aes.Padding = PaddingMode.ISO10126;
aes.Mode = CipherMode.CBC;
// LĂ oĂč on va recueillir la valeur de la clĂ©, l'IV et les donnĂ©es chiffrĂ©es
Dictionary<string, byte[]> staticArrays = new Dictionary<string, byte[]>();
foreach (var type in module.Types)
{
foreach (var field in type.Fields)
{
// Conditions pour récupérer que ce qui nous intéresse
if (type.Name.Contains("PrivateImplementationDetails"))
{
// Pareil ici
if (field.HasFieldRVA && field.InitialValue != null)
{
// Juste pour les logs
Console.WriteLine($"[+] {field.Name} ({field.InitialValue.Length})");
// Valeur de la donnée
byte[] fieldValue = field.InitialValue;
// En fonction de sa taille, on en déduit ce que c'est
if (field.InitialValue.Length == 16) staticArrays["IV"] = fieldValue;
else if (field.InitialValue.Length == 32) staticArrays["Key"] = fieldValue;
else staticArrays["EncryptedData"] = fieldValue;
}
}
}
}
// Si on a pas récupéré d'IV (ou de clé) alors c'est qu'il n'y avait rien à déchiffrer
// Donc on le print sous forme UTF-8 (spoil: ce sera le flag)
if (!staticArrays.ContainsKey("IV")) {
Console.WriteLine(Encoding.UTF8.GetString(staticArrays["EncryptedData"]));
// Lance une Exception pour prévenir qu'il n'y a rien à déchiffrer
throw new InvalidOperationException("DLL not encrypted");
} else {
// Sinon on déchiffre et on save le résultat dans le outPath
aes.IV = staticArrays["IV"];
aes.Key = staticArrays["Key"];
ICryptoTransform decryptor = aes.CreateDecryptor();
byte[] decryptedData = decryptor.TransformFinalBlock(staticArrays["EncryptedData"], 0, staticArrays["EncryptedData"].Length);
File.WriteAllBytes(outPath, decryptedData);
}
}
}
AprÚs avoir build le projet, on va lancer en boucle notre exécutable sur la DLL avec python, jusqu'à ce que ça plante.
import subprocess
import pathlib
import shutil
import os
tmp_path = '2Decompile.dll' # Copie temporaire de la DLL d'oĂč extraire la prochaine DLL
out_path = 'Decompiled.dll' # Résultat du déchiffrement
# Copie de la DLL originale
shutil.copy('DLLception.dll', tmp_path)
i = 0
while True:
i += 1
print(f"[DLLCeption n°{i}]")
# On lance notre programme .NET sur tmp_path vers out_path
output = subprocess.run(f'"F:/CTF/HackDay 2025/Decompiler/bin/Debug/net9.0/Decompiler.exe" "{tmp_path}" "{out_path}"', shell=True, capture_output=True)
# Les "logs" de notre programme
print(output.stdout.decode())
# Si on trigger l'Exception dans notre programme, on sort de la boucle
if output.stderr:
break
# La DLL dĂ©chiffrĂ©e devient notre prochaine DLL oĂč l'on va extraire
shutil.move(out_path, tmp_path)
[DLLCeption n°1]
[+] 824445315B8CF03B9888ADB0129286C2CD18F225609D1E1E4544A82705D432CB (16)
[+] C8CDC9395004ACCD0DA5472C9BF81C89F9B738641167B1BF1A49E2858FBE8FD3 (3185680)
[+] F786F1AA87FC66AAFF7043DE0659A779D51BB78B27EA6A1FD7A6E90930FA6DF9 (32)
[DLLCeption n°2]
[+] 54BC4AC75B5F18FDD67E21A0EA1DF5A8BF40A61427CA15C59F783B1833A533C0 (32)
[+] 562777F09214BB91F522EE960F26AB6CA393198DE992C58C5AEE8AE6305E4A3E (3164176)
[+] 60B592AC99898B6241ED519E8D04A5897A3ADF0549B15988537210CDDA2DEC61 (16)
[DLLCeption n°3]
[+] 3564CA53D2C742B172E9810CBCD103C0334D55442671DE3D9C93D1C37D7D703C (3142672)
[+] A860F771B35FD3ED874FF5013C9C6107CA8266331DC8F00A8B1D858585728836 (16)
[+] C2BD074BF038A6EC342C0C083A21366756DE02021269EA4AE1F18DE40591A069 (32)
[...]
[DLLCeption n°147]
[+] Field: 143AE4399B1D51A5D8FE2FAA1A96AA6E7724C9002FFC7D9D3B761116F0AA3392 (32)
[+] Field: 3FFABA7F0FC0FBAD457FC58DD43C9A40C9C459C80202438EB62FD13CC6DB93EB (46096)
[+] Field: 5DC7B12C6EA617E8E3C1E81D54E6F531A223A7DBCE7C7F1C44A3434529972759 (16)
[DLLCeption n°148]
[+] Field: 40E5B99AF1219C06AD26BC5326084100E42EA01EB85AC680B348C63249E9EE97 (16)
[+] Field: 768DCB7C98BF4D7AD9D22DF192ECE437B4E06B93F6642BBCFDCB3BC777CBE193 (32)
[+] Field: A1F28FC0C354227F91578439F1BD3B30C54BB49EF1B29659CB388ACAE9C20A5B (25104)
[DLLCeption n°149]
[+] Field: 4C3BFD04A6B27CD5F213655B76EBDBA5975FB409F7E16F6B01114B8861C2AB28 (32)
[+] Field: A2328EA49AF1572B447FD6C14D7A77ABC573C8166EDB852B7D3C88317FB06BF9 (4112)
[+] Field: F0DD5D0C36F76FFD9EA030A79346CA9D0907528E00B929611CFAFCDBC0EE0C60 (16)
[DLLCeption n°150]
[+] Field: 8A0586F8773B48256CC1DA1684325466CE06FA50D392EB17AEF5D6CEBF1B6876 (112)
HACKDAY{dllCeption-be9746fa-d0f7-4761-a5ba-0e461a162877}
Mis Ă jour
Ce contenu vous a-t-il été utile�