feat: add wave 1 plugins (dns, encode, hash, defang, revshell, cidr)
All pure stdlib, zero external dependencies: - dns: raw UDP resolver with A/AAAA/MX/NS/TXT/CNAME/PTR/SOA - encode: base64, hex, URL, ROT13 encode/decode - hash: md5/sha1/sha256/sha512 generation + type identification - defang: IOC defanging/refanging for safe sharing - revshell: reverse shell one-liners for 11 languages - cidr: subnet calculator with IP membership check Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
plugins/defang.py
Normal file
49
plugins/defang.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Plugin: defang and refang IOCs for safe sharing."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
|
||||
from derp.plugin import command
|
||||
|
||||
|
||||
def _defang(text: str) -> str:
|
||||
"""Defang a URL, domain, or IP for safe sharing."""
|
||||
# Protocols
|
||||
text = re.sub(r"https?://", lambda m: m.group().replace("://", "[://]"), text)
|
||||
text = re.sub(r"ftp://", "ftp[://]", text)
|
||||
# Dots in domains/IPs (but not in paths after first slash)
|
||||
parts = text.split("/", 1)
|
||||
parts[0] = parts[0].replace(".", "[.]")
|
||||
return "/".join(parts)
|
||||
|
||||
|
||||
def _refang(text: str) -> str:
|
||||
"""Reverse defanging to restore usable IOCs."""
|
||||
text = text.replace("[://]", "://")
|
||||
text = text.replace("[.]", ".")
|
||||
text = text.replace("hxxp", "http")
|
||||
text = text.replace("hXXp", "http")
|
||||
text = text.replace("[at]", "@")
|
||||
text = text.replace("[AT]", "@")
|
||||
return text
|
||||
|
||||
|
||||
@command("defang", help="Defang IOCs: !defang <url|ip|domain>")
|
||||
async def cmd_defang(bot, message):
|
||||
"""Defang URLs, IPs, and domains for safe pasting."""
|
||||
parts = message.text.split(None, 1)
|
||||
if len(parts) < 2:
|
||||
await bot.reply(message, "Usage: !defang <url|ip|domain>")
|
||||
return
|
||||
await bot.reply(message, _defang(parts[1]))
|
||||
|
||||
|
||||
@command("refang", help="Refang IOCs: !refang <defanged>")
|
||||
async def cmd_refang(bot, message):
|
||||
"""Restore defanged IOCs to usable form."""
|
||||
parts = message.text.split(None, 1)
|
||||
if len(parts) < 2:
|
||||
await bot.reply(message, "Usage: !refang <defanged>")
|
||||
return
|
||||
await bot.reply(message, _refang(parts[1]))
|
||||
Reference in New Issue
Block a user