V bash je zjevně zranitelnost (CVE-2014-6271):Bash speciálně vytvořený útok vkládání kódu proměnných prostředí
Snažím se přijít na to, co se děje, ale nejsem si úplně jistý, jestli tomu rozumím. Jak může echo
být proveden tak, jak je v jednoduchých uvozovkách?
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
vulnerable
this is a test
UPRAVIT 1 :Opravený systém vypadá takto:
$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test
ÚPRAVA 2 :Existuje související chyba zabezpečení / oprava:CVE-2014-7169, která používá mírně odlišný test:
$ env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"
neopravený výstup :
vulnerable
bash: BASH_FUNC_x(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_x(): line 0: `BASH_FUNC_x() () { :;}; echo vulnerable'
bash: error importing function definition for `BASH_FUNC_x'
test
částečně (časná verze) opravený výstup :
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
bash: error importing function definition for `BASH_FUNC_x()'
test
opravený výstup do a včetně CVE-2014-7169:
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `BASH_FUNC_x'
test
ÚPRAVA 3 :příběh pokračuje:
- CVE-2014-7186
- CVE-2014-7187
- CVE-2014-6277
Přijatá odpověď:
bash ukládá exportované definice funkcí jako proměnné prostředí. Exportované funkce vypadají takto:
$ foo() { bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() { bar
}
Tedy proměnná prostředí foo
má doslovný obsah:
() { bar
}
Když se spustí nová instance bash, hledá tyto speciálně vytvořené proměnné prostředí a interpretuje je jako definice funkcí. Můžete si dokonce jeden napsat sami a uvidíte, že to stále funguje:
$ export foo='() { echo "Inside function"; }'
$ bash -c 'foo'
Inside function
Bohužel, analýza definic funkcí z řetězců (proměnných prostředí) může mít širší účinky, než bylo zamýšleno. V neopravených verzích také interpretuje libovolné příkazy, které nastanou po ukončení definice funkce. To je způsobeno nedostatečnými omezeními při určování přijatelných funkčních řetězců v prostředí. Například:
$ export foo='() { echo "Inside function" ; }; echo "Executed echo"'
$ bash -c 'foo'
Executed echo
Inside function
Všimněte si, že echo mimo definici funkce bylo neočekávaně spuštěno během spouštění bash. Definice funkce je jen krůček k vyhodnocení a využití, samotná definice funkce a použitá proměnná prostředí jsou libovolné. Shell se dívá na proměnné prostředí, vidí foo
, který vypadá, že splňuje omezení, která ví o tom, jak vypadá definice funkce, a vyhodnotí řádek a neúmyslně také provede echo (což může být jakýkoli příkaz, škodlivý nebo ne).
To je považováno za nejisté, protože proměnné obvykle nejsou povoleny ani se neočekává, že by samy o sobě přímo způsobily vyvolání libovolného kódu v nich obsaženého. Možná váš program nastavuje proměnné prostředí z nedůvěryhodného uživatelského vstupu. Bylo by velmi neočekávané, že by s těmito proměnnými prostředí bylo možné manipulovat takovým způsobem, že by uživatel mohl spouštět libovolné příkazy bez vašeho explicitního záměru tak učinit pomocí dané proměnné prostředí z důvodu uvedeného v kódu.
Zde je příklad životaschopného útoku. Spouštíte webový server, který někde v rámci své životnosti provozuje zranitelný shell. Tento webový server předává proměnné prostředí bash skriptu, například pokud používáte CGI, jsou informace o požadavku HTTP často zahrnuty jako proměnné prostředí z webového serveru. Například HTTP_USER_AGENT
může být nastaveno na obsah vašeho uživatelského agenta. To znamená, že pokud podvrhnete svého uživatelského agenta, aby byl něco jako „() { :; }; echo foo’, když se tento skript spustí, echo foo
bude popraven. Opět echo foo
může být cokoli, škodlivé nebo ne.