Zlovolný merge: škodlivý kód v merge-commitu Git
V kódové základně projektu byl objeven obfuskovaný škodlivý kód v souboru vite.config.js. Neobjevil se v pull requestu, ale přímo v merge-commitu při řešení konfliktů. GitHub v PR zobrazuje pouze rozdíly větve, ignoruje změny v samotném merge-commitu. Analýza pomocí git log odhalila merge-commit s identickými rodiči, ale změněným obsahem souboru.
MD5-hash rodičů se shodovaly:
- Rodič 1:
aa82acb0c335430d8300b6cb306dc824(čistý) - Rodič 2:
aa82acb0c335430d8300b6cb306dc824(čistý) - Merge:
2a54754defae4d13aab39f256738dbbf(změněný)
Při třístranném slučování Git by měl být výsledek nezměněný, pokud jsou soubory u rodičů identické. Jakékoliv odlišnosti naznačují ruční úpravy během merge.
Mechanismus vložení a obfuskace
Škodlivý kód byl vložen do dvou souborů různých modulů. Přispěvatel přidal payload při kliknutí na merge v PR. Kód se spouštěl při npm run dev a npm run build po dobu 3,5 měsíce.
Obfuskace zahrnovala:
- Obnovení řetězců
require,module,constructorpřes promíchání s numerickým seedem. - Použití
Functionmístoevalpro obejití statické analýzy. - Vlastní dekodér na bázi tabulky nahrazování znaků.
Payload neobsahoval URL ani IP adresy. Místo toho:
- Dotaz na poslední transakci TRON peněženky.
- Extrakce BSC-hash transakce.
- JSON-RPC
eth_getTransactionByHashk BSC uzlu. - XOR-dekódování kódu z pole
input.
Záložní varianta: Aptos při nedostupnosti TRON. Spuštění přes child_process.spawn s detached: true a stdio: 'ignore', časovač 30 sekund proti watch-režimu.
Důvody neodhalení
- GitHub nezobrazuje rozdíly merge-commitů v PR.
git logneodhaluje změny; je potřebagit diff <parent1>..<merge>.- Kód posunut mezerami za 200. sloupec.
- SAST nefungoval kvůli absenci signatur: žádné
eval, URL, base64.
Tato technika je známá jako zlovolný merge – merge, který zavádí změny, které nejsou přítomny u rodičů (gitglossary(7)). Byla popsána správcem Git v roce 2013, ale existuje málo nástrojů.
Evil Merge Detector: automatizovaný skener
Detektor v Go porovnává očekávané třístranné sloučení (přes společného předka) se skutečným merge-commitem. Rozdíly signalizují ruční úpravy.
Použití:
evilmerge scan /cesta/k/repozitari
Možnosti:
--format=sarifpro GitHub Code Scanning.- Úrovně závažnosti: ruční řešení konfliktů vs. úpravy bez konfliktů.
Integrace:
- GitHub Action:
```yaml
- uses: fimskiy/Evil-merge-detector@v1
with:
fail-on: warning
```
- GitHub App: kontrola PR a retrospektivní sken historie.
- Šablony pro GitLab, Bitbucket, self-hosted (pre-receive hooky).
Opatření a zranitelnosti workflow
Útoky přes přístup přispěvatele: legitimní commity, následovaná injekce v merge. PR je čistý.
Doporučení:
- Lineární historie (squash/rebase).
- Pre-receive hooky na serveru.
- GitHub: "Dismiss stale reviews" – opakované recenzování při změnách v PR větvi.
GitHub potvrdil: design je záměrný, možná budoucí omezení. Současná opatření jsou preventivní, ne detekční.
Co je důležité
- Zlovolný merge – oficiální termín pro ruční úpravy v merge-commitech.
- Payload využívá blockchain (TRON/BSC/Aptos) pro C2 bez URL/IP.
- Detektor v Go skenuje historii, integruje se do CI/CD.
- 3,5 měsíce neodhalené aktivity v projektu s CI a recenzemi.
- GitHub zatím nemění merge-workflow.
— Editorial Team
Zatím žádné komentáře.