La tua comprensione di setuid è corretta. Quando si esegue un programma che ha il bit suid, il processo eredita le autorizzazioni del proprietario del programma. Il pezzo di conoscenza che ti manca è ciò che fa la shell dopo che è stata invocata. Molte implementazioni popolari dei privilegi di sh drop all'avvio: reimpostano il loro UID effettivo al loro UID reale. Questo include bash, dash, mksh e BusyBox sh, quindi su Linux non vedrai nient'altro.
Quando il programma esegue una shell (ad esempio chiamando la funzione system
dalla libreria C standard o un equivalente in un'altra lingua), la shell inizia con privilegi elevati ma passa ai privilegi ordinari prima di eseguire qualsiasi codice utente. Questo mitiga gli exploit nei programmi setuid in cui l'utente malintenzionato può eseguire solo un comando shell che non era destinato all'esecuzione con privilegi elevati (ad esempio perché il comando della shell era nascosto nel codice della libreria di cui il programmatore dell'applicazione non era a conoscenza).
Questo non attenua gli exploit in cui l'autore dell'attacco può eseguire codice arbitrario. È solo che per ottenere una shell, devi lavorare un po 'più difficile di chiamare system
. Disporre di chiamare un interprete diverso, ad es. Esegui execve("/usr/bin/perl", "/usr/bin/perl")
(forchetta prima se non vuoi terminare il programma padre).