ExploitDB: search local exploit-db CSV mirror by keyword, EDB ID, or CVE identifier. In-bot update command downloads the latest CSV from GitLab. Also added to the update-data.sh script. Payload: built-in template library with 52 payloads across 6 categories (sqli, xss, ssti, lfi, cmdi, xxe). Supports browsing, numeric index, and keyword search within categories. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
269 lines
8.6 KiB
Markdown
269 lines
8.6 KiB
Markdown
# Usage Guide
|
|
|
|
## Running
|
|
|
|
```bash
|
|
# From project directory
|
|
derp
|
|
|
|
# With options
|
|
derp --config /path/to/derp.toml --verbose
|
|
```
|
|
|
|
## CLI Flags
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-c, --config PATH` | Config file path |
|
|
| `-v, --verbose` | Debug logging |
|
|
| `--cprofile [PATH]` | Enable cProfile, dump to PATH [derp.prof] |
|
|
| `-V, --version` | Print version |
|
|
| `-h, --help` | Show help |
|
|
|
|
## Configuration
|
|
|
|
All settings in `config/derp.toml`:
|
|
|
|
```toml
|
|
[server]
|
|
host = "irc.libera.chat" # IRC server hostname
|
|
port = 6697 # Port (6697 = TLS, 6667 = plain)
|
|
tls = true # Enable TLS encryption
|
|
nick = "derp" # Bot nickname
|
|
user = "derp" # Username (ident)
|
|
realname = "derp IRC bot" # Real name field
|
|
password = "" # Server password (optional)
|
|
sasl_user = "" # SASL PLAIN username (optional)
|
|
sasl_pass = "" # SASL PLAIN password (optional)
|
|
|
|
[bot]
|
|
prefix = "!" # Command prefix character
|
|
channels = ["#test"] # Channels to join on connect
|
|
plugins_dir = "plugins" # Plugin directory path
|
|
rate_limit = 2.0 # Max messages per second (default: 2.0)
|
|
rate_burst = 5 # Burst capacity (default: 5)
|
|
admins = [] # Hostmask patterns (fnmatch), IRCOPs auto-detected
|
|
|
|
[logging]
|
|
level = "info" # Logging level: debug, info, warning, error
|
|
```
|
|
|
|
## Built-in Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `!ping` | Bot responds with "pong" |
|
|
| `!help` | List all available commands |
|
|
| `!help <cmd>` | Show help for a specific command |
|
|
| `!help <plugin>` | Show plugin description and its commands |
|
|
| `!version` | Show bot version |
|
|
| `!uptime` | Show how long the bot has been running |
|
|
| `!echo <text>` | Echo back text (example plugin) |
|
|
| `!cert <domain> [...]` | Lookup CT logs for up to 5 domains |
|
|
| `!whoami` | Show your hostmask and admin status |
|
|
| `!load <plugin>` | Hot-load a plugin (admin) |
|
|
| `!reload <plugin>` | Reload a plugin (admin) |
|
|
| `!unload <plugin>` | Unload a plugin (admin) |
|
|
| `!admins` | Show admin patterns and detected opers (admin) |
|
|
| `!plugins` | List loaded plugins with handler counts |
|
|
| `!dns <target> [type]` | DNS lookup (A, AAAA, MX, NS, TXT, CNAME, PTR, SOA) |
|
|
| `!encode <fmt> <text>` | Encode text (b64, hex, url, rot13) |
|
|
| `!decode <fmt> <text>` | Decode text (b64, hex, url, rot13) |
|
|
| `!hash [algo] <text>` | Generate hash digests (md5, sha1, sha256, sha512) |
|
|
| `!hashid <hash>` | Identify hash type by format |
|
|
| `!defang <ioc>` | Defang URLs/IPs/domains for safe sharing |
|
|
| `!refang <text>` | Restore defanged IOCs |
|
|
| `!revshell <type> <ip> <port>` | Generate reverse shell one-liner |
|
|
| `!cidr <network>` | Subnet info (range, hosts, mask) |
|
|
| `!cidr contains <net> <ip>` | Check if IP belongs to network |
|
|
| `!whois <domain\|ip>` | WHOIS lookup via raw TCP (port 43) |
|
|
| `!portcheck <host> [ports]` | Async TCP port scan (max 20 ports) |
|
|
| `!httpcheck <url>` | HTTP status, redirects, response time |
|
|
| `!tlscheck <host> [port]` | TLS version, cipher, cert details |
|
|
| `!blacklist <ip>` | Check IP against 10 DNSBLs |
|
|
| `!rand <mode> [args]` | Random: password, hex, uuid, bytes, int, coin, dice |
|
|
| `!timer <duration> [label]` | Set countdown timer with notification |
|
|
| `!timer list` | Show active timers |
|
|
| `!timer cancel <label>` | Cancel a running timer |
|
|
| `!geoip <ip>` | GeoIP lookup (city, country, coords, timezone) |
|
|
| `!asn <ip>` | ASN lookup (AS number, organization) |
|
|
| `!tor <ip\|update>` | Check IP against Tor exit nodes |
|
|
| `!iprep <ip\|update>` | Check IP against Firehol/ET blocklists |
|
|
| `!cve <id\|search>` | CVE lookup from local NVD mirror |
|
|
| `!opslog <add\|list\|search\|del\|clear>` | Timestamped operational log |
|
|
| `!note <set\|get\|del\|list\|clear>` | Per-channel key-value notes |
|
|
| `!subdomain <domain> [brute]` | Subdomain enumeration (crt.sh + DNS) |
|
|
| `!headers <url>` | HTTP header fingerprinting |
|
|
| `!exploitdb <search\|id\|cve\|update>` | Search local Exploit-DB mirror |
|
|
| `!payload <type> [variant]` | Web vuln payload templates |
|
|
|
|
### Command Shorthand
|
|
|
|
Commands can be abbreviated to any unambiguous prefix:
|
|
|
|
```
|
|
!h -> !help (unique match)
|
|
!pi -> !ping (unique match)
|
|
!p -> error: ambiguous (ping, plugins)
|
|
```
|
|
|
|
Exact matches always take priority over prefix matches.
|
|
|
|
### `!cert` -- Certificate Transparency Lookup
|
|
|
|
Query [crt.sh](https://crt.sh) CT logs to enumerate SSL certificates for
|
|
domains. Reports totals (expired/valid) and flags domains still serving
|
|
expired certs.
|
|
|
|
```
|
|
!cert example.com
|
|
!cert example.com badsite.com another.org
|
|
```
|
|
|
|
Output format:
|
|
|
|
```
|
|
example.com -- 127 certs (23 expired, 104 valid)
|
|
badsite.com -- 45 certs (8 expired, 37 valid) | live cert EXPIRED
|
|
broken.test -- error: timeout
|
|
```
|
|
|
|
- Max 5 domains per invocation
|
|
- crt.sh can be slow; the bot confirms receipt before querying
|
|
- Live cert check runs only when expired CT entries exist
|
|
|
|
## Admin System
|
|
|
|
Commands marked as `admin` require elevated permissions. Admin access is
|
|
granted via:
|
|
|
|
1. **IRC operator status** -- detected automatically via `WHO` on channel join
|
|
2. **Hostmask patterns** -- configured in `[bot] admins`, fnmatch-style
|
|
|
|
```toml
|
|
[bot]
|
|
admins = [
|
|
"*!~user@trusted.host",
|
|
"ops!*@*.ops.net",
|
|
]
|
|
```
|
|
|
|
Empty by default -- only IRC operators get admin access unless patterns
|
|
are configured.
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `!whoami` | Show your hostmask and admin status |
|
|
| `!admins` | Show configured patterns and detected opers (admin) |
|
|
|
|
Admin-restricted commands: `!load`, `!reload`, `!unload`, `!admins`.
|
|
|
|
### Writing Admin Commands
|
|
|
|
```python
|
|
@command("dangerous", help="Admin-only action", admin=True)
|
|
async def cmd_dangerous(bot, message):
|
|
...
|
|
```
|
|
|
|
## Local Databases (Wave 3)
|
|
|
|
Several plugins rely on local data files in the `data/` directory. Use the
|
|
update script or in-bot commands to populate them.
|
|
|
|
### Data Update Script
|
|
|
|
```bash
|
|
./scripts/update-data.sh # Update all feeds
|
|
MAXMIND_LICENSE_KEY=xxx ./scripts/update-data.sh # Include GeoLite2
|
|
```
|
|
|
|
The script is cron-friendly (exit 0/1, quiet unless `NO_COLOR` is unset).
|
|
|
|
### In-Bot Updates
|
|
|
|
```
|
|
!tor update # Download Tor exit node list
|
|
!iprep update # Download Firehol/ET blocklist feeds
|
|
!cve update # Download NVD CVE feed (slow, paginated)
|
|
```
|
|
|
|
### Data Directory Layout
|
|
|
|
```
|
|
data/
|
|
GeoLite2-City.mmdb # MaxMind GeoIP (requires license key)
|
|
GeoLite2-ASN.mmdb # MaxMind ASN (requires license key)
|
|
tor-exit-nodes.txt # Tor exit node IPs
|
|
iprep/ # Firehol/ET blocklist feeds
|
|
firehol_level1.netset
|
|
firehol_level2.netset
|
|
et_compromised.ipset
|
|
...
|
|
nvd/ # NVD CVE JSON files
|
|
nvd_0000.json
|
|
...
|
|
```
|
|
|
|
GeoLite2 databases require a free MaxMind license key. Set
|
|
`MAXMIND_LICENSE_KEY` when running the update script.
|
|
|
|
## Plugin Management
|
|
|
|
Plugins can be loaded, unloaded, and reloaded at runtime without
|
|
restarting the bot.
|
|
|
|
```
|
|
!load crtsh # Hot-load a new plugin from plugins/
|
|
!reload crtsh # Reload a changed plugin
|
|
!unload crtsh # Remove a plugin and all its handlers
|
|
!plugins # List loaded plugins with handler counts
|
|
```
|
|
|
|
The `core` plugin cannot be unloaded (prevents losing `!load`/`!reload`),
|
|
but it can be reloaded.
|
|
|
|
## Writing Plugins
|
|
|
|
Create a `.py` file in the `plugins/` directory:
|
|
|
|
```python
|
|
from derp.plugin import command, event
|
|
|
|
@command("hello", help="Greet the user")
|
|
async def cmd_hello(bot, message):
|
|
"""Handler receives bot instance and parsed Message."""
|
|
await bot.reply(message, f"Hello, {message.nick}!")
|
|
|
|
@event("JOIN")
|
|
async def on_join(bot, message):
|
|
"""Event handlers fire on IRC events (JOIN, PART, QUIT, etc.)."""
|
|
if message.nick != bot.nick:
|
|
await bot.send(message.target, f"Welcome, {message.nick}")
|
|
```
|
|
|
|
### Plugin API
|
|
|
|
The `bot` object provides:
|
|
|
|
| Method | Description |
|
|
|--------|-------------|
|
|
| `bot.send(target, text)` | Send message to channel or nick |
|
|
| `bot.reply(msg, text)` | Reply to source (channel or PM) |
|
|
| `bot.action(target, text)` | Send `/me` action |
|
|
| `bot.join(channel)` | Join a channel |
|
|
| `bot.part(channel [, reason])` | Leave a channel |
|
|
| `bot.quit([reason])` | Disconnect from server |
|
|
|
|
The `message` object provides:
|
|
|
|
| Attribute | Description |
|
|
|-----------|-------------|
|
|
| `message.nick` | Sender's nickname |
|
|
| `message.prefix` | Full `nick!user@host` prefix |
|
|
| `message.command` | IRC command (PRIVMSG, JOIN, etc.) |
|
|
| `message.target` | First param (channel or nick) |
|
|
| `message.text` | Trailing text content |
|
|
| `message.is_channel` | Whether target is a channel |
|
|
| `message.params` | All message parameters |
|