Skip to main content
PPPhishPondPhishing Tradecraft Intelligence

Attack · Detection · Validation

CampaignTradecraftInfrastructureDetectionResearchRadarNewsroomAboutSubscribe
CampaignTradecraftInfrastructureDetectionResearchRadarNewsroomAboutSubscribe

Research Desk

PhishPond

Phishing tradecraft research desk covering campaign analysis, adversary infrastructure, detection engineering, and validation workflows.

High signal for security teams who need tradecraft, not recycled filler.

Navigate

  • Home
  • Newsroom
  • Research
  • Subscribe

Signals

  • editorial@phishpond.dev
  • Research Mission & Ethics
  • Intel Brief
  • RSS Feed
  • Submit Research Tip
© 2026 PhishPond. Authorized security research use only.

GitHub RadarDual-use project

0xDanielLopez/TweetFeed

TweetFeed collects Indicators of Compromise (IOCs) shared by the infosec community at Twitter. Here you will find malicious URLs, domains, IPs, and SHA256/MD5 hashes. 681 stars.

681 stars69 forkspushed Sep 11, 2026CC0-1.0

Project links:Open GitHub projectBack to radar

README Preview

Fetched from GitHub

<div align="center"> <h1 align="center">TweetFeed</h1> <h3 align="center">Feeds of IOCs posted by the community on Twitter/X</h3>

<p align="center"> <b> <a href="https://tweetfeed.live">TweetFeed.live</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp; <a href="https://tweetfeed.live/docs/">Docs</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp; <a href="https://api.tweetfeed.live/v1">API</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp; <a href="https://github.com/0xDanielLopez/TweetFeed/issues/new/choose">Feedback</a> </b> </p>

---

Image: TweetFeed.live

--- </div>

☰ Content

  • Consuming this data
  • Data collected
  • Programmatic access
  • Some statistics
  • How it works
  • Use TweetFeed in your stack
  • Agent-ready surface
  • License
  • Author
  • Disclaimer
The counters below (timestamp, per-type totals, tag count, top tags, top reporters) are regenerated by the pipeline every 15 minutes. Hand-written sections are stable.

:satellite: Consuming this data

  • Please do not clone or poll this repository to keep a feed fresh. The same data is served with conditional requests from the API and the ready-made files: JSON windows at `api.tweetfeed.live/v1/today` (week, month, type/tag/user filters), blocklists (domains.txt, ips.txt, urls.txt, hosts.txt, adguard.txt, rpz.txt, zeek-intel.txt, Wazuh CDB lists...), TAXII 2.1 / STIX 2.1, the MISP feed and RSS.
  • Poll at most every 15 minutes (the pipeline publishes every 15 minutes) and send If-None-Match (ETag) or If-Modified-Since: every 200 response carries ETag and Last-Modified, and an unchanged file answers 304 with an empty body.
  • If you really need a local copy: the history of this repository is rewritten once a day (single-commit snapshot), so a plain git pull breaks daily. Use git clone --depth 1 --filter=blob:none https://github.com/0xDanielLopez/TweetFeed.git and refresh with git fetch --depth 1 origin master && git reset --hard origin/master, never more often than every 15 minutes.
  • Freshness: `/v1/status` gives a verdict per artifact and `/v1/manifest` lists every published file.

:heart: Support the project

If you like the project, please consider:

  • Giving it a star :star:
  • Invite to a coffee :coffee:

:page_facing_up: Data collected

<div align="center">

<h3>CSV feeds</h3>

<table> <thead> </thead> <tbody> <tr> <th colspan=4>2026-09-11 09:00:20 (UTC)</th> </tr> <tr> <th>Today</th> <th>Last 7 days</th> <th>Last 30 days</th> <th>Last 365 days</th> </tr> <tr> <td>:clipboard: <a href="https://github.com/0xDanielLopez/TweetFeed/blob/master/today.csv">Today</a> (<a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/today.csv">raw</a>)</td> <td>:clipboard: <a href="https://github.com/0xDanielLopez/TweetFeed/blob/master/week.csv">Week</a> (<a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/week.csv">raw</a>)</td> <td>:clipboard: <a href="https://github.com/0xDanielLopez/TweetFeed/blob/master/month.csv">Month</a> (<a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/month.csv">raw</a>)</td> <td>:clipboard: <a href="https://github.com/0xDanielLopez/TweetFeed/blob/master/year.csv">Year</a> (<a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/year.csv">raw</a>)</td> </tr> </tbody> </table>

<h3>Other formats</h3>

<table> <thead> <tr> <th>Format</th> <th>URL</th> <th>Notes</th> </tr> </thead> <tbody> <tr> <td><b>RSS 2.0</b></td> <td><a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/rss.xml">rss.xml</a></td> <td>Today's IOCs (regenerated every 15 min)</td> </tr> <tr> <td><b>MISP</b></td> <td><a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/misp/manifest.json">misp/manifest.json</a></td> <td>One event per day, 365 days of history. Add as a feed in MISP via <i>Sync Actions &rarr; Feeds &rarr; Add</i>, using the directory <code>https://tweetfeed.live/misp</code> - MISP appends <code>/manifest.json</code> itself.</td> </tr> <tr> <td><b>MISP hash cache</b></td> <td><a href="https://tweetfeed.live/misp/hashes.csv">misp/hashes.csv</a></td> <td><code>md5(value),event-uuid</code> pairs for MISP's <i>Cache feed</i> correlation, last 31 days</td> </tr> <tr> <td><b>STIX 2.1</b></td> <td><a href="https://raw.githubusercontent.com/0xDanielLopez/TweetFeed/master/stix/manifest.json">stix/manifest.json</a></td> <td>Bundles for <a href="https://tweetfeed.live/stix/today.json">today</a> / <a href="https://tweetfeed.live/stix/week.json">week</a> / <a href="https://tweetfeed.live/stix/month.json">month</a>. No year bundle on purpose - it would land north of 80 MB, close to GitHub's push limit. Use the diff endpoint below to stay in sync instead.</td> </tr> <tr> <td><b>TAXII 2.1</b></td> <td><a href="https://api.tweetfeed.live/taxii2/">api.tweetfeed.live/taxii2/</a></td> <td>Read-only TAXII server, no auth. One collection, <code>b7dc78af-1d12-5059-898c-3f0e77636204</code> (<i>TweetFeed IOCs, rolling 31 days</i>). Point any TAXII 2.1 client at the discovery URL.</td> </tr> <tr> <td><b>Blocklists</b></td> <td><a href="https://api.tweetfeed.live/v1/blocklist/domains.txt">v1/blocklist/&lt;format&gt;</a></td> <td>Rolling 30 days, ready to drop into a resolver: 16 formats, see <a href="https://tweetfeed.live/blocklists/">tweetfeed.live/blocklists/</a> or <a href="#mag-use-tweetfeed-in-your-stack">DNS / network blocking</a> below.</td> </tr> <tr> <td><b>Scoped RSS</b></td> <td><code>rss/{tag,type,user}/&lt;name&gt;.xml</code></td> <td>Narrower feeds than the firehose: <a href="https://tweetfeed.live/rss/tag/phishing.xml">per tag</a> (any tag active in the last 7 days), <a href="https://tweetfeed.live/rss/type/url.xml">per IOC type</a> (always all five), and per reporter handle.</td> </tr> </tbody> </table>

</div>

<div align="center">

<h3>Output example</h3>

<p><b>CSV schema</b></p>

<pre><code>date, user, type, value, tags, tweet_url</code></pre>

<sub><b>No header row</b> - the first line is already data, so do not set <code>ignoreFirstRecord</code> / <code>skip_header</code> or you will drop a real IOC. Dates are UTC, <code>tags</code> is space-separated. Live sample: <a href="https://github.com/0xDanielLopez/TweetFeed/blob/master/today.csv">today.csv</a></sub>

</div>

:gear: Programmatic access

<div align="center">

<table> <thead> <tr> <th>Surface</th> <th>URL</th> <th>Use case</th> </tr> </thead> <tbody> <tr> <td><b>REST API</b></td> <td><a href="https://api.tweetfeed.live/v1">api.tweetfeed.live</a></td> <td>JSON, no auth, CORS enabled. <code>/v1/{today,week,month,year}[/filter][/filter]</code> where a filter is an IOC type, a tag, or an <code>@handle</code>. Order does not matter: <code>/v1/today/url/phishing</code> and <code>/v1/today/phishing/url</code> are the same query.</td> </tr> <tr> <td><b>Incremental sync</b></td> <td><code>/v1/since/&lt;ISO8601&gt;</code></td> <td>Only what landed after a timestamp, same filter syntax. Poll this instead of re-downloading <code>year.csv</code>. Returns <code>410</code> past the 365-day horizon.</td> </tr> <tr> <td><b>Single-IOC lookup</b></td> <td><code>/v1/ioc?value=&lt;ioc&gt;</code></td> <td>Exact match across the full 365-day window, plus AI context, related infrastructure and network metadata when available. Backs <a href="https://tweetfeed.live/search/">tweetfeed.live/search/</a>.</td> </tr> <tr> <td><b>Campaigns / trends / counts</b></td> <td><code>/v1/{campaigns,trends,counts}</code></td> <td><a href="https://api.tweetfeed.live/v1/campaigns">Campaign clusters</a> from the last 7 days, <a href="https://api.tweetfeed.live/v1/trends">31-day trend series</a> (movers, TLDs, novelty), and <a href="https://api.tweetfeed.live/v1/counts">raw per-window counters</a>.</td> </tr> <tr> <td><b>MCP server</b></td> <td><a href="https://mcp.tweetfeed.live">mcp.tweetfeed.live</a></td> <td>JSON-RPC 2.0 endpoint exposing 13 tools (<code>query_iocs</code>, <code>check_url</code>, <code>check_ip</code>, <code>check_hash</code>, <code>list_recent_iocs</code>, <code>get_tag_info</code>, <code>get_trending</code>, <code>enrich_ioc</code>, <code>get_campaigns</code>, <code>get_campaign_iocs</code>, <code>get_trends</code>, <code>search</code>, <code>fetch</code>) for Claude / AI agents</td> </tr> </tbody> </table>

Full request/response shapes live in the <a href="https://tweetfeed.live/openapi.yaml">OpenAPI spec</a>; see <a href="https://tweetfeed.live/agents/">tweetfeed.live/agents/</a> for the copy-paste MCP config and full tool reference.

</div>

:bar_chart: Some statistics

<div align="center">

<h3>Types</h3>

| Type | Today | Week | Month | Year | | :--- | :---: | :---: | :---: | :---: | | :link: URLs | 10 | 250 | 2062 | 50965 | | :globe_with_meridians: Domains | 10 | 228 | 1827 | 41672 | | :triangular_flag_on_post: IPs | 5 | 36 | 367 | 8005 | | :1234: SHA256 | 1 | 32 | 265 | 2682 | | :1234: MD5 | 0 | 10 | 103 | 2343 |

</div>

---

<div align="center">

<h3>Top 10 tags <sub>(by year activity, refreshed every 15 min)</sub></h3>

<!-- TAG_TABLE_START --> | Tag | Today | Week | Month | Year | | :--- | :---: | :---: | :---: | :---: | | #phishing | 26 | 419 | 2508 | 39828 | | #Kimsuky | 0 | 2 | 84 | 13230 | | #DPRK | 0 | 0 | 64 | 11647 | | #C2 | 0 | 6 | 95 | 6086 | | #scam | 0 | 6 | 26 | 5072 | | #malware | 7 | 135 | 370 | 2799 | | #APT | 0 | 8 | 131 | 1657 | | #CobaltStrike | 0 | 2 | 10 | 1073 | | #AsyncRAT | 0 | 0 | 21 | 775 | | #stealer | 0 | 3 | 35 | 732 | <!-- TAG_TABLE_END -->

These are the busiest 10 of <!-- TAG_COUNT_START -->93<!-- TAG_COUNT_END --> tags being matched. Every one of them is queryable through the API and has its own RSS feed; the highest-volume ones also get a curated landing page at tweetfeed.live/tags/.

</div>

---

<div align="center">

<h3>Top Reporters (today)</h3>

<!-- TOP_REPORTERS_START --> | Number | User | IOCs | | :--- | :---: | :---: | | #1 | masaomi346 | 7 | | #2 | eqv_sec | 7 | | #3 | TKemmerling | 6 | | #4 | phishunt_io | 3 | | #5 | PhishStats | 3 | | #6 | - |