GNU/Linux >> Znalost Linux >  >> Linux

Identifikujte vlastnosti zabezpečení v systému Linux pomocí checksec

Kompilací zdrojového kódu vznikne binární soubor. Během kompilace můžete kompilátoru poskytnout příznaky pro povolení nebo zakázání určitých vlastností binárního souboru. Některé z těchto vlastností jsou relevantní pro zabezpečení.

Checksec je šikovný malý nástroj (a skript shellu), který kromě jiných funkcí identifikuje vlastnosti zabezpečení, které byly zabudovány do binárního souboru při jeho kompilaci. Kompilátor může ve výchozím nastavení povolit některé z těchto vlastností a možná budete muset poskytnout specifické příznaky, abyste povolili ostatní.

Tento článek vysvětluje, jak použít checksec k identifikaci vlastností zabezpečení binárního souboru, včetně:

  1. Základní příkazy, které checksec používá k vyhledání informací o vlastnostech zabezpečení
  2. Jak povolit vlastnosti zabezpečení pomocí GNU Compiler Collection (GCC) při kompilaci ukázkového binárního souboru

Instalovat checksec

Chcete-li nainstalovat checksec na Fedoru a další systémy založené na RPM, použijte:

$ sudo dnf install checksec 

Pro distribuce založené na Debianu použijte ekvivalentní apt příkaz.

Skript prostředí

Checksec je jednosouborový shell skript, i když poměrně velký. Výhodou je, že si můžete skript rychle přečíst a porozumět všem spuštěným systémovým příkazům, abyste našli informace o binárních nebo spustitelných souborech:

$ soubor /usr/bin/checksec
/usr/bin/checksec:Shell skript Bourne-Again, spustitelný text ASCII, s velmi dlouhými řádky

$ wc -l /usr /bin/checksec
2111 /usr/bin/checksec

Proveďte checksec pro jednotku s binárním souborem, který pravděpodobně používáte denně:všudypřítomný ls příkaz. Formát příkazu je checksec --file= následuje absolutní cesta k ls binární:

 $ CheckSec --file =/ usr / bin / ls 
Relro zásobník symboly nx pie rath rathath symboly opevněné opevněné opevněné opevněné canary counters counters opevněný canary nalezeno nx enabled pie? 5       17              /usr/bin/ls

Když to spustíte v terminálu, uvidíte barevné kódování, které ukazuje, co je dobré a co pravděpodobně ne. Říkám „pravděpodobně“, protože i když je něco červeně, nemusí to nutně znamenat, že jsou věci hrozné – může to znamenat, že prodejci distribucí udělali určité kompromisy při kompilaci binárních souborů.

První řádek poskytuje různé vlastnosti zabezpečení, které jsou obvykle dostupné pro binární soubory, jako je RELRO , STACK CANARY , NX , a tak dále (podrobně vysvětluji níže). Druhý řádek zobrazuje stav těchto vlastností pro daný binární soubor (ls , v tomto případě). Například NX enabled znamená, že pro tento binární soubor je povolena nějaká vlastnost.

Ukázkový binární soubor

Pro tento tutoriál použiji následující program „hello world“ jako ukázkový binární soubor.

#include 

int main()
{
        printf("Hello World\n");
        return 0;
}

Všimněte si, že jsem neuvedl gcc se všemi dalšími příznaky během kompilace:

$ gcc hello.c -o hello
 
$ file hello
ahoj:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV), dynamicky propojený, interpret / lib64/ld-linux-x86-64.so.2, BuildID[sha1]=014b8966ba43e3ae47fab5acae051e208ec9074c, pro GNU/Linux 3.2.0, neodstraněno

$ ./Ahoj světe /před>

Spusťte binární soubor přes checksec. Některé vlastnosti jsou jiné než u ls příkaz výše (na vaší obrazovce se mohou zobrazit červeně):

 $ CheckSec --file =. / hello 
Relro stack Symboly NX Pie rath rathpath symboly opevněné opevněné opevněné opevněné řízený soubor
částečné relro žádné kanárky nalezeno nx enabled no pie no rath no rutpath 85) symboly č. 0 0./ahoj
$

Změna výstupního formátu

Checksec umožňuje různé výstupní formáty, které můžete určit pomocí --output . Vyberu si formát JSON a výstup nasměruji do jq nástroj pro pěkný tisk.

Chcete-li pokračovat, ujistěte se, že máte jq nainstalován, protože tento tutoriál používá tento výstupní formát k rychlému vyhledání konkrétních vlastností z výstupu a hlášení yes nebo no na každém:

$ checksec --file=./hello --output=json | jq
{
  "./hello":{
    "relro":"částečné",
    "kanár":"ne",
    "nx":" ano",
    "koláč":"ne",
    "rpath":"ne",
    "runpath":"no",
    "symboly":"ano" ,
    "fortify_source":"no",
    "fortified":"0",
    "fortify-able":"0"
  }
}

Procházení vlastnostmi zabezpečení

Více o zabezpečení

  • Průvodce obranným kódováním
  • Webinář:Automatizace zabezpečení systému a soulad se standardním operačním systémem
  • 10 vrstev zabezpečení kontejneru Linux
  • Omalovánky SELinux
  • Další články o zabezpečení

Výše uvedený binární soubor obsahuje několik bezpečnostních vlastností. Porovnám to binární s ls binární výše, abyste prozkoumali, co je povoleno, a vysvětlili, jak checksec tyto informace našel.

1. Symboly

Začnu nejprve tím jednodušším. Během kompilace jsou do binárního souboru zahrnuty určité symboly, většinou pro ladění. Tyto symboly jsou vyžadovány při vývoji softwaru a vyžadují několik cyklů pro ladění a opravy věcí.

Tyto symboly jsou obvykle odstraněny (odstraněny) z konečného binárního souboru předtím, než je uvolněn pro obecné použití. To nijak neovlivňuje provádění binárního souboru; poběží stejně jako se symboly. Odstraňování se často provádí za účelem úspory místa, protože binární kód je po odstranění symbolů poněkud světlejší. V uzavřeném zdrojovém nebo proprietárním softwaru jsou symboly často odstraněny, protože pokud jsou tyto symboly v binární podobě, je poněkud snadné odvodit vnitřní fungování softwaru.

Podle checksec jsou v tomto binárním souboru přítomny symboly, ale nebyly v ls binární. Tyto informace můžete také najít spuštěním file příkaz v programu – vidíte not stripped ve výstupu ke konci:

$ checksec --file=/bin/ls --output=json | jq | grep symbols
    "symbols":"no",

$ checksec --file=./hello --output=json | jq | grep symbols
    "symbols":"yes",

$ file ahoj
ahoj:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV), dynamicky propojený , interpret /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=014b8966ba43e3ae47fab5acae051e208ec9074c, pro GNU/Linux 3.2.0, neodstraněno

Jak checksec našel tyto informace? Poskytuje praktický --debug možnost zobrazit, které funkce byly spuštěny. Spuštění následujícího příkazu by vám proto mělo ukázat, které funkce byly spuštěny v rámci skriptu shellu:

$ checksec --debug --file=./hello 

V tomto tutoriálu hledám základní příkazy používané k nalezení těchto informací. Vzhledem k tomu, že se jedná o skript Shell, můžete vždy využít funkce Bash. Tento příkaz vypíše každý příkaz, který byl spuštěn ze skriptu shellu:

$ bash -x /usr/bin/checksec --file=./hello 

Pokud procházíte výstupem, měli byste vidět echo_message následuje kategorie bezpečnostní vlastnosti. Zde je to, co checksec hlásí o tom, zda binární soubor obsahuje symboly:

+ readelf -W --symbols ./hello
+ grep -q '\.symtab'
+ echo_message '\033[31m96) Symbols\t\033[m  ' Symboly, ' symboly ="yes"' '"symbols":"yes",'

Pro zjednodušení používá checksec readelf nástroj pro čtení binárního kódu a poskytuje speciální --symbols příznak, který uvádí všechny symboly v binárním systému. Poté hledá speciální hodnotu, .symtab , který poskytuje počet záznamů (symbolov), které najde. Můžete vyzkoušet následující příkazy na testovacím binárním souboru, který jste zkompilovali výše:

$ readelf -W --symbols ./ahoj
$ readelf -W --symbols ./hello | grep -i symtab

Jak odstranit symboly

Symboly můžete odstranit po kompilaci nebo během kompilace.

  • Kompilace příspěvku: Po kompilaci můžete použít strip nástroj na binární k odstranění symbolů. Pomocí file potvrďte, že to fungovalo příkaz, který nyní zobrazuje výstup jako stripped :
    $ gcc hello.c -o hello
    $
    $ file hello
    ahoj:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV) , dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=322037496cf6a2029dcdcf68649a4ebc63780138, pro GNU/Linux>$ 3.2.0, nezbaveno
    $ br />$
    $ soubor ahoj
    ahoj:ELF 64bitový LSB spustitelný soubor, x86-64, verze 1 (SYSV), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so .2, BuildID[sha1]=322037496cf6a2029dcdcf68649a4ebc63780138, pro GNU/Linux 3.2.0, zbaveno
    $

Jak odstranit symboly během kompilace

Místo ručního odstraňování symbolů po kompilaci můžete požádat kompilátor, aby to udělal za vás zadáním -s argument:

$ gcc -s ahoj.c -o ahoj
$
$ soubor ahoj
ahoj:ELF 64bitový spustitelný soubor LSB, x86-64, verze 1 (SYSV), dynamicky propojený , interpret /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=247de82a8ad84e7d8f20751ce79ea9e0cf4bd263, pro GNU/Linux 3.2.0, zbavený
$

Po opětovném spuštění checksec uvidíte, že symbols jsou zobrazeny jako no :

$ checksec --file=./hello --output=json | jq | grep symbols
    "symbols":"no",
$

2. Kanár

Canaries jsou známé hodnoty, které jsou umístěny mezi vyrovnávací pamětí a kontrolními daty v zásobníku ke sledování přetečení vyrovnávací paměti. Když se aplikace spustí, jsou jí přiřazeny dva druhy paměti. Jedním z nich je zásobník , což je jednoduše datová struktura se dvěma operacemi:push , který ukládá data do zásobníku, a pop , který odebírá data ze zásobníku v opačném pořadí. Škodlivý vstup by mohl přetéct nebo poškodit zásobník speciálně vytvořeným vstupem a způsobit selhání programu:

$ checksec --file=/bin/ls --output=json | jq | grep canary
    "canary":"ano",
$
$ checksec --file=./hello --output=json | jq | grep canary
    "canary":"ne",
$

Jak checksec zjistí, zda je binární soubor povolen s kanárkem? Pomocí výše uvedené metody jej můžete zúžit spuštěním následujícího příkazu v rámci skriptu shellu:

$ readelf -W -s ./hello | grep -E '__stack_chk_fail|__intel_security_cookie' 

Povolit canary

K ochraně před těmito případy kompilátor poskytuje -stack-protector-all příznak, který přidá do binárního souboru další kód pro kontrolu takového přetečení vyrovnávací paměti:

$ gcc -fstack-protector-all hello.c -o hello

$ checksec --file=./hello --output=json | jq | grep canary
    "canary":"ano",

Checksec ukazuje, že vlastnost je nyní povolena. Můžete to také ověřit pomocí:

$ readelf -W -s ./ahoj | grep -e '__stack_chk_fail | __intel_security_ChOokie' 
2:0000000000000000 0 func globální default und __stack_chk_fail@glubc_2.4 (3)
83:000000000000000000 0
83:000000000000000000 0
83:000000000000000000 0
Func Global Default und __stack_chk_fail @@ glibc_2.4
$

3. KORÁČ

PIE znamená spustitelný soubor nezávislý na pozici. Jak název napovídá, je to kód, který je umístěn někde v paměti pro provedení bez ohledu na jeho absolutní adresu:

$ checksec --file=/bin/ls --output=json | jq | grep pie
    "koláč":"ano",

$ checksec --file=./hello --output=json | jq | grep pie
    "koláč":"ne",

PIE je často povolen pouze pro knihovny a nikoli pro samostatné programy příkazového řádku. Ve výstupu níže hello je zobrazen jako LSB executable , zatímco libc standardní knihovna (.so ) je soubor označen jako LSB shared object :

$ file ahoj
ahoj:ELF 64-bit LSB spustitelný, x86-64, verze 1 (SYSV), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, BuildID[ sha1]=014b8966ba43e3ae47fab5acae051e208ec9074c, pro GNU/Linux 3.2.0, neodstraněno

$ soubor /lib64/libc-2.32.so
/lib64/libc-6bit-2.3 LSB sdílený objekt, x86-64, verze 1 (GNU/Linux), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=4a7fb374097fb927fb93d35ef98ba89262,x0c4 nesvlečené

Checksec se pokusí najít tyto informace pomocí:

$ readelf -W -h ./ahoj | grep EXEC
  Typ:                             EXEC (spustitelný soubor)

Pokud místo EXEC zkusíte stejný příkaz na sdílené knihovně , uvidíte DYN :

$ readelf -W -h /lib64/libc-2.32.so | grep DYN
  Typ:                             DYN (soubor sdíleného objektu)

Povolit PIE

Chcete-li povolit PIE v testovacím programu, pošlete kompilátoru následující argumenty:

$ gcc -pie -fpie hello.c -o hello 

Aktivaci PIE můžete ověřit pomocí checksec:

$ checksec --file=./hello --output=json | jq | grep pie
    "koláč":"ano",
$

Měl by se zobrazit jako spustitelný soubor PIE s typem změněným z EXEC na DYN :

$ file ahoj
ahoj:spustitelný ELF 64bitový LSB koláč, x86-64, verze 1 (SYSV), dynamicky propojený, interpret /lib64/ld-linux-x86-64.so.2, BuildID [sha1]=bb039adf2530d97e02f534a94f0f668cd540f940, pro GNU/Linux 3.2.0, neodstraněno

$ readelf -W -h ./ahoj | grep DYN
  Typ:                             DYN (soubor sdíleného objektu)

4. NX

NX je zkratka pro "non-executable." Často je povoleno na úrovni CPU, takže operační systém s povoleným NX může označit určité oblasti paměti jako nespustitelné. Využití přetečení vyrovnávací paměti často umístí kód do zásobníku a poté se jej pokusí spustit. Pokud však tuto zapisovatelnou oblast změníte na nespustitelnou, můžete takovým útokům zabránit. Tato vlastnost je standardně povolena během běžné kompilace pomocí gcc :

$ checksec --file=/bin/ls --output=json | jq | grep nx
    "nx":"ano",

$ checksec --file=./hello --output=json | jq | grep nx
    "nx":"ano",

Checksec určuje tyto informace pomocí příkazu níže. RW směrem ke konci znamená, že zásobník je čitelný a zapisovatelný; protože tam není E , není spustitelný:

$ readelf -W -l ./ahoj | grep GNU_STACK
  GNU_STACK      0x000000 0x0000000000000000 0x000000000000000 0x000000 0x000000 RW  0x10

Zakázat NX pro účely ukázky

Nedoporučuje se to, ale můžete zakázat NX při kompilaci programu pomocí -z execstack argument:

$ gcc -z execstack hello.c -o hello

$ checksec --file=./hello --output=json | jq | grep nx
    "nx":"ne",

Po kompilaci se zásobník stane spustitelným (RWE ), který umožňuje spuštění škodlivého kódu:

$ readelf -W -l ./ahoj | grep GNU_STACK
  GNU_STACK      0x000000 0x0000000000000000 0x000000000000000 0x000000 0x000000 RWE 0x10

5. RELRO

RELRO znamená Relocation Read-Only. Binární soubor ELF (Executable Linkable Format) používá k dynamickému řešení funkcí globální tabulku posunu (GOT). Je-li tato vlastnost povolena, způsobí, že GOT je v binárním systému pouze pro čtení, což zabraňuje některým formám útoků na přemístění:

$ checksec --file=/bin/ls --output=json | jq | grep relro
    "relro":"plné",

$ checksec --file=./hello --output=json | jq | grep relro
    "relro":"částečné",

Checksec najde tyto informace pomocí příkazu níže. Zde je povolena jedna z vlastností RELRO; proto binární soubor ukazuje "částečný" při ověřování pomocí checksec:

$ readelf -W -l ./ahoj | grep GNU_RELRO
  GNU_RELRO      0x002e10 0x0000000000403e10 0x0000000000403e10 0x0001f0 0x0001f0 Wlo - d. /e$ 0x1f0 R 0 /e$ 0x1lf grep BIND_NOW

Povolit úplné RELRO

Chcete-li povolit plné RELRO, použijte při kompilaci pomocí gcc následující argumenty příkazového řádku :

$ gcc -Wl,-z,relro,-z,nyní ahoj.c -o ahoj

$ checksec --file=./hello --output=json | jq | grep relro
    "relro":"plné",

Nyní je také povolena druhá vlastnost, takže program je plný RELRO:

$ readelf -W -l ./ahoj | grep GNU_RELRO
  GNU_RELRO      0x002dd0 0x0000000000403dd0 0x0000000000403dd0 0x000230 0x000230 0x000230 0x000230 Wlo - d$ čteno - 0 /hel - hel grep BIND_NOW
 0x0000000000000018 (BIND_NOW)          

6. Opevnit

Fortify je další bezpečnostní vlastnost, ale je mimo rozsah tohoto článku. Nechám se učit, jak checksec ověřuje fortify v binárních souborech a jak je povoleno pomocí gcc jako cvičení, které musíte řešit.

$ checksec --file=/bin/ls --output=json | jq  | grep -i forti
    "fortify_source":"yes",
    "fortified":"5",
    "fortify-able":"17"

$ checksec --file=./hello --output=json | jq  | grep -i forti
    "fortify_source":"no",
    "fortified":"0",
    "fortify-able":"0"

Další funkce checksec

Téma bezpečnosti je nekonečné, a i když zde není možné pokrýt vše, chci se zmínit o několika dalších funkcích checksec příkaz, se kterým je radost pracovat.

Spustit proti více binárním souborům

Nemusíte poskytovat každý binární soubor pro checksec jednotlivě. Místo toho můžete zadat cestu k adresáři, kde je uloženo několik binárních souborů, a checksec je všechny najednou ověří:

$ checksec --dir=/usr/bin 

Procesy

Kromě binárních souborů funguje checksec také na programy během provádění. Následující příkaz najde vlastnosti zabezpečení všech spuštěných programů ve vašem systému. Můžete použít --proc-all pokud chcete, aby kontroloval všechny běžící procesy, nebo můžete vybrat konkrétní proces pomocí jeho názvu:

$ checksec --proc-all

$ checksec --proc=bash

Vlastnosti jádra

Kromě uživatelských aplikací checksec popsaných v tomto článku jej můžete použít také ke kontrole vlastností jádra zabudovaného do vašeho systému:

$ checksec --kernel 

Vyzkoušejte to

Checksec je dobrý způsob, jak pochopit, jaké vlastnosti uživatelské země a jádra jsou povoleny. Projděte si podrobně každou vlastnost zabezpečení a snažte se porozumět důvodům povolení jednotlivých funkcí a druhům útoků, kterým brání.


Linux
  1. Ladění Linuxu pomocí ProcDump

  2. 13 kurzů zabezpečení Linuxu

  3. IPC využívající signály na linuxu

  1. Použití příkazu ripgrep (rg) v Linuxu

  2. 50 Výukové programy Sysadmin pro UNIX / Linux

  3. Kali Linux na Androidu pomocí Linux Deploy

  1. Příklady použití příkazu dmsetup v Linuxu

  2. Příklad použití getnstimeofday v jádře Linuxu

  3. Přesuňte složku v Linuxu pomocí příkazu mv