
ASLR bypass sem infoleak
Neste artigo, vou discutir a aplicação da técnica descrita por Samuel Groß em sua Remote iPhone Exploitation Part 2: Bringing Light into the Darkness -- a Remote ASLR Bypass, para contornar o ASLR no Linux x86_64.
Para demonstrar isso, vou resolver um desafio pwnable do Buckeye CTF, o guess_god.
Vou tentar manter o conteúdo o mais amigável possível para iniciantes, então fique à vontade para pular qualquer seção se você se sentir confiante e quiser apenas ver o exploit.

Eu não joguei o CTF, mas me interessei pelo desafio cerca de 2 horas antes do fim do CTF graças ao Guray00, que estava pedindo ajuda no discord do fibonhack sobre algumas artimanhas de criptografia.
Não consegui ajudá-lo, mas dei uma olhada nos desafios pwnable e pensei que seria bom entender o post do blog da P0 e, quem sabe, conseguir aquela recompensa.
Randomização do Layout do Espaço de Endereço (ASLR) é uma técnica de segurança de computadores que envolve posicionar aleatoriamente o endereço base de um executável e a posição das bibliotecas, heap e stack, no espaço de endereço de um processo.
No Linux, você pode inspecionar os mapeamentos de um processo dado o seu pid através do procfs, lendo o arquivo /proc/<pid>/maps.
Se você é um processo e quer conhecer seus próprios mapeamentos de memória, pode ler /proc/self/maps.
Por exemplo, você pode tentar ler /proc/self/maps com 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]
### Padrões de mapeamentos de memória
Se você fizer isso algumas vezes, poderá deduzir que:
* A base PIE do binário deve estar no intervalo 0x00005500_00000000-0x00005700_00000000, o que significa 2TB de endereços possíveis.
* O heap fica próximo ao binário.
* As bibliotecas ficam no intervalo 0x00007f00_00000000 - 0x00007fff_ffffffff, 1TB de endereços possíveis.
* A pilha fica \(na maioria das vezes\) no intervalo 0x00007ffc_00000000 - 0x00007fff_ffffffff, 16gb de endereços possíveis.
* O intervalo 0xffffffffff600000 - 0xffffffffff601000 está sempre mapeado; você pode ler [este artigo](http://terenceli.github.io/%E6%8A%80%E6%9C%AF/2019/02/13/vsyscall-and-vdso) se tiver curiosidade sobre o que é.
## 1.3 Como contornar o ASLR sem vazamento de informações
Vamos discutir o que você pode fazer para contornar o ASLR quando nenhum vazamento de informações é possível.
Esta é a minha tentativa de resumir o que aprendi lendo o post do blog do Saelo.
Para contornar o ASLR, você precisa de:
* Uma técnica de memory spraying, que permite mapear memória contígua de um determinado tamanho, em um determinado intervalo de endereços.
Como ele diz, há duas maneiras de fazer isso:
1. Ao abusar de um memory leak (não um vazamento de informações!), um bug no qual um bloco de memória é “esquecido” e nunca liberado, e ao acioná-lo várias vezes até que a quantidade desejada de memória tenha sido vazada.
2. Ao encontrar e abusar de um “amplification gadget”: um pedaço de código que pega um bloco de dados existente e o copia, potencialmente várias vezes, permitindo assim que o atacante pulverize uma grande quantidade de memória enviando apenas um número relativamente pequeno de bytes.
* Um oráculo `isAddressMapped`, que, dado um endereço, diz se esse endereço está ou não mapeado.