The file landed at 12:04 PM. By 12:10 we were reading a script that would have run, silently, on the laptop of whoever opened our new client's NDA. The client wasn't a client. The NDA was bait. And the instruction that made the whole thing work was one line most developers would follow without a second thought: check out the NDA branch.
This is the full account of the September 29, 2026 lure, written so the next agency that gets the same email finds this page first. The short version is right below, and the indicators your security team needs are at the end.
Key facts
- What happened: a fake client inquiry that delivered malware through a git post-checkout hook hidden in a project archive.
- Who it targeted: ivector, a software development agency. The inquiry came through our contact form, attributed to a referral from our Clutch profile.
- The trigger: running
git checkout NDAinside the archive the "client" sent, supposedly to read and sign an NDA. - The payload host:
brightlaunch-ext75642[.]vercel[.]app, with one download path per operating system. - The sender's domain:
catapultsystemsinc[.]com, registered on September 28, 2026, a lookalike of Catapult Systems. Catapult Systems and its parent Quisitive were not involved. - The outcome: nothing ran. We reported it to Vercel, Dropbox, Hostinger, Clutch, Quisitive and the FBI's IC3 the same afternoon.
- Our assessment (not proven): it matches public reporting on North Korea's "Contagious Interview" campaign.
How it unfolded
| When (Pacific) | What happened |
|---|---|
| Sept 28 | catapultsystemsinc[.]com is registered |
| Sept 29, morning | An inquiry arrives through our contact form, attributed to our Clutch profile |
| Late morning | Two friendly emails each way. He offers "a more detailed project document" |
| 11:05 AM | A Dropbox link arrives, with the request to open the NDA branch first |
| 12:04 PM | We download the archive and list its contents without extracting it |
| About 12:10 PM | We're reading .git/hooks/post-checkout |
| 12:23 PM | The sample is locked in a password-protected evidence archive |
| Afternoon | Reports go to Vercel, Dropbox, Hostinger, Clutch, Quisitive and IC3 |
It came through the contact form on our site, and our analytics attributed it to a referral from our Clutch profile. That matters, because it's the channel agencies trust most: a buyer who found you on a review platform and filled in your form is exactly what a sales pipeline is built to welcome.
The pitch was a good one. An "education credential verification platform": universities issue digital credentials, students share them, employers and government bodies verify them, all with an audit trail. They wanted a development partner to build an MVP they could show to institutional and government stakeholders. The sender signed as a consultant at Catapult Systems, a real Texas IT consultancy owned by Quisitive, and wrote from an address at catapultsystemsinc[.]com.
We replied the same day, as you would. Two friendly emails later he offered "a more detailed project document" and sent a Dropbox link to a file called Education_Credential_Verification_Project.tar.gz. His note said that before any detailed discussion he'd need our signature on a project NDA, and that "the NDA is available in the separate NDA branch of the repository."
Nobody needs a git branch to share a Word document. That sentence is why we opened the archive in read-only mode instead of the usual way.
What was inside the archive
A normal-looking git repository. The main branch held 18 markdown files of project documentation: overview, requirements, data model, API specification, roles and permissions, security, a 14-week timeline. They were coherent, generic, and clean, with no links, scripts or hidden characters. (They were also the kind of generic you get from a language model asked for a spec: every file dated the same day, "Example University" as sample data, invented dashboard numbers, no real names anywhere.)
The NDA branch held one file, a Word document styled as a mutual NDA from Catapult Systems. It had no macros or external links either. It did have a blank "[Full Legal Name of Partner]" slot, Texas governing law with New Jersey courts, and a pre-filled signer who, as far as we can tell, has no connection to Catapult at all.
The payload wasn't in any of those files. It was in .git/hooks/post-checkout, a place most people never look.
How the post-checkout hook works
Git hooks are scripts git runs automatically at set moments, and post-checkout runs every time you switch branches. So the moment anyone types git checkout NDA (or clicks the branch in their editor's git panel), this is what the hook did:
- 1.Checked the operating system with
uname. - 2.Picked a download URL to match:
/api/mfor macOS,/api/lfor Linux,/api/wfor Windows, all onbrightlaunch-ext75642[.]vercel[.]app. - 3.Downloaded that script with
curlinto the temp folder asrun-command.sh(orrun-command.cmdon Windows). - 4.Made it executable and ran it in the background, with all output thrown away.
- 5.Wrote a marker file,
.git-checker, containing the textakke.
The script dresses this up as housekeeping. Its comments describe a "Chrome / extension update helper" that only runs when a changed file is over 100 bytes. That size check is decoration: the trigger variable is set to 0 and never changed, so the download runs on every checkout, every time.
We never fetched what that server sends back, so we can't tell you exactly what it does. We can tell you what it's able to do. Whatever comes back runs as you, with your access to SSH keys, browser sessions, saved passwords, .env files, cloud credentials and every client repository on the laptop. For an agency that last part is the real exposure: one developer's machine can hold keys to a dozen client systems.
Why a tarball and not a GitHub link
This is the detail worth remembering. Hooks don't travel with git clone. If he'd sent a GitHub URL, we'd have cloned a harmless repository, because git never copies .git/hooks from a remote. The only way to deliver a working hook is to send the whole folder, .git directory included, as an archive. And the only reason to insist on a branch checkout is to make the hook fire.
So the two slightly odd requests (an archive instead of a link, an NDA in a branch instead of a PDF) were the attack. Each is harmless-sounding on its own. Together they're the whole mechanism.
The other details that didn't add up
Once we looked properly, the rest fell apart quickly:
| Signal | What we found |
|---|---|
| Sender domain | catapultsystemsinc[.]com was registered on September 28, 2026, the day before the inquiry. Catapult's real domain is catapultsystems.com. |
| Domain setup | Parked DNS at a budget registrar, no website |
| Phone number | A Rhode Island area code for a company based in Austin |
| Archive owner | Packed by a user account with a different name from the sender |
| Hook timestamp | Older than the repository, copied in after the commits were made |
| NDA | Blank partner name, mismatched law and venue, a signer not tied to the company |
To be clear about the company: Catapult Systems and Quisitive had no involvement. Their name and their Austin address were borrowed, and we've told them.
Who we think is behind it
This part is our reading of public reporting, not something we can prove from one sample.
The brightlaunch-* naming isn't new. Socket's February 2026 research into 26 malicious npm packages it called StegaBin lists Vercel fallback domains built on the same pattern, attributed to North Korea's "Contagious Interview" operation. OpenSourceMalware reported in May 2026 that the same group had started hiding its loader in git pre-commit and post-checkout hooks that fetch from Vercel. And on September 18, 2026, the FBI's IC3 and partner agencies in Japan, Australia and Germany published an alert on the group (which they call WaterPlum) saying it had infected at least 30,000 computers in more than 100 countries, and that its actors pose as employers or as clients on freelance and gig platforms.
That alert doesn't mention git hooks, and it doesn't mention agencies or Clutch. What looks new in our case is the angle: not a fake job for one developer, but a fake client for a whole agency, arriving through a legitimate lead channel with an NDA as the trigger. It makes sense as a target. A fake recruiter gets one engineer's laptop. A fake client gets the laptop of someone who holds client credentials.
The server was live well before it reached us: a public urlscan.io scan shows /api/w answering on August 5, 2026. We're almost certainly not the first agency to get this email.
How to check a client's repo before you open it
Our rule now, and one we'd suggest to any shop that takes inbound work:
- Never open a stranger's repository from an archive. If it needs to be a repo, ask for a hosted link and clone it fresh. Hooks won't come along.
- If you must look, list before you extract.
tar -tzvf file.tar.gz | grep hooks/shows any hook. Anything that isn't a.samplefile means stop. - Read files without git's help.
git --git-dir=path/.git cat-file -p <hash>reads a document out of a branch without checking it out, so no hook runs. - Grep for the tells. In any hook, task or install script, look for
curl,wget,base64,chmod +xandvercel.app. The IC3 alert lists curl and base64 among its warning signs too. - Open unknown code only in a throwaway VM, never on the laptop that holds client keys.
- NDAs come as PDFs or e-signature links. "It's in the branch" is a red flag on its own.
- Check the domain's age. A client domain registered this week is a question worth asking before a call.
- Call the company, not the number in the email. Use the one on their official website.
If you already switched branches in something like this, look in your temp folder (echo $TMPDIR on a Mac) for run-command.sh and .git-checker. If they're there, disconnect the machine, and from a different device rotate your SSH keys, git and cloud tokens and browser passwords. The IC3 alert also advises moving any crypto to a new wallet created on a clean device, and reinstalling the operating system.
Other ways the same lure can arrive
The hook is one delivery route. When we reviewed our own exposure we listed every other place a "client project" can run code on open, because the next version of this email won't use the same trick:
- Hooks in an archive (
.git/hooks): our case. Fires on checkout, commit or merge. - Committed hook folders (
.githooks,.husky): hooks committed into the repo, which activate once someone runs the project's setup script. - Editor tasks (
.vscode/tasks.jsonand workspace settings): tasks set to run when the folder opens, if you click "trust" on the prompt. The IC3 alert names a VS Code variant. - Package installs (
npm install): apostinstallscript inpackage.json, or a malicious dependency. - "Run the demo": a follow-up asking you to start the project to "see the prototype", which is the same thing with extra steps.
- A second link: "here's an updated version of the repo" after the first one didn't get opened.
- A call: a request to screen-share and install a meeting tool or "our internal viewer".
Indicators of compromise
For anyone doing detection (defanged):
- Payload host:
brightlaunch-ext75642[.]vercel[.]app, paths/api/m,/api/l,/api/w - Temp files:
run-command.sh,run-command.cmd,.git-checker(contentsakke) - Hook SHA-256:
44bc94150790aa1fbec9895a444ffc954b3d5f3e02b420e9592ab6501ef42547 - Archive SHA-256:
e8e48f4c6de0719000274c3aa30ba41933df0bb72297598d5c023fdc7edd5aa0 - File name:
Education_Credential_Verification_Project.tar.gz, branchNDA - Sender domain:
catapultsystemsinc[.]com(lookalike, registered 2026-09-28), sender addressalex@catapultsystemsinc[.]com
We reported the payload server to Vercel, the file to Dropbox, the domain to its registrar, the referral to Clutch, and the whole thing to the FBI through IC3. Catapult's parent company has been told as well.
Nobody here was infected, mostly because the request was slightly off and we stopped to read before running. If your team takes inbound project work and wants a second pair of eyes on something that feels off, or wants a lightweight checklist like the one above built into how you onboard new clients, our cybersecurity team does exactly that, and we're happy to look at a suspicious repo with you through our contact page. For the broader question of choosing who you let into your codebase, we've written about vetting a development partner and the trust questions in white-label delivery.
We've also written up the practical side: how to check a client's git repo for malicious hooks in about ten minutes, and nine checks for spotting a fake client inquiry before the first call. A first-hour plan for when someone on the team has already run something goes up next.
Sources
- FBI IC3 and partners: North Korean "WaterPlum" (Contagious Interview) targeting IT professionals, Sept 18, 2026
- Socket: StegaBin, 26 malicious npm packages using Pastebin steganography
- OpenSourceMalware: DPRK hides malware in git hooks
- Microsoft Security: Contagious Interview malware delivered through fake developer job interviews
- Git documentation: githooks