Cosa significa setresuid()
e setresgid()
fare?
Per comprendere meglio questo esempio, dobbiamo dare un'occhiata a queste due funzioni e ai tre parametri che accettano.
Da questa risposta (e dalla pagina man delle credenziali(7):
Su Linux, ogni processo ha i seguenti identificatori di utenti e gruppi:
ID utente reale e ID gruppo reale. Questi ID determinano chi possiede il processo. Per riassumere, questo è chi sei .
ID utente effettivo e ID gruppo effettivo. Questi ID vengono utilizzati dal kernel per determinare le autorizzazioni che il processo avrà quando accede a risorse condivise come code di messaggi, memoria condivisa e semafori. Sulla maggior parte dei sistemi UNIX, questi ID determinano anche le autorizzazioni per l'accesso ai file. Tuttavia, Linux utilizza gli ID del file system per questa attività. Per riassumere, questo è quello che puoi fare .
Set-user-ID salvato e set-group-ID salvato. Questi ID vengono utilizzati nei programmi set-user-ID e set-group-ID per salvare una copia degli ID effettivi corrispondenti impostati quando il programma è stato eseguito. Un programma set-user-ID può assumere e abbandonare i privilegi scambiando il proprio ID utente effettivo avanti e indietro tra i valori nel suo ID utente reale e l'ID set-utente salvato. Per riassumere, questo è quello che eri prima .
Inoltre, è importante comprendere il bit SetUID. Ciò che fa è eseguire un programma eseguibile con i diritti del proprietario, non di colui che lo chiama.
Un nightmare
di sicurezza
La tua domanda menziona specificamente quel nightmare
è di proprietà di root
e ha il SetUID-Bit impostato. Ciò significa che qualsiasi utente a cui è consentito eseguire nightmare
essenzialmente lo esegue come root
. Ciò significa che tutti i processi figli di nightmare
- come quelli generati quando si chiama system()
- vengono eseguiti anche come root
.
Ma davvero ora, cosa significa setresuid()
fare?
In tale contesto? Niente. Poiché l'utente sta già eseguendo cose come root
, non influisce in alcun modo sull'ulteriore sfruttamento.
Potresti usare /dev/tty
?
Questa domanda non ha molto senso in questo contesto. Devi guardare lo snippet di codice pertinente per vedere dove si trova la stringa /dev/tty
viene da.
if (open("/dev/tty", O_RDWR) != -1) {
fire();
rax = sub_4008d0();
}
Ciò significa che il programma sta tentando di aprire /dev/tty
per leggere e scrivere e se ciò riesce, chiama fire()
.
Denominando una funzione bash /dev/tty()
, non ottieni i risultati desiderati, come open()
richiede il percorso di un file come primo parametro. È completamente indipendente da bash
e non ha il concetto di funzioni bash.
Che ne dici di puts()
?
Allo stesso modo, questo non ha molto senso. strings
non è una magia e non capisce il contesto. Tutto ciò che fa è cercare una serie di byte che siano caratteri ASCII stampabili.
puts()
è solo una funzione C che emette una stringa.
Che ne dici di /usr/bin/aafire
?
Anche se non l'ho provato personalmente, sembra praticamente /usr/bin/aafire
avrebbe potuto essere usato al posto di /usr/bin/sl -al
. Se questo non è corretto, per favore commenta e modificherò questa parte.
Funzionerebbe ancora se venisse utilizzato un percorso relativo?
Sì, in realtà anche meglio! system()
chiama internamente sh -c
, che deve risolvere il $PATH
variabile per trovare sl
. Se la variabile del percorso è stata modificata per includere .
o qualsiasi altra directory scrivibile dall'utente con priorità superiore a /usr/bin
, quindi potrei semplicemente collegare simbolicamente ./sl
a /bin/bash
.
Ha importanza che tipo di binario/ELF è il file SUID radice?
Sì, perché il bit SetUID viene ignorato negli script di shell. Deve essere un eseguibile nativo.