3615 Incident (2)

Catégorie: Forensique

Points: 330

Description: Une victime de plus tombée sous le coup d’un rançongiciel. Le paiement de la rançon n’est pas envisagée vu le montant demandé. Vous êtes appelé pour essayer de restaurer les fichiers chiffrés. Une suite d’éléments est nécessaire pour avancer dans l’investigation et constituer le rapport d’incident. Retrouvez la clé de chiffrement de ce rançongiciel! Note : l’image disque fait environ 440 Mo compressée et environ 1.4 Go décompressée. Elle est identique au challenge 3615 Incident - 1. Réponse attendue au format ECSC{clé}.

Fichiers: mem.dmp

TL;DR

Une analyse du rançongiciel nous donne un pattern à retrouver qui contient la cle de chiffrement. Le cle est retrouve grace à strings et grep.

Méthodologie

Maintenant qu'on connaît l'identité du ransomware on va pouvoir le décortiquer.

Pour commencer on va l'extraire du dump mémoire avec Volatillity.

>_ volatility -f mem.dmp --profile=Win10x64 procdump -p 5208 -D dump
Volatility Foundation Volatility Framework 2.6.1
Process(V)         ImageBase          Name                 Result
------------------ ------------------ -------------------- ------
0xffffe000106bb840 0x0000000000400000 ?                    OK: executable.5208.exe

Et maintenant on va faire un peu de reverse avec Ghidra car j'aime bien son décompilateur intégré.

code analyse avec ghidra

Comme j'y connais pas grand chose en reverse, je décide de me focaliser sur les strings.

ghidra strings

On remarque qu'il y a un lien vers github. Allons voir ce que c'est.

Le repo github a l'air d'être le code source du ransomware.

En comparant le code du repo avec le code décompilé il y a beaucoup de similarités. On en déduis que le code du repo correspond au malware analyse.

Dans le fichier cryptofs/file.go il y a une méthode intéressante:

func (file *File) Encrypt(enckey string, dst io.Writer) error {
    [...]
}

La cle de chiffrement est passe en paramètre à la méthode Encrypt.

En regardant ou est généré cette cle on arrive vers un fichier qui s'appelle ransomware.go et qui contient cette méthode:

func encryptFiles() {
    [...]

    // Generate the id and encryption key
    keys["id"], _ = utils.GenerateRandomANString(32)
    keys["enckey"], _ = utils.GenerateRandomANString(32)

    // Persist the key pair on server
    res, err := Client.AddNewKeyPair(keys["id"], keys["enckey"])
    if err != nil {
        cmd.Logger.Println("Ops, something went terribly wrong when contacting the C&C... Aborting...")
        cmd.Logger.Println(err)
        return
    }

    [...]

    // Encrypt the file sending the content to temporary file
    err = file.Encrypt(keys["enckey"], tempFile)
    [...]
}

On peut voir que la cle est générée puis envoyée sur un serveur distant

Volatility nous le confirme:

volatility -f mem.dmp --profile=Win10x64 netscan                                                                                                                                                     9:44:20
Volatility Foundation Volatility Framework 2.6.1
Offset(P)          Proto    Local Address                  Foreign Address      State            Pid      Owner          Created
[...]
0xe0001265ad10     TCPv4    192.168.248.133:49774          192.168.1.25:8080    ESTABLISHED      5208     ?              2019-05-08 20:00:17 UTC+0000
[...]

Si la connexion a ete établie et envoyée vers un serveur elle est forcement quelque part dans la mémoire.

Dans le code on peut voir quelle est envoyée suivant un pattern bien précis: {"id": "%s", "enckey": "%s"}

// AddNewKeyPair persist a new keypair on server
func (c *Client) AddNewKeyPair(id, encKey string) (*http.Response, error) {
    payload := fmt.Sprintf(`{"id": "%s", "enckey": "%s"}`, id, encKey)
    return c.SendEncryptedPayload("/api/keys/add", payload, map[string]string{})
}

Bon bah strings est notre ami en CTF ! On va chercher toutes les lignes qui contiennent le mot enckey et on va prendre 10 lignes au dessus et en dessous.

>_ strings mem.dmp | grep -A 10 -B 10 enckey
[...]
"C:\Users\TNKLSAI3TGT7O9\Downloads\assistance.exe" 
C:\Users\TNKLSAI3TGT7O9\Downloads\assistance.exe
S-1-5-21-2377780471-3200203716-3353778491-1000
{"id": "cd18c00bb476764220d05121867d62de", "enckey": "
cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac24cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac2495511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b95511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b
Encrypting C:\Users\Administrateur\Contacts\desktop.ini...
C:\Users\TNKLSA~1\AppData\Local\Temp\desktop.ini
C:\Users\TNKLSA~1\AppData\Local\Temp\desktop.ini
Encrypting C:\Users\Administrateur\Documents\desktop.ini...
C:\Users\TNKLSA~1\AppData\Local\Temp\desktop.ini
C:\Users\TNKLSA~1\AppData\Local\Temp\desktop.ini
Walking C:\Users\Administrateur\Favorites\Bing.url
Walking C:\Users\Administrateur\Favorites\Bing.url
C:\Users\Administrateur\Favorites\Links\desktop.ini
[...]

Parmis toutes les sorties il y en a une qui est interessante.

{"id": "cd18c00bb476764220d05121867d62de", "enckey": "
cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac24cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac2495511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b95511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b

On observe le pattern {"id": "%s", "enckey": "%s"} avec le parametre enckey qui parrait un peu long: cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac24cd18c00bb476764220d05121867d62de64e0821c53c7d161099be2188b6cac2495511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b95511870061fb3a2899aa6b2dc9838aa422d81e7e1c2aa46aa51405c13fed15b

le parametre enckey commence par la meme cle que l'id. On decoupe la string en 8 parts egales et on obtient 4 potentielles cles de chiffrement. En realite 3 car on peut exclure celle qui correspond à l'id.

cd18c00bb476764220d05121867d62de
64e0821c53c7d161099be2188b6cac24
cd18c00bb476764220d05121867d62de
64e0821c53c7d161099be2188b6cac24

95511870061fb3a2899aa6b2dc9838aa
422d81e7e1c2aa46aa51405c13fed15b
95511870061fb3a2899aa6b2dc9838aa
422d81e7e1c2aa46aa51405c13fed15b

Bon bah on va essayer de les retrer pour voir celle qui passe.

La plus probable est celle ci mais elle passe pas 64e0821c53c7d161099be2188b6cac24.

On retente avec la 2e 95511870061fb3a2899aa6b2dc9838aa et elle flag.

FLAG_IS:

ECSC{95511870061fb3a2899aa6b2dc9838aa}