├── .github └── workflows │ └── python-publish.yml ├── .gitignore ├── LICENSE ├── README.md ├── README.zh-ch.md ├── bin └── vulhub-cli ├── requirements.txt ├── setup.cfg ├── setup.py └── vulhub ├── __init__.py ├── cli ├── __init__.py ├── base_cli.py ├── command.py ├── local_cli.py ├── main.py └── remote_cli.py └── plugin ├── __init__.py └── huoxian_iast.py /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | push: {branches: main} 8 | pull_request: {branches: main} 9 | 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Set up Python 18 | uses: actions/setup-python@v2 19 | with: 20 | python-version: '3.x' 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install -r requirements.txt 25 | pip install setuptools wheel twine 26 | - name: Build and publish 27 | env: 28 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 29 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 30 | run: | 31 | python setup.py sdist bdist_wheel 32 | twine upload dist/* 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # pycharm 132 | .idea 133 | 134 | # Mac OS 135 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 huoxian 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vulhub-compose 2 | [![license](https://img.shields.io/github/license/huoxianclub/vulhub-compose.svg)](https://github.com/huoxianclub/vulhub-compose/blob/main/LICENSE) 3 | [![build](https://github.com/huoxianclub/vulhub-compose/actions/workflows/python-publish.yml/badge.svg)](https://github.com/huoxianclub/vulhub-compose/actions/workflows/python-publish.yml) 4 | 5 | `vulhub-cli` is a command line tool of the vulhub project, which makes the operation of `docker-compose` transparent and reduces the difficulty of using the vulhub shooting range. Vulhub-cli supports local mode and remote mode. The remote mode can directly start the related shooting range without downloading the complete vulhub project, which is more convenient to use. 6 | 7 | [中文文档](https://github.com/huoxianclub/vulhub-compose/blob/main/README.zh-ch.md) 8 | 9 | ## Quick start 10 | If you want to download the vulhub project or have already downloaded the vulhub project, you can directly use the local mode; if you don’t want to download, you can use the remote mode 11 | 12 | #### download vulhub-cli 13 | ```shell script 14 | $ pip install vulhub-cli 15 | ``` 16 | 17 | #### local mode 18 | ```shell script 19 | # Specify relative path 20 | $ vulhub-cli local start --app fastjson/1.2.24-rce 21 | $ vulhub-cli local start --app ./fastjson/1.2.24-rce 22 | 23 | # Specify absolute path 24 | $ vulhub-cli local start --app /opt/vulhub/fastjson/1.2.24-rce 25 | 26 | # Stop environment use vulhub-cli 27 | $ vulhub-cli local stop --app fastjson/1.2.24-rce 28 | 29 | # Stop environment with agent use vulhub-cli 30 | $ vulhub-cli local stop --app fastjson/1.2.24-rce 31 | ``` 32 | 33 | #### remote mode 34 | ```shell script 35 | # Specify vulhub app's name, eg: fastjson/1.2.24-rce 36 | $ vulhub-cli remote start --app fastjson/1.2.24-rce 37 | 38 | # Stop environment with agent use vulhub-cli 39 | $ vulhub-cli remote stop --app fastjson/1.2.24-rce 40 | ``` 41 | 42 | 43 | ## Plugin System 44 | `vulhub-cli` provides plug-in functions, which can support custom plug-ins to achieve specific functions. 45 | 46 | ### Plugin: dongtai 47 | Lingzhi IAST is an interactive application security testing tool independently developed by [FireWire platform](https://www.huoxian.cn/) to detect vulnerabilities in application systems; dongtai IAST supports the detection of some 0 Day vulnerabilities. Now, you can use the vulhub-cli tool to quickly create a shooting range and install dongtai IAST to experience the vulnerability detection function. 48 | 49 | #### Usage 50 | The startup method is the same as the normal startup method, just add the `plugin` parameter to specify the use of the `dongtai` plugin. 51 | ```shell script 52 | # Start the vulhub's app with public Lingzhi IAST agent 53 | $ vulhub-cli remote start --app fastjson/1.2.24-rce --plugin dongtai 54 | 55 | # Start the vulhub's app with your own Lingzhi IAST agent 56 | $ vulhub-cli remote start --app fastjson/1.2.24-rce --plugin dongtai --plugin-args "token=" 57 | 58 | # Stop the vulhub's app with Lingzhi IAST 59 | $ vulhub-cli remote stop --app fastjson/1.2.24-rce --plugin dongtai 60 | ``` 61 | -------------------------------------------------------------------------------- /README.zh-ch.md: -------------------------------------------------------------------------------- 1 | # vulhub-compose 2 | [![license](https://img.shields.io/github/license/huoxianclub/vulhub-compose.svg)](https://github.com/huoxianclub/vulhub-compose/blob/main/LICENSE) 3 | [![build](https://github.com/huoxianclub/vulhub-compose/actions/workflows/python-publish.yml/badge.svg)](https://github.com/huoxianclub/vulhub-compose/actions/workflows/python-publish.yml) 4 | 5 | vulhub-compose是一款屏蔽docker-compose的命令行工具,目的是降低火线平台社区用户使用vulhub靶场的难度,减少学习docker-compose的时间成本;同时,支持直接安装洞态IAST(原灵芝IAST)到vulhub靶场,用于漏洞复现、漏洞挖掘。 6 | 7 | [English](https://github.com/huoxianclub/vulhub-compose/blob/main/README.md) 8 | 9 | ## 快速开始 10 | 如果要下载vulnhub项目或已经下载了vulnhub项目,则可以直接使用本地模式。 如果您不想下载,可以使用远程模式。vulhub项目的前置安装步骤依然需要完成,请自行前往[vulhub项目](https://github.com/vulhub/vulhub)安装docker及其它部分。 11 | 12 | #### 下载vulhub-cli 13 | ```shell script 14 | $ pip install vulhub-cli 15 | ``` 16 | 17 | #### 本地模式 18 | ```shell script 19 | # 使用相对路径启动靶场环境 20 | $ vulhub-cli local start --app fastjson/1.2.24-rce 21 | $ vulhub-cli local start --app ./fastjson/1.2.24-rce 22 | 23 | # 使用绝对路径启动靶场环境 24 | $ vulhub-cli local start --app /opt/vulhub/fastjson/1.2.24-rce 25 | 26 | # 停止并销毁靶场环境 27 | $ vulhub-cli local stop --app fastjson/1.2.24-rce 28 | ``` 29 | 30 | #### 远程模式 31 | ```shell script 32 | # 指定vulhub app的名称,如: fastjson/1.2.24-rce 33 | $ vulhub-cli remote start --app fastjson/1.2.24-rce 34 | 35 | # 停止并销毁靶场环境 36 | $ vulhub-cli remote stop --app fastjson/1.2.24-rce 37 | ``` 38 | 39 | 40 | ## Plugin System 41 | `vulhub-cli` provides plug-in functions, which can support custom plug-ins to achieve specific functions. 42 | 43 | ### Plugin: dongtai 44 | 灵芝IAST推出代码审计版本,在Java WEB应用中安装agent后可用于收集污点调用链,包括组件级数据,只需要编写对应的hook策略即可实现部分**0 Day**漏洞的挖掘,教程可在[官方文档](https://huoxianclub.github.io/LingZhi/#/README)中查看。 45 | 46 | #### 使用方法 47 | 启动方法与正常启动方法相同,只需要增加`plugin`参数指定使用`dongtai`插件即可,如需在靶场中安装**私有**agent,需要前往[洞态](http://aws.iast.huoxian.cn:8000/)的**部署页面**获取并指定token 48 | ```shell script 49 | # 启动靶场并安装公共的灵芝IAST agent 50 | $ vulhub-cli remote start --app fastjson/1.2.24-rce --plugin dongtai 51 | 52 | # 启动靶场并安装个人灵芝IAST agent,token可前往"部署IAST"页面获取 53 | $ vulhub-cli remote start --app fastjson/1.2.24-rce --plugin dongtai --plugin-args "token=" 54 | 55 | # 停止并销毁预装IAST的靶场环境 56 | $ vulhub-cli remote stop --app fastjson/1.2.24-rce --plugin dongtai 57 | ``` -------------------------------------------------------------------------------- /bin/vulhub-cli: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from vulhub.cli.main import main 3 | 4 | main() 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fire==0.4.0 2 | docker-compose==1.28.5 -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = vulhub-cli 3 | version = 0.0.6 4 | author = owefsad 5 | author_email = dongzhiyong@huoxian.cn 6 | description = easy command tool for vulhub 7 | long_description = file: README.md 8 | long_description_content_type = text/markdown 9 | url = https://github.com/HXSecurity/vulhub-compose 10 | project_urls = 11 | Bug Tracker = https://github.com/HXSecurity/vulhub-compose/issues 12 | classifiers = 13 | Programming Language :: Python :: 3 14 | License :: OSI Approved :: MIT License 15 | Operating System :: OS Independents -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/16 下午7:33 5 | # project: vulhub-compose 6 | import codecs 7 | import os 8 | import re 9 | 10 | from setuptools import find_packages 11 | from setuptools import setup 12 | 13 | 14 | def read(*parts): 15 | path = os.path.join(os.path.dirname(__file__), *parts) 16 | with codecs.open(path, encoding='utf-8') as fobj: 17 | return fobj.read() 18 | 19 | 20 | def find_version(*file_paths): 21 | version_file = read(*file_paths) 22 | version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", 23 | version_file, re.M) 24 | if version_match: 25 | return version_match.group(1) 26 | raise RuntimeError("Unable to find version string.") 27 | 28 | 29 | install_requires = [ 30 | 'docker-compose >= 1.28.5', 31 | 'fire >= 0.4.0', 32 | ] 33 | 34 | extras_require = { 35 | ':python_version < "3.5"': ['backports.ssl_match_hostname >= 3.5, < 4'], 36 | ':sys_platform == "win32"': ['colorama >= 0.4, < 1'], 37 | } 38 | 39 | setup( 40 | name='vulhub-cli', 41 | version=find_version("vulhub", "__init__.py"), 42 | description='easy command tool for vulhub', 43 | long_description=read('README.md'), 44 | long_description_content_type='text/markdown', 45 | url='https://www.huoxian.cn/', 46 | project_urls={ 47 | 'Source': 'https://github.com/huoxianclub/vulhub-compose', 48 | 'Tracker': 'https://github.com/huoxianclub/vulhub-compose/issues', 49 | 'VulHub': 'https://github.com/vulhub/vulhub', 50 | 'DongTai-IAST': 'http://iast.huoxian.cn:8000/', 51 | 'DongTai-Doc': 'https://hxsecurity.github.io/DongTaiDoc/#/doc/deploy/vulns' 52 | }, 53 | author='Owefsad, Inc.', 54 | license='MIT License', 55 | packages=find_packages(exclude=['tests.*', 'tests']), 56 | include_package_data=True, 57 | install_requires=install_requires, 58 | extras_require=extras_require, 59 | python_requires='>=3.4', 60 | entry_points={ 61 | 'console_scripts': ['vulhub-cli=vulhub.cli.main:main'], 62 | }, 63 | classifiers=[ 64 | 'Development Status :: 5 - Production/Stable', 65 | 'Environment :: Console', 66 | 'Intended Audience :: Developers', 67 | 'License :: OSI Approved :: MIT License', 68 | 'Programming Language :: Python :: 3', 69 | 'Programming Language :: Python :: 3.4', 70 | 'Programming Language :: Python :: 3.6', 71 | 'Programming Language :: Python :: 3.7', 72 | 'Programming Language :: Python :: 3.8', 73 | 'Programming Language :: Python :: 3.9', 74 | ], 75 | ) 76 | -------------------------------------------------------------------------------- /vulhub/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/16 下午3:39 5 | # project: vulhub-compose 6 | 7 | __version__ = '0.0.6' 8 | -------------------------------------------------------------------------------- /vulhub/cli/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #-*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/16 下午3:45 5 | # project: vulhub-compose 6 | -------------------------------------------------------------------------------- /vulhub/cli/base_cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/18 下午4:13 5 | # project: vulhub-compose 6 | import os 7 | 8 | from vulhub.plugin.huoxian_iast import DongTai 9 | 10 | 11 | class BaseCli(object): 12 | PLUGINS = { 13 | 'dongtai': DongTai() 14 | } 15 | 16 | def __init__(self): 17 | pass 18 | 19 | def start(self, app, plugin, plugin_args): 20 | pass 21 | 22 | def stop(self, app, plugin, plugin_args): 23 | pass 24 | 25 | @staticmethod 26 | def get_yaml_path(path): 27 | # 检查是否存在 28 | yaml_path = BaseCli.normal_path(path) 29 | if yaml_path and os.path.exists(yaml_path): 30 | yaml_file = BaseCli.get_yaml_file(yaml_path) 31 | return os.path.join(yaml_path, yaml_file) 32 | else: 33 | raise FileNotFoundError(f'path:{yaml_path if path else path} not exists.') 34 | 35 | @staticmethod 36 | def get_yaml_file(yaml_path): 37 | """ 38 | docker-compose.yml or docker-compose.yaml need in yaml_path 39 | :param yaml_path: 40 | :return: 41 | """ 42 | files = os.listdir(yaml_path) 43 | if 'docker-compose.yml' in files: 44 | yaml_file = 'docker-compose.yml' 45 | elif 'docker-compose.yaml' in files: 46 | yaml_file = 'docker-compose.yaml' 47 | else: 48 | raise FileNotFoundError(f'path: docker-compose.yml or docker-compose.yaml not found in {yaml_path}') 49 | return yaml_file 50 | 51 | @staticmethod 52 | def normal_path(path): 53 | if path.startswith('/'): 54 | yaml_path = path 55 | else: 56 | # 获取当前路径 57 | base_path = os.path.abspath('.') 58 | yaml_path = os.path.normpath(os.path.join(base_path, path)) 59 | return yaml_path 60 | -------------------------------------------------------------------------------- /vulhub/cli/command.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/16 下午5:50 5 | # project: vulhub-compose 6 | import functools 7 | import logging 8 | import sys 9 | 10 | from compose.cli.colors import AnsiMode 11 | from compose.cli.docopt_command import DocoptDispatcher 12 | from compose.cli.errors import UserError 13 | from compose.cli.main import setup_logging, TopLevelCommand, setup_console_handler, setup_parallel_logger, \ 14 | perform_command 15 | from compose.cli.utils import get_version_info 16 | 17 | log = logging.getLogger(__name__) 18 | 19 | 20 | def dispatch(*args, **kwargs): 21 | console_stream = sys.stderr 22 | console_handler = logging.StreamHandler(console_stream) 23 | setup_logging(console_handler) 24 | dispatcher = DocoptDispatcher( 25 | TopLevelCommand, 26 | {'options_first': True, 'version': get_version_info('compose')}) 27 | 28 | options, handler, command_options = dispatcher.parse(*args) 29 | 30 | ansi_mode = AnsiMode.AUTO 31 | try: 32 | if options.get("--ansi"): 33 | ansi_mode = AnsiMode(options.get("--ansi")) 34 | except ValueError: 35 | raise UserError( 36 | 'Invalid value for --ansi: {}. Expected one of {}.'.format( 37 | options.get("--ansi"), 38 | ', '.join(m.value for m in AnsiMode) 39 | ) 40 | ) 41 | if options.get("--no-ansi"): 42 | if options.get("--ansi"): 43 | raise UserError("--no-ansi and --ansi cannot be combined.") 44 | log.warning('--no-ansi option is deprecated and will be removed in future versions.') 45 | ansi_mode = AnsiMode.NEVER 46 | 47 | setup_console_handler(console_handler, 48 | options.get('--verbose'), 49 | ansi_mode.use_ansi_codes(console_handler.stream), 50 | options.get("--log-level")) 51 | setup_parallel_logger(ansi_mode) 52 | if ansi_mode is AnsiMode.NEVER: 53 | command_options['--no-color'] = True 54 | return functools.partial(perform_command, options, handler, command_options) 55 | -------------------------------------------------------------------------------- /vulhub/cli/local_cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/18 下午4:14 5 | # project: vulhub-compose 6 | 7 | from vulhub.cli.base_cli import BaseCli 8 | from vulhub.cli.command import dispatch 9 | 10 | 11 | class Local(BaseCli): 12 | 13 | def __init__(self): 14 | super().__init__() 15 | 16 | def start(self, app, plugin=None, plugin_args=None): 17 | yaml_file = self.get_yaml_path(app) 18 | if plugin: 19 | plugin = self.PLUGINS.get(plugin) 20 | plugin.args = plugin_args 21 | yaml_file = plugin.attach(yaml_file) 22 | 23 | command_func = dispatch(['-f', yaml_file, 'up', '-d']) 24 | command_func() 25 | if plugin: 26 | plugin.detach(yaml_file) 27 | 28 | def stop(self, app, plugin=None, plugin_args=None): 29 | yaml_file = self.get_yaml_path(app) 30 | if plugin: 31 | plugin = self.PLUGINS.get(plugin) 32 | yaml_file = plugin.attach(yaml_file) 33 | 34 | command_func = dispatch(['-f', yaml_file, 'down']) 35 | command_func() 36 | 37 | if plugin: 38 | plugin.detach(yaml_file) 39 | -------------------------------------------------------------------------------- /vulhub/cli/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/16 下午3:45 5 | # project: vulhub-compose 6 | 7 | import fire as fire 8 | 9 | from vulhub.cli.local_cli import Local 10 | from vulhub.cli.remote_cli import Remote 11 | 12 | 13 | def main(): 14 | fire.Fire({ 15 | 'remote': Remote, 16 | 'local': Local 17 | }) 18 | -------------------------------------------------------------------------------- /vulhub/cli/remote_cli.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/18 下午4:13 5 | # project: vulhub-compose 6 | import logging 7 | import os 8 | import queue 9 | import tempfile 10 | from urllib.parse import urljoin 11 | 12 | import requests 13 | import platform 14 | 15 | from vulhub.cli.base_cli import BaseCli 16 | from vulhub.cli.local_cli import Local 17 | 18 | logger = logging.getLogger(__name__) 19 | 20 | IS_WINDOWS = False 21 | IS_LINUX = False 22 | IS_MAC = False 23 | 24 | if (platform.system() == 'Windows'): 25 | IS_WINDOWS = True 26 | elif (platform.system() == 'Linux'): 27 | IS_LINUX = True 28 | elif platform.system() == 'Darwin': 29 | IS_MAC = True 30 | 31 | 32 | class Remote(BaseCli): 33 | GITHUB_API = 'https://api.github.com/repos/{repo}/contents/{app}' 34 | VULHUB_APP = 'vulhub/vulhub' 35 | BASE_URLS = ('https://gitee.com/vulhub/vulhub/raw/master/',) 36 | TEMPLATES_YAML = ('docker-compose.yml', 'docker-compose.yaml') 37 | 38 | def __init__(self): 39 | super().__init__() 40 | 41 | def start(self, app, plugin=None, plugin_args=None): 42 | app = self.normalize_app(app) 43 | yaml_path = self.download_app(app) 44 | if yaml_path: 45 | Local().start(app=yaml_path, plugin=plugin, plugin_args=plugin_args) 46 | else: 47 | logger.error(f'[*] Failure: vulhub app[{app}] download failure') 48 | 49 | def stop(self, app, plugin=None, plugin_args=None): 50 | app = self.normalize_app(app) 51 | yaml_path = self.download_app(app) 52 | if yaml_path: 53 | Local().stop(app=yaml_path, plugin=plugin, plugin_args=plugin_args) 54 | else: 55 | logger.error(f'[*] Failure: vulhub app[{app}] download failure') 56 | 57 | @staticmethod 58 | def normalize_app(app): 59 | if app.startswith('/'): 60 | app = app[1:] 61 | return app 62 | 63 | def download_app(self, app): 64 | url = self.GITHUB_API.format(repo=self.VULHUB_APP, app=app) 65 | app_contents = None 66 | try: 67 | resp = requests.get(url) 68 | if resp.status_code == 200: 69 | app_contents = resp.json() 70 | except Exception as e: 71 | pass 72 | 73 | app_path = None 74 | if app_contents and len(app_contents) > 0: 75 | app_path = self.create_app_path(app=app) 76 | print(f'[+] download vulapp [ {app} ] to {app_path}') 77 | for app_content in app_contents: 78 | name = app_content.get('name') 79 | download_url = app_content.get('download_url') 80 | self.download_file(app=app, name=name, download_url=download_url, app_path=app_path) 81 | return app_path 82 | 83 | @staticmethod 84 | def download_file(app, name, download_url, app_path): 85 | download_queue = queue.Queue() 86 | 87 | def generate_download_urls(): 88 | download_queue.put(download_url) 89 | for BASE_URL in Remote.BASE_URLS: 90 | url = urljoin(BASE_URL, f'{app}/{name}') 91 | download_queue.put(url) 92 | 93 | def download(): 94 | while download_queue.empty() is False: 95 | url = download_queue.get() 96 | try: 97 | # fixme 使用head方法可以提升效率,但是这里使用head时出现了错误 98 | resp = requests.get(url, headers={'User-Agent': 'curl/7.64.1'}, timeout=(6, 6)) 99 | if resp.status_code == 200: 100 | Remote.write_file(app_path=app_path, name=name, content=resp.content) 101 | break 102 | except Exception as e: 103 | logger.debug(f'[-] Failure: download {name} from {url}') 104 | pass 105 | 106 | generate_download_urls() 107 | download() 108 | 109 | @staticmethod 110 | def create_app_path(app): 111 | if IS_MAC or IS_LINUX: 112 | temp_dir = os.path.join(os.path.expanduser('~'), '.vulhpp') 113 | else: 114 | temp_dir = tempfile.gettempdir() 115 | path = os.path.join(temp_dir, app) 116 | if os.path.exists(path) is False: 117 | os.makedirs(path) 118 | return path 119 | 120 | @staticmethod 121 | def write_file(app_path, name, content): 122 | with open(f'{app_path}/{name}', 'wb') as f: 123 | f.write(content) 124 | -------------------------------------------------------------------------------- /vulhub/plugin/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/17 下午12:09 5 | # project: vulhub-compose 6 | 7 | 8 | class BasePlugin(object): 9 | def __init__(self): 10 | self._args = "" 11 | 12 | @property 13 | def args(self): 14 | return self._args 15 | 16 | @args.setter 17 | def args(self, args): 18 | self._args = args 19 | 20 | def parse_args(self): 21 | pass 22 | 23 | def attach(self, yaml_file): 24 | pass 25 | 26 | def detach(self, yaml_file): 27 | pass 28 | -------------------------------------------------------------------------------- /vulhub/plugin/huoxian_iast.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf-8 -*- 3 | # author: owefsad@huoxian.cn 4 | # datetime: 2021/3/17 下午12:09 5 | # project: vulhub-compose 6 | import logging 7 | import os 8 | 9 | import requests 10 | import yaml 11 | 12 | from vulhub.plugin import BasePlugin 13 | 14 | logger = logging.getLogger(__name__) 15 | """ 16 | todo: 17 | 1. 支持设置自定义token,安装agent 18 | 2. 根据环境版本自动选择下载的agent版本(以前根据选择,现在自行判断) 19 | """ 20 | 21 | 22 | class DongTai(BasePlugin): 23 | @staticmethod 24 | def get_iast_yaml_content(yaml_file): 25 | with open(yaml_file, 'r') as f: 26 | data = yaml.safe_load(f) 27 | 28 | services = data['services'] 29 | for service_name, service_value in services.items(): 30 | # 添加环境变量 31 | if 'environment' not in service_value: 32 | service_value['environment'] = ['JAVA_TOOL_OPTIONS=-javaagent:/tmp/agent.jar'] 33 | else: 34 | service_value['environment'].append('JAVA_TOOL_OPTIONS=-javaagent:/tmp/agent.jar') 35 | 36 | if 'volumes' not in service_value: 37 | service_value['volumes'] = ['./agent.jar:/tmp/agent.jar'] 38 | else: 39 | service_value['volumes'].append('./agent.jar:/tmp/agent.jar') 40 | 41 | return data 42 | 43 | @staticmethod 44 | def get_iast_file(yaml_file): 45 | data = DongTai.get_iast_yaml_content(yaml_file) 46 | path = os.path.dirname(yaml_file) 47 | iast_yaml = os.path.join(path, 'iast.yml') 48 | with open(iast_yaml, 'w') as f: 49 | yaml.safe_dump(data=data, stream=f) 50 | return iast_yaml 51 | 52 | @staticmethod 53 | def remove_iast_yaml_file(yaml_file): 54 | if os.path.exists(yaml_file): 55 | os.remove(yaml_file) 56 | 57 | @staticmethod 58 | def download_agent(): 59 | pass 60 | 61 | def parse_args(self): 62 | args = dict() 63 | 64 | def _parse(): 65 | if self.args: 66 | _args = self.args.split(';') 67 | for arg in _args: 68 | name, value = arg.split('=') 69 | args[name] = value 70 | 71 | _parse() 72 | url = 'http://openapi.aws.iast.huoxian.cn:8000/api/v1/agent/download?url=http://openapi.aws.iast.huoxian.cn:8000&jdk.version=Java%201.8' 73 | headers = { 74 | 'Authorization': f'Token {args["token"] if "token" in args else "88d2f0096662335d42580cbd03d8ddea745fdfab"}' 75 | } 76 | try: 77 | # fixme 使用head方法可以提升效率,但是这里使用head时出现了错误 78 | resp = requests.get(url, headers=headers, timeout=(10, 30)) 79 | if resp.status_code == 200: 80 | with open(f'{self.base_path}/agent.jar', 'wb') as f: 81 | f.write(resp.content) 82 | return True 83 | except Exception as e: 84 | logger.debug(f'[-] Failure: download agent failed. Token: {args["token"]}\nReason: {e}') 85 | 86 | def attach(self, yaml_file): 87 | self.base_path = os.path.dirname(yaml_file) 88 | if self.parse_args(): 89 | return self.get_iast_file(yaml_file) 90 | return yaml_file 91 | 92 | def detach(self, yaml_file): 93 | self.remove_iast_yaml_file(yaml_file) 94 | --------------------------------------------------------------------------------