Co dělá setresuid()
a setresgid()
dělat?
Abychom tomuto příkladu lépe porozuměli, musíme se podívat na tyto dvě funkce a tři parametry, které mají.
Z této odpovědi (a manuálové stránky pověření(7)):
V systému Linux má každý proces následující identifikátory uživatele a skupiny:
Skutečné ID uživatele a ID skutečné skupiny. Tato ID určují, kdo je vlastníkem procesu. Abych to shrnula, toto je kdo jste .
Efektivní ID uživatele a efektivní ID skupiny. Tato ID používá jádro k určení oprávnění, která bude mít proces při přístupu ke sdíleným prostředkům, jako jsou fronty zpráv, sdílená paměť a semafory. Na většině systémů UNIX určují tato ID také oprávnění při přístupu k souborům. Linux však pro tento úkol používá ID systému souborů. Abych to shrnul, to můžete udělat .
Uloženo set-user-ID a uložené set-group-ID. Tato ID se používají v programech set-user-ID a set-group-ID k uložení kopie odpovídajících efektivních ID, která byla nastavena při spuštění programu. Program set-user-ID může převzít a zrušit oprávnění přepínáním jeho efektivního uživatelského ID tam a zpět mezi hodnotami v jeho skutečném uživatelském ID a uloženým set-user-ID. Stručně řečeno, toto je kým jste byli dříve .
Dále je důležité porozumět SetUID-Bit. To znamená, že spouští spustitelný program s právy vlastníka, nikoli toho, kdo jej volá.
Zabezpečení nightmare
Vaše otázka konkrétně zmiňuje, že nightmare
je ve vlastnictví root
a má nastaven SetUID-Bit. To znamená, že každý uživatel, který má povoleno spouštět nightmare
v podstatě jej provede jako root
. To znamená, že všechny podřízené procesy nightmare
- jako jsou vytvářeny při volání system()
- jsou také spuštěny jako root
.
Ale teď opravdu, co dělá setresuid()
dělat?
V tomto kontextu? Nic. Protože uživatel již provádí věci jako root
, nijak to neovlivňuje další využití.
Mohli byste použít /dev/tty
?
Tato otázka v tomto kontextu nedává příliš smysl. Musíte se podívat na příslušný fragment kódu, abyste viděli, kde je řetězec /dev/tty
pochází z.
if (open("/dev/tty", O_RDWR) != -1) {
fire();
rax = sub_4008d0();
}
To znamená, že se program pokouší otevřít /dev/tty
pro čtení a zápis a pokud to uspěje, zavolá fire()
.
Pojmenováním funkce bash /dev/tty()
, nezískáte požadované výsledky, jako open()
vyžaduje jako první parametr cestu k souboru. Je zcela nezávislý na bash
a nemá žádnou koncepci bashových funkcí.
A co puts()
?
Podobně to nedává moc smysl. strings
není kouzlo a nerozumí kontextu. Jediné, co dělá, je hledat řadu bajtů, které jsou tisknutelné znaky ASCII.
puts()
je pouze C-funkce, která vydává řetězec.
A co /usr/bin/aafire
?
I když jsem to osobně nezkoušel, zdá se, že prakticky /usr/bin/aafire
mohl být použit místo /usr/bin/sl -al
. Pokud to není správné, napište komentář a já tuto část upravím.
Fungovalo by to stále, kdyby se použila relativní cesta?
Ano, vlastně ještě lepší! system()
interně volá sh -c
, který musí vyřešit $PATH
proměnnou najít sl
. Pokud byla proměnná cesty upravena tak, aby zahrnovala .
nebo jakýkoli jiný uživatelsky zapisovatelný adresář s vyšší prioritou než /usr/bin
, pak bych mohl jen symbolicky propojit ./sl
na /bin/bash
.
Záleží na tom, jaký druh binárního/ELF je kořenový soubor SUID?
Ano, protože SetUID-Bit je ve skriptech shellu ignorován. Musí to být nativní spustitelný soubor.