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.