# IP Threat Intelligence & Open Ports Scraper (`ninhothedev/ip-threat-intel-scraper`) Actor

$1/1K 🔥 IP threat intel scraper! Open ports, CVEs, hostnames & ASN per IP or domain. No key. JSON, CSV, Excel or API in seconds. Map your attack surface & hunt threats ⚡

- **URL**: https://apify.com/ninhothedev/ip-threat-intel-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## IP Threat Intelligence & Open Ports Scraper

**Find out what the internet already knows about any IP address — open ports, known CVEs, hostnames, tags and CPEs — plus full ASN and geolocation context. No API key, no scanning, no setup.**

Feed the actor a list of IP addresses or a list of domains. For domains it resolves the A records first, then looks up every resulting IP. You get one clean row per host, ready for a spreadsheet, a SIEM, or your asset inventory.

***

### ⚠️ This is passive data — nothing is scanned

This actor **does not scan, probe, connect to, or touch the target hosts in any way**. It reads a pre-computed **public index** (Shodan InternetDB) that has already been collected and published, and merges it with public WHOIS/RDAP-derived ASN data. Every request goes to the index APIs, never to your targets.

That makes it safe to run against third-party infrastructure, vendors, and acquisition targets without triggering IDS alerts, rate limits, or abuse complaints — and without the legal grey area of active port scanning. It also means the data reflects the index's last crawl, not this second.

***

### How this differs from my other IP actors

I publish three IP-related actors. They answer three different questions:

| Actor | Question it answers | Typical fields |
|---|---|---|
| **ip-threat-intel-scraper** (this one) | **"How exposed is this host?"** — security posture | open ports, CVE list, tags, CPEs, hostnames, risk level |
| [ip-geolocation-scraper](https://apify.com/ninhothedev/ip-geolocation-scraper) | **"Where is this IP and who runs it?"** — location & network identity | country, city, coordinates, ISP, timezone, currency |
| [ripestat-scraper](https://apify.com/ninhothedev/ripestat-scraper) | **"How is this prefix routed?"** — BGP & registry data | announced prefixes, BGP routing status, RIR allocation, abuse contacts |

Short version: **geolocation tells you where, RIPEstat tells you how it's routed, this one tells you what's exposed.** This actor includes a slim geo/ASN enrichment layer so you don't have to run two actors for a basic report — but if you need deep location or deep routing data, use the dedicated actors above.

***

### Use cases

#### Attack surface monitoring

Schedule a daily run over your own IP ranges and public domains. Get alerted the moment a new port appears or a fresh CVE gets attached to a host you own. Because the data is passive, you can monitor continuously without generating any traffic against production.

#### Security audits

Auditing a client, a vendor, or an acquisition target? Drop in their domains, get back a per-host exposure table with CVE counts and a risk level in seconds. Perfect as the reconnaissance appendix in a pentest report or a third-party risk questionnaire.

#### Asset inventory

Shadow IT is the hard part of asset management. Resolve every domain you own, scan the resulting IPs, and compare the discovered hostnames and open ports against your CMDB. The `hostnames` field frequently surfaces forgotten subdomains and legacy load balancers.

#### Threat hunting

Enrich IOCs from your logs. Feed a list of suspicious IPs and instantly see which ones are running exposed databases, have `tags` like `honeypot`, `vpn` or `cloud`, or carry known CVEs — plus the ASN and org that owns them, so you know who to contact.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `ips` | `ips` scans the IP list directly. `domains` resolves A records first, then scans each IP. |
| `ips` | array | `["8.8.8.8","1.1.1.1"]` | IPv4/IPv6 addresses, one per line. Used in `ips` mode. |
| `domains` | array | – | Domains such as `example.com`. Used in `domains` mode. Schemes, paths and `www.` are stripped for you. |
| `enrichGeo` | boolean | `true` | Add ASN, org, ISP, country, city, coordinates and timezone. Turn off for a faster ports-only run. |
| `maxItems` | integer | `100` | Hard cap on hosts scanned per run (max 1000). |

```json
{
  "mode": "domains",
  "domains": ["github.com", "example.com"],
  "enrichGeo": true,
  "maxItems": 100
}
```

### Output

One item per host. Every field is nullable, so downstream parsers never break.

```json
{
  "ip": "140.82.121.3",
  "query": "github.com",
  "found": true,
  "open_ports": [22, 80, 443],
  "port_count": 3,
  "vulns": [],
  "vuln_count": 0,
  "has_vulns": false,
  "hostnames": ["lb-140-82-121-3-fra.github.com"],
  "tags": [],
  "cpes": [],
  "risk_level": "low",
  "asn": 36459,
  "asn_org": "Github, Inc.",
  "isp": "Github, Inc.",
  "org_domain": "github.com",
  "country": "Germany",
  "country_code": "DE",
  "region": "Hessen",
  "city": "Frankfurt am Main",
  "latitude": 50.110859,
  "longitude": 8.6821259,
  "is_eu": true,
  "timezone": "Europe/Berlin",
  "source": "shodan-internetdb+ipwhois",
  "scraped_at": "2026-07-28T14:34:59Z"
}
```

#### Field notes

- **`query`** keeps whatever you originally supplied. In `domains` mode this is the domain, so you can group multiple A records back to their hostname.
- **`found`** is `false` when the index has no record for that IP. The row is still emitted — that way you can tell "clean/unknown" apart from "never checked". This is the single most useful field for diffing runs.
- **`risk_level`** is a simple, transparent heuristic: `high` if `vuln_count > 0`, else `medium` if `port_count > 5`, else `low`. Use it for triage and sorting, not as a verdict.
- **`vulns`** contains CVE identifiers, uppercased and deduplicated. Cross-reference them against NVD for severity scores.
- **`cpes`** is capped at 20 entries per host to keep rows compact.

### Pricing

Roughly **$1 per 1,000 hosts**. Both upstream data sources are free and key-less, so you are only paying Apify compute. The actor runs on 512 MB and paces itself at about one host per second to respect the index's rate limits — budget ~1 minute per 50 hosts.

### Related actors

- [IP Geolocation Scraper](https://apify.com/ninhothedev/ip-geolocation-scraper) — deep location, ISP, currency and timezone data per IP
- [RIPEstat Scraper](https://apify.com/ninhothedev/ripestat-scraper) — BGP routing, announced prefixes and RIR registry data
- [SSL Certificate Checker](https://apify.com/ninhothedev/ssl-certificate-checker) — certificate chain, issuer, expiry and SAN list per domain
- [Domain Intel Scraper](https://apify.com/ninhothedev/domain-intel-scraper) — WHOIS, DNS records and registrar intelligence per domain

### Legal & fair use

All data comes from publicly published indexes and public registry information. No authentication is bypassed and no host is contacted. You are still responsible for using the output lawfully — this is a reconnaissance and defensive-monitoring tool, not permission to attack anything.

# Actor input Schema

## `mode` (type: `string`):

Choose what you feed the actor. 'IP addresses' scans the IPs in the 'IP addresses' field directly. 'Domains' first resolves every domain's A records via DNS and then scans each resulting IP.

## `ips` (type: `array`):

IPv4 or IPv6 addresses to look up, one per line. Used when mode is 'IP addresses'. Invalid entries are skipped automatically.

## `domains` (type: `array`):

Domains to resolve and then scan, one per line (e.g. example.com). Used when mode is 'Domains'. Schemes, paths and 'www.' prefixes are stripped for you.

## `enrichGeo` (type: `boolean`):

Add ASN number, ASN organisation, ISP, org domain, country, region, city, coordinates, EU flag and timezone to every host via the free ipwho.is API. Turn off for a faster, ports-and-CVEs-only run.

## `maxItems` (type: `integer`):

Hard cap on how many hosts (dataset items) are scanned in one run. Protects you from runaway runs when a domain resolves to many A records.

## Actor input object example

```json
{
  "mode": "ips",
  "ips": [
    "8.8.8.8",
    "1.1.1.1"
  ],
  "domains": [
    "example.com"
  ],
  "enrichGeo": true,
  "maxItems": 100
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "ips": [
        "8.8.8.8",
        "1.1.1.1"
    ],
    "domains": [
        "example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/ip-threat-intel-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "ips": [
        "8.8.8.8",
        "1.1.1.1",
    ],
    "domains": ["example.com"],
}

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/ip-threat-intel-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "ips": [
    "8.8.8.8",
    "1.1.1.1"
  ],
  "domains": [
    "example.com"
  ]
}' |
apify call ninhothedev/ip-threat-intel-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ninhothedev/ip-threat-intel-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/qpqiRBhigwdqMvpk4/builds/aZgQnCz1jvN6HuZKR/openapi.json
