
Esta es una prueba de concepto para abusar del filtro clean de git contra IDEs y Sublime.
Este es un problema documentado (conocido), pero lo encontré durante mi investigación y es bastante útil para RT/PT.
Resumen: La directiva filter.<name>.clean en .git/config apunta a un script y .gitattributes vincula ese filtro a un archivo rastreado. Cada vez que git renderiza un git diff real de ese archivo, primero pasa el contenido del árbol de trabajo por el comando clean, por lo que git lanza ciegamente cualquier ruta que especifiquemos allí.
Ahora es donde se pone interesante. Nuestros editores ejecutan git diff automáticamente en el momento en que haces clic en un archivo modificado para poblar su panel de SCM (Source Control Management) y las anotaciones del gutter. Abrir la carpeta por sí solo no es suficiente, pero ver el cambio sí lo es, y es algo bastante natural cuando llegas a un repositorio.
Esta es la misma idea que core.fsmonitor, solo que en una directiva diferente, y no es fsmonitor, por lo que cualquiera que esté vigilando eso no lo verá. Esta técnica encaja en compromisos de RT y escenarios de asunción de brecha con cualquier C2 o nuestro XRayC2 para obtener un callback que evade las defensas tradicionales de red. (Por supuesto, se requieren correos de phishing para engañar al usuario final, pero abrir una carpeta en un IDE y hacer clic en un archivo parece una operación justa).
Prueba de trabajo. git clone no se lleva .git/config, así que envía la carpeta con .git/ intacto. Configuración en .git/config:
[filter "poc"]
clean = ./icons/clean.sh
smudge = cat
.gitattributes:
sample.txt filter=poc
sample.txt está confirmado, pero se envía modificado en el árbol de trabajo. En el momento en que git le aplica diff, el filtro clean se dispara. clean.sh abre Calculator y pasa el contenido sin cambios, por lo que el árbol de trabajo nunca se corrompe:
#!/bin/sh
pgrep -x Calculator >/dev/null 2>&1 || open -a Calculator 2>/dev/null
exec cat
Abre la carpeta en tu editor, haz clic en sample.txt para ver su cambio, y aparece una calculadora. (Sal de Calculator para volver a ejecutarlo). Este POC es específico de macOS; modifícalo para tu entorno.
Probado en Cursor (git CLI) y Sublime Text (libgit2).
El filtro clean se ejecuta solo en un git diff completo, no en git status, por lo que se dispara cuando el editor renderiza el cambio, no solo al abrir la carpeta. Curiosamente, Sublime lo activa en el propio proceso vía libgit2; el padre del payload es el propio sublime_text, sin ningún binario git en la cadena, por lo que esto no se limita a herramientas que ejecutan git mediante shell.
https://github.com/user-attachments/assets/31ea495f-1ed8-44f8-bef3-8c6366a0eece
Al igual que fsmonitor, esto está controlado por el mensaje de "¿confiar en esta carpeta?" del editor. La mayoría de los desarrolladores mantienen ~/Downloads y carpetas de nivel superior similares como confiables, y Cursor trae la confianza del espacio de trabajo desactivada por defecto, por lo que el PoC se ejecuta en silencio. Si un repositorio se encuentra fuera de esas rutas confiables, el IDE preguntará "¿confiar en este publicador?" antes de leer .git/config.
Documentación de Git: core.fsmonitor y filter.* en https://git-scm.com/docs/gitattributes.