Files
telegram-rss-bot/README.md
T

148 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# telegram-rss-bot
Telegram bot that monitors cybersecurity RSS feeds and delivers real-time alerts. Articles are classified by severity and quality before delivery.
## Project Structure
```
rss_telegram_bot/
├── threat_intel_bot.py # Main bot — commands, subscriptions, alert dispatch
├── rss_manager.py # Feed fetching, dedup, message formatting
├── content_classifier.py # Severity/quality scoring, CVE/actor/malware extraction
├── check_feeds.py # CLI utility to check feed health
├── feeds/
│ ├── news_feeds.json
│ ├── malware_feeds.json
│ ├── threat_intel_feeds.json
│ ├── osint_feeds.json
│ └── research_feeds.json
├── .env # Not committed — BOT_TOKEN + optional filters
├── subscribers.json # Auto-managed — chat/topic subscriptions
└── seen_articles.db # SQLite — tracks sent articles (7-day retention)
```
## Setup
```bash
pip install python-telegram-bot feedparser aiohttp beautifulsoup4
```
Create `.env`:
```env
BOT_TOKEN=your_token_here
MIN_QUALITY_SCORE=0
ALLOWED_SEVERITIES=critical,high,medium,low
```
Run:
```bash
python3 threat_intel_bot.py
```
## Bot Commands
| Command | Action |
|---|---|
| `/on_<category>` | Subscribe this chat/topic to a category |
| `/off_<category>` | Unsubscribe |
| `/stats` | Check feed health and subscriber count |
| `/help` | Show commands |
Categories: `news`, `malware`, `threat_intel`, `osint`, `research`
**Telegram Topics:** Run `/on_<category>` inside each topic to route categories to separate threads.
## Feed Management
Each `feeds/*.json` file follows this structure:
```json
{
"category_name": {
"Feed Display Name": "https://example.com/rss.xml"
}
}
```
Add or remove feeds by editing the JSON, then restart the bot. Run `python3 check_feeds.py` to verify feed health before deploying.
## Message Format
Each alert follows this structure:
```
{emoji} Title
Description
📡 Source · Published (UTC)
🆔 CVE-2024-1234, CVE-2024-5678 (only if CVEs detected)
👤 APT28, Fancy Bear (only if threat actors detected)
🦠 LockBit, Cobalt Strike (only if malware families detected)
🔗 Read Full Article
```
The enrichment lines (CVEs, actors, malware) only appear when the classifier finds something — clean articles stay minimal.
## Classification
`content_classifier.py` extracts the following from article title + description:
**CVEs** — standard `CVE-YYYY-NNNNN` pattern matching.
**Threat actors** — APT groups and named adversaries: APT28/29/40/41, Lazarus, Sandworm, Volt Typhoon, Scattered Spider, FIN7, and others defined in `THREAT_ACTORS`.
**Malware families** — ransomware, C2 frameworks, loaders, stealers, and APT tooling: LockBit, Cobalt Strike, Emotet, QakBot, Sliver, PlugX, and others defined in `MALWARE_FAMILIES`. To add a family, append its display name to the set — matching is case-insensitive.
**Severity** is keyword-based:
- `critical` — zero-days, active exploitation, RCE, ransomware
- `high` — privesc, auth bypass, code execution, kernel exploits
- `medium` — XSS, CSRF, DoS, memory corruption
- `low` — everything else
**Quality score (0100)** factors in: source reputation, content length, CVE presence, PoC indicators, threat actor mentions.
Filter via env vars:
```env
MIN_QUALITY_SCORE=50
ALLOWED_SEVERITIES=critical,high
```
## Systemd Service (VPS)
`/etc/systemd/system/rss-bot.service`:
```ini
[Unit]
Description=Threat Intel RSS Telegram Bot
After=network.target
[Service]
Type=simple
User=your_user
WorkingDirectory=/home/your_user/rss_telegram_bot
EnvironmentFile=/home/your_user/rss_telegram_bot/.env
ExecStart=/usr/bin/python3 threat_intel_bot.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now rss-bot
sudo journalctl -u rss-bot -f
```
## Notes
- First run marks all current articles as seen — no flood on startup
- Polling interval: 5 minutes (`asyncio.sleep(300)` in `threat_intel_bot.py`)
- Only today's UTC articles are processed (strict date gate in `rss_manager.py`)
- `seen_articles.db` auto-purges entries older than 7 days