Zero to Red Team: Master Shodan Dorking in One Read

medium.com · Shubham Gupta · 20 days ago · tutorial
quality 7/10 · good
0 net
Tags
Zero to Red Team: Master Shodan Dorking in One Read | by Shubham Gupta - Freedium Milestone: 20GB Reached We’ve reached 20GB of stored data — thank you for helping us grow! Patreon Ko-fi Liberapay Close < Go to the original Zero to Red Team: Master Shodan Dorking in One Read From Zero Queries to Enterprise Red Team Reconnaissance — Everything You Need to Master the World's Most Powerful Search Engine Shubham Gupta Follow ~25 min read · March 22, 2026 (Updated: March 22, 2026) · Free: Yes Before We Start — A Quick Reality Check You've probably heard this before: "Security through obscurity is not security." But here's the thing nobody tells you — the internet has been quietly proving that point every single day, for years. Right now, as you read this, there are hundreds of thousands of devices sitting exposed on the public internet. Databases with no passwords. Security cameras streaming live footage. Industrial control systems running power grids. All of it — findable, indexable, and searchable — if you know which tool to open. That tool is Shodan . And the skill of writing precise, targeted Shodan queries? That's called Shodan Dorking — and it might just be the most underrated skill in the entire cybersecurity field. This is not a surface-level "here are 5 cool Shodan tricks" article. This is the complete picture — from how Shodan actually works under the hood, to the dorks that professional red teams use, to building a full enterprise attack surface map. Grab a coffee. Let's go deep. 🎉 Fun Fact #1: Shodan was built by John Matherly in 2009. He originally called it the "Sentient Hyper-Optimized Data Access Network." He was 18 when he started working on it. The cybersecurity industry has never been the same. Part 1: What Is Shodan and Why Is It Different From Google? Google crawls web pages . It follows links, reads HTML, and builds a map of content humans wrote for humans to read. Shodan crawls everything else . Every device that listens on the internet — every open port, every responding service — Shodan's scanners have connected to it, grabbed the raw response (called a banner ), and indexed every single byte of it. That means: Webcams streaming live footage Routers running firmware from 2014 Industrial control systems managing water treatment plants Databases with no authentication enabled Smart fridges, smart TVs, smart locks — the whole IoT mess Corporate servers with forgotten admin panels Printers that have more open ports than your firewall policy allows Google will never show you these. Shodan exists specifically to show you these. 🎉 Fun Fact #2: In 2012, a security researcher found over 500,000 devices still using the Telnet default password "1234" — just from a single Shodan search. Half a million devices. Default password. On the public internet. The genius of Shodan is that it's not doing anything illegal or special. It's just connecting to publicly reachable IP addresses on publicly open ports — the same thing your browser does when you visit a website. The difference is scale. Shodan does this continuously, across the entire IPv4 address space , 24 hours a day, 7 days a week. Part 2: How Shodan Actually Works — The Technical Truth Before you write a single query, you need to understand what data Shodan is actually collecting. This changes everything about how you search. The Banner — Shodan's Atomic Unit of Data When Shodan's scanner connects to an open port, the server responds with raw protocol data. That response is called a banner . Here's a real example of what a banner from an HTTPS server looks like: HTTP/1.1 200 OK Server: Apache/2.4.29 (Ubuntu) X-Powered-By: PHP/7.2.24 Content-Type: text/html; charset=UTF-8 X-Frame-Options: SAMEORIGIN Set-Cookie: PHPSESSID=abc123; path=/; HttpOnly That one banner just told you: the web server type and exact version, the PHP version running behind it, that it's an Ubuntu box, and that session cookies exist. An attacker now knows to look up CVEs for Apache 2.4.29 and PHP 7.2.24. All from one HTTP response. Shodan also grabs: SSL/TLS certificate data (which leaks domain names, org names, expiry dates) Geolocation from IP (country, city, ISP) ASN (Autonomous System Number — tells you which company owns the IP block) Reverse DNS / PTR records (the hostname pointing to that IP) Open port list (all ports Shodan found open on that host) Raw banner text (everything the service said when Shodan knocked) This is what you search against when you write a Shodan query. Not web pages. Not content humans wrote. Raw machine responses. 🎉 Fun Fact #3: Shodan scans roughly 1,500 ports on every IP address. The full IPv4 space is about 4.3 billion addresses. Shodan processes millions of banners every hour. That's more data collected per day than most companies store in a year. Part 3: Your First Shodan Queries — Learning the Syntax Shodan's query language is clean and elegant once you understand the logic. Let's break it down from first principles. Plain Text Search The simplest query is just a word or phrase. Shodan searches across all banner text for matches: webcam This returns every host where the word "webcam" appeared anywhere in the banner. Not very precise, but it's a start. Filter Syntax The power comes from filters — filter:value pairs that narrow your results: port:22 country:IN org:"Tata Consultancy Services" product:nginx No spaces around the colon. Values with spaces go in quotes. Combining Filters Multiple filters are ANDed together by default. There's no need to write AND explicitly: port:3306 country:IN This finds MySQL servers (port 3306) in India. That's it. Two tokens, massively narrowed scope. Adding Free Text to Filters Mix free-text keywords with filters freely: "MongoDB Server Information" country:IN This finds MongoDB instances (identified by a string in their banner) located in India. Exclusions Use a - prefix to exclude results: product:nginx -port:80 -port:443 This finds nginx servers NOT running on the standard web ports — a classic indicator of shadow IT or misconfigured services. Wildcards in String Values You can use * in some filter values: ssl.cert.subject.cn:"*.bankofbaroda.com" This finds all IPs serving SSL certificates issued to any subdomain of bankofbaroda.com. Incredibly powerful for org reconnaissance. Part 4: The Critical Data Fields — Know Your Search Space These are the fields Shodan indexes and that you can filter against. Memorize these. They are your vocabulary. Filter What It Searches ip Exact IP address port Open port number org Organization name from WHOIS/ASN data hostname Reverse DNS / PTR record net CIDR network range (e.g., net:10.0.0.0/8 ) asn Autonomous System Number (e.g., asn:AS15169 ) country Two-letter country code city City of geolocation os Detected operating system product Identified software product version Software version string ssl.cert.subject.cn SSL Common Name (the domain in the cert) ssl.cert.subject.o Organization field in the SSL cert ssl.cert.issuer.cn Who issued the certificate ssl.cert.expired true or false — cert expiry status ssl.cert.fingerprint SHA fingerprint — useful for pivoting http.title The HTML tag of the page http.status HTTP response code (200, 401, 403…) http.html Search inside the page body HTML vuln Matched CVE identifier (API key required) has_screenshot true if Shodan captured a screenshot before Results indexed before a date after Results indexed after a date Part 5: The Dorks That Actually Matter — A Professional Library This is the section you came for. These are real dorks that real security teams use. ⚠️ Ethical Reminder: Finding an exposed system on Shodan and accessing it are two completely different things. The first is OSINT. The second is unauthorized access. Only test systems you own or have explicit written permission to test. Category 1: Exposed Databases — The Goldmine Every month, thousands of databases are accidentally left open to the internet. These searches find them. # Open MongoDB — no authentication required "MongoDB Server Information" -"partially" # Elasticsearch clusters (check for .kibana = unauthenticated) port:9200 http.title:"Kibana" port:9200 json # Redis open to internet (can lead to RCE via config write) port:6379 "redis_version" "redis_version" -authentication # MySQL exposed to public internet (should never happen) port:3306 "mysql_native_password" port:3306 country:IN # PostgreSQL open port port:5432 "PostgreSQL" # CouchDB admin panel accessible port:5984 http.title:"CouchDB" # Cassandra port:9042 # Memcached - can be abused for massive DDoS amplification port:11211 "STORED" 🎉 Fun Fact #4: In 2017, a security researcher found 73 million records from a US voter database in an open MongoDB instance — just from a Shodan search. The organization didn't know it was exposed. It had been sitting open for weeks. Category 2: Industrial Control Systems — The Actually Scary Stuff ICS/SCADA systems should never be internet-exposed. They almost always run old firmware with known vulnerabilities and control physical infrastructure. # Modbus — the industrial communication protocol # Used in power plants, factories, water treatment port:502 # Siemens S7 PLCs (power grids, manufacturing) port:102 # DNP3 - power utility communications port:20000 # BACnet - building automation (HVAC, elevators, lighting) port:47808 # Rockwell/Allen-Bradley PLCs port:44818 # SCADA HMI web interfaces http.title:"SCADA" http.title:"HMI" http.title:"Wonderware" http.title:"InTouch" # GE iFIX SCADA http.title:"iFIX" # Schneider Electric http.title:"Schneider Electric" 🎉 Fun Fact #5: In 2016, Shodan's creator John Matherly discovered that over 50,000 ICS devices were directly accessible from the internet with zero authentication — including systems for water treatment, nuclear facilities, and power substations. He published the finding. Many still haven't been patched. Category 3: Remote Access — Every Attacker's Favorite Entry Points Exposed remote access interfaces are ransomware groups' single biggest source of initial access. # RDP (Remote Desktop) exposed to internet — ransomware entry #1 port:3389 product:"Remote Desktop Protocol" port:3389 "Windows" # VNC with authentication disabled port:5900 "authentication disabled" port:5900 "VNC" # SSH on port 22 (not bad by itself, but useful for attack surface mapping) port:22 "OpenSSH" org:"Target" # Citrix Netscaler / ADC Gateway http.title:"Citrix Gateway" http.title:"Citrix ADC" # Cisco ASA VPN / ASDM http.title:"Cisco ASDM" http.title:"SSL VPN" # Fortinet FortiGate SSL-VPN ssl:"Fortinet" http.title:"FortiGate" product:"FortiGate" # Pulse Secure VPN (multiple critical CVEs) http.title:"Pulse Secure" # Sonicwall VPN http.title:"SonicWall" # Palo Alto GlobalProtect http.title:"GlobalProtect" # TeamViewer port:5938 # WinRM - Windows Remote Management (can mean lateral movement risk) port:5985 port:5986 Category 4: Security Cameras and IoT — The Surveillance Nightmare # Hikvision cameras (largest camera manufacturer, common default creds) http.title:"Hikvision" product:"Hikvision IP Camera" "hikvision" port:8000 # Dahua cameras http.title:"WEB SERVICE" product:"Dahua" "Dahua" port:37777 # Axis network cameras http.title:"AXIS" http.status:200 # Bosch cameras http.title:"Bosch" # Generic RTSP streams (live video) port:554 "rtsp" port:554 has_screenshot:true # IP camera interfaces http.title:"IP Camera" http.status:200 http.title:"Network Camera" # Webcam interfaces has_screenshot:true port:8080 has_screenshot:true http.title:"camera" # Netwave cameras (common in hospitals, offices) "netwave" port:8080 # D-Link cameras http.title:"D-Link" 🎉 Fun Fact #6: There's an unofficial Shodan command called has_screenshot:true that returns devices where Shodan actually captured a screenshot. You can see the live output of open cameras, exposed desktops, and IoT device dashboards — without even connecting to them yourself. Category 5: Cloud, DevOps & Developer Misconfigurations This category has exploded in the last 5 years. Developers spinning up services fast often skip security configuration. # Kubernetes API server exposed (cluster takeover risk) port:6443 "k8s" http.title:"Kubernetes" port:8080 "Kubernetes" # Docker daemon API exposed (instant code execution) port:2375 "/containers/json" port:2376 "Docker" # Grafana dashboards exposed (check for CVE-2021-43798 path traversal) http.title:"Grafana" # Jenkins CI/CD (check for Script Console = RCE) http.title:"Dashboard [Jenkins]" http.title:"Jenkins" http.status:200 # Jupyter Notebooks - exposed Python execution environment http.title:"Jupyter Notebook" -"password" http.title:"Jupyter" http.status:200 # GitLab CE exposed http.title:"GitLab" # Portainer - Docker management UI http.title:"Portainer" # HashiCorp Vault http.title:"Vault" # Consul (service mesh - can be abused for data exfil) port:8500 "Consul" # Prometheus metrics endpoint (data leakage) http.title:"Prometheus Time Series Collection and Processing Server" # Traefik dashboard http.title:"Traefik" # Airflow scheduler dashboard http.title:"Airflow" # Rancher Kubernetes management http.title:"Rancher" Category 6: Network Infrastructure — The Foundation Layer # Exposed router admin panels http.title:"Router" http.status:200 http.title:"D-Link" http.status:200 http.title:"Netgear" http.status:200 http.title:"ASUS RT" # MikroTik routers (very common in ISPs) "MikroTik" port:8291 http.title:"RouterOS" # Cisco IOS devices "Cisco IOS" port:23 "IOS" "Cisco" # Juniper devices "Juniper" port:830 # pfSense / OPNsense firewalls exposed http.title:"pfSense" http.title:"OPNsense" # Exposed SNMP (can enumerate full device config) port:161 # Telnet wide open (2024 and people still do this) port:23 # FTP with anonymous login port:21 "220" "anonymous" # SMTP open relay (can be abused for spam) port:25 "220 ESMTP" "open relay" Category 7: CVE-Specific Hunting Dorks This is advanced dorking — targeting specific known vulnerabilities. # Log4Shell (CVE-2021-44228) — VMware Horizon http.title:"VMware Horizon" http.status:200 # ProxyShell (CVE-2021-34473) - Microsoft Exchange http.title:"Outlook Web App" product:"Microsoft Exchange httpapi" # ProxyLogon - Exchange 2013, 2016, 2019 "Microsoft HTTPAPI httpd 2.0" port:443 # PaperCut (CVE-2023-27350) - unauthenticated RCE http.title:"PaperCut" http.status:200 # MOVEit Transfer (CVE-2023-34362) - SQL injection + RCE http.title:"MOVEit Transfer" # Citrix Bleed (CVE-2023-4966) http.title:"Citrix ADC" ssl:"Citrix" # F5 BIG-IP (CVE-2023-46747) http.title:"BIG-IP" product:"F5 BIG-IP" # Apache Struts (CVE-2023-50164) product:"Apache Tomcat" # GoAnywhere MFT (CVE-2023-0669) http.title:"GoAnywhere" # Ivanti Connect Secure VPN (CVE-2024-21887, CVE-2023-46805) http.title:"Ivanti" ssl:"Ivanti" # Using Shodan's built-in vuln filter (requires API key) vuln:CVE-2021-44228 vuln:CVE-2023-27350 vuln:CVE-2021-34473 org:"Target Organization" Part 6: The Secret Weapon Nobody Talks About — http.favicon.hash This is the single most powerful Shodan filter that most guides never mention. If you take one thing from this entire article beyond basic syntax, make it this. Every web application has a favicon — that tiny icon in your browser tab. Favicons are unique fingerprints per product. A Grafana favicon looks the same on every Grafana instance worldwide. A Cobalt Strike C2 server's favicon looks the same regardless of which threat actor is running it. A Fortinet gateway always serves the same icon. Shodan hashes every favicon it encounters. You grab that hash, and you can find every single instance of that product on the entire internet — regardless of what port it's running on, what hostname it has, or how hard the operator tried to hide it. 🎉 Fun Fact #7: Security researchers have found active Cobalt Strike command-and-control servers run by APT groups purely through favicon hash matching. The attacker changed everything — port, TLS cert, hostname — but couldn't change the favicon without breaking the product. The hash never lies. How to Get a Favicon Hash import mmh3 import requests import codecs def get_favicon_hash(url): response = requests.get(url, timeout=5) favicon = codecs.encode(response.content, "base64") # mmh3 MurmurHash3 - same algorithm Shodan uses hash_value = mmh3.hash(favicon) return hash_value # Example hash_val = get_favicon_hash('https://target.com/favicon.ico') print(f"Shodan query: http.favicon.hash:{hash_val}") Ready-to-Use Favicon Hash Dorks These are confirmed, tested hashes for real products: # Cobalt Strike C2 team servers (threat actor infrastructure) http.favicon.hash:-335242539 # Grafana dashboards http.favicon.hash:116323821 # Fortinet / FortiGate http.favicon.hash:-1028703694 # Jenkins CI/CD http.favicon.hash:81586312 # GitLab http.favicon.hash:1278323681 # Jupyter Notebooks http.favicon.hash:541088007 # Kibana (Elasticsearch frontend) http.favicon.hash:-1659512841 # phpMyAdmin http.favicon.hash:1722105798 # Netdata monitoring http.favicon.hash:-1524558921 # Webmin server admin panel http.favicon.hash:-471426521 # Traefik reverse proxy dashboard http.favicon.hash:542093262 # Harbor container registry http.favicon.hash:854992623 # Rancher Kubernetes UI http.favicon.hash:-1401658736 # VMware vSphere / vCenter http.favicon.hash:1621371862 # Outlook Web App (OWA) http.favicon.hash:442749392 # Oracle WebLogic console http.favicon.hash:-1286589462 # SAP Web GUI http.favicon.hash:-338745917 The Threat Actor Hunt Use Case This is what makes favicon hashing elite-level: # Find Cobalt Strike C2 globally http.favicon.hash:-335242539 # Narrow to specific country (threat intel correlation) http.favicon.hash:-335242539 country:CN # Find Metasploit handler endpoints http.favicon.hash:-127886975 # Find Empire C2 (PowerShell Empire) http.favicon.hash:1278323681 # Find Havoc C2 framework http.favicon.hash:893284639 Red teams use this to find their own C2 infrastructure before blue teams do. Threat intel teams use it to map active adversary infrastructure. It's one of the few techniques that genuinely works on both offense and defense. Part 7: Advanced Enterprise Targets — The Real Red Team Hits These are the targets that appear in actual breach reports, CISA advisories, and bug bounty hall-of-fames. Every serious red team knows these by heart. VMware vCenter and ESXi — Ransomware's Favorite Entry Point VMware vCenter and ESXi hosts sitting directly on the internet are the #1 ransomware initial access vector in enterprise environments right now. Ransomware groups actively hunt these with Shodan. # VMware vCenter Server (manage entire VM infrastructure) http.title:"vSphere Client" http.title:"VMware vCenter Server" product:"VMware vCenter" # VMware ESXi hosts exposed directly http.title:"VMware ESXi" product:"VMware ESXi" "VMware ESXi" port:443 # VMware Horizon (Log4Shell was devastating here) http.title:"VMware Horizon" http.title:"VMware Horizon View" # VMware vRealize (automation platform) http.title:"vRealize" # CVE-2021-21985, CVE-2021-22005, CVE-2023-20867 - all vCenter vuln:CVE-2021-21985 product:"VMware vCenter" vuln:CVE-2023-20867 🎉 Fun Fact #8: After CVE-2021–22005 dropped (unauthenticated arbitrary file upload in vCenter), Shodan found over 6,700 exposed vCenter instances within 48 hours. Ransomware groups had working exploits the same day the patch released. Atlassian Confluence and Jira — Enterprise Collaboration = Enterprise Risk Atlassian products are everywhere in enterprise. Multiple critical CVEs with public exploits. Constantly targeted. # Confluence — wiki/documentation platform http.title:"Confluence" product:"Atlassian Confluence" http.title:"Log In - Confluence" # Jira - project management and ticketing http.title:"Jira" product:"Atlassian Jira" http.title:"Log In - Jira" # Bitbucket - source code repos (finding these is extremely valuable) http.title:"Bitbucket" product:"Atlassian Bitbucket" # CVE-2022-26134 - Confluence OGNL injection, unauthenticated RCE vuln:CVE-2022-26134 http.title:"Confluence" vuln:CVE-2022-26134 # CVE-2023-22518 - Confluence data destruction, no auth required http.title:"Confluence" vuln:CVE-2023-22518 # CVE-2022-0540 - Jira auth bypass http.title:"Jira" vuln:CVE-2022-0540 SAP NetWeaver — The Enterprise Goldmine Most People Miss SAP runs the financial backbone of 77% of Fortune 500 companies. SAP recon is niche, high-value, and massively overlooked in public Shodan guides. If you find exposed SAP infrastructure — that's ERP data, payroll, financial records, supply chain. # SAP NetWeaver Application Server "SAP NetWeaver Application Server" http.title:"SAP NetWeaver" # SAP Web GUI (ICM) http.title:"SAP" port:8000 http.title:"SAP" port:8443 http.title:"SAP Web GUI" # SAP Router (protocol gateway - often poorly configured) port:3299 "SAP Router" # SAP Message Server port:3600 port:3900 # SAP HANA database admin interface http.title:"SAP HANA" port:4300 "HANA" # SAP Fiori launchpad (modern UI) http.title:"SAP Fiori" # CVE-2020-6287 - SAP RECON, unauthenticated admin via ICM # CVSS 10.0 - highest possible score vuln:CVE-2020-6287 🎉 Fun Fact #9: CVE-2020–6287 (SAP RECON) has a CVSS score of 10.0 — the absolute maximum. It allows an unauthenticated attacker to create a new admin user in SAP over the internet. CISA issued an emergency alert. Researchers found hundreds of exposed instances using exactly these Shodan queries. ManageEngine — The MSP Attack Surface ManageEngine makes IT management tools used by thousands of companies and MSPs. Multiple critical CVEs exploited in the wild by both ransomware groups and nation-state actors. # ManageEngine ServiceDesk Plus (IT helpdesk) http.title:"ManageEngine ServiceDesk" http.title:"ServiceDesk Plus" # ManageEngine Desktop Central / Endpoint Central http.title:"Desktop Central" http.title:"ManageEngine Desktop Central" http.title:"ManageEngine Endpoint Central" # ManageEngine ADManager Plus (Active Directory management) http.title:"ManageEngine ADManager" # ManageEngine ADAudit Plus http.title:"ManageEngine ADAudit" # ManageEngine OpManager (network monitoring) http.title:"ManageEngine OpManager" # ManageEngine ADSelfService Plus (password reset portal - very exposed) http.title:"ADSelfService Plus" Oracle WebLogic — Deserialisation City Oracle WebLogic has had critical deserialisation vulnerabilities since 2015 and they keep coming. Large enterprises, banks, and government systems run WebLogic everywhere. # WebLogic admin console (port 7001 or 7002) http.title:"Oracle WebLogic Server Administration Console" port:7001 "WebLogic" port:7002 "WebLogic" # WebLogic T3 protocol (the deserialisation attack vector) port:7001 "HELO" port:7002 # Oracle WebLogic WLST (scripting interface) port:9999 "WebLogic" Web Admin Panels — Low Hanging Fruit These are common, often under-monitored, and frequently run with default credentials or known CVEs. # phpMyAdmin — database management over HTTP http.title:"phpMyAdmin" "phpMyAdmin" http.status:200 # Webmin - Linux server admin panel http.title:"Webmin" port:10000 "Webmin" # cPanel and WHM - web hosting control panels http.title:"cPanel" http.title:"WHM" port:2082 "cPanel" port:2083 "cPanel" port:2086 "WHM" # Plesk http.title:"Plesk" port:8443 "Plesk" # DirectAdmin http.title:"DirectAdmin" port:2222 # WHMCS (billing / client management for hosting) http.title:"WHMCS" # ISPConfig http.title:"ISPConfig" LDAP and Active Directory — Direct Domain Recon Finding exposed LDAP is finding the keys to the kingdom. Unauthenticated LDAP binds can enumerate entire Active Directory structures — every user, every group, every computer. # LDAP exposed (Active Directory / LDAP servers) port:389 # LDAPS (secure LDAP - still risky if misconfigured) port:636 # Global Catalog (full forest enumeration) port:3268 port:3269 # Anonymous LDAP bind (worst case - full AD enum without credentials) port:389 "namingContexts" # Specific DC discovery port:389 "DC=" org:"Target" # LDAP with specific domain context visible in banner port:389 "dc=targetcorp,dc=com" Rsync — Accidental File System Exposure Rsync servers exposed to the internet with no authentication essentially hand over their entire file system to anyone who connects. Backup servers, media servers, and CI/CD artifact stores are commonly exposed this way. # Open rsync daemons port:873 # Rsync with module listing enabled (shows what's shared) port:873 "rsync" "@RSYNCD" port:873 # Rsync with specific module names (often reveal purpose) port:873 "backup" port:873 "data" port:873 "files" Microsoft Exchange — Full OWA Coverage Exchange is one of the most attacked enterprise products of the past 5 years. Here's the complete picture beyond just ProxyShell: # Outlook Web Access — the primary attack surface http.title:"Outlook Web App" http.title:"Outlook" http.title:"Microsoft Exchange" # Exchange ActiveSync (mobile device sync endpoint) "/Microsoft-Server-ActiveSync" # Exchange Autodiscover (used in credential phishing) "/autodiscover/autodiscover.xml" # Exchange OWA with version detection product:"Microsoft Exchange httpapi" port:443 # Exchange Admin Center (EAC) http.title:"Exchange Admin Center" # ProxyShell (CVE-2021-34473 + CVE-2021-34523 + CVE-2021-31207) vuln:CVE-2021-34473 # ProxyNotShell (CVE-2022-41082) vuln:CVE-2022-41082 # CVE-2023-21529 - Exchange RCE vuln:CVE-2023-21529 Part 8: The Shodan Ecosystem — Tools You Need to Know Shodan Exploits Search exploit.shodan.io is a separate Shodan product that cross-references CVEs with known public exploit code. Combine it with your recon: Search a CVE on exploit.shodan.io → get exploit metadata Search the same CVE with vuln:CVE-xxxx on Shodan → get affected hosts Cross-reference with your target org's asset list → prioritize InternetDB API — Free, No Key Required Shodan's InternetDB is a free, no-API-key-required endpoint that gives you open ports, CPEs, CVEs, hostnames, and tags for any IP: import requests def internetdb_lookup(ip): url = f"https://internetdb.shodan.io/{ip}" response = requests.get(url) return response.json() # No API key needed - completely free data = internetdb_lookup("8.8.8.8") print(data) # Returns: ports, cpes, vulns, hostnames, tags This is incredibly useful for quick triage during engagements — no credits burned, instant results. 🎉 Fun Fact #10: InternetDB gets updated from the same Shodan scan data as the main API. For simple port/CVE lookups on specific IPs, it's faster than the full API and costs you nothing. Most people doing Shodan recon don't even know it exists. Shodan Maps maps.shodan.io visualizes search results geographically in real time. Incredibly useful for: Visualizing where an org's assets are concentrated geographically Spotting unusual geographic clustering (e.g., an org that should only operate in India suddenly has 40 assets in Eastern Europe) Understanding ISP distribution Shodan Images images.shodan.io shows only results where Shodan captured screenshots. It's a visual gallery of exposed interfaces — cameras, desktops, admin panels, IoT dashboards. Filter by search terms the same way as normal Shodan. Part 9: SSL Certificate Pivoting — The Hidden Superpower This technique alone has unlocked more reconnaissance than any other single Shodan skill. SSL certificates contain structured metadata that organizations embed themselves — and that metadata links assets together in ways DNS won't show you. # All IPs serving certs issued to a specific domain (finds hidden assets) ssl.cert.subject.cn:"*.example.com" # The organization field in the cert - links subsidiaries and acquisitions ssl.cert.subject.o:"Example Corporation" # Find expired certs (hygiene indicator - poor patch culture) ssl.cert.expired:true org:"Target" # Self-signed certs - often internal services accidentally exposed ssl.cert.issuer.cn:"example.com" # Find certs by the Certificate Authority (who they trust) ssl.cert.issuer.o:"Let's Encrypt" org:"Target" # SHA256 fingerprint - pivot from a known cert to find related servers ssl.cert.fingerprint:"aa:bb:cc:..." # Find all IPs with the same SSL cert (load balancers, CDN edges) ssl.cert.serial:"12345678901234567890" # Subject Alternative Names contain subdomain inventory ssl:"*.target.com" Why This Is So Powerful When a company acquires another company, the acquired org's servers often still have SSL certs issued to the old organization name. That means ssl.cert.subject.o:"Acquired Company" returns servers that are now part of the acquirer's attack surface — but that the acquirer's security team may not know about yet. This is how red teams find the forgotten corners. 🎉 Fun Fact #11: SSL certificate transparency logs + Shodan = the most complete subdomain enumeration possible. Every cert issued by a public CA is logged publicly. Tools like crt.sh give you the cert history, and Shodan tells you which IPs are actually serving each cert. Part 10: The Full Methodology — How Red Teams Actually Do It Ad-hoc dorks are great for practice. Professional reconnaissance is systematic. Here's the exact methodology for mapping an organization's full attack surface: Phase 1: Establish Your Anchors Start with what you know — the organization's name, primary domain, and any known IP ranges: # Anchor 1: Organization name from ASN WHOIS org:"Target Corporation" org:"Target Corp" # Try variations # Anchor 2: SSL certificate CN pivoting ssl.cert.subject.cn:"*.targetcorp.com" # Anchor 3: Known net ranges net:203.0.113.0/24 Phase 2: Map the IP Ranges Once you have confirmed IPs, find their full network ranges: # Sweep the surrounding /24 or /16 net:203.0.113.0/24 # Find all ranges via ASN asn:AS12345 # Cross-reference multiple ranges net:203.0.113.0/24 OR net:198.51.100.0/24 Phase 3: Enumerate All Hostnames Pull unique hostnames from all matching results. These reveal: Subdomain naming conventions ( dev- , staging- , internal- ) Cloud footprint ( *.aws.targetcorp.com , *.azure.com with target certs) Legacy infrastructure ( webserver-2009.targetcorp.com ) Third-party hosted services (Salesforce, Workday, etc.) Phase 4: Technology Stack Fingerprinting For each asset, record the technology stack: # Find all web servers across the org org:"Target" http.status:200 # Filter by specific tech org:"Target" product:"Microsoft IIS" org:"Target" product:"nginx" org:"Target" product:"Apache httpd" # Find PHP applications (often older, more vulnerable) org:"Target" "X-Powered-By: PHP" # Java application servers org:"Target" product:"Apache Tomcat" # Find WAF signatures in use org:"Target" "Server: cloudflare" org:"Target" "X-Sucuri-ID" Phase 5: CVE Correlation Map software versions to known CVEs. Cross-reference product and version fields with NVD: org:"Target" product:"Apache httpd" version:"2.4.49" org:"Target" product:"Microsoft IIS" version:"7.5" org:"Target" vuln:CVE-2023-27350 Phase 6: False Positive Removal — The Critical Step This is where most beginners fail. Raw Shodan results for an org search include: ISP infrastructure in the same AS block CDN edge nodes (Cloudflare, Akamai, Fastly) that serve the org's content Shared hosting where multiple clients share one IP Transit infrastructure (not actually the org's servers) How to validate an asset is genuinely the org's: Does the SSL cert CN contain the org's domain? Does the HTTP response title match the org's products? Does the hostname resolve to the org's domain? Does the response body contain the org's branding? Cross-reference with WHOIS for the specific IP Only report assets that pass at least 2–3 of these checks. Phase 7: Risk Grading and Reporting Grade findings by severity: Grade Meaning Examples A Clean surface, no major exposures Standard web ports, patched services B Minor issues, low risk Outdated TLS versions, minor info disclosure C Moderate risk, attention needed Admin panels public, some missing auth D High risk, remediate soon Exposed management interfaces, unpatched critical CVEs F Critical — drop everything Open databases, ICS exposed, active exploitable vulns Part 11: The Shodan API — Where It Gets Truly Powerful Manual searching is great. Programmatic access is where real recon happens. Every serious red team runs Shodan through its API. Python — The Basics import shodan api = shodan.Shodan('YOUR_API_KEY_HERE') # Simple search results = api.search('org:"Target Corporation" port:443') print(f"Total assets found: {results['total']}") for host in results['matches']: print(f"IP: {host['ip_str']}") print(f"Port: {host['port']}") print(f"Product: {host.get('product', 'unknown')}") print(f"Version: {host.get('version', 'unknown')}") # CVEs matched by Shodan (gold dust for red teams) if 'vulns' in host: for cve, details in host['vulns'].items(): print(f" ⚠️ CVE: {cve} - CVSS: {details.get('cvss', '?')}") print("---") Pagination — Getting All Results Shodan's free web UI shows 10 results. The API gives you 100 per page. Deep mode requires pagination: import shodan import time api = shodan.Shodan('YOUR_API_KEY') all_results = [] query = 'org:"Target Corporation"' # Pull up to 5 pages (500 results) for page in range(1, 6): try: results = api.search(query, page=page) all_results.extend(results['matches']) print(f"Page {page}: {len(results['matches'])} results") time.sleep(1) # Be polite to the API # Stop if we've got everything if len(results['matches']) < 100: break except shodan.APIError as e: print(f"Error: {e}") break print(f"Total collected: {len(all_results)} assets") Full Host Lookup — Everything Shodan Knows # Get the complete profile for a single IP host = api.host('203.0.113.1') print(f"IP: {host['ip_str']}") print(f"Organization: {host.get('org', 'n/a')}") print(f"ISP: {host.get('isp', 'n/a')}") print(f"Operating System: {host.get('os', 'n/a')}") print(f"Country: {host.get('country_name', 'n/a')}") print(f"City: {host.get('city', 'n/a')}") print(f"ASN: {host.get('asn', 'n/a')}") print(f"All open ports: {host['ports']}") print(f"Hostnames: {host.get('hostnames', [])}") # Iterate every service banner for every open port for service in host['data']: print(f"\nPort {service['port']} - {service.get('product', '?')} {service.get('version', '')}") print(service.get('banner', '')[:300]) The CLI — Quick One-Liners # Install pip install shodan # Initialize with your key shodan init YOUR_KEY_HERE # Count results before burning credits shodan count 'org:"Target Corporation"' # Search and get clean output shodan search --fields ip_str,port,product,hostnames 'org:"Target" port:22' # Look up a single IP shodan host 203.0.113.1 # Download results in bulk (uses query credits) shodan download target_scan 'org:"Target Corporation"' shodan parse --fields ip_str,port,product target_scan.json.gz # Set up monitoring alert for your own network shodan alert create --triggers open_port 'net:203.0.113.0/24' # List your active alerts shodan alert list Part 12: HTTP Analysis and Banner Intelligence Shodan stores the first ~4KB of HTTP responses. This gives you a searchable archive of what web services are actually saying. Searching Page Titles # Admin panels and login pages http.title:"Admin Panel" http.title:"Administration" http.title:"Control Panel" http.title:"phpMyAdmin" http.title:"WebAdmin" # Default installation pages (still running default config) http.title:"Apache2 Ubuntu Default Page" http.title:"Welcome to nginx!" http.title:"IIS Windows Server" http.title:"Test Page for the Apache HTTP Server" # CMS installations http.title:"Powered by WordPress" org:"Target" http.title:"Drupal" http.title:"Joomla" Searching Inside Page Content # Error pages that leak stack traces / framework info http.html:"stack trace" http.html:"Fatal error" org:"Target" # Pages leaking internal IP addresses http.html:"192.168." http.html:"10.0.0." # Default credentials pages http.html:"admin:admin" http.html:"password: admin" # Configuration files accidentally exposed http.html:"[database]" http.html:"DB_PASSWORD" # Git repository indicators http.html:".git" HTTP Status Code Hunting # Services returning 200 on unusual ports (shadow IT) org:"Target" http.status:200 -port:80 -port:443 -port:8080 -port:8443 # 401/403 - exists but protected (still valuable for surface mapping) org:"Target" http.status:401 org:"Target" http.status:403 # 500 errors - might expose debug info org:"Target" http.status:500 Part 13: Shodan Monitoring — Going From Offensive to Defensive Here's something most Shodan tutorials skip: Shodan is an incredible defensive tool too. Once you know how to find exposed assets, you can use the same capability to watch your own infrastructure. Shodan Alerts # Alert when any new port opens on your IP range shodan alert create --triggers open_port 'net:YOUR.IP.RANGE.0/24' # Alert on specific vulnerabilities detected shodan alert create --triggers vuln 'net:YOUR.IP.RANGE.0/24' # Alert on any new Shodan scan of your IPs shodan alert create --triggers malware 'net:YOUR.IP.RANGE.0/24' When Shodan detects a change — a new port opens, a new vulnerability is matched, a new service appears — you get notified. This means you can catch exposed dev servers before threat actors do. Shodan Monitor vs. Manual Recon Set up alerts on your own org's CIDR blocks and let Shodan tell you when something changes. This is free threat intelligence running 24/7 on your attack surface. 🎉 Fun Fact #12: Some bug bounty hunters have automated Shodan API monitoring on their target programs. When a new asset appears in scope, they're the first to test it — often within hours of it going live. The fastest finders get the biggest bounties. Part 14: Correlation With Other OSINT Tools Shodan alone is powerful. Shodan combined with other OSINT sources is a different beast entirely. The Full Recon Stack Censys — Similar to Shodan but with better SSL certificate data and a more structured query syntax. Cross-reference Shodan findings with Censys to find assets one misses. FOFA — Chinese alternative to Shodan with excellent coverage of Asian internet infrastructure. Critical if your target has operations in China, Taiwan, or Southeast Asia. Netlas.io — Newer entrant, strong on HTTP response data and has some unique filtering that Shodan lacks. GreyNoise — Takes Shodan data and adds context about who's actually scanning what. Lets you distinguish between "this IP is exposed" and "this IP is actively being targeted by threat actors right now." Shodan + crt.sh — Certificate transparency logs give you the full historical subdomain list. Cross-reference with Shodan to find which subdomains have live IP addresses. Shodan + SecurityTrails — SecurityTrails has historical DNS data. Shodan tells you what's live now. Combined, you can see assets that used to point to certain IPs and might still be running on those IPs even after DNS changes. Shodan + VirusTotal — IPs that appear on Shodan as exposed services that also appear in VirusTotal's malware/phishing datasets are a red flag — someone might already be exploiting them. A Practical Correlation Workflow Step 1: shodan search → get IP list for org Step 2: crt.sh → get all cert-logged subdomains Step 3: SecurityTrails → resolve historical DNS for all subdomains Step 4: Compare: which IPs appear in both Shodan + SecurityTrails? Step 5: GreyNoise → which of those IPs are being actively targeted? Step 6: VirusTotal → which appeared in threat intelligence? Step 7: Manual validation → verify the highest-priority findings Part 15: Tips, Tricks, and Pro Moves A few things that take you from "I know Shodan" to "I really know Shodan": Credit Management Shodan search credits are finite and cost real money. Before running any search that returns thousands of results: # Always count first — free operation, no credits shodan count 'org:"Target Corporation"' If the count is 50,000, you need a plan before you run the search. Use facets to explore the data shape first, then narrow your query before pulling raw results. Saving and Reusing Results import json # Save locally — re-running same query = wasted credits with open('target_results.json', 'w') as f: json.dump(results, f) # Load from cache with open('target_results.json', 'r') as f: results = json.load(f) The " has_screenshot:true" Trick One of the most underrated Shodan features. When you add has_screenshot:true to any query, results include a visual thumbnail of what the service looks like. Great for quickly triaging camera feeds, exposed desktops, and web admin panels without ever connecting to them directly. has_screenshot:true org:"Target" has_screenshot:true port:5900 has_screenshot:true http.title:"Remote Desktop" Searching Before/After Dates # Find assets that appeared in Shodan's index recently after:2024-01-01 org:"Target" # Find assets that haven't been seen recently (potentially stale, but still running) before:2023-06-01 org:"Target" port:3389 Boolean OR Queries # Find multiple port types in one query org:"Target" port:22 OR port:23 OR port:3389 # Multiple products product:"Apache" OR product:"nginx" org:"Target" 🎉 Fun Fact #13: The U.S. Department of Homeland Security's Cybersecurity and Infrastructure Security Agency (CISA) uses Shodan as part of their infrastructure monitoring. The same tool red teamers use to find vulnerabilities is used by defenders to catch them first. The Last Section — I Built Something to Automate All of This After a couple of days doing this manually — running the same org queries, removing the same ISP false positives, writing the same reports in slightly different formats, paginating through results page by page — I got frustrated. So I automated it. ShodanX v1.0 is a Python-based enterprise recon engine I built from scratch. You give it an organization name and an API key. It handles everything else. Here's what makes it different from just writing a Shodan query yourself: QueryIntelligence — before a single credit gets spent, the tool analyzes the org name, detects known abbreviations, infers the industry, generates probable domains, and ranks 100+ Shodan queries by confidence score. You see exactly what's going to run and what it'll cost before anything happens. You pick the threshold. You stay in control. Multi-source chaining — it doesn't stop at Shodan. It chains crt.sh certificate transparency, HackerTarget passive DNS, mass parallel DNS resolution, and InternetDB enrichment into a single automated pipeline. Subdomains get discovered and resolved before Shodan even runs. Intelligent false positive removal — a RelevanceFilter cross-checks every result against the target's hostnames, SSL cert CNs, org metadata, and SAN extensions. ISP infrastructure and CDN edge nodes never make it into the report. Only assets verifiably belonging to the target org get counted. CVE severity breakdown — instead of just counting CVEs, every finding gets categorized into Critical, High, Medium, and Low. The difference between "they have 47 CVEs" and "they have 2 Critical RCEs, 5 Highs, and 12 Mediums" is the difference between noise and a decision. Favicon fingerprinting — every HTTP and HTTPS service gets its favicon hashed and matched against known products. Cobalt Strike C2 servers, Grafana, Jenkins, VMware, Oracle WebLogic, SAP, and 15 more — identified from a hash before you ever connect. This is the technique most Shodan guides never mention. Full tech stack fingerprinting — WAF presence, web server type, and application framework all detected from response headers and SSL data. You know exactly what you're walking into before you write a single payload. A-to-F risk grading — the final report assigns the organization a letter grade with an executive summary. Not a score out of 100 that nobody interprets consistently. An actual grade, plain-English explanation, and a clear picture of what needs to happen. CISO-ready HTML reports — dark-themed enterprise dashboard with charts, a sortable asset table, CVE breakdown, geographic distribution, favicon hit table, and CSV export. Marked CONFIDENTIAL. The kind of output you hand to a client without reformatting anything. It's three files: shodanx.py for the core engine, query_intelligence.py for the smart query planner, and shodanx_html_template.py for the report. Run python shodanx.py , enter your API key, enter the org name, pick a mode, and walk away. Come back to a complete attack surface report. Is it a replacement for actually knowing Shodan? Absolutely not — and that's why this article came first. You need to understand the data, the filters, the techniques, and the methodology before you trust any tool that runs them automatically. But once you do understand all that? Having the repetitive parts automated means you can spend your time on the analysis that actually matters. https://github.com/ShubhamGupta-VULNDETOX/ShodanX If this helped, follow me for more red team, OSINT, and offensive security deep-dives. I write about real techniques, real tools, and real methodology — not surface-level "top 10 hacking tools" listicles. Found something interesting with Shodan? Learned a dork that wasn't in here? Drop it in the comments — the community gets smarter when we share. Tags: Shodan, Ethical Hacking, Cybersecurity, OSINT, Red Team, Penetration Testing, InfoSec, Bug Bounty, Attack Surface Management, Shodan Dorking, Cybersecurity Tools, Network Security © This writeup is for educational purposes and authorized security research only. #ethical-hacking #cybersecurity #penetration-testing #bug-bounty #hacking Reporting a Problem Sometimes we have problems displaying some Medium posts. If you have a problem that some images aren't loading - try using VPN. Probably you have problem with access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you). </div> <div class="mt-8 pt-4 border-t border-gray-100 dark:border-gray-800"> <a href="/" class="text-sm text-gray-500 dark:text-gray-400 hover:underline">← Back to stories</a> </div> </div> <script> function vote(dir) { fetch('/api/vote', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({source: 'medium_bb', source_id: 'https://medium.com/@vulndetox/zero-to-red-team-master-shodan-dorking-in-one-read-24df16f2b84e?source=rss------bug_bounty-5', vote: dir}) }) .then(r => r.json()) .then(d => { document.getElementById('count-up').textContent = d.upvotes; document.getElementById('count-down').textContent = d.downvotes; document.getElementById('vote-net').textContent = d.net + ' net'; const btnUp = document.getElementById('btn-up'); const btnDown = document.getElementById('btn-down'); // Reset classes btnUp.classList.remove('text-green-600', 'dark:text-green-400', 'text-gray-400', 'dark:text-gray-500'); btnDown.classList.remove('text-red-500', 'dark:text-red-400', 'text-gray-400', 'dark:text-gray-500'); if (d.user_vote === 1) { btnUp.classList.add('text-green-600', 'dark:text-green-400'); btnDown.classList.add('text-gray-400', 'dark:text-gray-500'); } else if (d.user_vote === -1) { btnUp.classList.add('text-gray-400', 'dark:text-gray-500'); btnDown.classList.add('text-red-500', 'dark:text-red-400'); } else { btnUp.classList.add('text-gray-400', 'dark:text-gray-500'); btnDown.classList.add('text-gray-400', 'dark:text-gray-500'); } }); } </script> </main> <footer class="mt-auto"> <div class="max-w-6xl mx-auto px-6 pt-16 pb-10"> <div class="border-t border-gray-200 dark:border-gray-800 pt-10"> <div class="grid grid-cols-2 md:grid-cols-5 gap-8 mb-12"> <div class="col-span-2 md:col-span-1"> <a href="/" class="flex items-center gap-2.5 mb-4"> <svg class="w-5 h-5 text-gray-900 dark:text-gray-100" viewBox="0 0 28 28" fill="none"> <path d="M7 19l5-5-5-5" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/> <line x1="14" y1="19" x2="21" y2="19" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/> </svg> <span class="text-[15px] font-semibold tracking-tight text-gray-900 dark:text-gray-100">rdintel</span> </a> <p class="text-sm text-gray-400 dark:text-gray-500 leading-relaxed">Agentic threat intelligence for security teams and AI agents.</p> </div> <div> <p class="text-xs font-semibold text-gray-900 dark:text-gray-100 uppercase tracking-wider mb-4">Product</p> <div class="flex flex-col gap-2.5 text-sm text-gray-500 dark:text-gray-400"> <a href="/api" class="hover:text-gray-900 dark:hover:text-white transition-colors">API</a> <a href="/mcp" class="hover:text-gray-900 dark:hover:text-white transition-colors">MCP Server</a> <a href="/api/docs/" class="hover:text-gray-900 dark:hover:text-white transition-colors">OpenAPI Docs</a> <a href="/pricing" class="hover:text-gray-900 dark:hover:text-white transition-colors">Pricing</a> <a href="/changelog" class="hover:text-gray-900 dark:hover:text-white transition-colors">Changelog</a> <a href="/status" class="hover:text-gray-900 dark:hover:text-white transition-colors">Status</a> </div> </div> <div> <p class="text-xs font-semibold text-gray-900 dark:text-gray-100 uppercase tracking-wider mb-4">Intelligence</p> <div class="flex flex-col gap-2.5 text-sm text-gray-500 dark:text-gray-400"> <a href="/cve" class="hover:text-gray-900 dark:hover:text-white transition-colors">CVE Search</a> <a href="/api#domain-intel" class="hover:text-gray-900 dark:hover:text-white transition-colors">Domain Intel</a> <a href="/ip/8.8.8.8" class="hover:text-gray-900 dark:hover:text-white transition-colors">IP Lookup</a> <a href="/asn/AS13335" class="hover:text-gray-900 dark:hover:text-white transition-colors">ASN Lookup</a> <a href="/malware-intel" class="hover:text-gray-900 dark:hover:text-white transition-colors">Malware Intel</a> </div> </div> <div> <p class="text-xs font-semibold text-gray-900 dark:text-gray-100 uppercase tracking-wider mb-4">Company</p> <div class="flex flex-col gap-2.5 text-sm text-gray-500 dark:text-gray-400"> <a href="/about" class="hover:text-gray-900 dark:hover:text-white transition-colors">About</a> <a href="https://blog.rdintel.com" class="hover:text-gray-900 dark:hover:text-white transition-colors">Blog</a> <a href="https://news.rdintel.com" class="hover:text-gray-900 dark:hover:text-white transition-colors">News</a> <a href="/contact" class="hover:text-gray-900 dark:hover:text-white transition-colors">Contact</a> </div> </div> <div> <p class="text-xs font-semibold text-gray-900 dark:text-gray-100 uppercase tracking-wider mb-4">Legal</p> <div class="flex flex-col gap-2.5 text-sm text-gray-500 dark:text-gray-400"> <a href="/terms" class="hover:text-gray-900 dark:hover:text-white transition-colors">Terms of Service</a> <a href="/privacy" class="hover:text-gray-900 dark:hover:text-white transition-colors">Privacy Policy</a> <a href="/impressum" class="hover:text-gray-900 dark:hover:text-white transition-colors">Impressum</a> <a href="/responsible-disclosure" class="hover:text-gray-900 dark:hover:text-white transition-colors">Responsible Disclosure</a> </div> </div> </div> <div class="border-t border-gray-100 dark:border-gray-800/50 pt-6"> <p class="text-xs text-gray-400 dark:text-gray-500">© 2026 rdintel. All rights reserved.</p> </div> </div> </div> </footer> <!-- Cookie consent --> <div id="cookie-banner" class="fixed bottom-0 left-0 right-0 z-40 hidden"> <div class="max-w-6xl mx-auto px-6 py-4"> <div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 bg-gray-900 dark:bg-gray-800 text-white px-6 py-4 rounded-lg shadow-lg"> <p class="text-sm">We use cookies for analytics and essential site functionality. See our <a href="/privacy" class="underline decoration-1 underline-offset-2">privacy policy</a>.</p> <div class="flex gap-3 shrink-0"> <button onclick="acceptCookies()" class="text-xs font-medium px-4 py-2 bg-white text-gray-900 hover:bg-gray-200 transition-colors rounded">Accept</button> <button onclick="rejectCookies()" class="text-xs font-medium px-4 py-2 border border-gray-600 hover:border-gray-400 transition-colors rounded">Reject</button> </div> </div> </div> </div> <script> (function() { if (!localStorage.getItem('cookie_consent')) { document.getElementById('cookie-banner').classList.remove('hidden'); } })(); function acceptCookies() { localStorage.setItem('cookie_consent', 'accepted'); document.getElementById('cookie-banner').classList.add('hidden'); } function rejectCookies() { localStorage.setItem('cookie_consent', 'rejected'); document.getElementById('cookie-banner').classList.add('hidden'); // Disable analytics var scripts = document.querySelectorAll('script[data-website-id]'); scripts.forEach(function(s) { s.remove(); }); } </script> <div id="loading-overlay" class="fixed inset-0 bg-white/80 dark:bg-[#0b0d11]/80 backdrop-blur-sm z-50 hidden items-center justify-center"> <div class="flex flex-col items-center gap-3"> <div class="w-6 h-6 border-2 border-gray-200 dark:border-gray-700 border-t-gray-800 dark:border-t-gray-200 rounded-full animate-spin"></div> </div> </div> <script> function toggleDarkMode() { document.documentElement.classList.toggle('dark'); localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light'); } (function() { const overlay = document.getElementById('loading-overlay'); document.querySelectorAll('form').forEach(form => { form.addEventListener('submit', () => { overlay.classList.remove('hidden'); overlay.classList.add('flex'); }); }); document.querySelectorAll('a[href^="/search"], a[href^="/cidr"], a[href^="/ip"], a[href^="/cve/"]').forEach(link => { if (/\/(download|archive)\//.test(link.getAttribute('href'))) return; link.addEventListener('click', () => { overlay.classList.remove('hidden'); overlay.classList.add('flex'); }); }); window.addEventListener('pageshow', () => { overlay.classList.add('hidden'); overlay.classList.remove('flex'); }); })(); </script> </body> </html>