Een potentiële klant probeerde externe code uit te voeren via de ingebouwde hooks van Git.

Een potentiële klant probeerde externe code uit te voeren via de ingebouwde hooks van Git.

SToFU Systems · Incidentonderzoek · 20 oktober 2026

Inhoud

  1. Het begon met een ontwikkelaanvraag
  2. De bestanden downloaden en inspecteren
  3. Hoe de Git-hook post-checkout kon worden uitgevoerd
  4. Wat de downloader in de Git-hook doet
  5. Zat er een applicatie verborgen in het archief?
  6. Wat de downloadserver retourneerde
  7. Kon dit een legitiem hulpprogramma zijn geweest?
  8. Een onbekende Git-repository beoordelen
  9. Na de beoordeling van het archief
  10. Correspondentie en bewijsbestanden

Het begon met een ontwikkelaanvraag

Het eerste bericht kwam op 15 oktober 2026 binnen via onze website. De afzender wilde hulp bij het bouwen van een platform om financiële fraude op te sporen. Het voorgestelde systeem zou transactierisico's scoren en gedragsanalyse gebruiken, met onder meer blockchainverificatie en rapportage als aanvullende vereisten.

Op 19 oktober ontvingen we de downloadlink. De begeleidende e-mail verwees ons naar de branch conf voor de architectuur en de branch NDA voor de overeenkomst. De e-mail herhaalde het verzoek om de geheimhoudingsovereenkomst te beoordelen en te ondertekenen.

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

Wie deze instructies volgde, zou na het uitpakken van het archief in Git van branch wisselen. De e-mail presenteerde beide handelingen als onderdeel van het lezen van de documentatie. Er werd niets gezegd over het uitvoeren van een gedownload programma.

De e-mail met het projectarchief en de instructies om de NDA-branch te openen. Identificerende gegevens zijn afgedekt met grijze rechthoeken.

De e-mail met het projectarchief en de instructies om de NDA-branch te openen. Identificerende gegevens zijn afgedekt met grijze rechthoeken.

De bestanden downloaden en inspecteren

De link leidde naar een standaardpagina van Dropbox voor het delen van bestanden. We downloadden AI-Fraud-Detection_Blockchain.tar.gz naar een geïsoleerde beoordelingsomgeving en bewaarden het oorspronkelijke archief als referentie. De specifieke deel-URL wordt hier niet gepubliceerd.

We maakten een overzicht van de archiefinhoud en lazen de meegeleverde Git-objecten rechtstreeks. Zo konden we de documenten uit alle drie de branches terughalen zonder een branch uit te checken of de meegeleverde code uit te voeren. In de trees van de branches vonden we 15 Markdown-bestanden en één Word-document.

Branch Bestanden Wat we aantroffen
master 8 Markdown-bestanden Een README, een projectoverzicht, productvereisten en zakelijke gebruiksscenario's. Andere documenten behandelden prestaties, beveiliging, testen en beheer.
conf 7 Markdown-bestanden Richtlijnen voor een ontwikkelvoorstel, blockchainarchitectuur en -integratie, vereisten voor smart contracts, gegevens- en API-ontwerp, een AI-risico-engine en opleveringsmijlpalen.
NDA 1 DOCX-bestand Een geheimhoudingsovereenkomst met een ondertekeningsblok en plaatsaanduidingen uit een sjabloon.

Het voorgestelde product combineerde transactieanalyse, frauderegels en scores op basis van machine learning met blockchainverificatie. De voorgestelde technologiestack bestond uit Node.js en TypeScript met Express, PostgreSQL, Python-bibliotheken voor machine learning en Ethereum. Het opleveringsdocument beschreef zes mijlpalen over 24 weken. In alle aangeleverde trees vonden we planningsdocumenten, zonder applicatie-implementatie, getraind model of broncode van smart contracts om te beoordelen.

Sommige details verdienden een nadere blik. De API-voorbeelden bevatten de letterlijke tekenreeksen <built-in function id> en <built-in function hash> in endpointpaden. De geheimhoudingsovereenkomst bevatte nog plaatsaanduidingen uit een sjabloon. Deze inconsistenties riepen vragen op over de zorgvuldigheid waarmee het materiaal was opgesteld.

Het uitvoerbare bestand .git/hooks/post-checkout was een ernstigere vondst. De commentaren beschreven een hulpprogramma voor browser- of extensie-updates, dat geen duidelijk verband had met het beoordelen van dit project. Bij het lezen van het script vonden we instructies om een extern programma te downloaden en op de achtergrond te starten. Het verzoek in de e-mail om van branch te wisselen kon iemand tijdens het lezen van de geheimhoudingsovereenkomst naar dat uitvoeringspad leiden.

We hielden de repository inactief en onderzochten de hook als tekst. Hieronder volgen de relevante archiefmetadata en het gedrag van het script.

Hoe de Git-hook post-checkout kon worden uitgevoerd

Het bestand AI-Fraud-Detection_Blockchain.tar.gz is 779,429 bytes lang. De 100 TAR-items omvatten 60 reguliere bestanden. Bij de documenten werd een volledige .git-map geleverd.

De hooks-map bevatte de gebruikelijke .sample-bestanden en een uitvoerbaar bestand met de naam post-checkout.

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

Er is geen achtervoegsel .sample. De TAR-modus is 0777, inclusief uitvoeringsrechten, en de lengte is 2,774 bytes.

Git roept post-checkout aan na het bijwerken van de werkboom via handelingen zoals checkout of switch, mits de omgeving toestaat dat de hook wordt uitgevoerd. De Git-documentatie beschrijft de trigger.

Waarom de gearchiveerde .git-map van belang is

Een normale git clone kopieert de lokale clienthooks van een bronrepository niet, zoals Pro Git uitlegt. Deze levering bevatte de bestaande .git-map in een archief, waardoor de lokale hook werd meegeleverd.

Het pad, de modus en de grootte van de hook, rechtstreeks uit het oorspronkelijke TAR gelezen. We hebben de ontvangen map niet als Git-repository gebruikt.

Het pad, de modus en de grootte van de hook, rechtstreeks uit het oorspronkelijke TAR gelezen. We hebben de ontvangen map niet als Git-repository gebruikt.

We inspecteerden de container en Git-objecten rechtstreeks, zonder checkout of switch op de ontvangen repository uit te voeren.

Wat de downloader in de Git-hook doet

Commentaren in het shellscript beschrijven een hulpprogramma voor browser- of extensie-updates. In de projectdocumenten vonden we geen vereiste voor zo'n hulpprogramma. Het script bestaat uit niet-verhulde platte tekst.

De ongebruikte groottedrempel

Het script stelt THRESHOLD in op 100 en vraagt Git om een lijst met gewijzigde bestandsnamen. Het initialiseert TRIGGER op nul.

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

Binnen de lus berekent het SIZE. Er is geen vergelijking met THRESHOLD en geen toewijzing die TRIGGER verandert. Het downloadblok wordt uitgevoerd wanneer TRIGGER nul is.

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

Bij het normale verloop van dit script is de voorwaarde waar, zelfs wanneer de lijst met gewijzigde bestanden leeg is. De drempel beperkt de download niet.

De oorspronkelijke regelnummers zijn behouden. TRIGGER blijft op nul staan. THRESHOLD wordt gedeclareerd maar nooit in een vergelijking gebruikt.

De oorspronkelijke regelnummers zijn behouden. TRIGGER blijft op nul staan. THRESHOLD wordt gedeclareerd maar nooit in een vergelijking gebruikt.

Afzonderlijke downloads voor Linux, macOS en Windows

De waarde die uname -s retourneert, bepaalt het downloadpad en de lokale bestandsnaam.

Gedetecteerd systeem Serverpad Lokale bestandsnaam
Linux /api/l run-command.sh
Darwin / macOS /api/m run-command.sh
MINGW, MSYS, CYGWIN, Windows_NT /api/w run-command.cmd
Niet-herkend systeem /api/l run-command.sh

De URL's delen één host, hier vervangen door <DOWNLOAD_DOMAIN>. We hebben de ongeredigeerde hook privé bewaard. De vertakkingen ondersteunen Linux, macOS en Windows, met Linux als terugvaloptie voor een niet-herkend systeem. We hebben de uitvoering op die systemen niet getest.

Het bestand downloaden en proberen het uit te voeren

De hook slaat het bestand op in ${TMPDIR:-/tmp} met curl, of met wget als curl niet beschikbaar is. Vóór de volgende uitvoeringsinstructies wordt geen handtekening of verwachte hash gecontroleerd.

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

Het afsluitende ampersandteken start de opdracht op de achtergrond. Zowel de standaarduitvoer als de standaardfoutuitvoer gaat naar /dev/null.

Na de uitvoeringspoging schrijft de hook azuku naar .git-checker in de tijdelijke map. Voordat er opnieuw wordt gedownload, controleert de hook nooit of die markering aanwezig is. Ook wacht de hook niet op het slagen van het achtergrondproces voordat het bestand wordt geschreven. De markering kan daarom ook na een mislukte uitvoeringspoging bestaan.

De oorspronkelijke instructies voor downloaden, chmod, uitvoering op de achtergrond en het schrijven van de markering. Het programma van de tweede fase is niet aanwezig in dit fragment.

De oorspronkelijke instructies voor downloaden, chmod, uitvoering op de achtergrond en het schrijven van de markering. Het programma van de tweede fase is niet aanwezig in dit fragment.

Een commentaar tegen het einde zegt dat de tijdelijke downloadmap moet worden verwijderd. Daaronder staat geen verwijderopdracht.

Zat er een applicatie verborgen in het archief?

De netwerkdownload riep nog een vraag op. Zat er al een applicatie in het archief, misschien in de Git-geschiedenis of de geheimhoudingsovereenkomst? We onderzochten de containergrenzen, decodeerden vervolgens elk aangeleverd Git-object en inspecteerden de DOCX-inhoud.

De archiefgrenzen

We legden de SHA-256 van het oorspronkelijke archief vast voordat we de inhoud inspecteerden.

6f44ff4e461828dd1fe6ede75ca8d9d4b579c2ac223463629e9a7537b9df5040

Het decomprimeren van gzip als gegevens leverde een TAR-stroom van 890,880 bytes op. De gzip-stroom eindigde correct, zonder ongebruikte bytes erachter. De laatste 5,120 bytes na het laatste TAR-item waren opvulling met nulbytes.

Daarna onderzochten we de bestanden en objecten die door die containeritems werden vertegenwoordigd.

Opgeslagen controles van het einde van de gzip-stroom en de TAR-opvulling. Er is geen code uit het onderzochte materiaal uitgevoerd.

Opgeslagen controles van het einde van de gzip-stroom en de TAR-opvulling. Er is geen code uit het onderzochte materiaal uitgevoerd.

De hook vinden in de TAR-header

De header van het item post-checkout begint op 0xCF600, ofwel 849,408, in het gedecomprimeerde TAR. De bestandsgegevens beginnen op 849,920. Deze offsets verwijzen naar de TAR-stroom, niet naar het gecomprimeerde .gz-bestand.

Op die offset begint de header met het pad naar post-checkout.

TAR / hexadecimale weergave

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  |................|

In een TAR-header beslaat mode de bytes [100:108] en size de bytes [124:136]. De gedecodeerde velden voor dit item volgen na de dump.

TAR-veld Ruwe bytes / waarde
mode b'0000777\x00'
size b'00000005326\x00'
Octale modus 0777
Decimale grootte 2774 bytes
Opgeslagen / berekende controlesom 10301 / 10301

De octale grootte wordt gedecodeerd als 2,774 bytes. De opgeslagen headercontrolesom is 10,301. Herberekening met het controlesomveld gevuld met spaties geeft hetzelfde resultaat.

De ruwe TAR-header van de hook en de gedecodeerde velden. De naam, rechten en grootte zijn zichtbaar in de containerbytes.

De ruwe TAR-header van de hook en de gedecodeerde velden. De naam, rechten en grootte zijn zichtbaar in de containerbytes.

We berekenden ook de hash van de hook die uit dit item werd geëxtraheerd.

854b3b88b06fad9d9ffec36b35be0133b1d502084d4d7cce232eda2b2dd03092

De dump van het TAR-item en de geanonimiseerde hook zijn bij het artikel gevoegd. De bovenstaande hash identificeert het privé bewaarde ongeredigeerde origineel, niet de geredigeerde publicatiekopie.

Git-objecten lezen zonder checkout

Er zijn 24 losse objecten in .git/objects, elk opgeslagen in een zlib-stroom. De gedecomprimeerde gegevens bevatten een Git-header, gevolgd door de objectinhoud.

<type> <size>\0<body>

We controleerden de opgegeven lengte van de objectinhoud en berekenden SHA-1 over de volledige gedecodeerde reeks, inclusief de header en de NUL-byte. Het resultaat moet overeenkomen met de object-ID in de bestandsnaam. Hiermee wordt de integriteit van het object gecontroleerd. Het zegt niets over wie het heeft gemaakt.

Voor elk object vergeleken we de opgegeven lengte met de lengte van de objectinhoud en verifieerden we de hash over de volledige gedecodeerde gegevens.

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

We controleerden ook de uiteinden van de zlib-stromen. De objecten bestaan uit 16 blobs, 5 trees en 3 commits. Het volgen van de drie branchkoppen, hun bovenliggende commits en onderliggende trees verklaart alle 24 objecten. Onder de aangeleverde objecten bevinden zich geen onbereikbare blobs.

Git / relaties tussen commits

master 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f
  tree   feb0feaf7b8e826b085e90dea5399772d7b91f02
  parent (none)

conf   239b9aa2edc8c5e21fddeea5ed0e937496ae013f
  tree   048b51f9673f94354251ce16a78e663c71667a4c
  parent 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f

NDA    a1311875d86bf6f1a6b9f2fee6527abbd1ce647d
  tree   cc020d922090835ea4ac3a3e418d0213d7a2ad94
  parent 239b9aa2edc8c5e21fddeea5ed0e937496ae013f

De volledige objectinventaris omvat ook de objecten buiten de huidige werkboom.

Inventaris van alle 24 Git-objecten

Object-ID Type Objectinhoud, bytes
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

Lengte en SHA-1 zijn geverifieerd op basis van de oorspronkelijke Git-codering van elk object. Alle 24 controles zijn geslaagd.


De geheimhoudingsovereenkomst volgen van tree tot bytes

De branch NDA verwijst naar een tree met één bestand, Non-Disclosure-Agreement.docx. Een Git-tree-item slaat de modus en bestandsnaam op als tekst, gevolgd door een NUL en 20 ruwe bytes voor de blob-ID. We ontleedden het item rechtstreeks uit de tree-inhoud.

Git-tree / hexadecimale weergave

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.\.-.|

Ruwe bytes van de NDA-tree en de gedecodeerde verwijzing naar de bijbehorende DOCX-blob.

Ruwe bytes van de NDA-tree en de gedecodeerde verwijzing naar de bijbehorende DOCX-blob.

Dat item verwijst naar de volgende blob.

5a51550933b593eb65da458bbdd579f85c082dab

Na zlib-decompressie begint het object met blob 752100\0. Direct na de header staan de bytes 50 4b 03 04, de PK-signatuur van een ZIP-container.

Git-blob / na zlib-decompressie

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|

Gecomprimeerde objectbytes, de gedecodeerde Git-header en het begin van de DOCX. Lengte en object-ID zijn gecontroleerd aan de hand van het volledige object.

Gecomprimeerde objectbytes, de gedecodeerde Git-header en het begin van de DOCX. Lengte en object-ID zijn gecontroleerd aan de hand van het volledige object.

De objectinhoud is 752,100 bytes lang. De SHA-256 komt overeen met die van de DOCX die we apart voor analyse hebben opgeslagen.

9d85170d2c0aa7a9b90dfc3855715a31d971bba7abb563e9efa1153fdc15634f

Deze objecten verklaren het pad van de branch NDA naar de bytes van het document.

Alle 16 blobs verklaren

Vijftien blobs worden gedecodeerd als UTF-8 Markdown-projectdocumenten. De overgebleven blob is de bovenstaande DOCX. Geen enkele begint met een PE-, ELF- of Mach-O-header.

Pad in trees Grootte, bytes Type / eerste bytes
04-solution-proposal-guidance.md 2054 UTF-8-tekst · 23 20 44 65 76 65 6c 6f 70 6d 65 6e 74 20 43 6f
06-blockchain-architecture.md 6497 UTF-8-tekst · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 41 72 63
07-blockchain-integration-specification.md 2807 UTF-8-tekst · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 49 6e 74
08-smart-contract-specification.md 2610 UTF-8-tekst · 23 20 53 6d 61 72 74 20 43 6f 6e 74 72 61 63 74
09-data-and-api-architecture.md 2776 UTF-8-tekst · 23 20 44 61 74 61 20 26 20 41 50 49 20 41 72 63
11-ai-fraud-and-risk-engine.md 3062 UTF-8-tekst · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63
14-deliverables-acceptance-and-milestones.md 6316 UTF-8-tekst · 23 20 44 65 6c 69 76 65 72 61 62 6c 65 73 2c 20
Detailed/03-business-and-use-cases.md 3061 UTF-8-tekst · 23 20 42 75 73 69 6e 65 73 73 20 52 65 71 75 69
Detailed/05-non-functional-requirements.md 2033 UTF-8-tekst · 23 20 4e 6f 6e 2d 46 75 6e 63 74 69 6f 6e 61 6c
Detailed/10-security-and-privacy-requirements.md 2433 UTF-8-tekst · 23 20 53 65 63 75 72 69 74 79 20 26 20 50 72 69
Detailed/12-testing-and-quality-requirements.md 2425 UTF-8-tekst · 23 20 54 65 73 74 69 6e 67 20 26 20 51 75 61 6c
Detailed/13-deployment-monitoring-and-operations.md 2281 UTF-8-tekst · 23 20 44 65 70 6c 6f 79 6d 65 6e 74 2c 20 4d 6f
Intro/01-project-overview.md 8402 UTF-8-tekst · 23 20 50 72 6f 6a 65 63 74 20 4f 76 65 72 76 69
Intro/02-product-requirements.md 3191 UTF-8-tekst · 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 UTF-8-tekst · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63

Alle 16 aangeleverde blobs zijn geclassificeerd. De trees bevatten projectdocumenten; er is geen productimplementatie gevonden.

Alle 16 aangeleverde blobs zijn geclassificeerd. De trees bevatten projectdocumenten; er is geen productimplementatie gevonden.

We lazen de tekstinhoud en controleerden ook de signaturen. De DOCX was de enige blob die niet uit tekst bestond en vereiste een afzonderlijke containerinspectie.

De DOCX openen als ZIP

Het document bevat 25 ZIP-items, bestaande uit 17 bestandsonderdelen en 8 mappen. We lazen elk bestandsonderdeel en controleerden de CRC.

DOCX-onderdeel Grootte, bytes 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

Namen, lengtes en CRC32-waarden van DOCX-onderdelen. We inspecteerden ZIP- en XML-gegevens zonder het document in Office te openen.

Namen, lengtes en CRC32-waarden van DOCX-onderdelen. We inspecteerden ZIP- en XML-gegevens zonder het document in Office te openen.

De onderdelenlijst bevat geen vbaProject.bin of OLE-bijlage. Twee PNG-bestanden bevatten een logo en een afbeelding van een handtekening. We inspecteerden ook de XML-relaties en vonden een verwijzing naar een lokaal Office-sjabloonpad op de machine van de documentauteur. We hebben die verwijzing niet gevolgd of geladen.

De afbeelding van de handtekening en de Git-auteursvelden bieden geen betrouwbare manier om de afzender te identificeren. Beide kunnen worden gekopieerd of vervangen.

We vonden geen afzonderlijke applicatie of productimplementatie in de aangeleverde inhoud. De hook haalt het volgende programma op via het netwerk. Onze containerinspectie sluit niet elke mogelijke exploit of steganografische techniek uit.

Wat de downloadserver retourneerde

We haalden de drie exacte URL's op als gegevens, zonder de antwoorden uit te voeren of omleidingen te volgen. Op 19 oktober, van 17:29:27 tot 17:29:28 UTC, retourneerden ze elk HTTP 200. Alle drie de antwoordinhouden bestonden uit hetzelfde bericht van 21 bytes.

Permanently suspended

De drie opgeslagen endpointwaarnemingen. Tijdens het voorbereiden van dit artikel deden we geen verdere verzoeken aan de downloader-URL's.

De drie opgeslagen endpointwaarnemingen. Tijdens het voorbereiden van dit artikel deden we geen verdere verzoeken aan de downloader-URL's.

We hebben geen bytes van de tweede fase om te reverse-engineeren. We weten ook niet wat die endpoints eerder, aan een andere bezoeker of onder andere verzoekomstandigheden retourneerden. De opschortingsmelding geeft ons geen geverifieerde verklaring voor de reden waarom de dienst is opgeschort.

De hook probeert een extern bestand te downloaden en uit te voeren. Beweringen over gestolen wachtwoorden, tokens, broncode of wallets zouden bewijsmateriaal vereisen dat we niet hebben.

Kon dit een legitiem hulpprogramma zijn geweest?

Een intern updateprogramma kan per ongeluk in een archief terechtkomen. Git-hooks, achtergrondprocessen en curl hebben allemaal legitieme toepassingen.

Bij deze inzending vroeg de e-mail ons expliciet om een andere branch te bezoeken. Dat kon de meegeleverde downloader aanroepen, hoewel de opgegeven reden voor het wisselen van branch het lezen van een overeenkomst was. De e-mail vermeldde de uitvoering niet. We vonden ook geen verband tussen een browserupdateprogramma en het voorgestelde systeem, en de groottecontrole in het script was onvolledig.

We behandelden de inzending als een aanvalspoging via het aanleveren van code en voorkwamen dat de hook werd uitgevoerd. Om die beoordeling te heroverwegen, zouden we de broncode van de gedownloade bestanden nodig hebben en een verifieerbare uitleg waarom een opdrachtnemer ze moest uitvoeren om de geheimhoudingsovereenkomst te beoordelen.

We hebben de identiteit van de uitvoerende partij niet vastgesteld. Het afzenderadres, de commitmetadata en de namen in het document zijn onvoldoende om de aanval aan iemand toe te schrijven.

Analysediagram van de uitvoeringsstappen die de meegeleverde hook beschrijft.

Analysediagram van de uitvoeringsstappen die de meegeleverde hook beschrijft.

Een onbekende Git-repository beoordelen

Een ontwikkelaar die de e-mail volgde, kon de uitvoeringstrigger bereiken terwijl die nog over het project las. Het was niet nodig om de voorgestelde applicatie te bouwen of te starten.

Als u inzendingen van klanten beoordeelt op een machine met SSH-sleutels voor productie of cloudtokens, kan een onverwacht script toegang hebben tot die middelen. Een wegwerpomgeving moet die inloggegevens buiten bereik houden. Browsersessies op de beoordelingsmachine verdienen dezelfde aandacht.

De beoordeling moet de meegeleverde .git-map en alle IDE-automatisering omvatten voordat een ontwikkelaar de gebruikelijke opdrachten gaat gebruiken. Ook installatiescripts moeten kritisch worden bekeken. In hostlogboeken zouden we zoeken naar Git of een shell die een bestand naar een tijdelijke map downloadt en het daarna uitvoert. Een curl-proces op zichzelf vertelt ons veel minder.

Door de oorspronkelijke e-mail en het archief te bewaren, kan een latere beoordelaar controleren wat er is aangeleverd. Hashes en hostgebeurtenissen helpen vast te stellen wat er op de machine is gebeurd. Een ontbrekende markering kan niet aantonen dat een programma nooit is uitgevoerd.

Kan het downloaden of uitpakken van het archief deze hook uitvoeren?

Downloaden en gewoon uitpakken roepen de Git-hook post-checkout op zichzelf niet aan. In dit onderzochte materiaal is de gedocumenteerde trigger het bijwerken van de werkboom door Git via checkout of switch, wanneer hookuitvoering is toegestaan. We inspecteerden de aangeleverde objecten rechtstreeks zonder die handelingen aan te roepen.

Na de beoordeling van het archief

We hadden verwacht dat de volgende uitwisseling over architectuur en opleverdata zou gaan. In plaats daarvan stuurden we een reactie over de hook en bewaarden we het materiaal voor nader onderzoek. We kunnen nog steeds niet zeggen wat het externe programma deed of wie het beheerde. De hook gaf ons voldoende reden om de gevraagde Git-werkwijze te stoppen.

Al meer dan vijf jaar helpen SToFU Systems en onze oplossingen bedrijven hun systemen te beschermen, ook tegen aanvallen via zakelijke correspondentie en ontwikkelmateriaal. Onze beveiligingsaudits onderzoeken hoe code en toegang kunnen worden misbruikt. We bieden ook reverse engineering wanneer een team onbekende software moet doorgronden.

Als een repository of binair bestand vragen oproept, bespreek dan met ons team een technische beoordeling voordat u deze in uw normale ontwikkelomgeving opneemt.

Correspondentie en bewijsbestanden

De vier onderstaande berichten gebruiken plaatsaanduidingen voor persoonsnamen, adressen, identiteiten van derden en identificerende links. De overige tekst van elk nieuw bericht is behouden. Herhaalde citaten zijn weggelaten omdat elke e-mail afzonderlijk wordt weergegeven. Ook het service-IP van het webformulier en de adressen van niet-betrokken ontvangers worden niet gepubliceerd.

1. De eerste aanvraag via onze website

E-mail / identificerende gegevens vervangen

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.
---

De eerste aanvraag via onze website. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

De eerste aanvraag via onze website. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

SHA-256 van het privé bewaarde ongeredigeerde EML-bestand: bf7d0f3a59b84f509ca436e0750640e844e9731ce363a42a99d5be60cdf8597e


2. Onze reactie met het verzoek om de materialen

E-mail / identificerende gegevens vervangen

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>

Onze reactie met het verzoek om de materialen. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

Onze reactie met het verzoek om de materialen. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

SHA-256 van het privé bewaarde ongeredigeerde EML-bestand: 1e5330dd82e02911254722744a3202e9b761c8c1d2950be937cd5d539c1bcad9


3. De archiefmail waarin de branches NDA / conf worden genoemd

E-mail / identificerende gegevens vervangen

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>

De archiefmail waarin de branches NDA / conf worden genoemd. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

De archiefmail waarin de branches NDA / conf worden genoemd. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

SHA-256 van het privé bewaarde ongeredigeerde EML-bestand: f7007ed3053d3ba2ef71ea01c74ec0c4aebfd48417f757ecec8d9d7d5884bf33


4. Onze reactie na het ontdekken van de hook

E-mail / identificerende gegevens vervangen

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

Onze reactie na het ontdekken van de hook. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

Onze reactie na het ontdekken van de hook. Geanonimiseerde publicatieweergave van de bewaarde e-mail.

SHA-256 van het privé bewaarde ongeredigeerde EML-bestand: 31df91adb2eb52be2171836d3e26610328a0a1a1273dbf7d56efe4354bb62e19


Geanonimiseerde weergave van de volledige hook

Alle 101 bronregelnummers zijn behouden. Identificerende gegevens zijn afgedekt met grijze rechthoeken.

Alle 101 bronregelnummers zijn behouden. Identificerende gegevens zijn afgedekt met grijze rechthoeken.


Ongeredigeerde originelen worden privé bewaard. Openbare bewijsbestanden gebruiken plaatsaanduidingen en schermafbeeldingen gebruiken ondoorzichtige grijze rechthoeken. Hashes die als origineel zijn aangeduid, identificeren de privébron, niet een bewerkte publicatiekopie. De afbeeldingen zijn schermafbeeldingen van lokale bewijsweergaven, waarbij identificerende tekst vóór het renderen is verwijderd. Er is geen ontvangen code uitgevoerd.

SToFU Systems

SToFU Systems

Terug naar Blogs

Contact

Begin het gesprek

Een paar heldere regels zijn genoeg. Beschrijf het systeem, de druk en de beslissing die vastzit. Of mail direct naar midgard@stofu.io.

0 / 10000
Geen bestand gekozen