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,55 @@
|
||||
"""Bounded PROXY-v1 parser and trusted reverse-proxy client-IP extraction."""
|
||||
import ipaddress
|
||||
|
||||
CLIENT_HEADERS = ('CF-Connecting-IP', 'True-Client-IP', 'X-Real-IP')
|
||||
|
||||
|
||||
def public_ip(value):
|
||||
"""Return a normalized global client IP, or None for private/spoofed values."""
|
||||
try:
|
||||
ip = ipaddress.ip_address(value.strip())
|
||||
except (ValueError, AttributeError):
|
||||
return None
|
||||
if not ip.is_global or ip.is_multicast:
|
||||
return None
|
||||
return str(ip)
|
||||
|
||||
|
||||
def forwarded_client(headers):
|
||||
"""Real client IP from a trusted proxy. Priority: single-hop headers, then nearest XFF hop."""
|
||||
for name in CLIENT_HEADERS:
|
||||
value = headers.get(name)
|
||||
if value:
|
||||
ip = public_ip(value)
|
||||
if ip:
|
||||
return ip, name
|
||||
for hop in reversed((headers.get('X-Forwarded-For') or '').split(',')):
|
||||
ip = public_ip(hop)
|
||||
if ip:
|
||||
return ip, 'X-Forwarded-For'
|
||||
return None, None
|
||||
|
||||
|
||||
def source(connection, transport, trusted):
|
||||
if transport[0] != trusted:
|
||||
raise ValueError('untrusted PROXY transport')
|
||||
header = bytearray()
|
||||
while len(header) < 108:
|
||||
value = connection.recv(1)
|
||||
if not value:
|
||||
raise ValueError('incomplete PROXY header')
|
||||
header.extend(value)
|
||||
if header.endswith(b'\r\n'):
|
||||
break
|
||||
else:
|
||||
raise ValueError('oversize PROXY header')
|
||||
fields = header.decode('ascii').strip().split(' ')
|
||||
if len(fields) != 6 or fields[0] != 'PROXY' or fields[1] not in ('TCP4', 'TCP6'):
|
||||
raise ValueError('invalid PROXY header')
|
||||
version = 4 if fields[1] == 'TCP4' else 6
|
||||
if any(ipaddress.ip_address(ip).version != version for ip in fields[2:4]):
|
||||
raise ValueError('PROXY address family mismatch')
|
||||
ports = [int(value) for value in fields[4:]]
|
||||
if any(not 0 < port <= 65535 for port in ports):
|
||||
raise ValueError('invalid PROXY port')
|
||||
return (fields[2], ports[0]), bytes(header)
|
||||
Reference in new issue
Block a user