Powrót do strony głównej

Evil merge w Git: złośliwy kod w merge-kommicie

Artykuł opisuje atak przez evil merge w Git: wprowadzenie ofuskowanego kodu w merge-komit. Payload używa blockchain do C2. Przedstawiono detektor w Go do automatycznego skanowania repozytoriów.

Złośliwy evil merge: 3,5 miesiąca w kodzie
Advertisement 728x90

Evil merge: złośliwy kod w kommicie scalania Git

W bazie kodu projektu wykryto złośliwy kod w pliku vite.config.js, który został zamaskowany. Pojawił się nie w PR, a bezpośrednio w kommicie scalania podczas rozwiązywania konfliktów. GitHub wyświetla w PR tylko różnice między gałęziami, ignorując zmiany w samym kommicie scalania. Analiza za pomocą git log ujawniła kommit scalania z identycznymi rodzicami, ale zmodyfikowaną zawartością pliku.

MD5-hash rodziców były identyczne:

  • Rodzic 1: aa82acb0c335430d8300b6cb306dc824 (czysty)
  • Rodzic 2: aa82acb0c335430d8300b6cb306dc824 (czysty)
  • Scalanie: 2a54754defae4d13aab39f256738dbbf (zmodyfikowany)

W trójstronnym scalaniu Git, gdy pliki u rodziców są identyczne, wynik powinien pozostać niezmieniony. Wszelkie różnice wskazują na ręczną edycję podczas scalania.

Google AdInline article slot

Mechanizm wstrzykiwania i maskowania

Złośliwy kod został wstrzyknięty do dwóch plików różnych modułów. Kontrybutor dodał ładunek po naciśnięciu przycisku scalania w PR. Kod uruchamiał się podczas npm run dev i npm run build przez 3,5 miesiąca.

Maskowanie obejmowało:

  • Odtwarzanie ciągów require, module, constructor poprzez mieszanie z numerycznym ziarnem.
  • Użycie Function zamiast eval do obejścia statycznej analizy.
  • Niestandardowy dekoder oparty na tabeli zamiany znaków.

Ładunek nie zawierał URL ani IP. Zamiast tego:

Google AdInline article slot
  • Pobieranie ostatniej transakcji portfela TRON.
  • Wyodrębnianie hasha transakcji BSC.
  • Wykonanie JSON-RPC eth_getTransactionByHash do węzła BSC.
  • Dekodowanie kodu z pola input za pomocą XOR.

Rezerwowo: Aptos, jeśli TRON był niedostępny. Uruchamianie przez child_process.spawn z detached: true i stdio: 'ignore', timer 30 sekund przeciw trybowi watch.

Przyczyny niezauważenia

  • GitHub nie pokazuje różnic w kommitach scalania w PR.
  • git log nie ujawnia zmian; wymagane jest git diff <parent1>..<merge>.
  • Kod przesunięty spacjami za 200. kolumną.
  • SAST nie zadziałał z powodu braku sygnatur: brak eval, URL, base64.

Technika znana jako evil merge — scalanie wprowadzające zmiany nieobecne u rodziców (gitglossary(7)). Opisana przez maintainera Git w 2013 roku, ale narzędzi jest mało.

Evil Merge Detector: automatyczny skaner

Detektor w Go porównuje oczekiwane trójstronne scalanie (poprzez wspólnego przodka) z rzeczywistym kommitem scalania. Różnice sygnalizują ręczne poprawki.

Google AdInline article slot

Użycie:

evilmerge scan /ścieżka/do/repozytorium

Opcje:

  • --format=sarif dla GitHub Code Scanning.
  • Poziomy ważności: ręczne rozwiązywanie konfliktów vs. poprawki bez konfliktów.

Integracje:

  • GitHub Action:

```yaml

- uses: fimskiy/Evil-merge-detector@v1

with:

fail-on: warning

```

  • GitHub App: sprawdzanie PR i retrospektywne skanowanie historii.
  • Szablony dla GitLab, Bitbucket, self-hosted (pre-receive hooks).

Środki zaradcze i podatności workflow

Ataki przez dostęp kontrybutora: legalne commity, następnie wstrzyknięcie w scalaniu. PR czysty.

Rekomendacje:

  • Liniowa historia (squash/rebase).
  • Pre-receive hooks na serwerze.
  • GitHub: „Dismiss stale reviews” — ponowne recenzowanie przy zmianach w gałęzi PR.

GitHub potwierdził: projekt celowy, możliwe przyszłe ograniczenia. Obecne środki — prewencja, nie detekcja.

Co jest ważne

  • Evil merge — oficjalny termin na ręczne poprawki w kommitach scalania.
  • Ładunek używa blockchain (TRON/BSC/Aptos) dla C2 bez URL/IP.
  • Detektor w Go skanuje historię, integruje się z CI/CD.
  • 3,5 miesiąca niezauważonej aktywności w projekcie z CI i recenzjami.
  • GitHub nie zmienia workflow scalania na razie.

— Editorial Team

Advertisement 728x90

Czytaj dalej