
urx v0.11.0
استخراج عناوين URL من أرشيفات OSINT للحصول على رؤى أمنية
يستخرج عناوين URL من أرشيفات OSINT للحصول على رؤى أمنية.
Urx هي أداة سطر أوامر مصممة لجمع عناوين URL من أرشيفات OSINT، مثل Wayback Machine وCommon Crawl. بُنيت بلغة Rust لتحقيق الكفاءة، وهي تستفيد من المعالجة غير المتزامنة للاستعلام بسرعة من مصادر بيانات متعددة. تبسّط هذه الأداة عملية جمع معلومات عناوين URL لنطاق محدد، مما يوفر مجموعة بيانات شاملة يمكن استخدامها لأغراض متنوعة، بما في ذلك اختبار الأمان والتحليل.
الميزات
- جلب عناوين URL من مصادر متعددة بالتوازي (Wayback Machine، Common Crawl، OTX، Arquivo.pt)
- إمكانية توصيل أي خادم فهرس CDX آخر — أرشيفات الويب الوطنية، أو pywb خاص، أو OutbackCDX — باستخدام
--cdx-endpoint URL، دون الحاجة إلى تغيير الكود - بدون مفاتيح افتراضيًا: تعمل Wayback وCommon Crawl وOTX وArquivo.pt وURLScan (مجهول) جميعها دون مفتاح API
- مزوّد BeVigil: عناوين URL مستخرجة من تطبيقات Android غير المحزومة — نقاط نهاية لم يزحف إليها أي أرشيف ويب قط
- دعم تدوير مفاتيح API لمزوّدي VirusTotal وURLScan للتخفيف من حدود المعدل
- اختبار موثّق: تُطبَّق
-Hو--cookieو--user-agentعلى كل طلب يرسله urx إلى الهدف (--check-status،--extract-links،--extract-js-endpoints،--expand-specs) ولا تُرسَل عمدًا أبدًا إلى أي أرشيف - تصفية النتائج حسب امتدادات الملفات، أو أنماط السلاسل الفرعية، أو التعبيرات النمطية الكاملة (
--match-regex/--filter-regex) - إعدادات مسبقة محددة، سواء حسب عائلة الملفات ("no-images"، "only-js") أو حسب الاهتمام الأمني ("only-secrets"، "only-backup"، "only-config"، "only-api")
- التصفية من جهة الأرشيف: دفع رمز الحالة ونوع MIME ونطاق التاريخ إلى استعلام CDX نفسه، بحيث لا تعبر اللقطات المُصفّاة الشبكة أبدًا
- تصفية البيانات الوصفية من جهة العميل (
--meta-*): التصفية حسب تاريخ أول/آخر لقطة، ونوع MIME المسجّل، والحالة المسجّلة بشكل موحّد عبر كل مزوّد، بعد الجمع - أهداف محدّدة النطاق بالمسار: يدفع
urx example.com/shopالنطاق إلى استعلام CDX نفسه (url=example.com/shop*)، بحيث تكلّف شجرة فرعية من موقع كبير جزءًا بسيطًا من الفهرس الكامل بدلًا من تصفيتها من جهة العميل - ملفات نطاق Bug-bounty (
--scope-file): قائمة البرنامج الخاصة*.example.com/!admin.example.comتُستخدم كما هي، قابلة للتكرار ومُدمَجة، مع فوز الاستثناءات دائمًا - تطبيع عناوين URL وإزالة التكرار: ترتيب معاملات الاستعلام، وإزالة الشرطات المائلة اللاحقة، ودمج عناوين URL المتطابقة دلاليًا، وطيّ شبه التكرارات التي تختلف فقط في المعرّفات أو التجزئات أو التواريخ (
--dedup-similar) - دعم صيغ إخراج متعددة: نص عادي، JSON، JSON Lines، CSV، و
wordlist— مقاطع المسار وأسماء المعاملات التي بُني منها الهدف، مع استبعاد المعرّفات والتجزئات والتواريخ - عروض المعاملات والتشويش:
--params(جرد معاملات الهدف بالكامل)، و--params-by-endpoint(أي نقطة نهاية تأخذ ماذا)، و--fuzz-placeholder FUZZ(عنوان URL واحد بقوالب لكل توقيع معامل، جاهز لـ ffuf أو dalfox) - بيانات وصفية لالتقاط الأرشيف: تعود
first_seenوlast_seenوmimeوarchive_statusوdigestمع كل عنوان URL أبلغ عنه أرشيف CDX، دون تكلفة شبكة إضافية - إخراج متدفق (
--stream): تُكتب عناوين URL عند إبلاغ كل مزوّد عنها، بحيث يبدأ خط الأنابيب بالعمل فورًا بدلًا من انتظار أبطأ أرشيف - دعم إدخال الملفات المباشر: قراءة عناوين URL مباشرة من ملفات WARC، وملفات URLTeam المضغوطة، والملفات النصية
- إخراج النتائج إلى الطرفية أو ملف، أو البث عبر stdin لتكامل خطوط الأنابيب
- اختبار عناوين URL:
- تصفية والتحقق من عناوين URL بناءً على رموز حالة HTTP والأنماط.
- استخراج روابط إضافية من عناوين URL المجمّعة — المراسي، والسكربتات، وأوراق الأنماط، وإجراءات النماذج، والإطارات المدمجة، والصور، ومصادر الوسائط، والكائنات، والتضمينات، وأهداف meta-refresh
- استخراج أجسام الاستجابات المؤرشفة لعناوين URL المجمّعة (
--archive-body)، بحيث تُسلّم الصفحات التي لم تعد موجودة الروابط التي كانت تحتويها — طلب واحد لكل جسم مميّز، بفضل إزالة تكرار digest الخاص بـ CDX - مع
--extract-js-endpoints، استخراج JavaScript المؤرشف أيضًا: حزمة مسماة بتجزئة البناء تُرجع 404 لحظة إعادة نشر الموقع، والأرشيف هو المكان الوحيد الذي لا يزال سطح API الخاص بها موجودًا فيه - الاحتفاظ بالأجسام المُعاد تشغيلها (
--archive-body-dir) كمجموعة نصية للبحث عمّا لا يبحث عنه أي مستخرج روابط — تعليقات المطورين، وبيانات الاعتماد المضمّنة، وأسماء المضيفين الداخلية — دون طلبات إضافية - توسيع مواصفات API (
--expand-specs): مستندات OpenAPI 3.x وSwagger 2.0 واستقصاء GraphQL، بصيغة JSON أو YAML، تُحوَّل إلى كل مسار تصفه — طلب واحد يشتري السطح الموثّق بالكامل - بيانات وصفية للاستجابة: يسجّل
--check-statusأيضًاLocationوContent-LengthوContent-Type، ويضيف--check-titleوسم HTML<title>
- اكتشاف robots.txt وsitemap.xml المؤرشفين (
--archived-discovery): كل نسخة مميّزة يحتفظ بها Wayback Machine، بحيث لا يزالDisallow:من عام 2015 يسمّي المسارات التي توقّف الموقع عن ذكرها منذ ذلك الحين - التخزين المؤقت والفحص التدريجي:
- تخزين مؤقت محلي بـ SQLite أو بعيد بـ Redis لتجنّب إعادة فحص النطاقات
- وضع تدريجي لاكتشاف عناوين URL الجديدة فقط منذ آخر فحص
- مدة صلاحية قابلة للتكوين للتخزين المؤقت وتنظيف تلقائي للمدخلات المنتهية الصلاحية
- أمر فرعي
urx cacheلفحص التخزين المؤقت وصيانته:stats،list،prune،drop <domain>،clear

التثبيت
من Cargo```bash
https://crates.io/crates/urx
cargo install urx
### من Homebrew```bash
# https://formulae.brew.sh/formula/urx
brew install urx
من المصدر```bash
git clone https://github.com/hahwul/urx.git cd urx cargo build --release
سيكون الملف التنفيذي المُجمَّع متاحًا في `target/release/urx`.
### من Docker
[ghcr.io/hahwul/urx](https://github.com/hahwul/urx/pkgs/container/urx)
### إكمال الصدفة
يولّد `urx` نص الإكمال الخاص به، لذا فهو يتطابق دائمًا مع أعلام
الملف التنفيذي المثبَّت لديك فعليًا.```bash
# zsh — any directory on your $fpath works
urx --completions zsh > ~/.zfunc/_urx
# (make sure ~/.zfunc is on the fpath, then `compinit`)
# bash
urx --completions bash > ~/.local/share/bash-completion/completions/urx
# fish
urx --completions fish > ~/.config/fish/completions/urx.fish
powershell و elvish مدعومان أيضًا. لا يحتاج هذا الخيار إلى نطاق هدف.
صفحة الدليل```bash
urx --manpage > ~/.local/share/man/man1/urx.1 man urx
## الاستخدام
### الاستخدام الأساسي```bash
# Scan a single domain
urx example.com
# Scan multiple domains
urx example.com example.org
# Scan domains from a file
cat domains.txt | urx
الخيارات```
Usage: urx [OPTIONS] [DOMAINS]... [COMMAND]
Commands: cache Inspect and maintain the URL cache: stats, list, prune, drop ..., clear
Arguments: [DOMAINS]... Domains to fetch URLs for
Options: -c, --config Config file to load --provider-config Separate provider config file holding only API keys (default: $XDG_CONFIG_HOME/urx/provider-config.toml). CLI/env > provider-config > main config. --completions Print a shell completion script (bash, zsh, fish, powershell, elvish) to stdout and exit --manpage Print the roff man page to stdout and exit -h, --help Print help -V, --version Print version
Input Options:
--files ... Read URLs directly from files (supports WARC, URLTeam compressed, and text files)
--domain-list File of newline-separated domains to scan (repeatable; merged with positional DOMAINS and stdin; # comments allowed)
Output Options:
-o, --output Output file to write results
--output-dir Write one file per domain into this directory (extension matches --format). Coexists with --output / stdout.
-f, --format Output format: "plain", "json" (one array), "jsonl" (one JSON object per line), "csv", "wordlist" (path segments and parameter names, deduplicated and sorted) [default: plain]
--stream Write URLs as each provider reports them instead of once at the end (unsorted; bypasses cache; rejects options needing the full result set)
--merge-endpoint Merge endpoints with the same path and merge URL parameters
--normalize-url Normalize URLs for better deduplication (sorts query parameters, removes trailing slashes)
--dedup-similar Collapse URLs that differ only in variable data (numeric ids, UUIDs, hashes, dates, query values)
--params Replace the URL list with every query parameter name the run saw, once each
--params-by-endpoint
One line per endpoint: the endpoint and the comma-separated union of the parameter names seen on it (id-looking path segments collapse to {id})
--fuzz-placeholder
Replace every query parameter value with VALUE, keeping one URL per parameter signature — output you can feed straight to ffuf or dalfox
Provider Options:
--providers
Providers to use (comma-separated, e.g., "wayback,cc,otx,arquivo,vt,urlscan") [default: wayback,cc,otx]
--exclude-providers <EXCLUDE_PROVIDERS>
Providers to exclude (comma-separated). Wins on conflict with --providers / --all-providers.
--all-providers
Enable every supported provider. API-keyed providers only activate when a key is available.
--list-providers
List every supported provider then exit.
--subs
Include subdomains when searching
--cc-index <CC_INDEX>
Common Crawl index to use; accepts comma-separated list to query multiple indexes in parallel (e.g. CC-MAIN-2026-17,CC-MAIN-2025-51). latest (the default) resolves the newest via collinfo.json. [default: latest]
--cdx-endpoint
Query an additional CDX index server (any pywb, OutbackCDX, or classic Internet-Archive-style CDX API) by its full API URL, e.g. https://vefsafn.is/cdx. Repeatable. Each endpoint becomes a provider with id cdx:<host> and honours --subs, --from/--to and the --archive-* filters. See "Custom CDX Endpoints" below
--cdx-dialect
Which CDX dialect the --cdx-endpoint servers speak: pywb or classic. Unset: urx probes each endpoint once and falls back to pywb when the answer is ambiguous
--from
Restrict every CDX-backed provider (wayback, cc, arquivo, --cdx-endpoint) to captures at or after DATE (YYYY/YYYYMM/YYYYMMDD/YYYYMMDDhhmmss). Alias: --wayback-from
--to
Restrict every CDX-backed provider to captures at or before DATE (same format as --from). Alias: --wayback-to
--archive-status
Keep only captures the archive recorded with this HTTP status code (e.g. "200"). Applied by the CDX index itself, so unlike --include-status it costs no extra requests. A multi-value list works on wayback only — see "Archive-side Filtering" below
--archive-exclude-status
Drop captures the archive recorded with these HTTP status codes (comma-separated, e.g. "404,500"). Multi-value works on every CDX provider
--archive-mime
Keep only captures with this recorded MIME type (e.g. "application/json"). Catches endpoints with no file extension, which -e/--extensions cannot
--archive-exclude-mime
Drop captures with these recorded MIME types (comma-separated, e.g. "text/html,image/png")
--vt-api-key <VT_API_KEY>
API key for VirusTotal (can be used multiple times for rotation, can also use URX_VT_API_KEY environment variable with comma-separated keys)
--urlscan-api-key <URLSCAN_API_KEY>
Optional API key for Urlscan; the provider also works anonymously (rate-limited ~30 req/min per IP). Can be used multiple times for rotation, or via URX_URLSCAN_API_KEY (comma-separated keys)
--github-api-key <GITHUB_API_KEY>
Personal access token for the GitHub Code Search provider (also reads URX_GITHUB_API_KEY, comma-separated for rotation)
--bevigil-api-key <BEVIGIL_API_KEY>
API key for BeVigil, which returns URLs extracted from unpacked Android apps (also reads URX_BEVIGIL_API_KEY, comma-separated for rotation). Required for the bevigil provider
Discovery Options:
--exclude-robots
Exclude robots.txt discovery
--exclude-sitemap
Exclude sitemap.xml discovery
--archived-discovery
Also read every distinct archived version of robots.txt and sitemap.xml the Wayback Machine holds
--archived-discovery-limit
Maximum archived documents fetched per domain by each archived provider (nested sitemaps count) [default: 50]
Display Options:
-v, --verbose Show verbose output
--silent Silent mode (no output)
--no-progress No progress bar
--no-color Disable ANSI color in the progress UI and output (NO_COLOR is also honored)
--show-sources Annotate output URLs with the providers that returned them
--show-meta Annotate plain-text URLs with the archive capture metadata
--stats Print a per-provider summary to stderr at end of run
Filter Options:
-p, --preset
Filter Presets (e.g., "no-resources,no-images,no-audio,only-js,only-style,only-secrets,only-backup,only-config,only-api")
-e, --extensions
Filter URLs to only include those with specific extensions (comma-separated, e.g., "js,php,aspx")
--exclude-extensions <EXCLUDE_EXTENSIONS>
Filter URLs to exclude those with specific extensions (comma-separated, e.g., "html,txt")
--patterns
Filter URLs to only include those containing specific patterns (comma-separated)
--exclude-patterns <EXCLUDE_PATTERNS>
Filter URLs to exclude those containing specific patterns (comma-separated)
--match-regex
Keep only URLs matching this regular expression (repeatable, ORed; case-sensitive; never comma-split)
--filter-regex
Drop URLs matching this regular expression (repeatable; one match is enough)
--show-only-host
Only show the host part of the URLs
--show-only-path
Only show the path part of the URLs
--show-only-param
Only show the parameters part of the URLs
--min-length <MIN_LENGTH>
Minimum URL length to include
--max-length <MAX_LENGTH>
Maximum URL length to include
--strict
Enforce exact host validation (default)
--no-strict
Disable host validation (keep URLs on any host a provider returns). Wins over --strict. A target's path scope still applies: only the host check is waived
--scope-file
Bug-bounty scope file: one host pattern per line, ! to exclude, *.example.com for a wildcard (which covers the apex too), # for a comment. Repeatable and unioned; exclusions always win. See "Scope Files" below
--meta-first-seen-after
Keep URLs whose oldest archived capture is on or after DATE (YYYY/YYYYMM/YYYYMMDD/YYYYMMDDhhmmss)
--meta-first-seen-before
Keep URLs whose oldest archived capture is on or before DATE
--meta-last-seen-after
Keep URLs whose newest archived capture is on or after DATE — "still alive as of"
--meta-last-seen-before
Keep URLs whose newest archived capture is on or before DATE — "dead since"
--meta-mime
Keep only URLs whose archived MIME type is one of these (comma-separated; image/* matches any subtype)
--meta-exclude-mime
Drop URLs whose archived MIME type is one of these
--meta-status
Keep only URLs whose archived status code matches (comma-separated; 20x / 5xx patterns)
--meta-exclude-status
Drop URLs whose archived status code matches
Network Options:
--network-scope <NETWORK_SCOPE> Control which components network settings apply to (all, providers, testers, or providers,testers) [default: all]
--proxy Use proxy for HTTP requests (format: http://proxy.example.com:8080)
--proxy-auth <PROXY_AUTH> Proxy authentication credentials (format: username:password)
--insecure Skip SSL certificate verification (accept self-signed certs)
--random-agent Use a random User-Agent for HTTP requests
-H, --header <NAME: VALUE> Extra request header, repeatable; sent only on requests urx makes to the target, never to an archive
--cookie Cookie header for requests to the target; shorthand for -H "Cookie: ..."
--user-agent User-Agent for requests to the target, overriding the default and --random-agent
--timeout Request timeout in seconds [default: 120]
--retries Number of retries for failed requests [default: 2]
--parallel Maximum domains fetched concurrently per provider (and concurrent URL tests); a provider's --rate-limit is shared across them [default: 5]
--rate-limit <RATE_LIMIT> Rate limit (requests per second)
--rate-limit-by Per-provider rate overrides (e.g. vt=1,wayback=10); falls back to --rate-limit for unlisted providers
--max-time <MAX_TIME> Global ceiling on provider enumeration time in seconds (0 = unlimited) [default: 0]
Testing Options:
--check-status
Check HTTP status code of collected URLs [aliases: ----cs]
--check-title
Also record each response's HTML while checking statuses; implies --check-status
--include-status <INCLUDE_STATUS>
Include URLs with specific HTTP status codes or patterns (e.g., --is=200,30x) [aliases: ----is]
--exclude-status <EXCLUDE_STATUS>
Exclude URLs with specific HTTP status codes or patterns (e.g., --es=404,50x,5xx) [aliases: ----es]
--extract-links
Extract additional links from collected URLs (requires HTTP requests)
--extract-js-endpoints
Fetch collected JavaScript files and extract the endpoint paths and URLs found in their string literals (requires HTTP requests); with --archive-body this also mines the archived copy of each script
--max-js-files
Maximum number of files --extract-js-endpoints will fetch (0 = unlimited) [default: 500]
--archive-body
Fetch the archived body of each collected URL from the Wayback Machine and extract the links inside it (works for pages that no longer exist)
--archive-body-limit
Maximum number of archived bodies --archive-body fetches per run; bounds distinct bodies, not URLs [default: 500]
--archive-body-dir
Keep every body --archive-body replays in DIR, with an index.jsonl mapping each file back to its URL, capture and content type
--expand-specs
Fetch the API specification documents among the collected URLs (OpenAPI, Swagger, GraphQL introspection; JSON or YAML) and expand every route they document into a URL. See "Expanding API Specifications" below
--max-spec-files
Maximum number of specification documents --expand-specs will fetch (0 = unlimited) [default: 50]
Cache Options:
--incremental Enable incremental scanning mode (only return new URLs compared to previous scans)
--cache-type Cache backend: sqlite or redis [default: sqlite]
--cache-path Path for the SQLite cache database
--redis-url Redis connection URL for remote caching
--cache-ttl Cache time-to-live in seconds [default: 86400]
--no-cache Disable caching entirely
Notification Options:
--notify POST a run summary to this webhook when the run ends (repeatable; also URX_NOTIFY_URL, provider-config notify_url, or [notify].url)
--notify-on <NOTIFY_ON> When to send: new (only if URLs were emitted), always, or never [default: new]
--notify-format <NOTIFY_FORMAT> Payload shape: json (urx summary), slack ({"text"}), or discord ({"content"}) [default: json]
`--extract-links` يقرأ كل وسم يحمل عنوان URL، وليس فقط المراسي: `<a href>`،
`<script src>`، `<link href>`، `<form action>`، ``، ``،
`<source src>`، `<object data>`، `<embed src>`، وأهداف `<meta http-equiv="refresh">`.
تُحل عناوين URL النسبية مقابل الصفحة (مع احترام `<base href>`)،
وتُدمج التكرارات، وتمر الروابط المكتشفة عبر نفس المرشحات
والتحقق من المضيف كبقية التشغيل. راجع
[docs/content/guide/cli-options.md](https://github.com/hahwul/urx/blob/main/docs/content/guide/cli-options.md) للاطلاع على
الجدول الكامل.
`--extract-js-endpoints` يخطو خطوة أبعد ويقرأ JavaScript
نفسه: كل عنوان URL مُجمَّع يبدو كسكربت يُجلب وتُستخرج حرفيًا سلاسله النصية
للعثور على المسارات وعناوين URL التي يستدعيها التطبيق —
`fetch("/api/v2/users")`، `axios.post("/graphql")`، البادئة الثابتة لـ
`` `/api/orders/${id}` ``. هذه هي نقاط النهاية التي لا تظهر أبدًا في HTML.
يُجرَّد المخرجات بقوة من الضوضاء (تُسقَط أنواع MIME، ومحدِّدات الوحدات، وbase64،
وقيم CSS، وشظايا regex وغيرها)، ويُحدَّد كل جسم بحد أقصى
10 MiB، ويُقيَّد عدد الملفات المجلوبة بـ `--max-js-files`، وتمر
نقاط النهاية المكتشفة عبر نفس المرشحات والتحقق من المضيف ككل شيء
آخر. سياسة الاستخراج الكاملة وكبت الضوضاء موجودة في
[docs/content/guide/cli-options.md](https://github.com/hahwul/urx/blob/main/docs/content/guide/cli-options.md#javascript-endpoint-extraction).
`--archive-body` يقوم بنفس الاستخراج على الأجسام التي *خزَّنها* Wayback Machine
بدلًا من الموقع الحي، لذا فإن صفحة حُذفت منذ سنوات
لا تزال تُنتج الروابط التي احتوتها. راجع
[استخراج أجسام الاستجابات المؤرشفة](#mining-archived-response-bodies).
### أمثلة```bash
# Save results to a file
urx example.com -o results.txt
# Output in JSON format
urx example.com -f json -o results.json
# Filter for JavaScript files only
urx example.com -e js
# Exclude HTML and text files
urx example.com --exclude-extensions html,txt
# Filter for API endpoints
urx example.com --patterns api,v1,graphql
# Exclude specific patterns
urx example.com --exclude-patterns static,images
# Use Fileter Preset (similar to --exclude-extensions=png,jpg,.....)
urx example.com -p no-images
# Use specific providers
urx example.com --providers wayback,otx
# Add the keyless Arquivo.pt (Portuguese web archive) provider
urx example.com --providers wayback,cc,otx,arquivo
# Query another CDX index server alongside the defaults (id: cdx:vefsafn.is)
urx example.is --cdx-endpoint https://vefsafn.is/cdx
# ...or on its own, rate-limited, with the archive-side filters it shares with wayback/cc
urx example.is --cdx-endpoint https://vefsafn.is/cdx --providers cdx:vefsafn.is \
--rate-limit-by cdx:vefsafn.is=1 --from 2020 --archive-status 200
# URLScan works without a key (anonymous, rate-limited); a key just raises limits
urx example.com --providers urlscan
# BeVigil: endpoints pulled out of unpacked Android apps (key required; auto-enables the provider)
URX_BEVIGIL_API_KEY=*** urx example.com
# Using VirusTotal and URLScan providers
# 1. Explicitly add to providers (with API keys via command line)
urx example.com --providers=vt,urlscan --vt-api-key=*** --urlscan-api-key=***
# 2. Using environment variables for API keys
URX_VT_API_KEY=*** URX_URLSCAN_API_KEY=*** urx example.com --providers=vt,urlscan
# 3. Auto-enabling: providers are automatically added when API keys are provided
urx example.com --vt-api-key=*** --urlscan-api-key=*** # No need to specify in --providers
# 4. Multiple API key rotation (to mitigate rate limits)
# Using repeated flags for multiple keys
urx example.com --vt-api-key=key1 --vt-api-key=key2 --vt-api-key=key3
# Using environment variables with comma-separated keys
URX_VT_API_KEY=key1,key2,key3 URX_URLSCAN_API_KEY=ukey1,ukey2 urx example.com
# Combining CLI flags and environment variables (CLI keys are used first)
URX_VT_API_KEY=env_key1,env_key2 urx example.com --vt-api-key=cli_key1 --vt-api-key=cli_key2
# URLs from robots.txt and sitemap.xml are included by default
# Exclude URLs from robots.txt files
urx example.com --exclude-robots
# Exclude URLs from sitemap
urx example.com --exclude-sitemap
# Also read every archived version of robots.txt and sitemap.xml, so paths the
# site once listed and has since removed come back
urx example.com --archived-discovery
# Only the versions captured in a given era
urx example.com --archived-discovery --from 2014 --to 2016 --exclude-sitemap
# Include subdomains
urx example.com --subs
# Check status of collected URLs
urx example.com --check-status
# Read URLs directly from a text file
urx --files urls.txt
# Combine file input with filtering
urx --files urls.txt --patterns api,admin -f json
# Extract additional links from collected URLs
# (anchors, scripts, stylesheets, form actions, iframes, images, media
# sources, objects, embeds, and meta-refresh targets)
urx example.com --extract-links
# Discovered links go through the same filters as everything else, so this
# keeps only the JavaScript the pages reference
urx example.com --extract-links -e js
# Read the collected JavaScript and pull out the API paths it calls
urx example.com --extract-js-endpoints --patterns api
# Chain them: collect the site's bundles, then mine those for endpoints
urx example.com --extract-links --extract-js-endpoints --max-js-files 100
# Mine the links inside the *archived* bodies instead — dead pages included.
# One request per distinct body; the limit bounds bodies, not URLs
urx example.com --archive-body --archive-body-limit 200 --rate-limit 5
# Network configuration
urx example.com --proxy http://localhost:8080 --timeout 60 --parallel 10 --insecure
# Advanced filtering
urx example.com -e js,php --patterns admin,login --exclude-patterns logout,static --min-length 20
# HTTP Status code based filtering (live requests: urx re-fetches each URL)
urx example.com --include-status 200,30x,405 --exclude-status 20x
# Archive-side filtering (free: the CDX index already knows these)
# Skip everything the archive recorded as a 404 — no extra requests
urx example.com --archive-exclude-status 404
# Only captures the archive served as JSON — finds extensionless API endpoints
urx example.com --archive-mime application/json
# Drop HTML to leave assets and endpoints behind
urx example.com --archive-exclude-mime text/html
# Restrict the crawl window across wayback, cc, arquivo, and any --cdx-endpoint alike
urx example.com --from 2023 --to 2024
# Disable host validation
urx example.com --strict false
# URL normalization and deduplication
# Normalize URLs by sorting query parameters and removing trailing slashes
urx example.com --normalize-url
# Combine normalization with endpoint merging for comprehensive deduplication
urx example.com --normalize-url --merge-endpoint
# URL normalization with file input
urx --files urls.txt --normalize-url
# Collapse /post/1, /post/2, /post/99999 ... into a single representative line
urx example.com --dedup-similar
# Regular-expression filtering (repeat either flag; they are never comma-split)
urx example.com --match-regex '/api/v[0-9]+/'
urx example.com --match-regex '\.php$' --match-regex '\.aspx$'
urx example.com --filter-regex '/(assets|static)/'
# Regexes are case-sensitive; ask for insensitivity explicitly
urx example.com --match-regex '(?i)admin'
# Security presets: match by path shape as well as by extension
urx example.com -p only-secrets # /.env, /.git/config, id_rsa, *.pem
urx example.com -p only-backup # *.bak, *.sql, /backup/, index.php~
urx example.com -p only-config # *.yaml, web.config, .htaccess, Dockerfile
urx example.com -p only-api # /api/, /v1/, /graphql, /swagger, *.wsdl
# Scope files: a bug bounty program's own host list, used verbatim
urx example.com --subs --scope-file scope.txt
# Metadata filters, applied after collection so every provider is covered
urx example.com --providers wayback --meta-last-seen-after 2024 --meta-exclude-mime 'image/*'
urx example.com --providers wayback --meta-mime application/json --meta-status 200
# What parameters does this target take, and where?
urx example.com --params
urx example.com --params-by-endpoint
# One templated URL per parameter signature, straight into a fuzzer
urx example.com --fuzz-placeholder FUZZ | ffuf -w - -u FUZZ
# A target-specific wordlist instead of a URL list
urx example.com --subs -f wordlist -o words.txt
# Open the API specifications the sweep found and expand every route in them
urx example.com -p only-api --expand-specs
# Status checks also keep the response head; --check-title adds the <title>
urx example.com --check-status -f jsonl
urx example.com --check-title --show-meta
# Inspect and maintain the cache
urx cache stats
urx cache drop example.com
تحديد نطاق التشغيل إلى مسار
قد يحدد الهدف مسارًا، وهو يعني ما يقوله: urx example.com/shop
يجمع الجزء من الموقع تحت /shop.```bash
urx example.com/shop
urx https://example.com/api/v2 # a pasted URL works too
هذا ليس مرشحًا يُطبَّق بعد جمع النتائج. فهرس CDX يجيب على استعلامات البادئة أصلاً، لذا يرسل urx `url=example.com/shop*` ولا يُرسل الأرشيف بقية الموقع عبر الشبكة — على هدف كبير، هذا هو الفرق بين بضع مئات من الصفوف وبضع مئات الآلاف. أما المزوّدون الذين لا يستطيعون التعبير عن مسار في استعلامهم (OTX، VirusTotal، urlscan، GitHub، BeVigil، ZoomEye) فيُسألون عن المضيف وتُضيّق إجاباتهم بعد ذلك، وكذلك نتائج تشغيل `--subs`، حيث لا يمكن الجمع بين صيغة `*.host` وبادئة مسار في استعلام CDX واحد.
النطاق يعني *عند المسار أو تحته*: `/shop` و `/shop/cart` داخلان، أما `/shopping` فليس كذلك. يُتجاهل اختلاف حالة الأحرف، لأن خادم CDX يحوّل عنوان URL بالكامل إلى أحرف صغيرة عند بناء مفتاح فهرسه — `example.com/Shop*` و `example.com/shop*` يُعيدان الصفوف نفسها، كلها مكتوبة بأحرف صغيرة، لذا فإن فحصًا حساسًا لحالة الأحرف سيتخلص من كل ما أعاده الأرشيف للتو. تُسقَط سلسلة الاستعلام أو الجزء (fragment) في الهدف — فهي تضيّق طلبًا، لا نطاقًا.
> ملاحظة: كان urx يتجاهل المسار من الهدف، لذا كان
> `urx https://example.com/shop` يفحص كامل `example.com`. الآن
> يفحص `/shop`. مرّر المضيف فقط للسلوك القديم؛ التشغيل الذي يحمل هدفه
> مسارًا يصرّح بذلك على stderr.
### التصفية بالتعبيرات النمطية
`--patterns` / `--exclude-patterns` هي اختبارات سلاسل فرعية بسيطة: يُحوَّل الطرفان إلى أحرف صغيرة، وكل محرف خاص يُعامل حرفيًا. أما `--match-regex` / `--filter-regex` فهما نظيرا التعبيرات النمطية، ويختلفان في ثلاث نواحٍ تستحق التذكر:
| | `--patterns` | `--match-regex` |
|---|---|---|
| المطابقة | سلسلة فرعية | [صيغة regex](https://docs.rs/regex/latest/regex/#syntax) كاملة |
| حالة الأحرف | غير حساسة (يُحوَّل الطرفان إلى أحرف صغيرة) | **حساسة** — استخدم `(?i)` لإلغاء ذلك |
| قيم متعددة | علم واحد مفصول بفواصل | كرّر العلم؛ لا تُقسَّم الفواصل أبدًا |
يُقيَّم كلا علمي regex مقابل **سلسلة URL الكاملة** كما جُمعت (المخطط، المضيف، المسار، والاستعلام)، لذا يعمل كل من `^https://` و `\.js$`. الاستبعاد يفوز: يُسقَط عنوان URL المطابق لـ `--filter-regex` حتى لو طابقه `--match-regex` أيضًا. التعبير المشوّه يُفشل التشغيل عند البدء، قبل الاستعلام عن أي أرشيف.
### ملفات النطاق
نطاق برنامج مكافآت الثغرات هو قائمة مضيفين، وكل منصة تكتبها بالطريقة نفسها. يأخذ `--scope-file` تلك القائمة كما هي بدلاً من إجبارك على ترجمتها يدويًا إلى بدائل regex مثبّتة — حيث يؤدي الخطأ في التثبيت إلى *توسيع* النطاق بصمت بدلاً من الفشل.```text
# scope.txt — in scope
*.example.com
api.example.org
# out of scope, even though the wildcard above covers them
!admin.example.com
!*.internal.example.com
ما الجديد في الإصدار 4.0.0
- إعادة كتابة كاملة بلغة Go — تمت إعادة كتابة الأداة بالكامل بلغة Go، مما أدى إلى تحسين الأداء بشكل كبير وتوزيع ثنائي بسيط.
- دعم بروتوكولات متعددة — دعم أصلي لـ HTTP/HTTPS و SOCKS4 و SOCKS5.
- كشف تلقائي للبروتوكول — يكتشف الأداة تلقائيًا بروتوكول الوكيل الصحيح.
- تحقق متزامن — فحص عدة وكلاء في وقت واحد باستخدام goroutines.
- إخراج JSON — إخراج منظم بصيغة JSON لسهولة التكامل مع الأدوات الأخرى.
- دعم المصادقة — دعم مصادقة اسم المستخدم/كلمة المرور للوكلاء.
- مهلة قابلة للتكوين — تعيين مهل اتصال مخصصة.
- إدخال من ملف — قراءة الوكلاء من ملف نصي.
- إخراج ملون — إخراج طرفي ملون لسهولة القراءة.
التثبيت
من المصدر
git clone https://github.com/example/proxychecker.git
cd proxychecker
go build -o proxychecker
باستخدام go install
go install github.com/example/proxychecker@latest
تنزيل ثنائي مُجمّع مسبقًا
قم بتنزيل أحدث إصدار من صفحة الإصدارات.
الاستخدام
proxychecker [options] [proxy...]
الخيارات
العلم الوصف الافتراضي -f, --fileقراءة الوكلاء من ملف -t, --timeoutمهلة الاتصال بالثواني 10-c, --concurrencyعدد عمليات الفحص المتزامنة 50-p, --protocolفرض بروتوكول محدد (http, socks4, socks5) تلقائي -o, --outputملف الإخراج --jsonالإخراج بصيغة JSON false--authبيانات اعتماد المصادقة (user:pass) -v, --verboseتمكين الإخراج المطوّل false-h, --helpعرض المساعدة
أمثلة
فحص وكيل واحد:
proxychecker 192.168.1.1:8080
فحص عدة وكلاء:
proxychecker 192.168.1.1:8080 10.0.0.1:1080 socks5://127.0.0.1:9050
قراءة الوكلاء من ملف:
proxychecker -f proxies.txt
الإخراج بصيغة JSON:
proxychecker -f proxies.txt --json -o results.json
استخدام المصادقة:
proxychecker --auth user:pass 192.168.1.1:8080
التكوين
يمكن تكوين ProxyChecker من خلال أعلام سطر الأوامر أو متغيرات البيئة:
متغير البيئة العلم المكافئ PROXYCHECKER_TIMEOUT--timeoutPROXYCHECKER_CONCURRENCY--concurrencyPROXYCHECKER_PROTOCOL--protocolPROXYCHECKER_OUTPUT--output
البناء من المصدر
المتطلبات الأساسية
- Go 1.21 أو أحدث
- Git
خطوات البناء
git clone https://github.com/example/proxychecker.git
cd proxychecker
go mod download
go build -o proxychecker
تشغيل الاختبارات
go test ./...
البناء لمنصات متعددة
GOOS=linux GOARCH=amd64 go build -o proxychecker-linux-amd64
GOOS=windows GOARCH=amd64 go build -o proxychecker-windows-amd64.exe
GOOS=darwin GOARCH=arm64 go build -o proxychecker-darwin-arm64
المساهمة
نرحب بالمساهمات! يرجى قراءة CONTRIBUTING.md للحصول على التفاصيل.
عملية سحب الطلبات
- قم بعمل fork للمستودع
- أنشئ فرع الميزة الخاص بك (
git checkout -b feature/amazing-feature)
- قم بعمل commit للتغييرات الخاصة بك (
git commit -m 'Add amazing feature')
- ادفع إلى الفرع (
git push origin feature/amazing-feature)
- افتح طلب سحب
الترخيص
هذا المشروع مرخص بموجب ترخيص MIT — راجع ملف LICENSE للحصول على التفاصيل.
إخلاء المسؤولية
هذه الأداة مخصصة لأغراض الاختبار الأمني المصرح به والبحث فقط. يجب عليك الحصول على إذن مناسب قبل استخدام هذه الأداة على أي شبكة أو نظام لا تملكه.```bash
urx example.com --subs --scope-file scope.txt
urx --domain-list targets.txt --subs --scope-file scope-a.txt --scope-file scope-b.txt
`*.example.com` يطابق النطاق الجذر وكذلك كل ما يندرج تحته (قراءة bug-bounty، وهو ما يعنيه جدول النطاق في المنصة)؛ المضيف المجرد يطابق ذلك المضيف بالضبط؛ `*` المنفرد يجعل الملف قائمة رفض خالصة؛ الاستثناءات تفوز دائمًا؛ `#` يبدأ تعليقًا. أي شيء لا يستطيع urx تلبيته — منفذ، مسار، حرف بدل في المنتصف — هو خطأ عند بدء التشغيل يذكر الملف والسطر بدلًا من نطاق أوسع بصمت. ينطبق المرشح على كل مزوّد وعلى الروابط المستخرجة، ويتحد مع `--strict` بدلًا من استبداله، لذا لا يزال سطر نطاق `*.example.com` بحاجة إلى `--subs`.
### مرشحات بيانات تعريف الأرشيف
يتم دفع `--from`/`--to` ومحمولات `--archive-*` إلى استعلام الأرشيف نفسه، مما يجعلها مجانية ويحدها أيضًا إلى المزوّدين المدعومين بـ CDX — وتختلف لهجتا CDX اختلافًا سيئًا بما يكفي بحيث تكون قائمة متعددة القيم موجبة (`--archive-status 200,301`) غير قابلة للتحقق على خوادم pywb. أما مرشحات `--meta-*` الثمانية فتعمل *بعد* الجمع بدلًا من ذلك، على مجموعة مدموجة واحدة من بيانات تعريف الالتقاط لكل URL، لذا تنطبق على كل مزوّد بشكل موحد.```bash
# Endpoints still being captured recently, with HTML and images out of the way
urx example.com --providers wayback --meta-last-seen-after 2024 --meta-exclude-mime 'text/html,image/*'
# Pages that died: nothing captured since 2019
urx example.com --providers wayback --meta-last-seen-before 2019
# JSON the archive served successfully
urx example.com --providers wayback --meta-mime application/json --meta-status 200
# First archived during 2020 (partial dates pad to the start / end of the period)
urx example.com --providers wayback --meta-first-seen-after 2020 --meta-first-seen-before 2020
عناوين URL التي لا تحمل أي بيانات وصفية — مزودو الخدمة غير CDX، ومدخلات --files، ونتائج الذاكرة المؤقتة — تُقسَّم حسب اتجاه المُسند: لا يمكن تلبية مُسند إيجابي بقيمة غائبة، لذا يُسقَط عنوان URL؛ أما الاستبعاد فلا يُسقط سوى ما يطابق بشكل إيجابي، لذا يبقى. يُبلِّغ --verbose عن التقسيم، وعندما تكون البيانات الوصفية المفقودة مسؤولة عن مجموعة النتائج بأكملها، يذكر urx ذلك حتى بدون -v، لأن إصابة الذاكرة المؤقتة تجعل تشغيلًا فارغًا يبدو وكأنه هدف لا يوجد فيه شيء للعثور عليه.
دمج المتشابهات تقريبًا
سيُعيد الأرشيف بكل سرور /post/1 حتى /post/99999. إنها نقطة نهاية واحدة، و--dedup-similar يطبع سطرًا واحدًا لها. يُعامَل مقطع المسار كبيانات — وليس كجزء من المسار — عندما يكون بالكامل أحد ما يلي:
- سلسلة من الأرقام (
/post/1، /page/42)
- معرّف UUID (
/u/550e8400-e29b-41d4-a716-446655440000)
- بصمة hex مكونة من 32/40/64 حرفًا (md5، sha1، sha256)
- تاريخ مفصول (
/blog/2024-01-02/)
- رمز طويل مختلط الحالة يحتوي على أرقام (معرّفات الجلسات، الكتل الموقّعة)
المقاطع التي تحتوي على أرقام فقط تبقى في مكانها، لذا يظل /api/v1/ و/api/v2/ نقطتي نهاية، والـ slug بأحرف صغيرة يُعد نصًا وليس رمزًا. تُجمَّع سلاسل الاستعلام حسب أسماء المعاملات فقط: ?q=cats&page=1 و?q=dogs&page=7 يُدمجان، بينما ?q=cats وحده لا يُدمج — فإسقاط معامل يغيّر الطلب.
الناجي من كل مجموعة هو عنوان URL الأصغر معجميًا، لذا فإن تشغيلين على نفس البيانات يطبعان نفس الشيء. يُبلِّغ --verbose عن عدد عناوين URL التي تم دمجها. الخيار مستقل عن --normalize-url و--merge-endpoint ويجتمع مع أي منهما؛ الثلاثة جميعًا يحتاجون إلى مجموعة النتائج الكاملة، لذا لا يعمل أي منها مع --stream.
عروض المعاملات والاختبار العشوائي
--show-only-param يقطع فقط سلسلة الاستعلام من كل عنوان URL، وهو ما لا يمكنه الإجابة على السؤال الأول الذي يطرحه المُختبِر: ما المعاملات التي يستقبلها هذا الهدف؟ ثلاثة عروض تجيب على ذلك، مبنية على نفس التجميع الذي يستخدمه --dedup-similar.```console
$ urx example.com --params
page
q
ref
sort
utm_source
$ urx example.com --params-by-endpoint
https://example.com/post/{id} ref,utm_source
https://example.com/search page,q,sort
$ urx example.com --fuzz-placeholder FUZZ
https://example.com/post/1?ref=FUZZ
https://example.com/post/2?utm_source=FUZZ
https://example.com/search?q=FUZZ&page=FUZZ
https://example.com/search?q=FUZZ&sort=FUZZ
`--params-by-endpoint` يطوي مقاطع المسار التي تشبه المعرّفات إلى `{id}` تمامًا كما
يفعل `--dedup-similar`، ويكتب نقطة النهاية بالكامل لأن urx
يفحص عادةً عدة مضيفين في تشغيل واحد. يُبقي `--fuzz-placeholder` عنوان URL واحدًا لكل
توقيع معامل ويحتفظ بمساره الحقيقي — إذ لن يتم توجيه `{id}` — لذا يتغذى
الناتج مباشرةً إلى أداة fuzzer:```bash
urx example.com --fuzz-placeholder FUZZ | ffuf -w - -u FUZZ
urx example.com --fuzz-placeholder FUZZ | dalfox pipe
جميعها تحتاج إلى مجموعة النتائج الكاملة، لذا فهي تعمل على دفعات فقط وتتعارض بشكل متبادل مع بعضها البعض ومع عروض --show-only-*.
مخرجات قائمة الكلمات
-f wordlist يحوّل التشغيل إلى قائمة كلمات خاصة بالهدف: كل مقطع مسار
واسم معامل استعلام رآه، منزوع التكرار عبر التشغيل بأكمله ومرتب،
مصطلح واحد في كل سطر.```bash
urx example.com --subs -f wordlist -o words.txt
ffuf -w words.txt -u https://example.com/FUZZ
المقاطع التي تبدو كبيانات وليست أسماء مسارات تُترك خارجًا، مع إعادة استخدام مجموعات اختبار `--dedup-similar` — فقائمة كلمات مليئة بـ `4711` ومعرّفات UUID والتواريخ ورموز الجلسات أسوأ من عدم وجود قائمة كلمات، لأن كل كلمة من هذه الكلمات موجودة على هدف واحد فقط. ويُستبعد أيضًا المقطع الذي يكون جذعه معرّفًا (`article-1234.html`). تُحفظ حالة الأحرف: فمقاطع المسار حساسة لحالة الأحرف في معظم الأصول، لذا فإن تحويل `WebResource.axd` إلى أحرف صغيرة سينتج كلمة تُرجع 404 في كل مكان تُجرَّب فيه. يجب أخذ الاتحاد على المجموعة الكاملة، لذا فإن الصيغة تعمل على دفعات فقط.
### الإخراج المتدفق
افتراضيًا، يجمع urx كل شيء، ثم يرشّح ويرتّب ويطبع مرة واحدة. على هدف كبير يعني ذلك عدم وجود أي إخراج حتى ينتهي أبطأ أرشيف. يكتب `--stream` كل URL في اللحظة التي يعود فيها المزوّد الذي أبلغ عنه:```bash
# Matches start appearing immediately instead of after the slowest provider
urx big-target.com --stream | grep admin
# Line-delimited JSON stays valid while it is still being written
urx big-target.com --stream -f jsonl | jq -r 'select(.url | test("/api/")) | .url'
تُمرَّر عناوين URL المتدفقة عبر نفس المرشحات تمامًا كما في التشغيل الدفعي، ولا تزال
منزوعة التكرار. هناك أمران مختلفان:
- الترتيب. تصل النتائج بترتيب اكتمال المزوّد، لذا يكون الناتج
غير مرتّب. مرّره عبر
sort إذا كنت بحاجة إلى ترتيب.
- النطاق. تُرفض مسبقًا الخيارات التي تحتاج إلى مجموعة النتائج الكاملة
(مع رسالة تسمّي كل واحد منها):
--merge-endpoint، --dedup-similar،
--check-status /
--include-status / --exclude-status، --extract-links،
--extract-js-endpoints، --archive-body، --expand-specs،
--incremental، --show-sources، --show-meta، ومرشحات --meta-*،
--params، --params-by-endpoint، --fuzz-placeholder، --output-dir، و
--files. يتم تجاوز التخزين المؤقت؛
ويُرفض --format json لصالح jsonl لأن مصفوفة JSON يجب أن
تعرف أي مدخل هو الأخير، ويُرفض --format wordlist لأنه لا يمكن معرفة
أن أي مصطلح جديد حتى تصل كل عناوين URL.
ولأن خريطة نتائج الدفعة لا تُملأ أبدًا في هذا الوضع، فإن التشغيل المتدفق
يحتفظ أيضًا بذاكرة أقل بكثير — فقط مجموعة إزالة التكرار لعناوين URL المكتوبة بالفعل.
بيانات وصفية لالتقاط الأرشيف
يسجّل فهرس CDX أكثر من عنوان URL: كل التقاط يحمل طابعًا زمنيًا، ونوع MIME
وحالة HTTP التي رآها الأرشيف، وبصمة لمحتوى الجسم. يحتفظ urx
بكل ذلك، لذا فإن المزوّدات المدعومة بـ CDX — wayback، cc، arquivo، وأي
--cdx-endpoint — تُبلّغ عن كل عنوان URL مع:
الحقل المعنى first_seenأقدم طابع زمني للالتقاط، بصيغة CDX المكوّنة من 14 رقمًا (YYYYMMDDhhmmss) last_seenأحدث طابع زمني للالتقاط mimeنوع MIME لأحدث التقاط سجّل واحدًا archive_statusحالة HTTP التي سجّلها الأرشيف وقت الالتقاط digestبصمة محتوى تمثيلية عبر عمليات الالتقاط
archive_status ليس status: لا يظهر status إلا تحت --check-status،
الذي يعيد طلب عنوان URL مباشرة الآن، بينما archive_status هو ما حصل عليه الزاحف
عندما التقط الصفحة. يمكن أن يكون عنوان URL تمامًا archive_status
200 وميتًا اليوم.
حيثما يأتي عنوان URL نفسه من عدة عمليات التقاط أو عدة أرشيفات، تُدمج
القيم: first_seen هو أقدم طابع زمني أبلغ عنه أي مصدر، وlast_seen
الأحدث، ويأتي mime/archive_status من أحدث التقاط
كان يمتلكهما. المزوّدات التي لا تملك فهرس التقاط (otx، vt، urlscan، zoomeye،
github، bevigil، robots، sitemap، ومدخل --files) تُبلّغ عن عنوان URL
وحده — لا تُختلق قيم لها.
تعتمد طريقة ظهور البيانات الوصفية على الصيغة:
json / jsonl — يظهر كل حقل كمفتاح عندما تكون له قيمة ويُحذف
تمامًا عندما لا تكون له، تمامًا مثل sources.
csv — يُضاف عمود فقط عندما يكون لصف واحد على الأقل قيمة له،
لذا فإن تشغيلًا بلا بيانات وصفية لا يزال ينتج عمود url واحدًا.
- نص عادي — دون تغيير افتراضيًا، عنوان URL واحد مجرّد لكل سطر، لذا تستمر
خطوط الأنابيب الحالية في العمل. مرّر
--show-meta لإلحاق الحقول.```bash
Rich records: when the URL was alive, and what it served
urx example.com --providers wayback -f jsonl
{"url":"https://example.com/old.php","first_seen":"20040112093000",
"last_seen":"20180722140311","mime":"text/html","archive_status":"200",
"digest":"HT2DYGA5UKZCPBSFVCV3JOBXGW2G5UUA"}
Triage by age: everything last captured before 2010
urx example.com -f jsonl | jq -r 'select(.last_seen < "20100101000000") | .url'
Opt plain output into the metadata
urx example.com --providers wayback --show-meta
البث (`--stream`) يبلّغ عن عناوين URL فقط. يُطبع عنوان URL عند أول رؤية له،
قبل وصول عمليات الالتقاط التي من شأنها توسيع نطاق `first_seen`/`last_seen` الخاص به،
لذلك يُرفض `--show-meta` هناك لنفس السبب الذي يُرفض به
`--show-sources`.
إصابة ذاكرة التخزين المؤقت لا تحمل أيضًا أي بيانات وصفية: تخزّن ذاكرة التخزين المؤقت عناوين URL، لذا فإن نطاقًا يُخدَّم
من ذاكرة التخزين المؤقت يبلّغ عن عناوين URL الخاصة به دون حقول الالتقاط. استخدم `--no-cache` (أو انتظر
انتهاء صلاحية TTL) للحصول على تشغيل يعيد ملء هذه الحقول.
### البيانات الوصفية للاستجابة الحية
`--check-status` يرسل بالفعل طلبًا وينتظر رأس الاستجابة، لذا فإن
ما يحمله ذلك الرأس يأتي مجانًا: يُسجَّل `Location` و`Content-Length` و
`Content-Type` إلى جانب رمز الحالة. لا تُتبَع عمليات إعادة التوجيه أبدًا،
لذا فإن الحالة المُبلَّغ عنها تنتمي دائمًا إلى عنوان URL الذي طُلب منه
و`location` تقول ببساطة إلى أين أشارت استجابة 3xx.
`--check-title` يضيف عنوان HTML `<title>`. إنه الحقل الوحيد غير المجاني —
فالعنوان يحتاج إلى جسم الاستجابة — لذا يقع خلف علم خاص به. القراءة
محدودة مرتين (بحد أقصى 64 KiB، وتتوقف عند وسم الإغلاق) وتُتخطى
بالكامل لجسم أعلن الخادم أنه غير HTML، لذا فإن واجهة JSON API أو صورة
لا تكلف شيئًا. يُدمج العنوان من المسافات البيضاء، ويُفكّ ترميز الكيانات، ويُقتطع إلى 200
حرف. `--check-title` يستلزم `--check-status`.```bash
urx example.com --check-status -f jsonl
urx example.com --check-title --show-meta
urx example.com --check-status --is 30x -f jsonl | jq -r '.url + " -> " + .location'
يتبع الإفصاح القاعدة التي حددتها بيانات تعريف الأرشيف مسبقًا: json/jsonl/csv
تحمل الحقول دائمًا (تُحذف المفاتيح الغائبة، وتُضاف أعمدة CSV
بعد الأعمدة الموجودة)، بينما يبقى النص العادي عنوان URL واحدًا مجردًا لكل سطر
ما لم يطلب --show-meta خلاف ذلك. في المخرجات العادية يُوضع العنوان بين علامتي اقتباس، لأنه
القيمة الوحيدة التي تحتوي عادةً على مسافات.
الطلبات الموثّقة والمخصّصة
--check-status و--extract-links و--extract-js-endpoints و
--expand-specs جميعها تعيد طلب عناوين URL المجمّعة من الهدف نفسه. يمنح -H
تلك الطلبات أي ترويسات تحتاجها:```bash
urx example.com --check-status -H "Authorization: Bearer $TOKEN"
urx example.com --extract-links --cookie "session=abc; role=admin"
urx example.com --check-status --user-agent "acme-security-scan/1.0"
`-H` قابل للتكرار، ويأخذ `Name: value`، وإذا كان مشوّهاً يوقف التشغيل
بدلاً من أن يمر دون أن يُلاحظ — فوسيط يُسقَط بصمت يترك
فحصاً مجهول الهوية يُقرأ كأنه موثّق. `--cookie` و
`--user-agent` اختصارات للترويسات المقابلة.
**هذه الترويسات لا تصل أبداً إلى أرشيف.** تُرسَل فقط من المكوّنات
التي تتحدث إلى الهدف: الفاحصات الأربعة أعلاه، بالإضافة إلى مزوّدي `robots` و
`sitemap`، اللذين يجلبان من الهدف أيضاً. كل مزوّد آخر
يستعلم من web.archive.org أو index.commoncrawl.org أو واجهة برمجة تطبيقات طرف ثالث، وكذلك
يفعل `--archive-body` عندما يعيد تشغيل لقطة محفوظة؛ تسليمهم ملف تعريف ارتباط جلسة الهدف
سيعني إرسال بيانات اعتماد بالبريد إلى خدمة تحتفظ بما
تستقبله، دون أي فائدة. استعلامات الأرشيف تحتفظ بـ User-Agent الخاص بـ urx، والذي
لا يزال `--random-agent` يبدّله.
### استخراج أجسام الاستجابات المؤرشفة
`--extract-links` يجلب كل رابط مُجمَّع من الموقع الحي، وهو
بالضبط المكان الخاطئ للبحث عن الصفحات التي يهتم بها مسح OSINT أكثر من غيرها:
تلك التي لم تعد موجودة. `--archive-body` يجلب الأجسام التي خزّنها Wayback
Machine بدلاً من ذلك. لكل رابط مُجمَّع يحمل طابعاً زمنياً للقطة محفوظة،
يعيد urx تشغيل تلك اللقطة بشكلها الخام
(`https://web.archive.org/web/<timestamp>id_/<url>` — علم `id_` يوقف
شريط أدوات Wayback وإعادة كتابة الروابط، فيكون الجسم هو البايتات الأصلية) و
يشغّل عليه نفس استخراج الروابط الذي يستخدمه `--extract-links`.```bash
# Links from the archived bodies of everything the CDX providers found
urx example.com --archive-body
# Bound the run and pace it; the archive is one host no matter how many URLs
urx example.com --archive-body --archive-body-limit 200 --rate-limit 5
# Only the JavaScript those pages referenced back then
urx example.com --archive-body -e js
لماذا يحتاج هذا إلى طلبات أقل بكثير من waymore. كل صف CDX يحمل
بصمة محتوى، ولقطتان لهما البصمة نفسها تكونان متطابقتين بايتًا ببايت في
المحتوى. الأرشيفات مليئة بها: كل نسخة ?utm_source= من صفحة،
وكل /index.html بجانب / الخاص بها، وكل تبديل لمعاملات التتبع
يقدّم بايتات متطابقة، لذا فإن قائمة بعشرات الآلاف من عناوين URL تنهار
عادةً إلى بضعة آلاف من المحتويات المتميزة. لا يملك waymore أي تصور
لهذا — فهو ينزّل استجابة واحدة لكل URL ويتعامل مع الحجم عبر حد
-l 5000 الفظ، الذي يرهق الأرشيف ويقتطع التغطية معًا. بينما urx
يطالب بكل بصمة عند رؤيتها لأول مرة ويتخطى كل URL لاحق كان سيعيد
نفس البايتات، لذا فإن نفس التغطية تكلّف طلبًا واحدًا لكل محتوى متميز.
يحدّ --archive-body-limit (الافتراضي 500) من المحتويات المتميزة،
وليس عناوين URL؛ لا تُحتسب التكرارات أبدًا ضده، ويبلّغ --verbose عن عدد
ما تم تخطيه.
استخراج JavaScript المؤرشف. تعيش واجهة API لتطبيق حديث في حزمه
كسلاسل نصية حرفية، ويجلب --extract-js-endpoints تلك من الموقع الحي — حيث
تكون غالبًا قد اختفت. تُسمّى الحزم ببصمة البناء، لذا فإن app.a3f9c2.js
يعطي 404 لحظة إعادة نشر الموقع، وتذهب معه نقاط النهاية التي كان يسميها.
شغّل العَلمين معًا وسيقوم urx باستخراج النسخة المؤرشفة بدلًا من ذلك،
وكتل كتل <script> المضمّنة في صفحة مؤرشفة إلى جانب روابطها:```bash
urx example.com --archive-body --extract-js-endpoints
**الاحتفاظ بالمحتوى.** الطلبات تُجرى بالفعل، لذا فإن كتابة المحتوى على القرص لا تكلّف شيئًا إضافيًا وتجيب على الأسئلة التي لا يطرحها أي مستخرج روابط: تعليق `<!-- staging.internal -->`، والرمز الذي قام بناء عام 2019 بتضمينه، وتتبع المكدس الذي يسمّي إصدار إطار العمل.```bash
urx example.com --archive-body --archive-body-dir ./corpus
grep -ri "api[_-]key" ./corpus
كل ملف يُسمّى باسم رابطه URL بالإضافة إلى تجزئة له، وcorpus/index.jsonl
يربط كل ملف مرة أخرى برابط URL الخاص به، وطابع وقت الالتقاط، والبصمة، ونوع المحتوى.
تُخزَّن فقط الأجسام النصية — HTML، script، JSON، XML، CSS، نص عادي —
حتى لا يمتلئ الدليل بصور الموقع وخطوطه. ولأن
الجلب مُزال التكرار حسب البصمة، فإن المجموعة تغطي قدرًا أكبر بكثير من الهدف لكل
طلب مما تفعله استجابة واحدة لكل URL.
تفاصيل جديرة بالمعرفة:
- فقط روابط URL التي لها طابع وقت التقاط هي المؤهلة. مزوّدو CDX (
wayback،
cc، arquivo) يوفّرون واحدًا؛ مدخل --files، والمزوّدون غير CDX، والنتائج
المخزّنة مؤقتًا (الذاكرة المؤقتة تخزّن روابط URL فقط) ليس لديها أي منها. يقول urx ذلك عندما لا
يكون هناك شيء لإعادة تشغيله — مرّر --no-cache للحصول على عمليات التقاط جديدة.
- يُعاد تشغيل أحدث عملية التقاط لكل URL. الطابع الزمني الذي يُبلّغ عنه أرشيف آخر
يهبط على أقرب عملية التقاط في Wayback؛ أما URL الذي لم يره Wayback Machine قط
فيجيب بـ 404 ويُتخطّى. عمليات الالتقاط التي سجّلها الأرشيف كأخطاء
لا تُستخرَج، تمامًا كما يتجاهل
--extract-links صفحات الأخطاء الحية.
- تخضع الروابط المكتشفة لنفس المرشّحات، والتحقق من المضيف، وتحويلات
المخرجات ككل شيء آخر، ويُحدّد سقف كل جسم عند 10 MiB.
- تنطبق
--rate-limit، و--rate-limit-by wayback=N، و--parallel، و--proxy،
و--timeout، و--retries جميعها على طلبات إعادة التشغيل.
- غير متوافق مع
--stream، مثل كل خيار يعمل بعد الجمع.
توسيع مواصفات API
مسح -p only-api يجد /swagger.json، و/openapi.yaml، و/v3/api-docs
ثم لا يفتحها أبدًا: --extract-links يحلّل HTML، و--extract-js-endpoints
يُسقط أجسام application/json، و--archive-body يشغّل محلّل HTML على
أي شيء يعيده الأرشيف. أما --expand-specs فيقرأها ويوسّع كل مسار
تصفه إلى مجموعة النتائج — طلب واحد يشتري السطح الموثّق بالكامل، دقيقًا ومُعامَلًا بالفعل.```bash
urx example.com -p only-api --expand-specs
urx example.com --expand-specs --max-spec-files 10 --rate-limit 2
Recover an API the live host no longer serves: read the archived document
urx example.com --archive-body --expand-specs
ما الذي يتم توسيعه:
* **OpenAPI 3.x** — `servers[].url` (مطلق، نسبي إلى المستند، وقوالب،
مع `{var}` يُحل من `variables[var].default` أو أول قيمة في `enum`)
متقاطعًا مع كل مفتاح في `paths`؛ حيث تتجاوز `servers` الخاصة بعنصر المسار
تلك الخاصة بالمستند.
* **Swagger 2.0** — `schemes` × `host` + `basePath`، مع رجوع كل جزء إلى
الجزء المقابل من عنوان URL الخاص بالمستند نفسه. يتم إسقاط `ws`/`wss`.
* **استبطان GraphQL** — عنوان URL واحد لكل حقل استعلام وطفرة واشتراك،
مكتوب كعنوان النقطة النهائية بالإضافة إلى `?query=…`. المخطط المحفوظ كملف
يُحل إلى نقطته النهائية (`/graphql/schema.json` → `/graphql`).
يتم قراءة كل من JSON و YAML. يتم اختيار الأهداف بالاسم أولاً ومجانًا (سلسلة
فرعية مميزة للمواصفة — `swagger`، `openapi`، `api-docs`، `graphql`،
`introspection` — بالإضافة إلى امتداد `json`/`yaml`/`yml` عند وجوده، لذا
فإن `swagger-ui.html` لا يكلف أي طلب)، ثم بواسطة `Content-Type` الخاص
بالاستجابة. يتم إصدار قوالب المسار كما يكتبها المستند (`/users/{id}`، وليس
`/users/%7Bid%7D`). يتم تحديد حجم الأجسام بحد أقصى 10 MiB، ويُرفض مستند YAML
يحتوي على أكثر من 32 مرجعًا بديلاً قبل التحليل لاستبعاد قنابل التوسيع.
يحد `--max-spec-files` (الافتراضي 50) من المستندات التي يتم جلبها. مع تفعيل
`--archive-body` أيضًا، تُقرأ المواصفة المؤرشفة كواحدة دون تكلفة طلب إضافية —
فقد كان الجسم يُجلب بالفعل.
### robots.txt و sitemap.xml المؤرشفان
يقرأ مزودا `robots` و `sitemap` الملفات *الحية*، التي تخبر فقط بما يخفيه
الموقع أو يسرده اليوم. يقرأ `--archived-discovery` أيضًا كل نسخة مميزة من
تلك الملفات خزّنها Wayback Machine. يشير `Disallow:` من عام 2015 إلى مسارات
توقف الموقع عن ذكرها منذ ذلك الحين — غالبًا لأنها كان يُقصد نسيانها، وليس
لأنها اختفت — كما تسرد خريطة موقع قديمة كل ما أراد الموقع زحفه في يوم من
الأيام.```bash
# Every archived version of robots.txt and sitemap.xml, alongside the live ones
urx example.com --archived-discovery
# Bound it and pace it; both archived providers answer to --rate-limit-by
urx example.com --archived-discovery --archived-discovery-limit 20 --rate-limit-by robots=2,sitemap=2
# Only the versions captured in a given era
urx example.com --archived-discovery --from 2014 --to 2016
كيف يعمل، ولماذا هو رخيص:
- تُدرَج إصدارات المستند باستعلام CDX واحد لكل ملف
(
robots.txt، sitemap.xml، sitemap_index.xml، sitemap.txt)، باستخدام
collapse=digest بحيث تُطوى اللقطات المتتالية التي قدّمت البايتات نفسها في
صف واحد. لا يُطلب إلا الصفوف المسجّلة كنجاح: يطوي الفهرس www. والنطاق
الجذري في قائمة واحدة، وإلا فإن صفوف 301/200 المتشابكة بينها تُبطل
الطيّ — بالنسبة إلى github.com/robots.txt فإن ذلك يعني 325 ألف صف بدون
المرشّح و14 ألف صف معه، لنفس الإصدارات المميّزة البالغ عددها 107.
- يُعاد تشغيل كل إصدار مميّز بصيغته الخام (
/web/<timestamp>id_/…) ويُسلَّم
إلى المحلّل نفسه المستخدم مع الملف الحيّ. لا محلّل ثانٍ: يُقرأ ملف
robots.txt من 2015 بالقواعد نفسها التي يُقرأ بها الملف الحالي، بما في ذلك
ضوابط المسار المطلق وتخطّي الأنماط. ويُتبَع <sitemapindex> المؤرشف إلى
أبنائه كما كانوا في تلك اللحظة نفسها.
- تُتخطّى اللقطات التي سجّلها الأرشيف كأخطاء (كان robots.txt الخاص بـ
github.com يعيد 401 لجزء من عام 2007) دون إرسال طلب، ولا تُبلَّغ إلا تحت
--verbose.
- يحدّ
--archived-discovery-limit (الافتراضي 50) من عدد المستندات التي
يجلبها كل مزوّد مؤرشف لكل نطاق، بدءًا بأحدث الإصدارات؛ وتُحتسب خرائط
الموقع المتداخلة. ويخبرك --verbose عندما يقتطع الحدّ القائمة.
- تعمل المتغيّرات المؤرشفة كنسخ مزوّد مستقلة — "Robots.txt (archived)"
و"Sitemap (archived)" في
--stats و--show-sources — لكن تحت المعرّفات
الحالية robots / sitemap، لذا فإن --exclude-robots
و--exclude-sitemap و--rate-limit-by robots=N تحكم كلاً من القراءات
الحيّة والمؤرشفة. ويضيّق --from / --to الإصدارات التي تُؤخذ في الحسبان.
- يعمل مع
--stream؛ فهو مزوّد كأي مزوّد آخر.
الترشيح من جهة الأرشيف
يُقيَّم --archive-status و--archive-mime و--from و--to بواسطة فهرس CDX
الخاص بالأرشيف لا بواسطة urx. ومن الجدير معرفة نتيجتين:
- تنطبق فقط على المزوّدات المدعومة بـ CDX —
wayback وcc وarquivo وأي
--cdx-endpoint. وتتجاهلها المزوّدات الأخرى؛ ويحذّر urx عندما لا يكون أي
منها مفعّلاً.
- لا تتشارك الأرشيفات لهجة ترشيح واحدة. يتعامل Wayback Machine (وأي نقطة
نهاية
--cdx-dialect classic) مع القيم باعتبارها تعبيرات نمطية، لذا
فإن --archive-status "30." يطابق أي 3xx. أما Common Crawl وArquivo.pt
ونقاط نهاية pywb فتطابق مطابقة تامة، ويجمع فهرسها المرشّحات المتكرّرة
بمنطق AND — لذا فإن قائمة موجبة متعددة القيم مثل --archive-status 200,301
غير قابلة للتحقيق هناك. يتخطّى urx ذلك المرشّح لدى هؤلاء المزوّدين (مع
تحذير) بدلاً من إرسال استعلام سيعود فارغًا. أما الاستثناءات متعددة القيم
فتعني "ليس هذا وليس ذاك" وتعمل في كل مكان.
استخدم --archive-status عندما تريد ما سجّله الأرشيف وقت الزحف،
و--check-status / --include-status عندما تريد حالة الهدف الآن؛ فالأخيرة
تعيد طلب كل عنوان URL.
نقاط نهاية CDX المخصّصة
كل أرشيف ويب مبني على pywb أو OutbackCDX أو خادم CDX الخاص بـ Internet
Archive يوفّر واجهة الاستعلام نفسها. وبدلاً من ترميز مزوّد لكل أرشيف بشكل
ثابت، يحوّل --cdx-endpoint URL أي خادم من هذا القبيل إلى مزوّد في الحال:```bash
The Icelandic web archive, alongside the default providers
urx example.is --cdx-endpoint https://vefsafn.is/cdx
Several at once; each gets its own progress line, stats row and rate limit
urx example.com --cdx-endpoint https://vefsafn.is/cdx --cdx-endpoint http://localhost:8080/cdx
--rate-limit-by cdx:vefsafn.is=1
* معرّف المزوّد هو `cdx:<host>` (`cdx:vefsafn.is`)، وهو ما تستخدمه
`--exclude-providers` و`--rate-limit-by` و`--stats` و`--show-sources`.
تسمية نقطة نهاية تُفعّلها؛ لا حاجة إلى مدخل `--providers`، و
`--providers cdx:vefsafn.is` يشغّلها وحدها. يُظهر `--list-providers`
نقاط النهاية المُسمّاة على نفس سطر الأوامر مع المعرّفات التي ستعمل بها.
* كل ما تلتزم به مزوّدات CDX المدمجة ينطبق هنا أيضًا: `--subs`،
`--from`/`--to`، مرشّحات `--archive-*`، ترقيم الصفحات، `--rate-limit`، و
بيانات الالتقاط الوصفية المذكورة أعلاه.
* `--cdx-dialect classic|pywb` يسمّي لهجة الخادم (أسماء الحقول، دلالات
الترشيح، تنسيق الصفوف ومخطط ترقيم الصفحات كلها تتبعها — انظر
"الترشيح من جهة الأرشيف"). إذا تُرك دون تعيين، يستكشف urx نقطة النهاية
مرة واحدة لكل تشغيل ويرجع إلى `pywb`، اللهجة الأكثر شيوعًا؛ عيّنه صراحةً
عندما لا يستطيع الاستكشاف التمييز (إجابة فارغة لنطاق غير معروف، على سبيل
المثال).
* يمكن أيضًا تعيينه في ملف الإعدادات (`cdx_endpoint = [...]`، `cdx_dialect`).
**نقاط النهاية المُتحقَّق منها.** حتى كتابة هذه السطور، نقطة النهاية العامة
الوحيدة المؤكَّد عملها من البداية إلى النهاية هي `https://vefsafn.is/cdx`
(أرشيف الويب الأيسلندي التابع لـ Landsbókasafn، لهجة pywb). أمران يجب
معرفتهما عنها: أنها تتجاهل `limit` و`page` و`showNumPages` وتعيد مجموعة
النتائج الكاملة لكل استعلام، وهو ما يتعامل معه urx؛ وبعد بضعة طلبات قد تبدأ
في الإجابة بصفحة حماية من الروبوتات على نمط Anubis ("التحقق من الجلسة").
يكتشف urx إجابة HTML بدلًا من صفوف CDX ويبلّغ عنها كخطأ مزوّد يسمّي نقطة
النهاية — ولا تُحتسب أبدًا كـ "لا عناوين URL". إذا واجهتها، أبطئ باستخدام
`--rate-limit-by cdx:vefsafn.is=1` أو أعد المحاولة لاحقًا.
**المعروف أنها لا تعمل.** أرشيف الويب البريطاني (`webarchive.org.uk`)،
وأرشيف الويب لمكتبة الكونغرس (`webarchive.loc.gov`)، ومكتبة الإسكندرية،
والمكتبة الوطنية الأسترالية (`web.archive.org.au`) كلها تقف خلف حماية من
الروبوتات أو عمليات إعادة توجيه تحجب واجهات CDX الخاصة بها عن عميل سطر
الأوامر. لا يحاول urx الالتفاف على ذلك، لذا فإن توجيه `--cdx-endpoint`
إليها يُنتج خطأ إجابة HTML المذكور أعلاه.
### التخزين المؤقت والمسح التزايدي
يدعم Urx التخزين المؤقت لتحسين الأداء للمسحات المتكررة والمسح التزايدي
لاكتشاف عناوين URL الجديدة فقط.```bash
# Enable caching with SQLite (default)
urx example.com --cache-type sqlite --cache-path ~/.urx/cache.db
# Use Redis for distributed caching
urx example.com --cache-type redis --redis-url redis://localhost:6379
# Incremental scanning - only show new URLs since last scan
urx example.com --incremental
# Set cache TTL (time-to-live) to 12 hours
urx example.com --cache-ttl 43200
# Disable caching entirely
urx example.com --no-cache
# Combine incremental scanning with filters
urx example.com --incremental -e js,php --patterns api
# Configuration file with caching settings
urx -c example/config.toml example.com
إدارة الذاكرة المؤقتة
يفحص urx cache الذاكرة المؤقتة ويصونها دون الحاجة إلى لمس قاعدة البيانات يدويًا. تحترم كل أوامر فرعية نفس --cache-type و--cache-path و--redis-url و--cache-ttl التي يستخدمها الفحص، وجميع الأوامر الخمسة تعمل مع كلا الخلفيتين.```bash
urx cache stats # entries, domains, URLs, age span, size, expired count
urx cache list # per-domain counts, last scan, TTL remaining
urx cache list --domain '*.example.com'
urx cache prune # delete only what --cache-ttl has expired
urx cache drop example.com # rescan one target without clearing the rest
urx cache clear --yes # delete everything
machine-readable
urx cache stats -f json | jq '.expired_entries'
مطابقة النطاق غير حساسة لحالة الأحرف و**دقيقة** ما لم يحتوي النمط على
`*` — كان الافتراضي القائم على السلسلة الفرعية سيتيح لـ `drop example.com` إزالة
`notexample.com` أيضًا. يسأل `clear` قبل الحذف ويرفض
stdin غير تفاعلي بدلًا من افتراض إجابة، ويسمّي `drop` أي نمط
لم يطابق شيئًا، والنظر إلى ذاكرة التخزين المؤقت لا ينشئ واحدة أبدًا، ويتم كنس Redis
بـ `SCAN` بدلًا من `KEYS` الحاجب (مع حجب أي كلمة مرور في `--redis-url`
قبل طباعتها).
#### حالات استخدام التخزين المؤقت```bash
# Daily monitoring - only alert on new URLs (built-in webhook, see below)
urx target.com --incremental --silent --notify https://hooks.slack.com/services/... --notify-format slack
# ...or hand the new URLs to an external notifier
urx target.com --incremental --silent | notify-tool
# Efficient domain lists processing
cat domains.txt | urx --incremental --cache-ttl 3600 > new_urls.txt
# Distributed team scanning with Redis
urx example.com --cache-type redis --redis-url redis://shared-cache:6379
# Fast re-scans during development
urx test-domain.com --cache-ttl 300 # 5-minute cache for rapid iterations
إشعارات Webhook
--notify <URL> يرسل POST بملخص التشغيل إلى webhook عند انتهاء التشغيل،
مما يحوّل --incremental إلى مراقب: ضعه في cron ولن يُطلق الـ webhook
إلا عند ظهور شيء جديد.```bash
Slack incoming webhook, only when the run finds new URLs (the default)
urx target.com --incremental --silent
--notify https://hooks.slack.com/services/T000/B000/XXXX --notify-format slack
Discord, and send even when nothing is new
urx target.com --incremental --notify "$DISCORD_HOOK" --notify-format discord --notify-on always
Several receivers, urx's own JSON schema (the default format)
urx target.com --incremental --notify https://n8n.example/hook --notify https://ntfy.example/urx
Keep the webhook out of the shell history
export URX_NOTIFY_URL=https://hooks.slack.com/services/...
urx target.com --incremental --notify-format slack
- `--notify-on` هو `new` افتراضيًا: لا يُرسل شيء عندما لا يُنتج التشغيل أي
عناوين URL، لذا يبقى تشغيل cron الهادئ هادئًا. `always` يُرسل بغض النظر؛ `never`
يُبقي الإعدادات لكنه يُعطّل الإرسال.
- `--notify-format json` (الافتراضي) يُرسل مخطط urx: `domains`،
`incremental`، `url_count`، `new_url_count`، `elapsed_ms`، قائمة `providers`
لكل مزوّد (نفس الأرقام التي يطبعها `--stats`)، و`sample` لما يصل إلى
20 عنوان URL مُصدَر مع ضبط `sample_truncated` عند العثور على المزيد.
`slack` يُرسل `{"text": ...}` و`discord` يُرسل `{"content": ...}` مع
رسالة قصيرة مقروءة بشريًا؛ الرسائل الأطول مما تسمح به الخدمة تُقطع
عند حدّ السطر وتنتهي بـ `[truncated: N lines cut ...]`.
- التسليم لا يُغيّر رمز الخروج أبدًا. تكون عناوين URL بالفعل على stdout أو في
`--output` بحلول وقت استدعاء الـ webhook، لذا فإن webhook ميت يُعدّ تحذيرًا
على stderr ويظل التشغيل يخرج بالرمز 0. يُظهر `--verbose` حالة الاستجابة.
- عنوان URL الخاص بالـ webhook هو بيانات اعتماد. لا يطبع urx أبدًا أكثر من
مخططه ومضيفه — لا في `--verbose`، ولا في التحذيرات، ولا في `--stats`. لإبقائه
خارج إعدادات مُودَعة في المستودع، ضعه في `URX_NOTIFY_URL` أو كـ
`notify_url` في ملف إعدادات المزوّد؛ كما يعمل `[notify].url` في الإعدادات
الرئيسية. الأولوية هي CLI/env > إعدادات المزوّد > الإعدادات الرئيسية.
- يحترم الطلب `--proxy` و`--proxy-auth` و`--timeout` و`--insecure`.
لا ينطبق `--network-scope`: فهو يقسّم حركة المرور الموجّهة إلى الهدف
والأرشيفات، بينما الـ webhook هو نقطة النهاية الخاصة بك.
- لا يزال `--silent` يُرسل (فهذه هي حالة الاستخدام الرئيسية)؛ إنه فقط يخفي
التشخيصات.
## التكامل مع الأدوات الأخرى
يعمل Urx جيدًا في خطوط الأنابيب مع أدوات الأمن والاستطلاع الأخرى:```bash
# Find domains, then discover URLs
echo "example.com" | urx | grep "login" > potential_targets.txt
# Combine with other tools
cat domains.txt | urx --patterns api | other-tool
الإلهام
استُلهم Urx من gau (GetAllUrls)، وهي أداة تجلب عناوين URL المعروفة من AlienVault's Open Threat Exchange وWayback Machine وCommon Crawl. ورغم مشاركتهما لوظائف أساسية متشابهة، فقد بُني Urx من الصفر بلغة Rust مع التركيز على الأداء والتزامن وقدرات التصفية الموسّعة.
المساهمة
Urx مشروع مفتوح المصدر وصُنع بـ ❤️
إذا كنت ترغب في المساهمة في هذا المشروع، فيرجى الاطلاع على CONTRIBUTING.md وإرسال Pull-Request بمحتواك الرائع.