Skip to main content

Research tool for studying DPI, TLS fingerprinting, and content-delivery protections via ClientHello splitting and parallel-strategy bypass. For educational and research purposes only.

Project description

NullGazeX — Research Tool for Network Filtering Analysis

Important: NullGazeX is a research and educational tool designed to study network filtering, Deep Packet Inspection (DPI), TLS fingerprinting, and content-delivery protection mechanisms. It is not intended for unauthorized access to protected content. The author assumes no liability for any misuse or for any consequences arising from its use. By using this software you agree that you are solely responsible for complying with all applicable laws and the terms of service of any website you interact with.

NullGazeX implements a multi-tier pipeline of bypass strategies — raced in parallel for terrifying speed — to retrieve content through ISP SNI filters, Cloudflare challenges, TLS fingerprint checks, and hotlinking protections.


What NullGazeX Does

Capability Description
Image Downloading Download images through any firewall or anti-scraping protection.
Page Scraping Retrieve full page HTML, text, titles, or JSON from any URL — undetected.
DPI Bypass ClientHello packet splitting evades ISP SNI filters without external proxies or VPNs.
TLS Impersonation Rotates curl_cffi browser fingerprints (Chrome, Safari, Firefox, Edge) so traffic looks like a real browser.
Parallel Strategy Racing All bypass strategies launch concurrently — the fastest wins in fractions of a second.
Adaptive Anti-Blocking Per-domain cooldown, jittered delays, session cycling, and fingerprint rotation prevent server-side rate-limiting.
Stealth Browser Fallback Headless Chromium (via DrissionPage) with anti-detection flags for extreme JS challenges.

How It Works

NullGazeX uses a local loopback proxy that intercepts the TLS ClientHello handshake packet and splits it into two TCP segments with an 8 ms gap between them. The SNI (Server Name Indication) field is thus broken across two packets. DPI firewalls inspect packets individually and do not reassemble them — so the SNI check never fires.

Combined with rotating TLS fingerprints (the curl_cffi library impersonates Chrome 110–124, Safari 15–17, Firefox 116–117, and Edge 99–110), the traffic is indistinguishable from a real browser.

For more details see DPI_BYPASS_DOC.md.


Installation

Standard (image downloading + scraping)

pip install NullGazeX

With browser support (for extreme JS challenges)

pip install NullGazeX[browser]

Full installation (everything)

pip install NullGazeX[full]

Dependencies are resolved automatically:

Extra Includes
(none) requests, curl_cffi
browser DrissionPage (headless Chromium)
scrape beautifulsoup4 (HTML parsing)
full everything above

Quick Start — Image Downloading

Single image

from nullgaze import download_image

download_image(
    url="https://example.com/images/photo.jpg",
    output_path="outputs/photo.jpg",
    verbose=True
)

Batch download (concurrent)

from nullgaze import download_images

targets = [
    ("https://example.com/img1.jpg", "outputs/img1.jpg"),
    ("https://example.com/img2.jpg", "outputs/img2.jpg"),
    ("https://example.com/img3.jpg", "outputs/img3.jpg"),
]

results = download_images(targets, max_workers=10, verbose=True)

for i, res in enumerate(results):
    if isinstance(res, Exception):
        print(f"Failed {i+1}: {res}")
    else:
        print(f"Saved to: {res}")

Quick Start — Page Scraping

Scrape a page (raw HTML)

from nullgaze import scrape_page

html = scrape_page("https://example.com/article", verbose=True)
print(html[:500])

Scrape clean text

from nullgaze import scrape_text

text = scrape_text("https://example.com/article")
print(text)

Get page title

from nullgaze import scrape_title

title = scrape_title("https://example.com/article")
print(f"Title: {title}")

Scrape a JSON API

from nullgaze import scrape_json

data = scrape_json("https://api.example.com/data")
print(data)

Scrape multiple URLs in parallel

from nullgaze import scrape_bulk

urls = [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3",
]

results = scrape_bulk(urls, max_workers=10, verbose=True)
for i, res in enumerate(results):
    if isinstance(res, Exception):
        print(f"Failed {urls[i]}: {res}")
    else:
        print(f"Success: {len(res)} chars")

Object-Oriented API

Image Downloader

from nullgaze import ImageDownloader

downloader = ImageDownloader(verbose=True)

custom_headers = {
    "Referer": "https://custom-referer.com/",
    "Cookie": "session=abc123",
}

downloader.download(
    url="https://example.com/protected/image.png",
    output_path="outputs/image.png",
    headers=custom_headers,
    race_timeout=3.0,  # give up after 3s
)

Page Scraper

from nullgaze import PageScraper

scraper = PageScraper(verbose=True)

# All strategies race in parallel
html = scraper.scrape("https://example.com", race_timeout=5.0)

# Get just the title
title = scraper.scrape_title("https://example.com")

# Get clean text
text = scraper.scrape_text("https://example.com")

Strategy Pipeline

NullGazeX races these strategies in parallel — the first to succeed wins, the rest are cancelled:

Tier Strategy Speed Best For
1 Direct HTTP ⚡⚡⚡ ~0.3s Unrestricted servers
2 DPI-Bypass + TLS Impersonation ⚡⚡ ~0.5s ISP SNI blocks, fingerprint checks
3 Stealth Browser (Chromium) 🐢 ~3s Cloudflare Turnstile, JS challenges
4 Weserv Proxy (images only) ⚡⚡ ~1s General fallback

The library caches the successful strategy per domain so subsequent requests to the same domain skip the race and go straight to the winning strategy.


Anti-Blocking Features

Mechanism How It Works
Fingerprint rotation Each request picks a random TLS fingerprint (Chrome 110–124, Safari 15–17, Firefox 116–117, Edge 99–110).
Header rotation User-Agent, Accept, Accept-Language, and Sec-Fetch-* headers are randomized per request.
Jittered delays 50–200 ms random delay between bulk dispatches to avoid burst detection.
Adaptive cooldown When a server returns 429/503, the domain is cooled down with exponential backoff (2s → 4s → 8s → capped at 30s).
Session cycling curl_cffi sessions are cycled every 25 requests to rotate TLS session state.
Domain strategy cache Caches which strategy works per domain — avoids re-discovering on every request.

Error Handling

from nullgaze import (
    download_image,
    DownloadFailedError,
    InvalidURLError,
    ScrapeError,
    BlockedError,
)

# Image errors
try:
    download_image("https://example.com/img.jpg", "output.jpg")
except InvalidURLError:
    print("Bad URL")
except DownloadFailedError as e:
    print(f"All strategies failed: {e}")

# Scraping errors
from nullgaze import scrape_page
try:
    html = scrape_page("https://example.com")
except BlockedError:
    print("Server explicitly blocked us (403/429/503)")
except ScrapeError as e:
    print(f"Scraping failed: {e}")

Pre-Warming for Maximum Speed

Call engine_prewarm() at startup to pre-launch the DPI-bypass proxy and open a trial connection. The first real request will hit a hot path in under 100 ms:

from nullgaze import engine_prewarm, download_image

engine_prewarm()  # proxy ready, connections hot

# Now every request starts at full speed
download_image("https://example.com/img.jpg", "output.jpg")

License

MIT License. See LICENSE.


Disclaimer

This library is provided as a research and educational tool for studying network filtering, DPI, TLS fingerprinting, and web scraping techniques. The author is not responsible for how you use it. You are solely responsible for ensuring your use complies with all applicable laws, regulations, and the terms of service of any website you interact with. By using this software you acknowledge these terms.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nullgazex-2.2.0.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nullgazex-2.2.0-py3-none-any.whl (27.0 kB view details)

Uploaded Python 3

File details

Details for the file nullgazex-2.2.0.tar.gz.

File metadata

  • Download URL: nullgazex-2.2.0.tar.gz
  • Upload date:
  • Size: 24.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for nullgazex-2.2.0.tar.gz
Algorithm Hash digest
SHA256 ebc4c716f3eaf0d453e3541f60542521fb23b5730dcd5a3e43393c07372f52ad
MD5 f630e41f655b02fe113563e99ded16dd
BLAKE2b-256 d1a1d13dafd6336d2a5ebb19bc5d5b1ea82b26735d84a549cea3ad855f4a170e

See more details on using hashes here.

File details

Details for the file nullgazex-2.2.0-py3-none-any.whl.

File metadata

  • Download URL: nullgazex-2.2.0-py3-none-any.whl
  • Upload date:
  • Size: 27.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for nullgazex-2.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4029bda7e769fcd37eb2f4cf14dd0ea31ebf3fdb3683dcfccd4d89d8c9f81646
MD5 f7b15ea88f1daf38577fba94acaaa7b2
BLAKE2b-256 a12596b03ecb19fa2a17ddf8682ebc17ce86e39ca27ee9ecd5eb912fc6fd233c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page