
Bypass di ASLR senza infoleak
In questo articolo discuterò dell'applicazione della tecnica descritta da Samuel Groß nel suo Remote iPhone Exploitation Part 2: Bringing Light into the Darkness -- a Remote ASLR Bypass, per bypassare l'ASLR su Linux x86_64.
Per dimostrarlo, risolverò una sfida pwnable del Buckeye CTF, guess_god.
Cercherò di mantenere il contenuto il più possibile adatto ai principianti, quindi sentiti libero di saltare qualsiasi sezione se ti senti abbastanza sicuro e vuoi solo vedere l'exploit.

Non ho giocato alla CTF, ma la sfida mi ha interessato circa 2 ore prima della fine della CTF grazie a Guray00, che stava chiedendo aiuto nel discord di fibonhack su alcune stranezze crittografiche.
Non ho potuto aiutarlo, ma ho dato un'occhiata alle sfide pwnable e ho pensato che sarebbe stato utile capire il blogpost di P0 e magari ottenere quella bounty.
Address Space Layout Randomization (ASLR) è una tecnica di sicurezza informatica che prevede il posizionamento casuale dell'indirizzo di base di un eseguibile e della posizione di librerie, heap e stack, nello spazio degli indirizzi di un processo.
Su Linux, puoi ispezionare i mapping di un processo dato il suo pid tramite procfs, leggendo il file /proc/<pid>/maps.
Se sei un processo e vuoi conoscere i tuoi mapping di memoria, puoi leggere /proc/self/maps.
Ad esempio, puoi provare a leggere /proc/self/maps con cat:```
root@088ec31b2ce9:/home/ctf/challenge# cat /proc/self/maps
55faeb01c000-55faeb01e000 r--p 00000000 fe:01 2497233 /usr/bin/cat
55faeb01e000-55faeb023000 r-xp 00002000 fe:01 2497233 /usr/bin/cat
55faeb023000-55faeb026000 r--p 00007000 fe:01 2497233 /usr/bin/cat
55faeb026000-55faeb027000 r--p 00009000 fe:01 2497233 /usr/bin/cat
55faeb027000-55faeb028000 rw-p 0000a000 fe:01 2497233 /usr/bin/cat
55faeb115000-55faeb136000 rw-p 00000000 00:00 0 [heap]
7fe15dfb1000-7fe15dfd5000 rw-p 00000000 00:00 0
7fe15dfd5000-7fe15dffb000 r--p 00000000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15dffb000-7fe15e166000 r-xp 00026000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e166000-7fe15e1b2000 r--p 00191000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b2000-7fe15e1b5000 r--p 001dc000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b5000-7fe15e1b8000 rw-p 001df000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so
7fe15e1b8000-7fe15e1c3000 rw-p 00000000 00:00 0
7fe15e1c7000-7fe15e1c8000 r--p 00000000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1c8000-7fe15e1ef000 r-xp 00001000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1ef000-7fe15e1f9000 r--p 00028000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1f9000-7fe15e1fb000 r--p 00031000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fe15e1fb000-7fe15e1fd000 rw-p 00033000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so
7fff4388f000-7fff438b0000 rw-p 00000000 00:00 0 [stack]
7fff43989000-7fff4398d000 r--p 00000000 00:00 0 [vvar]
7fff4398d000-7fff4398f000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
root@088ec31b2ce9:/home/ctf/challenge# cat /proc/self/maps 55ffc0b1b000-55ffc0b1d000 r--p 00000000 fe:01 2497233 /usr/bin/cat 55ffc0b1d000-55ffc0b22000 r-xp 00002000 fe:01 2497233 /usr/bin/cat 55ffc0b22000-55ffc0b25000 r--p 00007000 fe:01 2497233 /usr/bin/cat 55ffc0b25000-55ffc0b26000 r--p 00009000 fe:01 2497233 /usr/bin/cat 55ffc0b26000-55ffc0b27000 rw-p 0000a000 fe:01 2497233 /usr/bin/cat 55ffc2108000-55ffc2129000 rw-p 00000000 00:00 0 [heap] 7f1ec6e0f000-7f1ec6e33000 rw-p 00000000 00:00 0 7f1ec6e33000-7f1ec6e59000 r--p 00000000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec6e59000-7f1ec6fc4000 r-xp 00026000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec6fc4000-7f1ec7010000 r--p 00191000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7010000-7f1ec7013000 r--p 001dc000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7013000-7f1ec7016000 rw-p 001df000 fe:01 2761561 /usr/lib/x86_64-linux-gnu/libc-2.33.so 7f1ec7016000-7f1ec7021000 rw-p 00000000 00:00 0 7f1ec7025000-7f1ec7026000 r--p 00000000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7026000-7f1ec704d000 r-xp 00001000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec704d000-7f1ec7057000 r--p 00028000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7057000-7f1ec7059000 r--p 00031000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7f1ec7059000-7f1ec705b000 rw-p 00033000 fe:01 2761539 /usr/lib/x86_64-linux-gnu/ld-2.33.so 7ffc72fa4000-7ffc72fc5000 rw-p 00000000 00:00 0 [stack] 7ffc72fe7000-7ffc72feb000 r--p 00000000 00:00 0 [vvar] 7ffc72feb000-7ffc72fed000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
### Pattern dei mapping di memoria
Se fai questo un paio di volte, puoi dedurre che:
* La base PIE del binario dovrebbe essere nell'intervallo 0x00005500_00000000-0x00005700_00000000, il che significa 2TB di indirizzi possibili.
* L'heap è vicino al binario.
* Le librerie rientrano nell'intervallo 0x00007f00_00000000 - 0x00007fff_ffffffff, 1TB di indirizzi possibili.
* Lo stack si colloca \(nella maggior parte dei casi\) nell'intervallo 0x00007ffc_00000000 - 0x00007fff_ffffffff, 16gb di indirizzi possibili.
* L'intervallo 0xffffffffff600000 - 0xffffffffff601000 è sempre mappato, puoi leggere [questo articolo](http://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/02/13/vsyscall-and-vdso) se sei curioso di sapere di cosa si tratta.
## 1.3 Come bypassare ASLR senza un infoleak
Discutiamo di cosa puoi fare per bypassare ASLR quando non è possibile alcun information leak.
Questo è il mio tentativo di riassumere ciò che ho ricavato leggendo il blogpost di Saelo.
Per bypassare ASLR ti serve:
* Una tecnica di memory spraying, che ti consente di mappare memoria contigua di una data dimensione, su un dato intervallo di indirizzi.
Come dice lui, ci sono due modi per farlo:
1. Abusando di un memory leak (non un information leak!), un bug in cui un blocco di memoria viene “dimenticato” e mai liberato, e innescandolo più volte finché la quantità di memoria desiderata è stata leakata.
2. Trovando e abusando di un “amplification gadget”: un pezzo di codice che prende un blocco di dati esistente e lo copia, potenzialmente più volte, consentendo quindi all'attaccante di sprayare una grande quantità di memoria inviando solo un numero relativamente piccolo di byte.
* Un oracolo `isAddressMapped`, che dato un indirizzo ti dice se quell'indirizzo è mappato o meno.