
This is a proof-of-work for abusing git's clean filter against IDEs & Sublime.
This is a documented (known) issue, but I found this during my research & its pretty useful for RT/PT.
Summary: The filter.<name>.clean directive in .git/config points at a script and .gitattributes binds that filter to a tracked file. Whenever git renders a real git diff of that file it runs the worktree content through the clean command first, so git blindly launches whatever path we specify there.
Now here's where it gets interesting. Our editors run git diff automatically the moment you click a changed file to populate their SCM (Source Control Management) panel and gutter annotations. Opening the folder alone isn't enough, but viewing the change is, and that's a pretty natural thing to do when you land in a repo.
This is the same idea as core.fsmonitor just on a different directive, and it isn't fsmonitor so anyone watching for that won't see it. The tradecraft fits RT engagements and assume-breach scenarios with any C2 or our XRayC2 to get a callback that evades traditional network defenses. (Of course, phishing emails are required to trick the end user, but opening a folder in an IDE and clicking a file seems like a fair operation.)
Proof of work. git clone won't carry .git/config so ship the folder with .git/ intact. Config under .git/config:
[filter "poc"]
clean = ./icons/clean.sh
smudge = cat
.gitattributes:
sample.txt filter=poc
sample.txt is committed but shipped modified in the working tree. The moment git diffs it, the clean filter fires. clean.sh pops Calculator and passes content through unchanged so the working tree is never corrupted:
#!/bin/sh
pgrep -x Calculator >/dev/null 2>&1 || open -a Calculator 2>/dev/null
exec cat
Open the folder in your editor, click sample.txt to view its change, and a calculator pops. (Quit Calculator to re-run it.) This POC is macOS specific, modify it for your env.
Tested on Cursor (git CLI) and Sublime Text (libgit2).
The clean filter runs only on a full git diff, not on git status, so it fires when the editor renders the change, not just on folder open. Interestingly Sublime triggers it in-process via libgit2, the payload's parent is sublime_text itself with no git binary in the chain, so this isn't limited to tools that shell out to git.
https://github.com/user-attachments/assets/31ea495f-1ed8-44f8-bef3-8c6366a0eece
Like fsmonitor this is gated by the editor's "trust this folder?" prompt. Most devs keep ~/Downloads and similar top level folders trusted, and Cursor ships workspace trust off by default, so the PoC runs silently. If a repo lives outside those trusted paths the IDE will ask "trust this publisher?" before reading .git/config.
Git docs: core.fsmonitor and filter.* at https://git-scm.com/docs/gitattributes.