capture d'écran de l'exécutable d'un malware se faisant passer pour une archive winRAR Rien qu'avec le nom c'est pourtant évident que même si ça a bien commencé, ça se terminera mal.

Vous pensiez que Python était seulement utilisé pour des projets légitimes et bien intentionnés ? Détrompez-vous. Dans cet article, nous allons disséquer un malware Python. De la détection du packer aux subtilités de l'analyse du bytecode. Découvrez comment ce stealer cible astucieusement les navigateurs de type Chromium, dérobant secrètement identifiants et cookies. Bienvenue dans le royaume de la résilience numérique.

(Merci ChatGPT pour cette introduction épique).

Sommaire

Première analyse du malware

La toute première commande à exécuter est liée à la recherche de chaînes de caractères intelligibles laissées par les développeurs dans le code (commentaires, debuggage, configuration, variables, etc.).

$ strings nudesmarie.exe > strings.txt

Dans les 82000 résultats, on retrouve beaucoup de bruit mais on lit néanmoins des éléments intéressants dont voici un extrait :

__main__
__file__
_MEIPASS2
_PYI_ONEDIR_MODE
Failed to get _MEIPASS as PyObject.
_MEIPASS
Installing PYZ: Could not get sys.path
PyList_New

Pas de doutes, il y a du code Python manifestement packé en exécutable pour Windows. La recherche sur un moteur de recherche d'un string d'aspect assez caractéristique comme _MEIPASS permet rapidement d'identifier le packerPyInstaller.

À la rédaction de l'article je m'aperçois qu'on avait aussi la chaine suivante plutôt explicite :

Cannot open PyInstaller archive from executable (%s) or external archive (%s)

Par ailleurs un packing avec PyInstaller se reconnait également par la présence de ces noms de fichiers :

mstruct
mpyimod01_os_path
mpyimod02_archive
mpyimod03_importers
mpyimod04_ctypes
spyiboot01_bootstrap
python39.dll

Notons que les versions antérieures à la 6.0 (sept 2023) supportent un chiffrement du payload en AES.ans le royaume de la résilienc La fonctionnalité a été retirée étant donné qu'en tant que chiffrement symétrique (reposant sur une clé), la clé doit être intégrée à l'exécutable pour que le code puisse être déchiffré dynamiquement (voir note sur le dépôt de PyInstaller et le changelog du projet). L'activation de cette fonctionnalité rajoute en effet le fichier pyimod00_crypto_key.py qui comme son nom l'indique contient… la clé. Pas super efficace.

Cas particulier du point d'entrée du programme vis à vis du chiffrement

L'entry-point du payload n'est jamais chiffré, même avec le chiffrement activé. Par conséquent les sources ne sont pas chiffrées tant qu'elles ne sont pas organisées en package.

En bonus, l'extraction de l'icône de l'application peut donner quelques indications sur l'arnaque en cours :

$ wrestool -x nudesmarie.exe

xxx Une archive RAR. Évidemment.

Recherche d'outils pour l'unpacking

À présent que le packer a été identifié, il est conseillé d'utiliser un programme d'unpacking dédié à celui-ci.

J'ai identifié 2 projets pour cela :

  • PyInstaller Extractor : requiert la bonne version de Python utilisée par le développeur pour décompresser les fichiers .pyz (archive du payload).

  • pyinstxtractor-ng : version standalone ne nécessitant pas l'exacte version de Python utilisée pour créer le malware ; supporte les exécutables chiffrés de manière transparente.

Les sources du malware ne sont pas chiffrées, j'ai donc utilisé pyinstxtractor sur Python3.9. Pour les curieux la FAQ de pyinstxtractor fournit un code pour traiter les fichiers chiffrés.

Et binwalk dans tout ça ?

Avoir recours à binwalk en étape préliminaire est très souvent une bonne idée pour voir les ressources embarquées dans un fichier.

Mais n'étant pas assez spécialisé, ce n'est clairement pas le bon outil ici. Il arrive à peine à extraire le manifeste du PE (Portable Executable) (format des exécutables et dll sous Windows) et produit de nombreux faux positifs.

C'est parti pour l'unpacking :

$ python pyinstxtractor.py nudesmarie.exe
[+] Processing nudesmarie.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.9
[+] Length of package: 6586187 bytes
[+] Found 32 files in CArchive
[+] Beginning extraction…please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_subprocess.pyc
[+] Possible entry point: pyi_rth_pkgutil.pyc
[+] Possible entry point: pyi_rth_multiprocessing.pyc
[+] Possible entry point: pyi_rth_inspect.pyc
[+] Possible entry point: Token.pyc
[+] Found 231 files in PYZ archive
[+] Successfully extracted pyinstaller archive: nudesmarie.exe

You can now use a python decompiler on the pyc files within the extracted directory

Le programme est vraiment bien fait puisqu'il oriente vers les tâches suivantes. Intuitivement, l'entry-point du payload est manifestement le fichier Token.pyc.

L'essentiel des 231 fichiers exportés constitue une part de la librairie standard de Python qui par le jeu des imports est requise pour que le payload fonctionne. Ils sont issus de l'archive PYZ-00.pyz qui contient aussi potentiellement du code malveillant.

Conclusion

Nous avons vu les étapes préliminaires lors de l'analyse d'un binaire suspect. Après identification du logiciel qui a été utilisé pour le produire, nous avons vu comment utiliser un programme pour défaire l'empaquetage réalisé.

Dans le prochain article j'aborderai le traitement du bytecode Python obtenu, puis finalement l'analyse du code lui-même. À condition de réussir à retrouver les sources ?