CitrixPot: NetScaler / Citrix ADC Gateway honeypot (initial public release)
This commit is contained in:
commit
4491b42714
54 files changed
+4532
No files matched your search
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""TCP forwarding with trusted PROXY v1 metadata, before any TLS bytes."""
|
||||
import argparse
|
||||
import asyncio
|
||||
import ipaddress
|
||||
import os
|
||||
|
||||
from env_file import load, env_int
|
||||
|
||||
|
||||
async def forward(reader, writer, target_host, target_port):
|
||||
upstream = None
|
||||
try:
|
||||
peer = writer.get_extra_info('peername')
|
||||
local = writer.get_extra_info('sockname')
|
||||
family = 'TCP6' if ipaddress.ip_address(peer[0]).version == 6 else 'TCP4'
|
||||
remote, upstream = await asyncio.wait_for(asyncio.open_connection(target_host, target_port), 5)
|
||||
upstream.write(f'PROXY {family} {peer[0]} {local[0]} {peer[1]} {local[1]}\r\n'.encode('ascii'))
|
||||
await upstream.drain()
|
||||
async def copy(source, destination):
|
||||
while data := await asyncio.wait_for(source.read(65536), 60):
|
||||
destination.write(data)
|
||||
await asyncio.wait_for(destination.drain(), 10)
|
||||
if destination.can_write_eof():
|
||||
destination.write_eof()
|
||||
await asyncio.wait_for(asyncio.gather(copy(reader, upstream), copy(remote, writer)), 120)
|
||||
except (OSError, asyncio.TimeoutError):
|
||||
pass
|
||||
finally:
|
||||
if upstream:
|
||||
upstream.close()
|
||||
writer.close()
|
||||
|
||||
|
||||
async def serve(args):
|
||||
active = set()
|
||||
allowed = [ipaddress.ip_network(item.strip(), strict=False)
|
||||
for item in (args.allow_from or '').split(',') if item.strip()]
|
||||
|
||||
def permitted(peer):
|
||||
return not allowed or any(ipaddress.ip_address(peer[0]) in network for network in allowed)
|
||||
|
||||
async def accept(reader, writer):
|
||||
if len(active) >= 64 or not permitted(writer.get_extra_info('peername')):
|
||||
writer.close()
|
||||
return
|
||||
task = asyncio.current_task()
|
||||
active.add(task)
|
||||
try:
|
||||
await forward(reader, writer, args.target, args.target_port)
|
||||
finally:
|
||||
active.discard(task)
|
||||
server = await asyncio.start_server(accept, args.bind, args.port, limit=65536)
|
||||
async with server:
|
||||
await server.serve_forever()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
load()
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--bind', default=os.environ.get('INGRESS_BIND', '127.0.0.1'))
|
||||
parser.add_argument('--port', type=int, default=env_int('INGRESS_PORT', 18443))
|
||||
parser.add_argument('--target', default=os.environ.get('INGRESS_TARGET', '127.0.0.1'))
|
||||
parser.add_argument('--target-port', type=int, default=env_int('INGRESS_TARGET_PORT', 19443))
|
||||
parser.add_argument('--allow-from', default=os.environ.get('INGRESS_ALLOW_FROM', ''),
|
||||
help='comma-separated CIDRs allowed to connect (empty = any)')
|
||||
asyncio.run(serve(parser.parse_args()))
|
||||
Reference in new issue
Block a user