Un client potentiel a tenté de faire exécuter du code distant au moyen des hooks intégrés de Git.

Un client potentiel a tenté de faire exécuter du code distant au moyen des hooks intégrés de Git.

SToFU Systems · Analyse d’incident · 20 octobre 2026

Sommaire

  1. Tout a commencé par une demande de développement
  2. Téléchargement et inspection des fichiers
  3. Comment le hook Git post-checkout pouvait s’exécuter
  4. Ce que fait le téléchargeur du hook Git
  5. Une application était-elle cachée dans l’archive ?
  6. Ce que le serveur de téléchargement a renvoyé
  7. Aurait-il pu s’agir d’un utilitaire légitime ?
  8. Examiner un dépôt Git inconnu
  9. Après l’examen de l’archive
  10. Correspondance et fichiers de preuve

Tout a commencé par une demande de développement

Le premier message est arrivé par notre site web le 15 octobre 2026. Son expéditeur souhaitait de l’aide pour développer une plateforme de détection de la fraude financière. Le système proposé devait évaluer le risque des transactions et utiliser l’analyse comportementale, avec notamment des exigences de vérification par blockchain et de production de rapports.

Le 19 octobre, nous avons reçu le lien de téléchargement. Le courriel qui l’accompagnait nous orientait vers la branche conf pour l’architecture et la branche NDA pour l’accord. Il réitérait la demande d’examiner et de signer l’accord de confidentialité.

Please review the project materials and review and sign the NDA in the NDA branch.

Suivre ces instructions amenait la personne chargée de l’examen à extraire l’archive, puis à changer de branche dans Git. Le courriel présentait ces deux opérations comme des étapes de la lecture de la documentation. Il ne mentionnait pas l’exécution d’un programme téléchargé.

Le courriel contenant l’archive du projet et les instructions pour ouvrir la branche NDA. Les informations permettant une identification sont recouvertes de rectangles gris.

Le courriel contenant l’archive du projet et les instructions pour ouvrir la branche NDA. Les informations permettant une identification sont recouvertes de rectangles gris.

Téléchargement et inspection des fichiers

Le lien menait à une page classique de partage de fichiers Dropbox. Nous avons téléchargé AI-Fraud-Detection_Blockchain.tar.gz dans un environnement d’examen isolé et conservé l’archive d’origine comme référence. L’URL de partage précise n’est pas divulguée ici.

Nous avons répertorié le contenu de l’archive et lu directement les objets Git fournis. Cela nous a permis de récupérer les documents des trois branches sans extraire de branche dans l’arbre de travail ni exécuter le code fourni. Dans les arbres des branches, nous avons trouvé 15 fichiers Markdown et un document Word.

Branche Fichiers Ce que nous avons trouvé
master 8 fichiers Markdown Un README, une présentation du projet, les exigences du produit et des cas d’usage métier. D’autres documents portaient sur les performances, la sécurité, les tests et l’exploitation.
conf 7 fichiers Markdown Des consignes pour une proposition de développement, l’architecture et l’intégration de la blockchain, les exigences des contrats intelligents, la conception des données et des API, un moteur de risque fondé sur l’IA et les jalons de livraison.
NDA 1 fichier DOCX Un accord de confidentialité avec un bloc de signature et des champs de modèle à remplir.

Le produit proposé combinait l’analyse des transactions, des règles de détection de fraude et des scores d’apprentissage automatique avec une vérification par blockchain. La pile suggérée utilisait Node.js et TypeScript avec Express, PostgreSQL, des bibliothèques Python d’apprentissage automatique et Ethereum. Le document de livraison prévoyait six jalons sur 24 semaines. Nous avons trouvé des documents de planification dans l’ensemble des arbres fournis, sans implémentation de l’application, modèle entraîné ni code source de contrat intelligent à examiner.

Certains détails méritaient un examen plus attentif. Les exemples d’API contenaient les chaînes littérales <built-in function id> et <built-in function hash> dans les chemins des points de terminaison. L’accord de confidentialité contenait encore des champs de modèle à remplir. Ces incohérences soulevaient des questions sur le soin apporté à la préparation des documents.

Le fichier exécutable .git/hooks/post-checkout constituait une découverte plus préoccupante. Ses commentaires décrivaient un utilitaire de mise à jour de navigateur ou d’extension, sans lien apparent avec l’examen du projet. La lecture du script a révélé des instructions visant à télécharger un programme externe et à le lancer en arrière-plan. La demande de changement de branche du courriel pouvait conduire une personne vers ce chemin d’exécution alors qu’elle cherchait à lire l’accord de confidentialité.

Nous avons maintenu le dépôt inactif et examiné le hook comme du texte. Les métadonnées pertinentes de l’archive et le comportement du script sont présentés ci-dessous.

Comment le hook Git post-checkout pouvait s’exécuter

Le fichier AI-Fraud-Detection_Blockchain.tar.gz mesure 779 429 octets. Ses 100 entrées TAR comprennent 60 fichiers ordinaires. Un répertoire .git complet était livré avec les documents.

Le répertoire des hooks contenait les fichiers .sample habituels ainsi qu’un exécutable nommé post-checkout.

AI-Fraud-Detection_Blockchain/.git/hooks/post-checkout

Il ne porte pas le suffixe .sample. Son mode TAR est 0777, ce qui inclut les permissions d’exécution, et sa taille est de 2 774 octets.

Git invoque post-checkout après avoir mis à jour l’arbre de travail au moyen d’opérations telles que checkout ou switch, à condition que l’environnement autorise l’exécution du hook. La documentation de Git décrit ce déclenchement.

Pourquoi le répertoire .git archivé est important

Un git clone ordinaire ne copie pas les hooks locaux côté client du dépôt source, comme l’explique Pro Git. Cette livraison contenait le répertoire .git existant dans une archive : le hook local était donc livré avec lui.

Le chemin, le mode et la taille du hook lus directement dans le TAR d’origine. Nous n’avons pas utilisé le répertoire reçu comme dépôt Git.

Le chemin, le mode et la taille du hook lus directement dans le TAR d’origine. Nous n’avons pas utilisé le répertoire reçu comme dépôt Git.

Nous avons inspecté directement le conteneur et les objets Git, sans exécuter checkout ni switch sur le dépôt reçu.

Ce que fait le téléchargeur du hook Git

Les commentaires du script shell décrivent un utilitaire de mise à jour de navigateur ou d’extension. Nous n’avons trouvé aucune exigence concernant un tel utilitaire dans les documents du projet. Le script est en texte clair, sans obfuscation.

Le seuil de taille inutilisé

Le script définit THRESHOLD à 100 et demande à Git une liste des noms de fichiers modifiés. Il initialise TRIGGER à zéro.

THRESHOLD=100
FILES=$(git diff --name-only "$OLD_HEAD" "$NEW_HEAD")
TRIGGER=0

Dans la boucle, il calcule SIZE. Aucune comparaison avec THRESHOLD n’est effectuée et aucune affectation ne modifie TRIGGER. Le bloc de téléchargement s’exécute lorsque TRIGGER vaut zéro.

if [ "$TRIGGER" -eq 0 ]; then

Dans le déroulement normal de ce script, la condition est vraie même lorsque la liste des fichiers modifiés est vide. Le seuil ne limite pas le téléchargement.

Numéros de ligne d’origine conservés. TRIGGER reste à zéro. THRESHOLD est déclaré, mais jamais utilisé dans une comparaison.

Numéros de ligne d’origine conservés. TRIGGER reste à zéro. THRESHOLD est déclaré, mais jamais utilisé dans une comparaison.

Des téléchargements distincts pour Linux, macOS et Windows

La valeur renvoyée par uname -s détermine le chemin de téléchargement et le nom du fichier local.

Système détecté Chemin sur le serveur Nom du fichier local
Linux /api/l run-command.sh
Darwin / macOS /api/m run-command.sh
MINGW, MSYS, CYGWIN, Windows_NT /api/w run-command.cmd
Système non reconnu /api/l run-command.sh

Les URL utilisent un même hôte, remplacé ici par <DOWNLOAD_DOMAIN>. Nous avons conservé le hook non expurgé à titre privé. Les branches conditionnelles couvrent Linux, macOS et Windows, avec un recours à Linux pour un système non reconnu. Nous n’avons pas testé l’exécution sur ces systèmes.

Téléchargement du fichier et tentative d’exécution

Le hook enregistre le fichier dans ${TMPDIR:-/tmp} à l’aide de curl, ou de wget si curl n’est pas disponible. Aucune vérification de signature ni de hachage attendu n’est effectuée avant les instructions d’exécution qui suivent.

chmod +x "$CMD_FILE"
"$CMD_FILE" > /dev/null 2>&1 &

L’esperluette finale lance la commande en arrière-plan. La sortie standard et la sortie d’erreur standard sont toutes deux redirigées vers /dev/null.

Après la tentative d’exécution, le hook écrit azuku dans .git-checker dans le répertoire temporaire. Il ne vérifie jamais la présence de ce marqueur avant de télécharger à nouveau. Il n’attend pas non plus la réussite du processus en arrière-plan avant d’écrire le fichier. Le marqueur pourrait donc exister après une tentative d’exécution infructueuse.

Les instructions d’origine de téléchargement, de chmod, d’exécution en arrière-plan et d’écriture du marqueur. Le programme de deuxième étape ne figure pas dans cet extrait.

Les instructions d’origine de téléchargement, de chmod, d’exécution en arrière-plan et d’écriture du marqueur. Le programme de deuxième étape ne figure pas dans cet extrait.

Un commentaire vers la fin indique de supprimer le répertoire temporaire de téléchargement. Aucune commande de suppression ne figure en dessous.

Une application était-elle cachée dans l’archive ?

Le téléchargement réseau soulevait une autre question. Une application se trouvait-elle déjà dans l’archive, peut-être dans l’historique Git ou dans l’accord de confidentialité ? Nous avons examiné les limites des conteneurs, puis décodé tous les objets Git fournis et inspecté le contenu du DOCX.

Les limites de l’archive

Nous avons enregistré le SHA-256 de l’archive d’origine avant d’inspecter son contenu.

6f44ff4e461828dd1fe6ede75ca8d9d4b579c2ac223463629e9a7537b9df5040

La décompression de gzip en tant que données a produit un flux TAR de 890 880 octets. Le flux gzip se terminait correctement, sans octet inutilisé après sa fin. Les 5 120 derniers octets après la dernière entrée TAR étaient du remplissage par des zéros.

Nous avons ensuite examiné les fichiers et objets correspondant à ces entrées de conteneur.

Vérifications enregistrées de la fin de flux gzip et du remplissage TAR. Aucun code de l’échantillon n’a été exécuté.

Vérifications enregistrées de la fin de flux gzip et du remplissage TAR. Aucun code de l’échantillon n’a été exécuté.

Repérage du hook dans l’en-tête TAR

L’en-tête de l’entrée post-checkout commence à 0xCF600, soit 849 408, dans le TAR décompressé. Les données du fichier commencent à 849 920. Ces décalages se rapportent au flux TAR, et non au fichier .gz compressé.

À ce décalage, l’en-tête commence par le chemin vers post-checkout.

TAR / affichage hexadécimal

000cf600  41 49 2d 46 72 61 75 64 2d 44 65 74 65 63 74 69  |AI-Fraud-Detecti|
000cf610  6f 6e 5f 42 6c 6f 63 6b 63 68 61 69 6e 2f 2e 67  |on_Blockchain/.g|
000cf620  69 74 2f 68 6f 6f 6b 73 2f 70 6f 73 74 2d 63 68  |it/hooks/post-ch|
000cf630  65 63 6b 6f 75 74 00 00 00 00 00 00 00 00 00 00  |eckout..........|
000cf640  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
000cf650  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|
000cf660  00 00 00 00 30 30 30 30 37 37 37 00 30 30 30 31  |....0000777.0001|
000cf670  37 35 30 00 30 30 30 31 37 35 30 00 30 30 30 30  |750.0001750.0000|
000cf680  30 30 30 35 33 32 36 00 31 35 32 35 32 30 30 34  |0005326.15252004|
000cf690  33 30 37 00 30 32 34 30 37 35 00 20 30 00 00 00  |307.024075. 0...|
000cf6a0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  |................|

Dans un en-tête TAR, mode occupe les octets [100:108] et size occupe [124:136]. Les champs décodés de cette entrée figurent après le dump.

Champ TAR Octets bruts / valeur
mode b'0000777\x00'
size b'00000005326\x00'
Mode en octal 0777
Taille en décimal 2774 octets
Somme de contrôle stockée / calculée 10301 / 10301

La taille en octal correspond à 2 774 octets. La somme de contrôle stockée dans l’en-tête est 10 301. Son recalcul en remplissant le champ de somme de contrôle avec des espaces donne le même résultat.

L’en-tête TAR brut du hook et ses champs décodés. Son nom, ses permissions et sa taille sont visibles dans les octets du conteneur.

L’en-tête TAR brut du hook et ses champs décodés. Son nom, ses permissions et sa taille sont visibles dans les octets du conteneur.

Nous avons également calculé le hachage du hook extrait de cette entrée.

854b3b88b06fad9d9ffec36b35be0133b1d502084d4d7cce232eda2b2dd03092

Le dump de l’entrée TAR et le hook anonymisé sont joints à l’article. Le hachage ci-dessus identifie l’original non expurgé conservé à titre privé, et non la copie expurgée destinée à la publication.

Lecture des objets Git sans checkout

Il y a 24 objets non empaquetés dans .git/objects, chacun stocké dans un flux zlib. Les données décompressées contiennent un en-tête Git suivi du corps de l’objet.

<type> <size>\0<body>

Nous avons vérifié la longueur déclarée du corps et calculé le SHA-1 sur l’ensemble de la séquence décodée, y compris l’en-tête et l’octet NUL. Le résultat doit correspondre à l’identifiant d’objet dans le nom du fichier. Cela vérifie l’intégrité de l’objet, sans rien indiquer sur son créateur.

Pour chaque objet, nous avons comparé la longueur déclarée à celle du corps et vérifié le hachage de l’ensemble des données décodées.

expanded = zlib.decompress(compressed_object)
header, body = expanded.split(b"\0", 1)
kind, declared_size = header.decode("ascii").split()

assert len(body) == int(declared_size)
assert hashlib.sha1(expanded).hexdigest() == object_id

Nous avons également vérifié les fins des flux zlib. Les objets se répartissent en 16 blobs, 5 arbres et 3 commits. Le parcours des têtes des trois branches, de leurs commits parents et de leurs arbres enfants permet de retrouver les 24 objets. Aucun blob n’est inaccessible parmi les objets fournis.

Git / relations entre commits

master 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f
  tree   feb0feaf7b8e826b085e90dea5399772d7b91f02
  parent (none)

conf   239b9aa2edc8c5e21fddeea5ed0e937496ae013f
  tree   048b51f9673f94354251ce16a78e663c71667a4c
  parent 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f

NDA    a1311875d86bf6f1a6b9f2fee6527abbd1ce647d
  tree   cc020d922090835ea4ac3a3e418d0213d7a2ad94
  parent 239b9aa2edc8c5e21fddeea5ed0e937496ae013f

L’inventaire complet des objets inclut ceux qui ne figurent pas dans l’arbre de travail courant.

Inventaire des 24 objets Git

Identifiant d’objet Type Corps, en octets
08e2cda2f440c1792c7c35a3499bfd1ade3e9bad blob 6497
22bb86aacf377c17c7ad0d52c5cefeeb93dfa13e blob 5123
2a7091bdd006a2f98a8c795fd7d2a04c8ee53056 blob 2610
39e13459086f36bc7c933d4e7b5d249a22db24bd blob 3061
3f50e45c67dee5aac77147a5418afe551e8871be blob 2433
476dc872c6def747dcdac549b67a8dc80948b7e1 blob 3191
5a51550933b593eb65da458bbdd579f85c082dab blob 752100
5e53fd0880963e1767ad23fb8612b76e31f04003 blob 2807
60a7cbff83445488fd34b12de1814dc56c956963 blob 2054
74d479352822f5cc1d03552f517cfb5b2d7aa6d3 blob 2281
84e694473554c8a7c01f038a1b6ef8d9355405f7 blob 2033
bb7b5d8bc28c4a6257f7d87a685c61ba16a3789c blob 2425
d83c8e0c416766be34276013944f5b94726e8c8f blob 2776
dfd0f171bca257780eb0d9e22ba2eda1db9d4b68 blob 8402
e3b57e48010fc25fd12e7f5f25e952aca843e537 blob 6316
ed325750862eb6cdc92b216258a00a784312d793 blob 3062
239b9aa2edc8c5e21fddeea5ed0e937496ae013f commit 213
4bc26f6c18910ca777c8238d2f88f6e725fcdc3f commit 165
a1311875d86bf6f1a6b9f2fee6527abbd1ce647d commit 212
048b51f9673f94354251ce16a78e663c71667a4c tree 438
2cb70db8d9317603cb5f0fee0029b66581a7162e tree 104
61874365e5498a30c8b61ef63bbb1d28b4cf4e22 tree 320
cc020d922090835ea4ac3a3e418d0213d7a2ad94 tree 57
feb0feaf7b8e826b085e90dea5399772d7b91f02 tree 104

Longueur et SHA-1 vérifiés sur l’encodage Git d’origine de chaque objet. Les 24 vérifications ont réussi.


Suivre l’accord de confidentialité depuis son arbre jusqu’à ses octets

La branche NDA pointe vers un arbre contenant un seul fichier, Non-Disclosure-Agreement.docx. Une entrée d’arbre Git stocke le mode et le nom du fichier sous forme de texte, suivis d’un NUL et de 20 octets bruts pour l’identifiant du blob. Nous avons analysé l’entrée directement à partir du corps de l’arbre.

Arbre Git / affichage hexadécimal

00000000  31 30 30 36 34 34 20 4e 6f 6e 2d 44 69 73 63 6c  |100644 Non-Discl|
00000010  6f 73 75 72 65 2d 41 67 72 65 65 6d 65 6e 74 2e  |osure-Agreement.|
00000020  64 6f 63 78 00 5a 51 55 09 33 b5 93 eb 65 da 45  |docx.ZQU.3...e.E|
00000030  8b bd d5 79 f8 5c 08 2d ab                       |...y.\.-.|

Octets bruts de l’arbre NDA et référence décodée à son blob DOCX.

Octets bruts de l’arbre NDA et référence décodée à son blob DOCX.

Cette entrée fait référence au blob suivant.

5a51550933b593eb65da458bbdd579f85c082dab

Après décompression zlib, l’objet commence par blob 752100\0. Juste après l’en-tête se trouvent les octets 50 4b 03 04, la signature PK d’un conteneur ZIP.

Blob Git / après décompression zlib

00000000  62 6c 6f 62 20 37 35 32 31 30 30 00 50 4b 03 04  |blob 752100.PK..|
00000010  0a 00 00 00 00 00 87 4e e2 40 00 00 00 00 00 00  |.......N.@......|
00000020  00 00 00 00 00 00 09 00 00 00 64 6f 63 50 72 6f  |..........docPro|
00000030  70 73 2f 50 4b 03 04 14 00 00 00 08 00 87 4e e2  |ps/PK.........N.|
00000040  40 a5 76 12 16 69 01 00 00 7b 02 00 00 10 00 00  |@.v..i...{......|
00000050  00 64 6f 63 50 72 6f 70 73 2f 61 70 70 2e 78 6d  |.docProps/app.xm|
00000060  6c 9d 92 c1 4e c3 30 10 44 ef 48 fc 43 94 7b 62  |l...N.0.D.H.C.{b|

Octets de l’objet compressé, en-tête Git décodé et début du DOCX. La longueur et l’identifiant de l’objet ont été vérifiés sur l’objet complet.

Octets de l’objet compressé, en-tête Git décodé et début du DOCX. La longueur et l’identifiant de l’objet ont été vérifiés sur l’objet complet.

Le corps mesure 752 100 octets. Son SHA-256 correspond à celui du DOCX que nous avons enregistré séparément pour analyse.

9d85170d2c0aa7a9b90dfc3855715a31d971bba7abb563e9efa1153fdc15634f

Ces objets permettent de retracer le chemin entre la branche NDA et les octets du document.

Identification des 16 blobs

Quinze blobs se décodent en documents de projet Markdown en UTF-8. Le blob restant est le DOCX ci-dessus. Aucun ne commence par un en-tête PE, ELF ou Mach-O.

Chemin dans les arbres Taille, en octets Type / premiers octets
04-solution-proposal-guidance.md 2054 Texte UTF-8 · 23 20 44 65 76 65 6c 6f 70 6d 65 6e 74 20 43 6f
06-blockchain-architecture.md 6497 Texte UTF-8 · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 41 72 63
07-blockchain-integration-specification.md 2807 Texte UTF-8 · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 49 6e 74
08-smart-contract-specification.md 2610 Texte UTF-8 · 23 20 53 6d 61 72 74 20 43 6f 6e 74 72 61 63 74
09-data-and-api-architecture.md 2776 Texte UTF-8 · 23 20 44 61 74 61 20 26 20 41 50 49 20 41 72 63
11-ai-fraud-and-risk-engine.md 3062 Texte UTF-8 · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63
14-deliverables-acceptance-and-milestones.md 6316 Texte UTF-8 · 23 20 44 65 6c 69 76 65 72 61 62 6c 65 73 2c 20
Detailed/03-business-and-use-cases.md 3061 Texte UTF-8 · 23 20 42 75 73 69 6e 65 73 73 20 52 65 71 75 69
Detailed/05-non-functional-requirements.md 2033 Texte UTF-8 · 23 20 4e 6f 6e 2d 46 75 6e 63 74 69 6f 6e 61 6c
Detailed/10-security-and-privacy-requirements.md 2433 Texte UTF-8 · 23 20 53 65 63 75 72 69 74 79 20 26 20 50 72 69
Detailed/12-testing-and-quality-requirements.md 2425 Texte UTF-8 · 23 20 54 65 73 74 69 6e 67 20 26 20 51 75 61 6c
Detailed/13-deployment-monitoring-and-operations.md 2281 Texte UTF-8 · 23 20 44 65 70 6c 6f 79 6d 65 6e 74 2c 20 4d 6f
Intro/01-project-overview.md 8402 Texte UTF-8 · 23 20 50 72 6f 6a 65 63 74 20 4f 76 65 72 76 69
Intro/02-product-requirements.md 3191 Texte UTF-8 · 23 20 50 72 6f 64 75 63 74 20 52 65 71 75 69 72
Non-Disclosure-Agreement.docx 752100 DOCX/ZIP · 50 4b 03 04 0a 00 00 00 00 00 87 4e e2 40 00 00
README.md 5123 Texte UTF-8 · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63

Les 16 blobs fournis ont été classés. Les arbres contiennent des documents de projet ; aucune implémentation du produit n’a été trouvée.

Les 16 blobs fournis ont été classés. Les arbres contiennent des documents de projet ; aucune implémentation du produit n’a été trouvée.

Nous avons lu les corps textuels en plus de vérifier leurs signatures. Le DOCX était le seul blob non textuel et nécessitait une inspection distincte de son conteneur.

Ouverture du DOCX en tant que ZIP

Le document contient 25 entrées ZIP, composées de 17 parties de fichier et de 8 répertoires. Nous avons lu chaque partie de fichier et vérifié son CRC.

Partie du DOCX Taille, en octets CRC32
[Content_Types].xml 1482 ec936159
_rels/.rels 737 1f222201
customXml/_rels/item1.xml.rels 296 7a393f74
customXml/item1.xml 400 4ed0e3fe
customXml/itemProps1.xml 327 457b4363
docProps/app.xml 635 161276a5
docProps/core.xml 595 d5626da7
docProps/custom.xml 722 8d44908d
word/_rels/document.xml.rels 1086 22475620
word/_rels/settings.xml.rels 398 e5802c0c
word/document.xml 91835 4df71596
word/fontTable.xml 4234 2796cccd
word/media/image1.png 712863 09063019
word/media/image2.png 10193 3aea21cf
word/settings.xml 4116 34faa9ef
word/styles.xml 30020 b4e9edbd
word/theme/theme1.xml 6329 ed5975e1

Noms, longueurs et valeurs CRC32 des parties du DOCX. Nous avons inspecté les données ZIP et XML sans ouvrir le document dans Office.

Noms, longueurs et valeurs CRC32 des parties du DOCX. Nous avons inspecté les données ZIP et XML sans ouvrir le document dans Office.

La liste des parties ne contient ni vbaProject.bin ni pièce jointe OLE. Deux fichiers PNG contiennent un logo et une image de signature. Nous avons aussi inspecté les relations XML et trouvé une référence à un chemin de modèle bureautique local sur la machine de l’auteur du document. Nous n’avons ni résolu cette référence ni chargé le modèle.

L’image de signature et les champs d’auteur Git ne nous donnent aucun moyen fiable d’identifier l’expéditeur. Les uns comme les autres peuvent être copiés ou remplacés.

Nous n’avons trouvé aucune application distincte ni implémentation du produit dans le contenu fourni. Le hook obtient son programme suivant par le réseau. Notre inspection des conteneurs n’exclut pas toutes les formes possibles d’exploitation ou de stéganographie.

Ce que le serveur de téléchargement a renvoyé

Nous avons récupéré les trois URL exactes en tant que données, sans exécuter les réponses ni suivre les redirections. Le 19 octobre, de 17:29:27 à 17:29:28 UTC, chacune a renvoyé le code HTTP 200. Les trois corps contenaient le même message de 21 octets.

Permanently suspended

Les trois observations enregistrées des points de terminaison. Nous n’avons effectué aucune autre requête vers les URL du téléchargeur pendant la préparation de cet article.

Les trois observations enregistrées des points de terminaison. Nous n’avons effectué aucune autre requête vers les URL du téléchargeur pendant la préparation de cet article.

Nous ne disposons d’aucun octet de deuxième étape à soumettre à la rétro-ingénierie. Nous ignorons aussi ce que ces points de terminaison renvoyaient auparavant, à un autre visiteur ou dans d’autres conditions de requête. Le message de suspension ne nous donne aucune explication vérifiée de la raison de la suspension du service.

Le hook tente de télécharger et d’exécuter un fichier externe. Affirmer que des mots de passe, jetons, du code source ou des portefeuilles ont été volés nécessiterait des preuves dont nous ne disposons pas.

Aurait-il pu s’agir d’un utilitaire légitime ?

Un outil interne de mise à jour pourrait se retrouver dans une archive par erreur. Les hooks Git, les processus en arrière-plan et curl ont tous des usages légitimes.

Dans cet envoi, le courriel nous demandait explicitement de passer sur une autre branche. Cette opération pouvait invoquer le téléchargeur fourni, alors que la raison annoncée du changement de branche était la lecture d’un accord. Le courriel ne mentionnait pas l’exécution. Nous n’avons par ailleurs trouvé aucun lien entre un outil de mise à jour de navigateur et le système proposé, et la vérification de taille du script était incomplète.

Nous avons traité cet envoi comme une tentative d’attaque par livraison de code et empêché l’exécution du hook. Réexaminer cette appréciation nécessiterait le code source des fichiers téléchargés et une explication vérifiable de la nécessité, pour un prestataire, de les exécuter afin d’examiner l’accord de confidentialité.

Nous n’avons pas établi l’identité de l’opérateur. L’adresse de l’expéditeur, les métadonnées des commits et les noms dans le document ne suffisent pas à attribuer l’opération.

Schéma d’analyse des étapes d’exécution décrites par le hook fourni.

Schéma d’analyse des étapes d’exécution décrites par le hook fourni.

Examiner un dépôt Git inconnu

Un développeur suivant le courriel pouvait atteindre le déclencheur d’exécution alors qu’il lisait encore les informations sur le projet. Il n’était pas nécessaire de compiler ni de démarrer l’application proposée.

Si vous examinez des envois de clients sur une machine contenant des clés SSH de production ou des jetons cloud, un script inattendu peut avoir accès à ces ressources. Un environnement jetable doit maintenir ces identifiants hors d’atteinte. Les sessions de navigateur sur la machine d’examen méritent la même attention.

L’examen doit inclure le répertoire .git fourni et toute automatisation de l’IDE avant qu’un ingénieur ne commence à utiliser ses commandes habituelles. Les scripts d’installation doivent également être examinés attentivement. Dans les journaux de l’hôte, nous rechercherions Git ou un shell téléchargeant un fichier dans un répertoire temporaire, puis l’exécutant. Un processus curl seul nous en dit beaucoup moins.

Conserver le courriel et l’archive d’origine permet à une autre personne de vérifier ultérieurement ce qui a été livré. Les hachages et les événements de l’hôte aident à établir ce qui s’est passé sur la machine. L’absence de marqueur ne permet pas d’établir qu’un programme ne s’est jamais exécuté.

Le téléchargement ou l’extraction de l’archive peuvent-ils exécuter ce hook ?

Le téléchargement et l’extraction ordinaires n’invoquent pas eux-mêmes le hook post-checkout de Git. Dans cet échantillon, le déclencheur documenté est la mise à jour de l’arbre de travail par Git au moyen de checkout ou de switch, lorsque l’exécution des hooks est autorisée. Nous avons inspecté directement les objets fournis sans invoquer ces opérations.

Après l’examen de l’archive

Nous nous attendions à ce que l’échange suivant porte sur l’architecture et les dates de livraison. Nous avons plutôt répondu au sujet du hook et conservé les éléments pour un examen ultérieur. Nous ne pouvons toujours pas dire ce que faisait le programme distant ni qui l’exploitait. Le hook nous donnait suffisamment de raisons d’interrompre le processus Git demandé.

Depuis plus de cinq ans, SToFU Systems et nos solutions aident les entreprises à protéger leurs systèmes, notamment contre les attaques transmises par la correspondance professionnelle et les supports de développement. Nos audits de sécurité examinent comment le code et les accès peuvent être détournés. Nous proposons aussi des services de rétro-ingénierie lorsqu’une équipe doit comprendre un logiciel inconnu.

Si un dépôt ou un binaire soulève des questions, contactez notre équipe pour un examen technique avant de l’introduire dans votre environnement de développement habituel.

Correspondance et fichiers de preuve

Les quatre messages ci-dessous utilisent des marqueurs de substitution pour les noms de personnes, les adresses, les identités de tiers et les liens permettant une identification. Le reste du texte de chaque nouveau message est conservé. Les citations répétées sont omises, chaque courriel étant présenté séparément. L’adresse IP du service du formulaire web et les adresses de destinataires sans rapport sont également masquées.

1. La première demande par notre site web

Courriel / données identifiantes remplacées

Date: Thu, 15 Oct 2026 12:55:21 +0000
From: SToFU Site Form <TEAM_EMAIL>
To: <TEAM_EMAIL>
Subject: SToFU Systems - Contact by <SENDER_NAME> <SENDER_EMAIL>
Reply-To: <SENDER_NAME> <SENDER_EMAIL>

Time: 2026-10-15T12:55:21+00:00
IP: [redacted]
Page: /contact
Name: <SENDER_NAME>
Email: <SENDER_EMAIL>
Attachments: none
Message:
We are currently developing an AI-powered FinTech fraud detection platform designed to help financial organizations identify suspicious transactions, assess potential risks in real time, and strengthen their fraud prevention and investigation processes.
The planned platform will incorporate AI/ML-based fraud detection, transaction risk scoring, behavioral analysis, configurable fraud-detection rules, blockchain-based verification, automated alerts, investigation support, and reporting and analytics.
We are looking to connect with an experienced technology partner with expertise in blockchain, financial technology, AI/ML, and scalable web platform development to help us bring this product to life.
We would welcome the opportunity to discuss your team’s capabilities, experience, and potential role in the project. The specific scope of your team’s involvement, technical responsibilities, and collaboration model can be determined through our discussion, based on your expertise and recommendations.
If this opportunity aligns with your team’s capabilities and interests, I’d be happy to share the project overview and technical roadmap for an initial review.
---

La première demande par notre site web. Vue anonymisée du courriel conservé, destinée à la publication.

La première demande par notre site web. Vue anonymisée du courriel conservé, destinée à la publication.

SHA-256 de l’EML privé non expurgé : bf7d0f3a59b84f509ca436e0750640e844e9731ce363a42a99d5be60cdf8597e


2. Notre réponse demandant les documents

Courriel / données identifiantes remplacées

Date: Sat, 17 Oct 2026 19:46:28 -0000
From: <TEAM_MEMBER_NAME> <TEAM_EMAIL>
To: <SENDER_NAME> <SENDER_EMAIL>
Subject: Re: Your AI fraud detection platform
Cc: [redacted: third-party addresses]

Hi <SENDER_NAME>,

Thank you for getting in touch through our website. I'm <TEAM_MEMBER_NAME>, <TEAM_MEMBER_ROLE> of SToFU Systems (<COMPANY_WEBSITE>). You can find me on <PROFESSIONAL_NETWORK> here:
<PROFILE_URL>

Your fraud detection platform sounds like a great project. Helping financial teams spot suspicious transactions and investigate them more effectively is a worthwhile problem to solve, and we'd be very happy to help you bring it to life.

We'd be glad to help with the architecture, development, security, and ongoing maintenance. We'll do everything we can to get the platform launched and keep it running reliably as it grows.

If you plan to seek investment, we can also help prepare the technical side for those conversations, including a working product or demo, clear architecture and documentation, and a practical development roadmap.

Please send over the project overview and technical roadmap you mentioned. It would be helpful to understand what you've already built and what you'd like to tackle first.

I'd be happy to arrange a call to discuss the project and how we could work together. What day and time would suit you? Please include your time zone so we can find a slot that works for both teams.

Thank you again for reaching out, and have a great day!

Best regards,
<TEAM_MEMBER_NAME>
<TEAM_MEMBER_ROLE>
SToFU Systems
<COMPANY_WEBSITE>

Notre réponse demandant les documents. Vue anonymisée du courriel conservé, destinée à la publication.

Notre réponse demandant les documents. Vue anonymisée du courriel conservé, destinée à la publication.

SHA-256 de l’EML privé non expurgé : 1e5330dd82e02911254722744a3202e9b761c8c1d2950be937cd5d539c1bcad9


3. Le courriel de l’archive mentionnant les branches NDA / conf

Courriel / données identifiantes remplacées

Date: Mon, 19 Oct 2026 09:03:41 +0000
From: <SENDER_EMAIL>
To: <TEAM_EMAIL>
Subject: Re: Your AI fraud detection platform

Hi <TEAM_MEMBER_NAME>,
Thank you for your interest in our AI-powered FinTech fraud detection platform.
I’ve also reviewed your <PROFESSIONAL_NETWORK> profile, and I’m confident that you and your team can make a valuable contribution to our project.
I’m happy to share the project materials for your review.
We’ve prepared the project overview, technical roadmap, and NDA, which provide the key information needed to understand the project, its objectives, and the proposed technical direction.
The platform focuses on AI-driven fraud detection, transaction risk assessment, behavioral analysis, fraud prevention, blockchain-based verification, automated alerts, investigation support, and financial risk analytics.
This is the Link:
<FILE_SHARE_URL>
Please review the project materials and review and sign the NDA in the NDA branch.
The NDA is required because the project materials contain confidential business, technical, architectural, and product information.
So, please send me the signed NDA as soon as possible.
In particular, we would appreciate your initial technical assessment of the proposed system architecture and timeline. The detailed documentation and specifications related to these areas are available in the conf branch.
After your review, we would like to arrange a meeting to discuss your technical observations, recommendations, questions, development approach, and potential partnership opportunities in more detail.
Once you have completed your review, please let me know your preferred meeting date and time and provide the signed NDA.
Please feel free to take the time you need to review the materials thoroughly. I look forward to receiving your feedback and speaking with you about the project.
Kind regards,
<SENDER_NAME>

Le courriel de l’archive mentionnant les branches NDA / conf. Vue anonymisée du courriel conservé, destinée à la publication.

Le courriel de l’archive mentionnant les branches NDA / conf. Vue anonymisée du courriel conservé, destinée à la publication.

SHA-256 de l’EML privé non expurgé : f7007ed3053d3ba2ef71ea01c74ec0c4aebfd48417f757ecec8d9d7d5884bf33


4. Notre réponse après la découverte du hook

Courriel / données identifiantes remplacées

Date: Mon, 19 Oct 2026 19:37:58 +0200
From: SToFU Systems <TEAM_EMAIL>
To: <SENDER_NAME> <SENDER_EMAIL>
Subject: Re: Your AI fraud detection platform

Hi <SENDER_NAME>,

We reviewed the materials you sent. Unfortunately, we found no application source code or working implementation, only planning documents and an NDA.

Execution of the supplied Git post-checkout hook was disabled during our review. The hook downloads and runs platform-specific files from <DOWNLOAD_DOMAIN>, hides their output, and writes a local marker. Our security policies do not allow the execution of untrusted third-party hooks.

Thank you for your time and for the elaborate attempt to deliver malicious code.

We have traced the technical delivery chain and preserved the archive, hook, download responses, correspondence, and author names and email addresses recorded in the repository. The relevant evidence will be passed to the competent law enforcement authorities in the applicable jurisdictions.

SToFU Systems

Notre réponse après la découverte du hook. Vue anonymisée du courriel conservé, destinée à la publication.

Notre réponse après la découverte du hook. Vue anonymisée du courriel conservé, destinée à la publication.

SHA-256 de l’EML privé non expurgé : 31df91adb2eb52be2171836d3e26610328a0a1a1273dbf7d56efe4354bb62e19


Vue anonymisée du hook complet

Les 101 numéros de ligne du code source ont été conservés. Les informations permettant une identification sont recouvertes de rectangles gris.

Les 101 numéros de ligne du code source ont été conservés. Les informations permettant une identification sont recouvertes de rectangles gris.


Les originaux non expurgés sont conservés à titre privé. Les fichiers de preuve publics utilisent des marqueurs de substitution, et les captures d’écran des rectangles gris opaques. Les hachages étiquetés comme originaux identifient la source privée, et non une copie modifiée destinée à la publication. Les figures sont des captures d’écran de vues locales des preuves, dont le texte permettant une identification a été retiré avant le rendu. Aucun code reçu n’a été exécuté.

SToFU Systems

SToFU Systems

Retour aux blogs

Contacter

Démarrer la conversation

Quelques lignes claires suffisent. Décrivez le système, la pression et la décision bloquée. Ou écrivez directement à midgard@stofu.io.

0 / 10000
Aucun fichier choisi