Bezpečnostní modul IPE zajistí integritu Linuxu, vyvíjí ho Microsoft

14. 4. 2020
Doba čtení: 5 minut

Sdílet

Microsoft oznámil vývoj nového bezpečnostního modulu, jehož cílem je zajistit bezpečnost především u statických instalací Linuxu, jako jsou různé routery či firewally. IPE zamezí spuštění cizího kódu.

Microsoft zveřejnil detaily nového projektu, který míří do linuxového jádra. Integrity Policy Enforcement (zkráceně IPE) je takzvaný Linux Security Module, podobně jako třeba SELinux. To jsou moduly, které pomocí standardizovaného rozhraní vytvářejí bezpečnostní politiku operačního systému.

Co se dozvíte v článku
  1. Integrita kódu
  2. Proti čemu chrání
  3. Zapnutí a ovládání modulu
  4. Zavedení politiky
  5. Příklady politik
  6. Známé nedokonalosti IPE
  7. Dokumentace ke studiu

Cílem projektu IPE je vyřešit problém integrity linuxového systému. Microsoft to řeší kvůli svým zákazníkům, kteří na jeho cloudové platformě Azure používají převážně právě Linux. Modul ovšem může využít kdokoliv, přestože je určen pro specifické účely.

Integrita kódu

IPE je linuxový modul, který dovoluje vytvářet a vynucovat politiku pro integritu celého operačního systému. Správce tak může zajistit, že veškerý spouštěný kód pochází z důvěryhodného zdroje a nebyl například nahrazen útočníkem. To je užitečné zejména u jednoúčelových instalací jako jsou firewally, protože právě na nich má běžet jen předem připravený software.

Předpokládá se, že při startu takového systému je například pomocí UEFI Secure Boot ověřena integrita zavaděče a jádra operačního systému, modul IPE pak řeší vynucení politiky při spouštění binárek v uživatelském prostoru. Provádí to pomocí elektronického podpisu a používá k tomu standardní linuxové rozhraní dm-verify.

Microsoft tvrdí, že výhodou hlavní proti jiným podobným řešením je nezávislost na metadatech uložených na souborovém systému. Na ta spoléhá například projekt IMA, který se snaží řešit stejný problém. IPE ovšem používá struktury, které jsou uložené výhradně v paměti jádra.

V jádře už existuje několik mechanismů, které dokáží zajistit integritu. Device mapper například umí kontrolovat integritu blokového zařízení, fs-verify zase hlídá integritu souborového systému. Zatím ovšem chyběla podpora pro průběžnou kontrolu toho, že spouštěné binárky pocházejí z těchto důvěryhodných zdrojů.

Proti čemu chrání

Cílem je nasazení elektronického podpisu a PKI pro ověřování integrity spouštěných binárek. To je efektivní ochrana proti unesení linkeru pomocí známých metod jako  LD_PRELOAD, LD_AUDIT či DLL Injection. Úspěšný útočník zároveň nemůže na disku vyměnit soubory a nepozorovaně vyměnit původní kód za svůj.

Zároveň to znemožňuje podvržení úplně nového kódu. Bez příslušného podpisu jej linuxové jádro nezavede a nespustí. To ovšem také nepřímo určuje, že IPE není určeno pro běžná univerzální nasazení, kde se software průběžně mění nebo kvůli zásahům uživatelů přibývá. Naopak je velmi dobře použitelný tam, kde správce vytvoří pevnou instalaci a tu zafixuje pomocí elektronických podpisů.

IPE běží ve dvou režimech, podobně jako například SELinux: permissive a enforcing. První jmenovaný provádí všechny testy, ale politiku ve skutečnosti nevynucuje. Loguje ale její porušení, což umožňuje politiku ladit před jejím ostrým startem s dopadem na běh systému.

Zapnutí a ovládání modulu

Modul samotný je možné zapnout při kompilaci jádra pomocí volby  CONFIG_SECURITY_IPE. Výchozí stav je enforcing a je možné to změnit při startu pomocí jaderného parametru ipe.enforce=(0|1) nebo vlastnost přepnout za běhu se sysctl. Dodatečné přepínání režimů je možné zakázat v konfiguraci přepnutím volby CONFIG_SECURITY_IPE_PERMISSIVE_SWITCH na  N.

Pro ladění se hodí možnost logování úspěšných testů, což se zapíná pomocí vlastnosti  ipe.success_audit=(0|1). Samotné politiky se pak do jádra nahrávají pomocí securityfs a aktivují přes  sysfs.

Při startu systému je načítána úvodní minimální politika, která zajišťuje připravenost systému na základní start a případné budoucí načtení hlavní politiky. Pokud tato „bootovací politika“ neexistuje, modul zůstane neaktivní a nebude plnit svou činnost. Cestu k textovému souboru popisujícímu politiku je možné vložit do jaderné konfigurační volby  SECURITY_IPE_BOOT_POLICY.

Zavedení politiky

Politika je uložená v podobě textového souboru, který je zkompilován a načten jádrem. Soubor musí být předem podepsán a klíč musí odpovídat certifikátu uloženému v  SYSTEM_TRUSTED_KEYRING. Podepsání je možné provést pomocí standardní utility OpenSSL:

# openssl smime -sign -in "$MY_POLICY" -signer "$MY_CERTIFICATE" \
    -inkey "$MY_PRIVATE_KEY" -binary -outform der -noattr -nodetach \
    -out "$MY_POLICY.p7s"

Poté je podepsaný soubor jednoduše předán jádru pomocí securityfs:

# cat "$MY_POLICY.p7s" > /sys/kernel/security/ipe/new_policy

Pokud je politika správně načtena, objeví se v podadresáři policies/ pod svým názvem. Pak je možné ji aktivovat:

# sysctl ipe.active_policy="$MY_POLICY_NAME"

Politiku je také možné aktualizovat zvýšením její verze nebo ji vymazat z jádra. To lze ovšem jen za předpokladu, že nejde o bootovací politiku a že je v danou chvíli deaktivovaná.

# echo -n "$MY_POLICY_NAME" > /sys/kernel/security/ipe/del_policy

Příklady politik

Dokumentace uvádí několik příkladů jednoduchých politik, které pomohou pochopit konfigurační jazyk:

Povol vše:

policy_name="Allow All" policy_version=0.0.0
DEFAULT action=ALLOW

Povol pouze spouštění z inicializačního superbloku:

policy_name="Allow All Initial SB" policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE boot_verified=TRUE action=ALLOW

Povol jakýkoliv svazek podepsaný dm-verify a inicializační superblok:

policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW

Zabraň spuštění z konkrétního svazku dm-verify:

policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE dmverity_roothash=401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=DENY
op=EXECUTE boot_verified=TRUE action=ALLOW
op=EXECUTE dmverity_signature=TRUE action=ALLOW

Povol pouze vybraný svazek dm-verify:

policy_name="AllowSignedAndInitial" policy_version=0.0.0
DEFAULT action=DENY

op=EXECUTE dmverity_roothash=401fcec5944823ae12f62726e8184407a5fa9599783f030dec146938 action=ALLOW

Známé nedokonalosti IPE

Vývojáři sami zmiňují dvě situace, kdy tento přístup nebude fungovat. První je použití anonymní paměti se spustitelným kódem, což používají třeba překladače typu JIT. Neexistuje způsob, jak by jádro mohlo zasahovat do vnitřních pochodů jednotlivých procesů a zajistit bezpečnost získání dynamicky kompilovaného kódu. Je potřeba myslet na to, že takový kód není pomocí IPE pokryt.

Podobný problém nastává u interpretace skriptů volaných jako parametry za názvem interpretru. V takové situaci se ke skriptu jádro nechová jako ke spustitelnému souboru, ale jako k běžným datům. Není tedy vyvolán patřičný hook, který by umožnil validovat obsah načítaného skriptu. Tento problém, stejně jako problém načítání citlivých dat, chtějí vývojáři v budoucnu řešit pomocí úpravy interpretrů, které by aktivně soubor předaly k validaci.

bitcoin_skoleni

Vývojáři také chtějí v budoucnu přidat vlastní testy do KernelCI a plánují zvýšit odolnost celého modulu proti roll-back útokům. Prozatím totiž existuje teoretická možnost, že by útočník během zavádění mohl podstrčit jádru starší verzi politiky, která obsahovala nějakou bezpečnostní mezeru. Tomu je možné zabránit, pokud do jádra vložíme informaci o minimální verzi politiky, která může být akceptována. K tomu je ale dnes potřeba jádro upravit a restartovat. V budoucnu by mělo být možné tuto informaci nastavit za běhu.

Dokumentace ke studiu

Pokud vás zajímají další podrobnosti, doporučuji projít obsáhlou dokumentaci, ze které také vycházel tento článek.

Autor článku

Petr Krčmář pracuje jako šéfredaktor serveru Root.cz. Studoval počítače a média, takže je rozpolcen mezi dva obory. Snaží se dělat obojí, jak nejlépe umí.