A prospective client tried to run remote code through Git's built-in hooks.

A prospective client tried to run remote code through Git's built-in hooks.

SToFU Systems · Incident research · 20 October 2026

Contents

  1. It started with a development enquiry
  2. Downloading and inspecting the files
  3. How the Git post-checkout hook could run
  4. What the Git hook downloader does
  5. Was an application hidden inside the archive?
  6. What the download server returned
  7. Could this have been a legitimate helper?
  8. Reviewing an unfamiliar Git repository
  9. After the archive review
  10. Correspondence and evidence files

It started with a development enquiry

The first message arrived through our website on 15 October 2026. The sender wanted help building a platform for detecting financial fraud. The proposed system would score transaction risk and use behavioural analysis, with blockchain verification and reporting among the other requirements.

On 19 October, we received the download link. The accompanying email directed us to the conf branch for the architecture and the NDA branch for the agreement. It repeated the request to review and sign the NDA.

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

Following those instructions would take a reviewer from extracting the archive to switching branches in Git. The email presented both operations as part of reading the documentation. It said nothing about executing a downloaded program.

The email with the project archive and instructions to open the NDA branch. Identifying details are covered with grey rectangles.

The email with the project archive and instructions to open the NDA branch. Identifying details are covered with grey rectangles.

Downloading and inspecting the files

The link led to a standard Dropbox file-sharing page. We downloaded AI-Fraud-Detection_Blockchain.tar.gz into an isolated review environment and kept the original archive for reference. The specific sharing URL is withheld here.

We listed the archive contents and read the supplied Git objects directly. This let us recover the documents from all three branches without checking out a branch or running the supplied code. Across the branch trees, we found 15 Markdown files and one Word document.

Branch Files What we found
master 8 Markdown files A README, project overview, product requirements and business use cases. Other documents covered performance, security, testing and operations.
conf 7 Markdown files Guidance for a development proposal, blockchain architecture and integration, smart-contract requirements, data and API design, an AI risk engine, and delivery milestones.
NDA 1 DOCX file A confidentiality agreement with a signature block and template placeholders.

The proposed product combined transaction analysis, fraud rules and machine-learning scores with blockchain verification. Its suggested stack used Node.js and TypeScript with Express, PostgreSQL, Python machine-learning libraries and Ethereum. The delivery document laid out six milestones over 24 weeks. We found planning documents throughout the supplied trees, with no application implementation, trained model or smart-contract source to review.

Some details deserved a second look. The API examples contained the literal strings <built-in function id> and <built-in function hash> in endpoint paths. The NDA still contained template placeholders. These inconsistencies raised questions about how carefully the material had been prepared.

The executable .git/hooks/post-checkout file was a more serious finding. Its comments described a browser or extension update helper, which had no apparent connection to reviewing this project. Reading the script revealed instructions to download an external program and launch it in the background. The email's request to switch branches could bring a reviewer to that execution path while trying to read the NDA.

We kept the repository inactive and examined the hook as text. The relevant archive metadata and the script's behaviour follow below.

How the Git post-checkout hook could run

The file AI-Fraud-Detection_Blockchain.tar.gz is 779,429 bytes long. Its 100 TAR entries include 60 regular files. A complete .git directory arrived with the documents.

The hooks directory contained the usual .sample files and an executable named post-checkout.

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

There is no .sample suffix. Its TAR mode is 0777, which includes execute permissions, and its length is 2,774 bytes.

Git invokes post-checkout after updating the working tree through operations such as checkout or switch, provided the environment permits the hook to execute. The Git documentation describes the trigger.

Why the archived .git directory matters

A normal git clone does not copy a source repository's local client hooks, as Pro Git explains. This delivery included the existing .git directory inside an archive, so the local hook came with it.

The hook's path, mode and size read directly from the original TAR. We did not operate the received directory as a Git repository.

The hook's path, mode and size read directly from the original TAR. We did not operate the received directory as a Git repository.

We inspected the container and Git objects directly, without running checkout or switch on the received repository.

What the Git hook downloader does

Comments in the shell script describe a browser or extension update helper. We found no requirement for such a helper in the project documents. The script is unobfuscated plain text.

The unused size threshold

The script sets THRESHOLD to 100 and asks Git for a list of changed filenames. It initialises TRIGGER to zero.

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

Inside the loop, it calculates SIZE. There is no comparison with THRESHOLD and no assignment that changes TRIGGER. The download block runs when TRIGGER is zero.

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

Along the normal path through this script, the condition is true even when the changed-file list is empty. The threshold does not restrict the download.

Original line numbers retained. TRIGGER stays at zero. THRESHOLD is declared but never used in a comparison.

Original line numbers retained. TRIGGER stays at zero. THRESHOLD is declared but never used in a comparison.

Separate downloads for Linux, macOS and Windows

The value returned by uname -s determines the download path and local filename.

Detected system Server path Local filename
Linux /api/l run-command.sh
Darwin / macOS /api/m run-command.sh
MINGW, MSYS, CYGWIN, Windows_NT /api/w run-command.cmd
Unrecognised system /api/l run-command.sh

The URLs share one host, replaced here with <DOWNLOAD_DOMAIN>. We retained the unredacted hook privately. The branches cover Linux, macOS and Windows, with a Linux fallback for an unrecognised system. We did not test execution on those systems.

Downloading the file and attempting to run it

The hook saves the file in ${TMPDIR:-/tmp} using curl, or wget if curl is unavailable. There is no signature or expected-hash check before the following execution instructions.

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

The final ampersand starts the command in the background. Both standard output and standard error go to /dev/null.

After the execution attempt, the hook writes azuku into .git-checker in the temporary directory. It never checks for that marker before downloading again. Nor does it wait for the background process to succeed before writing the file. The marker could therefore exist after an unsuccessful execution attempt.

The original download, chmod, background execution and marker-writing instructions. The second-stage program is not present in this excerpt.

The original download, chmod, background execution and marker-writing instructions. The second-stage program is not present in this excerpt.

A comment near the end says to remove the temporary download directory. There is no removal command beneath it.

Was an application hidden inside the archive?

The network download raised another question. Was there already an application in the archive, perhaps inside Git history or the NDA? We examined the container boundaries, then decoded every supplied Git object and inspected the DOCX contents.

The archive boundaries

We recorded the original archive's SHA-256 before inspecting its contents.

6f44ff4e461828dd1fe6ede75ca8d9d4b579c2ac223463629e9a7537b9df5040

Decompressing gzip as data produced an 890,880-byte TAR stream. The gzip stream ended cleanly, with no unused bytes after it. The final 5,120 bytes after the last TAR entry were zero padding.

We then examined the files and objects accounted for by those container entries.

Saved gzip end-of-stream and TAR padding checks. No code from the sample was executed.

Saved gzip end-of-stream and TAR padding checks. No code from the sample was executed.

Finding the hook in the TAR header

The post-checkout entry's header starts at 0xCF600, or 849,408, in the decompressed TAR. Its file data begins at 849,920. These offsets refer to the TAR stream, not the compressed .gz file.

At that offset, the header starts with the path to post-checkout.

TAR / hex dump

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 a TAR header, mode occupies bytes [100:108] and size occupies [124:136]. The decoded fields for this entry follow the dump.

TAR field Raw bytes / value
mode b'0000777\x00'
size b'00000005326\x00'
Octal mode 0777
Decimal size 2774 bytes
Stored / computed checksum 10301 / 10301

The octal size decodes to 2,774 bytes. The stored header checksum is 10,301. Recomputing it with the checksum field filled with spaces gives the same result.

The hook's raw TAR header and decoded fields. Its name, permissions and size are visible in the container bytes.

The hook's raw TAR header and decoded fields. Its name, permissions and size are visible in the container bytes.

We also hashed the hook extracted from this entry.

854b3b88b06fad9d9ffec36b35be0133b1d502084d4d7cce232eda2b2dd03092

The TAR entry dump and anonymised hook are included with the article. The hash above identifies the unredacted original held privately, not the redacted publication copy.

Reading Git objects without checkout

There are 24 loose objects in .git/objects, each stored in a zlib stream. The decompressed data contains a Git header followed by the object body.

<type> <size>\0<body>

We checked the declared body length and computed SHA-1 over the whole decoded sequence, including the header and NUL byte. The result must match the object ID in the filename. This checks the object's integrity. It says nothing about who created it.

For each object, we compared the declared length with the body length and verified the hash over the complete decoded 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

We checked the zlib stream endings too. The objects resolve to 16 blobs, 5 trees and 3 commits. Following the three branch heads, their parent commits and child trees accounts for all 24 objects. There are no unreachable blobs among the supplied objects.

Git / commit relationships

master 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f
  tree   feb0feaf7b8e826b085e90dea5399772d7b91f02
  parent (none)

conf   239b9aa2edc8c5e21fddeea5ed0e937496ae013f
  tree   048b51f9673f94354251ce16a78e663c71667a4c
  parent 4bc26f6c18910ca777c8238d2f88f6e725fcdc3f

NDA    a1311875d86bf6f1a6b9f2fee6527abbd1ce647d
  tree   cc020d922090835ea4ac3a3e418d0213d7a2ad94
  parent 239b9aa2edc8c5e21fddeea5ed0e937496ae013f

The complete object inventory includes the objects outside the current working tree.

Inventory of all 24 Git objects

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

Length and SHA-1 verified over the original Git encoding of each object. All 24 checks passed.


Following the NDA from its tree to its bytes

The NDA branch points to a tree containing one file, Non-Disclosure-Agreement.docx. A Git tree entry stores the mode and filename as text, followed by a NUL and 20 raw bytes for the blob ID. We parsed the entry directly from the tree body.

Git tree / hex dump

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

Raw NDA tree bytes and the decoded reference to its DOCX blob.

Raw NDA tree bytes and the decoded reference to its DOCX blob.

That entry references the following blob.

5a51550933b593eb65da458bbdd579f85c082dab

After zlib decompression, the object starts with blob 752100\0. Immediately after the header are the bytes 50 4b 03 04, the PK signature of a ZIP container.

Git blob / after 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|

Compressed object bytes, the decoded Git header and the beginning of the DOCX. Length and object ID were checked against the complete object.

Compressed object bytes, the decoded Git header and the beginning of the DOCX. Length and object ID were checked against the complete object.

The body is 752,100 bytes long. Its SHA-256 matches the DOCX we saved separately for analysis.

9d85170d2c0aa7a9b90dfc3855715a31d971bba7abb563e9efa1153fdc15634f

These objects account for the path from the NDA branch to the document's bytes.

Accounting for all 16 blobs

Fifteen blobs decode as UTF-8 Markdown project documents. The remaining blob is the DOCX above. None starts with a PE, ELF or Mach-O header.

Path in trees Size, bytes Type / first bytes
04-solution-proposal-guidance.md 2054 UTF-8 text · 23 20 44 65 76 65 6c 6f 70 6d 65 6e 74 20 43 6f
06-blockchain-architecture.md 6497 UTF-8 text · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 41 72 63
07-blockchain-integration-specification.md 2807 UTF-8 text · 23 20 42 6c 6f 63 6b 63 68 61 69 6e 20 49 6e 74
08-smart-contract-specification.md 2610 UTF-8 text · 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 text · 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 text · 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 text · 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 text · 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 text · 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 text · 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 text · 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 text · 23 20 44 65 70 6c 6f 79 6d 65 6e 74 2c 20 4d 6f
Intro/01-project-overview.md 8402 UTF-8 text · 23 20 50 72 6f 6a 65 63 74 20 4f 76 65 72 76 69
Intro/02-product-requirements.md 3191 UTF-8 text · 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 text · 23 20 41 49 20 46 72 61 75 64 20 44 65 74 65 63

All 16 supplied blobs classified. The trees contain project documents, with no product implementation found.

All 16 supplied blobs classified. The trees contain project documents, with no product implementation found.

We read the text bodies as well as checking their signatures. The DOCX was the only non-text blob and needed a separate container inspection.

Opening the DOCX as ZIP

The document contains 25 ZIP entries, made up of 17 file parts and 8 directories. We read every file part and checked its CRC.

DOCX part Size, 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

DOCX part names, lengths and CRC32 values. We inspected ZIP and XML data without opening the document in Office.

DOCX part names, lengths and CRC32 values. We inspected ZIP and XML data without opening the document in Office.

There is no vbaProject.bin or OLE attachment in the part list. Two PNG files contain a logo and a signature image. We also inspected the XML relationships and found a reference to a local office template path on the document author's machine. We did not resolve or load it.

The signature image and Git author fields give us no reliable way to identify the sender. Both can be copied or replaced.

We found no separate application or product implementation in the supplied contents. The hook obtains its next program through the network. Our container inspection does not rule out every possible exploit or steganographic technique.

What the download server returned

We fetched the three exact URLs as data, without executing the responses or following redirects. On 19 October, at 17:29:27 to 17:29:28 UTC, each returned HTTP 200. All three bodies were the same 21-byte message.

Permanently suspended

The three saved endpoint observations. We made no further requests to the downloader URLs while preparing this article.

The three saved endpoint observations. We made no further requests to the downloader URLs while preparing this article.

We have no second-stage bytes to reverse engineer. We also don't know what those endpoints returned earlier, to another visitor or under different request conditions. The suspension message gives us no verified explanation for why the service was suspended.

The hook attempts to download and execute an external file. Claims about stolen passwords, tokens, source code or wallets would require evidence we do not have.

Could this have been a legitimate helper?

An internal updater could end up in an archive by mistake. Git hooks, background processes and curl all have legitimate uses.

In this submission, the email explicitly asked us to visit another branch. Doing so could invoke the supplied downloader, although the stated reason for the branch change was to read an agreement. The email did not mention the execution. We also found no connection between a browser updater and the proposed system, and the script's size check was incomplete.

We treated the submission as an attempted code delivery attack and kept the hook from running. Reconsidering that assessment would require the downloaded files' source and a verifiable explanation of why a contractor needed to execute them to review the NDA.

We have not established the operator's identity. The sender address, commit metadata and names inside the document are insufficient for attribution.

Analysis diagram of the execution steps described by the supplied hook.

Analysis diagram of the execution steps described by the supplied hook.

Reviewing an unfamiliar Git repository

A developer following the email could reach the execution trigger while still reading about the project. There was no need to build or start the proposed application.

If you review client submissions on a machine with production SSH keys or cloud tokens, an unexpected script may have access to those resources. A disposable environment needs to keep those credentials out of reach. Browser sessions on the review machine deserve the same consideration.

The review should include the supplied .git directory and any IDE automation before an engineer starts using their usual commands. Installation scripts need scrutiny too. In host logs, we'd look for Git or a shell downloading a file into a temporary directory and then executing it. A curl process on its own tells us much less.

Preserving the original email and archive allows a later reviewer to check what was delivered. Hashes and host events help establish what happened on the machine. A missing marker cannot establish that a program never ran.

Can downloading or extracting the archive run this hook?

Downloading and ordinary extraction do not invoke Git's post-checkout hook themselves. In this sample, the documented trigger is Git updating the working tree through checkout or switch, when hook execution is allowed. We inspected the supplied objects directly without invoking those operations.

After the archive review

We had expected the next exchange to be about architecture and delivery dates. We sent a response about the hook instead and preserved the material for further review. We still cannot say what the remote program did or who operated it. The hook gave us enough reason to stop the requested Git workflow.

For more than five years, SToFU Systems and our solutions have helped companies protect their systems, including against attacks delivered through business correspondence and development materials. Our security audits examine how code and access can be misused. We also provide reverse engineering when a team needs to understand unfamiliar software.

If a repository or binary raises questions, talk to our team about a technical review before putting it into your normal development environment.

Correspondence and evidence files

The four messages below use placeholders for personal names, addresses, third-party identities and identifying links. Other new-message wording is retained. Repeated quotations are omitted because each email appears separately. The web form's service IP and unrelated recipients' addresses are also withheld.

1. The first enquiry through our website

email / identifying details replaced

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

The first enquiry through our website. Anonymised publication view of the preserved email.

The first enquiry through our website. Anonymised publication view of the preserved email.

Private unredacted EML SHA-256: bf7d0f3a59b84f509ca436e0750640e844e9731ce363a42a99d5be60cdf8597e


2. Our reply requesting the materials

email / identifying details replaced

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>

Our reply requesting the materials. Anonymised publication view of the preserved email.

Our reply requesting the materials. Anonymised publication view of the preserved email.

Private unredacted EML SHA-256: 1e5330dd82e02911254722744a3202e9b761c8c1d2950be937cd5d539c1bcad9


3. The archive email naming the NDA / conf branches

email / identifying details replaced

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>

The archive email naming the NDA / conf branches. Anonymised publication view of the preserved email.

The archive email naming the NDA / conf branches. Anonymised publication view of the preserved email.

Private unredacted EML SHA-256: f7007ed3053d3ba2ef71ea01c74ec0c4aebfd48417f757ecec8d9d7d5884bf33


4. Our reply after discovering the hook

email / identifying details replaced

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

Our reply after discovering the hook. Anonymised publication view of the preserved email.

Our reply after discovering the hook. Anonymised publication view of the preserved email.

Private unredacted EML SHA-256: 31df91adb2eb52be2171836d3e26610328a0a1a1273dbf7d56efe4354bb62e19


Anonymised view of the complete hook

All 101 source line numbers retained. Identifying details covered with grey rectangles.

All 101 source line numbers retained. Identifying details covered with grey rectangles.


Unredacted originals are held privately. Public evidence files use placeholders, and screenshots use opaque grey rectangles. Hashes labelled as original identify the private source, not an edited publication copy. Figures are screenshots of local evidence views, with identifying text removed before rendering. No received code was executed.

SToFU Systems

SToFU Systems

Back to Blogs

Contact

Start the Conversation

A few clear lines are enough. Describe the system, the pressure, the decision that is blocked. Or write to midgard@stofu.io directly.

0 / 10000
No file chosen