
# Progetto CMPT733 Cybersecurity Lab II: Plugin GDB per exploit heap ispirato a CVE-2021-3156

Progetto CMPT733 Cybersecurity Lab II
.
├── README.md
├── heaplens.png
├── heaplens.py
├── logs
│ ├── sudoedit-#.txt
│ └── ...
└── tests
├── Makefile
├── env-in-heap
└── ...
README.md: proprio qui!heaplens.py: lo script principalelogs/: contiene alcuni log di esempio catturati durante lo sviluppo e i testtests/: contiene alcuni binari (e i loro codici sorgente) per i testEcco un elenco di cose (e versioni) che abbiamo usato per testare l'exploit. Dovrebbero essere già installate nella VM. Nel caso manchi qualcosa, segui le istruzioni qui sotto.
python 3.8.10glibc 2.34gdb 9.2gef 2022.01
gef non è abilitato come root, dai un'occhiata a /root/.gdbinit~/.gdbinitsudo (per eseguire heaplens su sudo)È richiesto un binario di sudo con il debug abilitato. Un binario precompilato con simboli di debug è già stato installato nella VM.
cyberlab@ubuntu:~$ which sudo
/usr/local/bin/sudo
cyberlab@ubuntu:~$ sudo --version
Sudo version 1.8.31
Sudoers policy plugin version 1.8.31
Sudoers file grammar version 46
Sudoers I/O plugin version 1.8.31
cyberlab@ubuntu:~$ sudoedit -s /
sudoedit: /: not a regular file # sudo è vulnerabile
Questo è già stato fatto nella VM. Nel caso la configurazione sia errata, puoi seguire le istruzioni qui per caricare Heaplens.
Avvia gef e modifica la configurazione:
gef➤ gef config gef.extra_plugins_dir <percorso di>/heaplens
gef➤ gef save
gef➤ q
Questo dovrebbe aggiornare il file ~/.gef.rc o /root/.gef.rc (come root).
Aggiungi questa riga in ~/.gdbinit o /root/.gdbinit:
source <percorso di>/heaplens/heaplens.py
Si consiglia di eseguire gdb come root quando si esegue il debug di programmi privilegiati:
$ sudo su
# gdb
I messaggi di aiuto sono forniti per tutti i comandi. Puoi accedervi tramite <comando> -h in GDB.
heaplensRaccoglie informazioni sull'heap dalle funzioni di allocazione e deallocazione della memoria, incluse malloc, realloc, calloc e free.
L'idea di alto livello è che agganciando queste funzioni, possiamo automatizzare il processo di controllo e aggiornamento dello stack di chiamate e dell'indirizzo di ritorno dell'allocazione di memoria. Ispezionando le tracce, possiamo vedere quale chunk viene allocato da foo() in alcuni file C, e possiamo indagare ulteriormente, ad esempio controllando i chunk adiacenti, per trovare obiettivi adatti per lo sfruttamento dell'heap.
Supporta anche l'aggiunta di breakpoint personalizzati in mezzo se l'utente è interessato a un layout intermedio dell'heap.
Il comando in sé non è molto verboso e dovrai usare heaplens-dump per stampare i risultati.
heaplens -h
usage: [-h] [-b BREAKPOINT] [-v]
Collect heap info from memory (de)allocation functions.
optional arguments:
-h, --help show this help message and exit
-b BREAKPOINT, --breakpoint BREAKPOINT
stop the executions here (execute br {breakpoint} in gdb) (default: None)
-v, --verbose increase output verbosity (default: False)
Esempio di output:
gef➤ file sudoedit
gef➤ heaplens -b set_cmnd -- -s '\\' $(python3 -c 'print("A"*65535)')
----------------------------
Initializing Heaplens
----------------------------
Temporary breakpoint 1 at 0x5840: file ../../src/src/sudo.c, line 136.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
usage: sudoedit [-AknS] [-C num] [-g group] [-h host] [-p prompt] [-T timeout] [-u user] file ...
[Inferior 1 (process 82934) exited with code 01]
Setting breakpoint at set_cmnd...
Function "set_cmnd" not defined.
Breakpoint 2 (set_cmnd) pending.
Hooking free function...
Breakpoint 3 at 0x7f25cc163700: free. (2 locations)
Hooking malloc function...
Breakpoint 4 at 0x7f25cc163110: malloc. (2 locations)
Hooking realloc function...
Breakpoint 5 at 0x7f25cc163eb0: realloc. (2 locations)
Hooking calloc function...
Breakpoint 6 at 0x7f25cc164b40: calloc. (2 locations)
Running -s '\' $(python3 -c 'print("A"*65535)')...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 2, set_cmnd () at ../../../src/plugins/sudoers/sudoers.c:804
804 ../../../src/plugins/sudoers/sudoers.c: No such file or directory.
Removing breakpoints from mem_bkps...
heaplens-dumpScarica i log di Heaplens. Forniamo opzioni per scrivere i risultati su un file, output in formato JSON e ordinamento dei chunk per i loro indirizzi. Nel dump, ogni chunk avrà il suo indirizzo, dimensione, backtrace e la relativa funzione di allocazione della memoria registrati in modo più leggibile.
heaplens-dump -h
usage: [-h] [-o OUTPUT] [--json] [-s]
Dump Heaplens logs. Writes to stdout by default.
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
write to file at path {output} (default: None)
--json dump in json (default: False)
-s, --sort sort the chunks by their addresses (default: False)
Esempio di output:
gef➤ heaplens-dump
----------------------------
Dumping...
----------------------------
...
[malloc] Chunk 3 @ 0x55f3908ed2a0 | size 0xc
Trace:
#0 __GI___strdup (s=0x7fff6fb3b8dc "en_US.UTF-8") at strdup.c:44
#1 0x00007f285df363c5 in _nl_load_locale_from_archive (category=category@entry=0xc, namep=namep@entry=0x7fff6fb29f50) at loadarchive.c:464
#2 0x00007f285df351fe in _nl_find_locale (locale_path=0x0, locale_path_len=0x0, category=category@entry=0xc, name=name@entry=0x7fff6fb29f50) at findlocale.c:152
#3 0x00007f285df34925 in __GI_setlocale (locale=<optimized out>, category=<optimized out>) at setlocale.c:337
#4 __GI_setlocale (category=<optimized out>, locale=<optimized out>) at setlocale.c:217
#5 0x000055f3901d5965 in main (argc=0x4, argv=0x7fff6fb2a298, envp=0x7fff6fb2a2c0) at ../../src/src/sudo.c:1430
...
Dump complete.
heaplens-chunksOutput di una versione leggermente modificata di heap chunks di gef.
Questo estende heap chunks di GEF (che mostra indirizzi, flag, dimensioni e metadati dei chunk) integrando informazioni sui chunk liberi da heap bins (che elenca i chunk precedentemente allocati e liberati dai bin di glibc). GEF fornisce funzionalità che aiutano l'ispezione dell'heap come le due menzionate, ma è noioso combinarle. Ad alto livello, questo comando raccoglie gli indirizzi dei chunk liberi dal secondo e li etichetta nel risultato del primo.
heaplens-chunks -h
usage: [-h] [--nocolor]
A modified `heap chunks` with info about free chunks.
optional arguments:
-h, --help show this help message and exit
--nocolor disable ANSI color codes
Esempio di output:
gef➤ heaplens-chunks
Showing current heap info with freed chunks:
...
Chunk(addr=0x55dd7f91ddb0, size=0xed0, flags=PREV_INUSE) ← free chunk
[0x000055dd7f91ddb0 e0 fb ba e1 f8 7f 00 00 e0 fb ba e1 f8 7f 00 00 ...............]
Chunk(addr=0x55dd7f91ec80, size=0x50, flags=! PREV_INUSE)
[0x000055dd7f91ec80 2f 75 73 72 2f 6c 6f 63 61 6c 2f 73 62 69 6e 3a /usr/local/sbin]
Chunk(addr=0x55dd7f91ecd0, size=0x4010, flags=PREV_INUSE) ← free chunk
[0x000055dd7f91ecd0 f0 02 bb e1 f8 7f 00 00 f0 02 bb e1 f8 7f 00 00 ...............]
Chunk(addr=0x55dd7f922ce0, size=0x50, flags=! PREV_INUSE)
[0x000055dd7f922ce0 90 02 91 7f dd 55 00 00 00 00 00 00 00 00 00 00 .....U.........]
Chunk(addr=0x55dd7f922d30, size=0x2da0, flags=PREV_INUSE) ← free chunk
[0x000055dd7f922d30 d0 02 bb e1 f8 7f 00 00 d0 02 bb e1 f8 7f 00 00 ...............]
Chunk(addr=0x55dd7f925ad0, size=0x110, flags=! PREV_INUSE) ← free chunk
[0x000055dd7f925ad0 00 00 00 00 00 00 00 00 10 f0 90 7f dd 55 00 00 .............U.]
Chunk(addr=0x55dd7f925be0, size=0x30, flags=PREV_INUSE)
[0x000055dd7f925be0 00 00 00 00 00 00 00 00 d2 78 b7 7e dd 55 00 00 .........x.~.U.]
Chunk(addr=0x55dd7f925c10, size=0x20, flags=PREV_INUSE)
[0x000055dd7f925c10 65 6e 5f 55 53 2e 55 54 46 2d 38 00 00 00 00 00 en_US.UTF-8....]
Chunk(addr=0x55dd7f925c30, size=0xa3e0, flags=PREV_INUSE) ← top chunk
heaplens-clearCancella tutti i log / dati interni raccolti e usati da heaplens.
heaplens-clear -h
usage: [-h] [-v]
Clear Heaplens logs.
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
heaplens-list-envElenca le variabili d'ambiente che sono memorizzate e liberate nell'heap. È particolarmente utile quando vuoi eseguire il heap grooming poiché queste variabili potrebbero influenzare il layout dell'heap.
heaplens-list-env -h
usage: [-h] [-v] [--prefix PREFIX] [--suffix SUFFIX] [-b BREAKPOINT] [-s SKIP]
List environment variables that might affect the heap layout.
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
--prefix PREFIX environment variable value prefix
--suffix SUFFIX environment variable value suffix
-b BREAKPOINT, --breakpoint BREAKPOINT
stop the executions here (execute br {breakpoint} in gdb)
-s SKIP, --skip SKIP skip this environment variable
Esempio di output:
gef➤ file sudoedit
Reading symbols from sudoedit...
gef➤ heaplens-list-env -s LC_ALL -b set_cmnd --prefix C.UTF-8@ -- -s \\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
...
1st execution. Found following environment variable:
['LOCPATH', 'LC_ALL', 'LC_IDENTIFICATION', 'LANG', 'LC_MEASUREMENT', 'LC_TELEPHONE', 'LC_ADDRESS', 'LC_NAME', 'LC_PAPER', 'LC_MESSAGES', 'LC_MONETARY', 'LC_COLLATE', 'LC_TIME', 'LC_NUMERIC', 'LC_CTYPE', 'TZ', 'SHELL', 'LANGUAGE']
...
2nd execution. Possible environment variables for heap grooming:
['LC_IDENTIFICATION', 'LC_COLLATE', 'TZ', 'LC_TIME', 'LANGUAGE', 'LC_NAME', 'LOCPATH', 'LC_MESSAGES', 'LC_NUMERIC', 'LC_ADDRESS', 'LC_TELEPHONE', 'LC_MONETARY', 'LC_MEASUREMENT', 'LC_CTYPE', 'LC_PAPER']
Per compilare gli script dei casi di test (già compilati nella VM)
$ cd tests
$ make all
tests/heap-dumpgef➤ file tests/heap-dump
gef➤ heaplens -b breakme
gef➤ heaplens-dump
sudoedit in output.txtgef➤ file sudoedit
gef➤ heaplens -b set_cmnd -- -s \\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
gef➤ heaplens-dump -o output.txt
tests/env-in-heapgef➤ file tests/env-in-heap
gef➤ heaplens-list-env
...
----------------------------
2nd execution. Possible environment variables for heap grooming:
['ENV_IN_HEAP']
----------------------------
sudoeditgef➤ file sudoedit
gef➤ heaplens-list-env -s LC_ALL -b set_cmnd --prefix C.UTF-8@ -- -s \\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
...
----------------------------
1st execution. Found following environment variable:
['LOCPATH', 'LC_ALL', 'LC_IDENTIFICATION', 'LANG', 'LC_MEASUREMENT', 'LC_TELEPHONE', 'LC_ADDRESS', 'LC_NAME', 'LC_PAPER', 'LC_MESSAGES', 'LC_MONETARY', 'LC_COLLATE', 'LC_TIME', 'LC_NUMERIC', 'LC_CTYPE', 'TZ', 'SHELL', 'LANGUAGE']
----------------------------
...
----------------------------
2nd execution. Possible environment variables for heap grooming:
['LC_CTYPE', 'LC_PAPER', 'LC_MONETARY', 'TZ', 'LC_ADDRESS', 'LC_MEASUREMENT', 'LC_IDENTIFICATION', 'LC_COLLATE', 'LC_NUMERIC', 'LC_MESSAGES', 'LC_TIME', 'LANGUAGE', 'LC_NAME', 'LOCPATH', 'LC_TELEPHONE']
----------------------------
Fai riferimento alla pagina Issues per maggiori dettagli.