Evil Merge: Bösartiger Code in Git-Merge-Commit versteckt
Bösartiger, verschleierter Code wurde in der Datei vite.config.js eines Projekts entdeckt. Er wurde nicht über einen Pull Request (PR) eingeführt, sondern direkt innerhalb eines Merge-Commit während der Konfliktlösung. Die PR-Ansicht von GitHub zeigt nur den Unterschied zum Feature-Branch an und ignoriert Änderungen im Merge-Commit selbst. Eine Analyse mit git log offenbarte einen Merge-Commit mit identischen Eltern-Commits, aber verändertem Dateiinhalt.
Die MD5-Hashes der Eltern-Commits stimmten überein:
- Eltern 1:
aa82acb0c335430d8300b6cb306dc824(sauber) - Eltern 2:
aa82acb0c335430d8300b6cb306dc824(sauber) - Merge:
2a54754defae4d13aab39f256738dbbf(modifiziert)
Bei einem Drei-Wege-Merge sollte Git ein unverändertes Ergebnis liefern, wenn die Eltern-Dateien identisch sind. Jede Abweichung deutet auf manuelle Bearbeitung während des Merge-Prozesses hin.
Injektions- und Verschleierungsmechanismus
Die bösartige Nutzlast wurde in zwei Dateien über verschiedene Module injiziert. Der Beitragende fügte die Nutzlast hinzu, als er im PR auf die Merge-Schaltfläche klickte. Der Code wurde während npm run dev und npm run build über 3,5 Monate ausgeführt.
Verschleierungstechniken umfassten:
- Rekonstruktion von Strings wie
require,module,constructordurch Vermischung mit einem numerischen Seed. - Verwendung von
Functionanstelle voneval, um statische Analyse zu umgehen. - Ein benutzerdefinierter Decoder mit einer Zeichenersetzungstabelle.
Die Nutzlast enthielt keine URLs oder IP-Adressen. Stattdessen:
- Sie fragte die neueste Transaktion einer TRON-Wallet ab.
- Sie extrahierte einen BSC-Transaktions-Hash.
- Sie führte einen JSON-RPC-Aufruf
eth_getTransactionByHashan einen BSC-Knoten durch. - Sie XOR-dekodierte den Code aus dem
input-Feld der Transaktion.
Aptos wurde als Fallback verwendet, wenn TRON nicht verfügbar war. Die Ausführung nutzte child_process.spawn mit detached: true und stdio: 'ignore' sowie einen 30-Sekunden-Timer, um Watch-Mode-Erkennung zu umgehen.
Gründe, warum es unbemerkt blieb
- GitHub zeigt keine Diffs für Merge-Commits in PRs an.
git logzeigt keine Änderungen; man benötigtgit diff <parent1>..<merge>.- Der Code wurde mit Leerzeichen über die 200. Spalte verschoben.
- SAST-Tools versagten aufgrund fehlender Signaturen: kein
eval, URLs oder Base64.
Diese Technik ist als Evil Merge bekannt – ein Merge, der Änderungen einführt, die in keinem Eltern-Commit vorhanden sind (gitglossary(7)). Sie wurde 2013 von einem Git-Maintainer beschrieben, aber es gibt wenige Erkennungstools.
Evil Merge Detector: Automatisierter Scanner
Ein in Go geschriebener Detektor vergleicht das erwartete Drei-Wege-Merge-Ergebnis (über einen gemeinsamen Vorfahren) mit dem tatsächlichen Merge-Commit. Abweichungen signalisieren manuelle Bearbeitungen.
Verwendung:
evilmerge scan /pfad/zum/repo
Optionen:
--format=sariffür GitHub Code Scanning.- Schweregrade: manuelle Konfliktlösungen vs. Bearbeitungen ohne Konflikte.
Integrationen:
- GitHub Action:
```yaml
- uses: fimskiy/Evil-merge-detector@v1
with:
fail-on: warning
```
- GitHub App: PR-Prüfungen und retrospektive History-Scans.
- Vorlagen für GitLab, Bitbucket und selbstgehostete Setups (Pre-Receive-Hooks).
Gegenmaßnahmen und Workflow-Schwachstellen
Angriffe über Beitragszugang: legitime Commits gefolgt von Injektion während eines Merges. Der PR selbst bleibt sauber.
Empfehlungen:
- Lineare Historie verwenden (Squash/Rebase).
- Pre-Receive-Hooks auf dem Server implementieren.
- Auf GitHub: "Dismiss stale reviews" aktivieren, um eine erneute Prüfung zu erfordern, wenn der PR-Branch sich ändert.
GitHub bestätigte, dass dies beabsichtigtes Design ist, mit möglichen zukünftigen Einschränkungen. Aktuelle Maßnahmen konzentrieren sich auf Prävention, nicht Erkennung.
Wichtige Erkenntnisse
- Evil Merge ist der offizielle Begriff für manuelle Bearbeitungen in Merge-Commits.
- Die Nutzlast nutzt Blockchain (TRON/BSC/Aptos) für Command-and-Control ohne URLs/IPs.
- Der Go-basierte Detektor scannt die Historie und integriert sich in CI/CD.
- 3,5 Monate unentdeckte Aktivität in einem Projekt mit CI und Code-Review.
- GitHub plant keine unmittelbaren Änderungen am Merge-Workflow.
— Editorial Team
Noch keine Kommentare.