tom@home.htb:~$

Blog o HTB

17 January 2021

Supply chain uvnitř firmy: interní package registry

Úvod a kontext

Když se mluví o supply-chain útocích, pozornost často míří na veřejné ekosystémy jako PyPI, npm nebo RubyGems. Jenže podobně nebezpečný problém vzniká i uvnitř firmy. Interní package registry se často berou jako bezpečné právě proto, že jsou interní. Ve skutečnosti ale bývají ještě zrádnější:

SneakyMailer je přesně ten typ případu, kde registry sama není první foothold. Je až další vrstvou. Jakmile se útočník dostane k účtu, který smí do interního PyPI nahrávat, přestává jít o „repozitář balíčků“. Jde o execution kanál do důvěryhodného prostředí.

O čem tenhle článek je a o čem není

Tenhle text není o dependency confusion vůči veřejnému internetu. Neřeší situaci, kdy build omylem stáhne balíček z veřejného PyPI místo interního.

Řeší jiný model:

To je důležitý rozdíl. Tady problém nevzniká na hranici mezi interním a veřejným ekosystémem. Problém vzniká uvnitř organizace, protože interní důvěra se automaticky převádí na spuštění cizího kódu.

Proč je interní registry tak silný pivot

Interní registry je nebezpečná tím, že propojuje dvě věci:

Jakmile workflow dělá něco jako:

nepracuje už jen se statickými daty. Pracuje s objektem, který může během instalace:

To je přesně důvod, proč interní registry není „jen mirror“. Je to distribuční kanál pro kód.

SneakyMailer: od .pypirc k cizímu SSH účtu

Na SneakyMailer se po prvním footholdu objevila interní služba:

pypi.sneakycorp.htb

Současně se podařilo získat dva kritické podklady:

[local]
repository: http://pypi.sneakycorp.htb:8080
username: pypi
password: soufianeelhaoui

To je zásadní moment. Tím se z obyčejného config souboru stává mapa supply-chain cesty:

  1. existuje interní registry,
  2. existuje účet s upload oprávněním,
  3. existuje workflow, které z ní něco instaluje,
  4. a někdo jiný této registry implicitně věří.

Právě poslední bod je klíčový. Balíček nemá hodnotu sám o sobě. Hodnotu má proto, že ho někdo jiný nainstaluje jako legitimní součást interního procesu.

Proč nestačí říct „balíček obsahoval škodlivý setup.py“

To by bylo příliš úzké. Důležitý není konkrétní Python detail. Důležitý je obecný princip:

Ve SneakyMailer se to projevilo v setup.py, které při instalaci zapsalo útočníkův klíč do:

/home/low/.ssh/authorized_keys

Tím vznikl přístup k účtu low. Ale stejný model může v jiných ekosystémech znamenat:

Proto je lepší chápat interní registry jako execution trust boundary, ne jako prostý souborový sklad.

Jak vypadá interní supply-chain důvěra v praxi

V běžném prostředí bývají přítomné tyto vazby:

Jakmile tahle důvěra existuje, útok se láme na jedné otázce:

Pokud ano, další krok už není exploit služby. Je to zneužití legitimního distribučního kanálu.

Co při analýze hledat

Při pohledu na interní registry nebo lokální package workflow mají největší hodnotu tyto indicie:

1. Konfigurační soubory s přístupem do registry

Typicky:

Tyto soubory často neříkají jen „kam se připojit“. Říkají i:

2. Účty, které mají publish oprávnění

Upload účet do interní registry je vysoce citlivý. Nemusí mít SSH ani sudo. Pokud ale jeho balíček někdo důvěryhodně instaluje, jde prakticky o nepřímou cestu ke kódu.

3. Automatická nebo pravidelná instalace

Největší riziko vzniká tam, kde:

4. Možnost write -> authenticate

SneakyMailer je hezký právě tím, že škodlivý balíček neřešil reverzní shell během instalace. Využil jednodušší a stabilnější variantu: zapsal klíč do authorized_keys a otevřel legitimní přihlášení.

To je důležitá obranná lekce. Supply-chain dopad není vždy vidět jako hlučný malware. Často je to tichá změna důvěryhodné konfigurace.

Rozdíl proti článku o deployment trustu

Je užitečné tenhle článek oddělit od textu o repozitáři a deployment trustu.

Tam jde hlavně o to, že:

řídí produkční chování.

Tady je těžiště jinde:

Jinými slovy: neřešíme „repo jako zdroj nasazení“, ale „registry jako zdroj důvěryhodného kódu“.

Obrana a hardening

1. Považovat publish oprávnění za privilegovaný přístup

Účet, který smí do interní registry nahrávat balíčky, není obyčejný vývojářský účet. Je to účet s potenciálem ovlivnit cizí execution workflow.

2. Oddělit publish a consume identity

Když stejný nebo slabě chráněný účet:

vzniká přímý supply-chain kanál.

3. Zavést schvalování, podpisy nebo jiné ověření artefaktů

Interní neznamená automaticky důvěryhodné. Registry by měla odlišovat:

4. Minimalizovat účinek instalačního procesu

Účet, který balíček instaluje, nemá mít zbytečně široká práva. Čím vyšší oprávnění při instalaci, tím vyšší dopad kompromitované registry.

5. Monitorovat nové nebo neobvyklé publikace

Zejména varovné jsou:

Shrnutí klíčových poznatků

Co si odnést do praxe

tags: supply-chain - pypi - packages - registry - development