#!/usr/bin/env python3 """Harmless path checks against the local tunnel to the decoy; no payload execution.""" import argparse import http.client import ipaddress import urllib.parse PATHS = ( '/reports', '/reports/', '/admin', '/admin/', '/dashboard', '/evidence', '/evidence/', '/logs', '/logs/', '/logs/events.jsonl', '/events.jsonl', '/artifacts/', '/artifacts/' + '0' * 64 + '.bin', '/http/events.jsonl', '/network/events.jsonl', '/var/lib/decoy/http/events.jsonl', '/var/lib/decoy/network/events.jsonl', '/opt/decoy/honeypot.py', '/honeypot.py', '/evidence.py', '/vm_backend.py', '/guest.py', '/network_capture.py', '/ui/sources.json', '/README.md', '/../var/lib/decoy/http/events.jsonl', '/../../var/lib/decoy/http/events.jsonl', '/%2e%2e/%2e%2e/var/lib/decoy/http/events.jsonl', '/%2e%2e%2f%2e%2e%2fvar%2flib%2fdecoy%2fhttp%2fevents.jsonl', '/%252e%252e%252fvar%252flib%252fdecoy%252fhttp%252fevents.jsonl', '/..%5c..%5cvar%5clib%5cdecoy%5chttp%5cevents.jsonl', '//var/lib/decoy/http/events.jsonl', '/logs/../events.jsonl', '/logs%00/events.jsonl', ) def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--url', required=True, help='HTTP loopback tunnel URL') args = parser.parse_args() url = urllib.parse.urlsplit(args.url) if url.scheme != 'http' or url.username or url.password or url.query or url.fragment: parser.error('use an HTTP loopback tunnel URL without credentials or query') try: loopback = ipaddress.ip_address(url.hostname).is_loopback except ValueError: loopback = url.hostname == 'localhost' if not loopback or url.path not in ('', '/'): parser.error('test is restricted to the loopback tunnel root') def request(path): conn = http.client.HTTPConnection(url.hostname, url.port or 80, timeout=25) try: conn.request('GET', path) response = conn.getresponse() body = response.read(131073) assert len(body) <= 131072, 'unexpected large response for ' + path return response.status, body finally: conn.close() status, body = request('/') assert status == 200 and b'