En potentiel kunde forsøgte at køre ekstern kode gennem Gits indbyggede hooks.

En potentiel kunde forsøgte at køre ekstern kode gennem Gits indbyggede hooks.

SToFU Systems · Undersøgelse af sikkerhedshændelse · 20. oktober 2026

Indhold

  1. Det begyndte med en henvendelse om udvikling
  2. Hentning og undersøgelse af filerne
  3. Sådan kunne Git-hooken post-checkout blive kørt
  4. Hvad downloaderen i Git-hooken gør
  5. Var der skjult en applikation i arkivet?
  6. Hvad downloadserveren returnerede
  7. Kunne dette have været et legitimt hjælpeprogram?
  8. Gennemgang af et ukendt Git-repository
  9. Efter gennemgangen af arkivet
  10. Korrespondance og dokumentationsfiler

Det begyndte med en henvendelse om udvikling

Den første besked kom via vores hjemmeside den 15. oktober 2026. Afsenderen ønskede hjælp til at bygge en platform til at opdage økonomisk svindel. Det foreslåede system skulle risikovurdere transaktioner og bruge adfærdsanalyse, og blandt de øvrige krav var blockchainverifikation og rapportering.

Den 19. oktober modtog vi downloadlinket. Den ledsagende e-mail henviste os til branchen conf for arkitekturen og branchen NDA for aftalen. Den gentog anmodningen om at gennemgå og underskrive fortrolighedsaftalen.

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

Hvis en person under gennemgangen fulgte disse instruktioner, ville vedkommende gå fra at pakke arkivet ud til at skifte branch i Git. E-mailen fremstillede begge handlinger som en del af at læse dokumentationen. Den nævnte intet om at køre et hentet program.

E-mailen med projektarkivet og instruktionerne om at åbne NDA-branchen. Identificerende oplysninger er dækket af grå rektangler.

E-mailen med projektarkivet og instruktionerne om at åbne NDA-branchen. Identificerende oplysninger er dækket af grå rektangler.

Hentning og undersøgelse af filerne

Linket førte til en almindelig Dropbox-side til fildeling. Vi hentede AI-Fraud-Detection_Blockchain.tar.gz til et isoleret gennemgangsmiljø og beholdt det oprindelige arkiv som reference. Den konkrete delings-URL offentliggøres ikke her.

Vi opregnede arkivets indhold og læste de medfølgende Git-objekter direkte. Det gjorde det muligt at genskabe dokumenterne fra alle tre branches uden at tjekke en branch ud eller køre den medfølgende kode. I de forskellige branches' træstrukturer fandt vi 15 Markdown-filer og ét Word-dokument.

Branch Filer Hvad vi fandt
master 8 Markdown-filer En README, en projektoversigt, produktkrav og forretningsmæssige anvendelsestilfælde. Andre dokumenter omhandlede ydeevne, sikkerhed, test og drift.
conf 7 Markdown-filer Vejledning til et udviklingsforslag, blockchainarkitektur og -integration, krav til smart contracts, data- og API-design, en AI-risikomotor samt leverancemilepæle.
NDA 1 DOCX-fil En fortrolighedsaftale med et underskriftsfelt og pladsholdere fra en skabelon.

Det foreslåede produkt kombinerede transaktionsanalyse, svindelregler og scorer fra maskinlæring med blockchainverifikation. Den foreslåede teknologistak brugte Node.js og TypeScript med Express, PostgreSQL, Python-biblioteker til maskinlæring og Ethereum. Leverancedokumentet beskrev seks milepæle over 24 uger. Vi fandt planlægningsdokumenter i alle de medfølgende træstrukturer, men ingen applikationsimplementering, trænet model eller kildekode til smart contracts, som kunne gennemgås.

Nogle detaljer fortjente et ekstra kig. API-eksemplerne indeholdt de bogstavelige strenge <built-in function id> og <built-in function hash> i endpointstier. Fortrolighedsaftalen indeholdt stadig pladsholdere fra en skabelon. Disse uoverensstemmelser rejste spørgsmål om, hvor omhyggeligt materialet var udarbejdet.

Den eksekverbare fil .git/hooks/post-checkout var et mere alvorligt fund. Dens kommentarer beskrev et hjælpeprogram til opdatering af en browser eller udvidelse, hvilket ikke havde nogen tydelig forbindelse til gennemgangen af dette projekt. Ved at læse scriptet fandt vi instruktioner om at hente et eksternt program og starte det i baggrunden. E-mailens anmodning om at skifte branch kunne føre en person ind på denne eksekveringsvej under forsøget på at læse fortrolighedsaftalen.

Vi holdt repositoriet inaktivt og undersøgte hooken som tekst. Nedenfor følger de relevante arkivmetadata og scriptets adfærd.

Sådan kunne Git-hooken post-checkout blive kørt

Filen AI-Fraud-Detection_Blockchain.tar.gz er 779,429 bytes lang. Dens 100 TAR-poster omfatter 60 almindelige filer. Et komplet .git-katalog fulgte med dokumenterne.

Hooks-kataloget indeholdt de sædvanlige .sample-filer og en eksekverbar fil med navnet post-checkout.

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

Der er intet .sample-suffiks. Dens TAR-tilstand er 0777, hvilket omfatter eksekveringsrettigheder, og dens længde er 2,774 bytes.

Git kalder post-checkout efter at have opdateret arbejdstræet gennem handlinger som checkout eller switch, forudsat at miljøet tillader hooken at køre. Git-dokumentationen beskriver udløseren.

Hvorfor det arkiverede .git-katalog er vigtigt

En almindelig git clone kopierer ikke et kilderepositories lokale klienthooks, som Pro Git forklarer. Denne levering indeholdt det eksisterende .git-katalog i et arkiv, så den lokale hook fulgte med.

Hookens sti, tilstand og størrelse læst direkte fra det oprindelige TAR. Vi brugte ikke det modtagne katalog som et Git-repository.

Hookens sti, tilstand og størrelse læst direkte fra det oprindelige TAR. Vi brugte ikke det modtagne katalog som et Git-repository.

Vi undersøgte containeren og Git-objekterne direkte uden at køre checkout eller switch på det modtagne repository.

Hvad downloaderen i Git-hooken gør

Kommentarer i shellscriptet beskriver et hjælpeprogram til opdatering af en browser eller udvidelse. Vi fandt intet krav om et sådant hjælpeprogram i projektdokumenterne. Scriptet er almindelig tekst uden tilsløring.

Den ubrugte størrelsestærskel

Scriptet sætter THRESHOLD til 100 og beder Git om en liste over ændrede filnavne. Det initialiserer TRIGGER til nul.

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

I løkken beregner det SIZE. Der er ingen sammenligning med THRESHOLD og ingen tildeling, der ændrer TRIGGER. Downloadblokken kører, når TRIGGER er nul.

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

På den normale vej gennem dette script er betingelsen sand, selv når listen over ændrede filer er tom. Tærsklen begrænser ikke hentningen.

De oprindelige linjenumre er bevaret. TRIGGER forbliver nul. THRESHOLD erklæres, men bruges aldrig i en sammenligning.

De oprindelige linjenumre er bevaret. TRIGGER forbliver nul. THRESHOLD erklæres, men bruges aldrig i en sammenligning.

Separate downloads til Linux, macOS og Windows

Værdien, som uname -s returnerer, bestemmer downloadstien og det lokale filnavn.

Registreret system Serversti Lokalt filnavn
Linux /api/l run-command.sh
Darwin / macOS /api/m run-command.sh
MINGW, MSYS, CYGWIN, Windows_NT /api/w run-command.cmd
Ukendt system /api/l run-command.sh

URL'erne deler én vært, som her er erstattet med <DOWNLOAD_DOMAIN>. Vi har bevaret den uredigerede hook privat. Forgreningerne dækker Linux, macOS og Windows, med Linux som reservevalg ved et ukendt system. Vi testede ikke eksekvering på disse systemer.

Hentning af filen og forsøg på at køre den

Hooken gemmer filen i ${TMPDIR:-/tmp} ved hjælp af curl, eller wget, hvis curl ikke er tilgængelig. Der er ingen kontrol af signatur eller forventet hash før de følgende eksekveringsinstruktioner.

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

Det afsluttende og-tegn starter kommandoen i baggrunden. Både standardoutput og standardfejloutput sendes til /dev/null.

Efter eksekveringsforsøget skriver hooken azuku til .git-checker i det midlertidige katalog. Den kontrollerer aldrig, om denne markør findes, før den henter igen. Den venter heller ikke på, at baggrundsprocessen lykkes, før den skriver filen. Markøren kan derfor findes efter et mislykket eksekveringsforsøg.

De oprindelige instruktioner til hentning, chmod, eksekvering i baggrunden og skrivning af markøren. Programmet til anden fase er ikke med i dette uddrag.

De oprindelige instruktioner til hentning, chmod, eksekvering i baggrunden og skrivning af markøren. Programmet til anden fase er ikke med i dette uddrag.

En kommentar nær slutningen siger, at det midlertidige downloadkatalog skal fjernes. Der er ingen fjernelseskommando nedenunder.

Var der skjult en applikation i arkivet?

Netværkshentningen rejste endnu et spørgsmål. Var der allerede en applikation i arkivet, måske i Git-historikken eller fortrolighedsaftalen? Vi undersøgte containergrænserne og afkodede derefter hvert medfølgende Git-objekt og undersøgte DOCX-indholdet.

Arkivets grænser

Vi registrerede det oprindelige arkivs SHA-256, før vi undersøgte indholdet.

6f44ff4e461828dd1fe6ede75ca8d9d4b579c2ac223463629e9a7537b9df5040

Dekomprimering af gzip som data gav en TAR-strøm på 890,880 bytes. Gzip-strømmen sluttede korrekt uden ubrugte bytes bagefter. De sidste 5,120 bytes efter den sidste TAR-post var udfyldning med nuller.

Vi undersøgte derefter de filer og objekter, som disse containerposter dækkede.

Gemte kontroller af gzip-strømmens afslutning og TAR-udfyldningen. Ingen kode fra prøven blev kørt.

Gemte kontroller af gzip-strømmens afslutning og TAR-udfyldningen. Ingen kode fra prøven blev kørt.

Sådan findes hooken i TAR-headeren

Headeren for posten post-checkout begynder ved 0xCF600, eller 849,408, i det dekomprimerede TAR. Dens fildata begynder ved 849,920. Disse offsets henviser til TAR-strømmen, ikke den komprimerede .gz-fil.

Ved dette offset begynder headeren med stien til post-checkout.

TAR / heksadecimal visning

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

I en TAR-header optager mode bytes [100:108], og size optager [124:136]. De afkodede felter for denne post følger efter dumpet.

TAR-felt Rå bytes / værdi
mode b'0000777\x00'
size b'00000005326\x00'
Oktal tilstand 0777
Decimal størrelse 2774 bytes
Gemt / beregnet kontrolsum 10301 / 10301

Den oktale størrelse afkodes til 2,774 bytes. Den gemte headerkontrolsum er 10,301. Genberegning med kontrolsumfeltet udfyldt med mellemrum giver samme resultat.

Hookens rå TAR-header og afkodede felter. Dens navn, rettigheder og størrelse er synlige i containerens bytes.

Hookens rå TAR-header og afkodede felter. Dens navn, rettigheder og størrelse er synlige i containerens bytes.

Vi beregnede også hashværdien for den hook, der blev udtrukket fra denne post.

854b3b88b06fad9d9ffec36b35be0133b1d502084d4d7cce232eda2b2dd03092

Dumpet af TAR-posten og den anonymiserede hook er vedlagt artiklen. Hashværdien ovenfor identificerer den uredigerede original, der opbevares privat, ikke den redigerede udgivelseskopi.

Læsning af Git-objekter uden checkout

Der er 24 løse objekter i .git/objects, som hver er gemt i en zlib-strøm. De dekomprimerede data indeholder en Git-header efterfulgt af objektindholdet.

<type> <size>\0<body>

Vi kontrollerede den angivne længde af objektindholdet og beregnede SHA-1 over hele den afkodede sekvens, inklusive headeren og NUL-byten. Resultatet skal svare til objekt-ID'et i filnavnet. Dette kontrollerer objektets integritet. Det siger intet om, hvem der oprettede det.

For hvert objekt sammenlignede vi den angivne længde med objektindholdets længde og verificerede hashværdien over alle de afkodede data.

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

Vi kontrollerede også afslutningerne på zlib-strømmene. Objekterne fordeler sig på 16 blobs, 5 trees og 3 commits. Ved at følge de tre branchspidser, deres forældrecommits og underordnede trees kan der redegøres for alle 24 objekter. Der er ingen unåelige blobs blandt de medfølgende objekter.

Git / relationer mellem commits

master 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f
  tree   feb0feaf7b8e826b085e90dea5399772d7b91f02
  parent (none)

conf   239b9aa2edc8c5e21fddeea5ed0e937496ae013f
  tree   048b51f9673f94354251ce16a78e663c71667a4c
  parent 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f

NDA    a1311875d86bf6f1a6b9f2fee6527abbd1ce647d
  tree   cc020d922090835ea4ac3a3e418d0213d7a2ad94
  parent 239b9aa2edc8c5e21fddeea5ed0e937496ae013f

Den komplette objektoversigt omfatter objekterne uden for det aktuelle arbejdstræ.

Oversigt over alle 24 Git-objekter

Objekt-ID Type Objektindhold, 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

Længde og SHA-1 er verificeret ud fra hvert objekts oprindelige Git-kodning. Alle 24 kontroller bestod.


Fortrolighedsaftalen fulgt fra dens tree til dens bytes

Branchen NDA peger på et tree med én fil, Non-Disclosure-Agreement.docx. En Git-tree-post gemmer tilstanden og filnavnet som tekst, efterfulgt af en NUL og 20 rå bytes til blob-ID'et. Vi parsede posten direkte fra tree-indholdet.

Git-træ / heksadecimal visning

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

Rå bytes fra NDA-tree og den afkodede reference til dens DOCX-blob.

Rå bytes fra NDA-tree og den afkodede reference til dens DOCX-blob.

Denne post refererer til følgende blob.

5a51550933b593eb65da458bbdd579f85c082dab

Efter zlib-dekomprimering begynder objektet med blob 752100\0. Umiddelbart efter headeren kommer bytes 50 4b 03 04, som er en ZIP-containers PK-signatur.

Git-blob / efter zlib-dekomprimering

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|

Komprimerede objektbytes, den afkodede Git-header og begyndelsen af DOCX-filen. Længde og objekt-ID blev kontrolleret ud fra hele objektet.

Komprimerede objektbytes, den afkodede Git-header og begyndelsen af DOCX-filen. Længde og objekt-ID blev kontrolleret ud fra hele objektet.

Objektindholdet er 752,100 bytes langt. Dets SHA-256 svarer til den DOCX, vi gemte separat til analyse.

9d85170d2c0aa7a9b90dfc3855715a31d971bba7abb563e9efa1153fdc15634f

Disse objekter redegør for vejen fra branchen NDA til dokumentets bytes.

Redegørelse for alle 16 blobs

Femten blobs afkodes som UTF-8-kodede Markdown-projektdokumenter. Den resterende blob er DOCX-filen ovenfor. Ingen begynder med en PE-, ELF- eller Mach-O-header.

Sti i trees Størrelse, bytes Type / første 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 medfølgende blobs er klassificeret. Træstrukturerne indeholder projektdokumenter, og der blev ikke fundet nogen produktimplementering.

Alle 16 medfølgende blobs er klassificeret. Træstrukturerne indeholder projektdokumenter, og der blev ikke fundet nogen produktimplementering.

Vi læste tekstindholdet og kontrollerede også signaturerne. DOCX-filen var den eneste blob, der ikke bestod af tekst, og krævede en særskilt containerundersøgelse.

Åbning af DOCX-filen som ZIP

Dokumentet indeholder 25 ZIP-poster, fordelt på 17 fildele og 8 kataloger. Vi læste hver fildel og kontrollerede dens CRC.

DOCX-del Størrelse, 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

Navne, længder og CRC32-værdier for DOCX-dele. Vi undersøgte ZIP- og XML-data uden at åbne dokumentet i Office.

Navne, længder og CRC32-værdier for DOCX-dele. Vi undersøgte ZIP- og XML-data uden at åbne dokumentet i Office.

Der er ingen vbaProject.bin eller OLE-vedhæftning i listen over dele. To PNG-filer indeholder et logo og et billede af en underskrift. Vi undersøgte også XML-relationerne og fandt en reference til en lokal Office-skabelonsti på dokumentforfatterens maskine. Vi fulgte eller indlæste den ikke.

Underskriftsbilledet og Gits forfatterfelter giver os ingen pålidelig måde at identificere afsenderen på. Begge dele kan kopieres eller erstattes.

Vi fandt ingen separat applikation eller produktimplementering i det medfølgende indhold. Hooken henter sit næste program via netværket. Vores containerundersøgelse udelukker ikke enhver mulig exploit eller steganografisk teknik.

Hvad downloadserveren returnerede

Vi hentede de tre præcise URL'er som data uden at køre svarene eller følge omdirigeringer. Den 19. oktober fra 17:29:27 til 17:29:28 UTC returnerede de hver HTTP 200. Indholdet af alle tre svar var den samme besked på 21 bytes.

Permanently suspended

De tre gemte endpointobservationer. Vi sendte ingen yderligere forespørgsler til downloaderens URL'er under udarbejdelsen af denne artikel.

De tre gemte endpointobservationer. Vi sendte ingen yderligere forespørgsler til downloaderens URL'er under udarbejdelsen af denne artikel.

Vi har ingen bytes fra anden fase at foretage reverse engineering af. Vi ved heller ikke, hvad disse endpoints returnerede tidligere, til en anden besøgende eller under andre forespørgselsbetingelser. Suspenderingsbeskeden giver os ingen verificeret forklaring på, hvorfor tjenesten blev suspenderet.

Hooken forsøger at hente og køre en ekstern fil. Påstande om stjålne adgangskoder, tokens, kildekode eller wallets ville kræve dokumentation, som vi ikke har.

Kunne dette have været et legitimt hjælpeprogram?

Et internt opdateringsprogram kan havne i et arkiv ved en fejl. Git-hooks, baggrundsprocesser og curl har alle legitime anvendelser.

I denne indsendelse bad e-mailen os udtrykkeligt om at besøge en anden branch. Det kunne kalde den medfølgende downloader, selv om den angivne grund til branchskiftet var at læse en aftale. E-mailen nævnte ikke eksekveringen. Vi fandt heller ingen forbindelse mellem et browseropdateringsprogram og det foreslåede system, og scriptets størrelseskontrol var ufuldstændig.

Vi behandlede indsendelsen som et forsøg på et angreb via levering af kode og forhindrede hooken i at køre. En revurdering af denne vurdering ville kræve kildekoden til de hentede filer og en verificerbar forklaring på, hvorfor en leverandør skulle køre dem for at gennemgå fortrolighedsaftalen.

Vi har ikke fastslået operatørens identitet. Afsenderadressen, commitmetadata og navnene i dokumentet er utilstrækkelige til at tilskrive angrebet til nogen.

Analysediagram over de eksekveringstrin, som den medfølgende hook beskriver.

Analysediagram over de eksekveringstrin, som den medfølgende hook beskriver.

Gennemgang af et ukendt Git-repository

En udvikler, der fulgte e-mailen, kunne nå frem til eksekveringsudløseren, mens vedkommende stadig læste om projektet. Det var ikke nødvendigt at bygge eller starte den foreslåede applikation.

Hvis du gennemgår kunders indsendelser på en maskine med SSH-nøgler til produktion eller cloudtokens, kan et uventet script have adgang til disse ressourcer. Et engangsmiljø skal holde disse legitimationsoplysninger uden for rækkevidde. Browsersessioner på maskinen til gennemgang fortjener samme opmærksomhed.

Gennemgangen bør omfatte det medfølgende .git-katalog og enhver IDE-automatisering, før en udvikler begynder at bruge sine sædvanlige kommandoer. Installationsscripts skal også undersøges nøje. I værtslogfiler ville vi lede efter Git eller en shell, der henter en fil til et midlertidigt katalog og derefter kører den. En curl-proces alene fortæller os langt mindre.

Ved at bevare den oprindelige e-mail og arkivet kan en senere undersøger kontrollere, hvad der blev leveret. Hashværdier og værtshændelser hjælper med at fastslå, hvad der skete på maskinen. En manglende markør kan ikke fastslå, at et program aldrig blev kørt.

Kan hentning eller udpakning af arkivet køre denne hook?

Hentning og almindelig udpakning kalder ikke i sig selv Gits post-checkout-hook. I denne prøve er den dokumenterede udløser, at Git opdaterer arbejdstræet via checkout eller switch, når eksekvering af hooks er tilladt. Vi undersøgte de medfølgende objekter direkte uden at kalde disse handlinger.

Efter gennemgangen af arkivet

Vi havde forventet, at den næste udveksling skulle handle om arkitektur og leveringsdatoer. I stedet sendte vi et svar om hooken og bevarede materialet til yderligere undersøgelse. Vi kan stadig ikke sige, hvad det eksterne program gjorde, eller hvem der drev det. Hooken gav os tilstrækkelig grund til at stoppe den ønskede Git-arbejdsgang.

I mere end fem år har SToFU Systems og vores løsninger hjulpet virksomheder med at beskytte deres systemer, herunder mod angreb leveret gennem forretningskorrespondance og udviklingsmaterialer. Vores sikkerhedsaudits undersøger, hvordan kode og adgang kan misbruges. Vi tilbyder også reverse engineering, når et team har brug for at forstå ukendt software.

Hvis et repository eller en binærfil rejser spørgsmål, så tal med vores team om en teknisk gennemgang, før du tager det i brug i dit normale udviklingsmiljø.

Korrespondance og dokumentationsfiler

De fire beskeder nedenfor bruger pladsholdere til personnavne, adresser, tredjeparters identiteter og identificerende links. Den øvrige ordlyd i hver ny besked er bevaret. Gentagne citater er udeladt, da hver e-mail vises separat. Webformularens tjeneste-IP og uvedkommende modtageres adresser offentliggøres heller ikke.

1. Den første henvendelse via vores hjemmeside

E-mail / identificerende oplysninger erstattet

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

Den første henvendelse via vores hjemmeside. Anonymiseret udgivelsesvisning af den bevarede e-mail.

Den første henvendelse via vores hjemmeside. Anonymiseret udgivelsesvisning af den bevarede e-mail.

SHA-256 for den private, uredigerede EML-fil: bf7d0f3a59b84f509ca436e0750640e844e9731ce363a42a99d5be60cdf8597e


2. Vores svar med anmodning om materialerne

E-mail / identificerende oplysninger erstattet

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>

Vores svar med anmodning om materialerne. Anonymiseret udgivelsesvisning af den bevarede e-mail.

Vores svar med anmodning om materialerne. Anonymiseret udgivelsesvisning af den bevarede e-mail.

SHA-256 for den private, uredigerede EML-fil: 1e5330dd82e02911254722744a3202e9b761c8c1d2950be937cd5d539c1bcad9


3. E-mailen om arkivet, der nævner branchene NDA / conf

E-mail / identificerende oplysninger erstattet

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>

E-mailen om arkivet, der nævner branchene NDA / conf. Anonymiseret udgivelsesvisning af den bevarede e-mail.

E-mailen om arkivet, der nævner branchene NDA / conf. Anonymiseret udgivelsesvisning af den bevarede e-mail.

SHA-256 for den private, uredigerede EML-fil: f7007ed3053d3ba2ef71ea01c74ec0c4aebfd48417f757ecec8d9d7d5884bf33


4. Vores svar efter opdagelsen af hooken

E-mail / identificerende oplysninger erstattet

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

Vores svar efter opdagelsen af hooken. Anonymiseret udgivelsesvisning af den bevarede e-mail.

Vores svar efter opdagelsen af hooken. Anonymiseret udgivelsesvisning af den bevarede e-mail.

SHA-256 for den private, uredigerede EML-fil: 31df91adb2eb52be2171836d3e26610328a0a1a1273dbf7d56efe4354bb62e19


Anonymiseret visning af hele hooken

Alle 101 kildelinjenumre er bevaret. Identificerende oplysninger er dækket af grå rektangler.

Alle 101 kildelinjenumre er bevaret. Identificerende oplysninger er dækket af grå rektangler.


Uredigerede originaler opbevares privat. Offentlige dokumentationsfiler bruger pladsholdere, og skærmbilleder bruger uigennemsigtige grå rektangler. Hashværdier mærket som original identificerer den private kilde, ikke en redigeret udgivelseskopi. Figurerne er skærmbilleder af lokale dokumentationsvisninger, hvor identificerende tekst blev fjernet før rendering. Ingen modtaget kode blev kørt.

SToFU Systems

SToFU Systems

Tilbage til Blogs

Kontakt

Start samtalen

Et par klare streger er nok. Beskriv systemet, presset, beslutningen der er blokeret. Eller skriv direkte til midgard@stofu.io.

0 / 10000
Ingen fil valgt