Skip to content

Instantly share code, notes, and snippets.

@vient
Created June 1, 2018 23:47
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 vient/b1eb7480f9329d27b41c154599be8d9a to your computer and use it in GitHub Desktop.
Save vient/b1eb7480f9329d27b41c154599be8d9a to your computer and use it in GitHub Desktop.
diagon_alley
#!/usr/bin/env python
import sys
import struct
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from pwn import *
DEBUG = False
def attach_gdb():
pass
SERVER_COUNTER = 0
RECV_QUEUE = []
def interact(p):
global SERVER_COUNTER, RECV_QUEUE
our_key = RSA.generate(2048, e=65537)
public_key = our_key.publickey().exportKey("DER")
private_key = PKCS1_OAEP.new(our_key)
p.send(p64(len(public_key)))
p.send(public_key)
server_key_length = u64(p.recv(8))
server_key = p.recv(server_key_length)
assert server_key_length == len(server_key), 'kok'
server_key = PKCS1_OAEP.new(RSA.importKey(server_key))
data = p.recv(4096)
SERVER_COUNTER += 1
rand_auth_part = data[8:16]
orig_recv = p.recv
def new_recv(*args, **kwargs):
global SERVER_COUNTER, RECV_QUEUE
if 'orig' in kwargs:
return orig_recv(data)
if 'timeout' in kwargs:
kwargs['timeout'] = 1.0
res = ''
if not RECV_QUEUE:
t = orig_recv(4096, timeout=1.0)
else:
t = orig_recv(4096, timeout=0.01)
while True:
if len(t) >= 16 and u64(t[:8]) < 0x10000 and t[8:16] == rand_auth_part:
block_length = u64(t[:8])
print len(t), block_length
while len(t) < block_length:
t += orig_recv(4096, timeout=0.5)
SERVER_COUNTER += 1
RECV_QUEUE.append(private_key.decrypt(t[32:block_length]))
if len(t) == block_length:
break
else:
t = t[block_length:] + orig_recv(4096, timeout=0.01)
elif t:
return t
else:
break
if RECV_QUEUE:
return RECV_QUEUE.pop(0)
return t
p.recv = new_recv
orig_send = p.send
def new_send(data, **kwargs):
if 'orig' in kwargs:
return orig_send(data)
print data
data = server_key.encrypt(data)
data = p64(len(data) + 0x20) + rand_auth_part + p64(SERVER_COUNTER) + p64(len(data)) + data
# print hexdump(data)
return orig_send(data)
p.send = new_send
p.send('World')
p.interactive()
def main():
if not DEBUG:
if len(sys.argv) < 2:
log.warning('No address provided in first arg, using NOP team')
target = '10.66.1.2'
else:
target = sys.argv[1]
with remote(target, 4441) as p:
interact(p)
else:
with process('./diagon_alley_no_seccomp', raw=False, preexec_fn=attach_gdb) as p:
interact(p)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment