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.1.0.tar.gz (17.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.1.0-py3-none-any.whl (19.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: nullgazex-2.1.0.tar.gz
  • Upload date:
  • Size: 17.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.1.0.tar.gz
Algorithm Hash digest
SHA256 c577dccdff30d6d5eed5d73c589fb47b2295a66e64d55178d428116c8d59b839
MD5 7ae2d8a04a0c730ea7ce54b9c0dd3504
BLAKE2b-256 24520e1e3202150c0c44a405c5f3ff5dde3e847d923ba393fad2a9b4babbcce5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: nullgazex-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.9 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9ea169c596daba59e80d5aa5be5b6ef1c42e5ecf83c8aa028b04e2cc67403b25
MD5 e9b824753a149778fccc8255cf992a84
BLAKE2b-256 a370ac56f688cf17bd525ba02b03189946863c421b68639a3d374c177babc870

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