模块开发模板

#!/usr/bin/env python

"""
@Author: Castiel
@Email:  ca3tie1@gmail.com
@Blog:   https://ca3tie1.github.io
@Git:    https://github.com/ca3tie1
@Wechat: Ca5tie1
@Date:   2021/10/30 18:20
"""

from rich.progress import Progress
from ExpDepos.libs.core.base.ExploitBase import *


class example(ExploitBase):
    Name = "example"                                # exp名称
    Alias = "example"                               # 漏洞别名
    Author = "Castiel"                              # 编写作者
    VulType = VUL_TYPE.COMMAND_EXECUTION            # 漏洞类型
    Category = EXP_CATEGORY.EXPLOITS                # 漏洞分类
    Create_Date = '2021-10-30'                      # exp编写日期
    Update_Date = '2021-10-30'                      # exp更新日期
    Rank = 'Excellent'                              # exp效果(可选:Excellent Great Good Normal Average Low Manual)
    AppPowerLink = 'http://www.target.com'          # 漏洞厂商主页地址
    AppName = 'SimpleApp'                           # 漏洞应用名称
    AppVersion = '1.0'                              # 漏洞影响版本
    References = []                                 # 参考链接
    Desc = """用于模块开发的模板文件"""                 # 漏洞描述
    Description = """# module Description"""        # 漏洞详细

    def _options(self):
        options = dict()
        options["name"] = OptString("admin", description="字符类型示例", require=True)
        options["Age"] = OptInteger(20, description="整型参数示例", require=True)
        options["require"] = OptBoolean(False, description="非必选项参数示例", require=False)
        return options

    def _fingers(self):
        """
        当前模块指纹定义

        :return: dict
        """
        fingerprint = {
            "name": self.AppName,                           # 漏洞应用名作为指纹名称
            "author": self.Author,                          # 作者
            "version": "1.0",                               # 版本号
            "type": FINGERPRINT.FP_TYPE.WEBAPP,             # 指纹类型 详情请参考指纹类型表
            "logic": "or",                                  # 匹配逻辑 默认为 or
            "description": "指纹描述信息",                    # 描述信息
            "website": "https://www.tongda2000.com/",
            "filters": {                                    # 过滤属性,用于从操作系统平台、中间件、和脚本语言3个维度进行过滤
                "platform": ['windows', 'Unix'],
                "middleware": ['apache', 'nginx'],
                "language": ['PHP']
            },
            "matches": [{"url": "/tongda.ico?r={randstr()}", "hash": -759108386, "certainty": 100, "status": 200},
                        {"search": "headers", "keyword": "X-Powered-By: PHP/7.2.24-0ubuntu0.18.04.8"},
                        {"search": "headers[set-cookie]", "regex": "(aa)", "offset": 1, "version": "2.2",
                         "aim": "version"},
                        {"name": "matchName", "keyword": "test <||> referer"},
                        {"status": 200}],
            "sets": {                                       # 主动式匹配的一些HTTP Request设置
                "headers": {"testHeader": "testHeader{randstr(10)}"},
                "cookies": {"cname": "cValue{randstr(5,true)}"},
                "params": {"test": "bbbb"},
                "data": ""
            }
        }
        return fingerprint

    async def _request(self):
        response = await self.asyncRequest.get("/")
        assert response.status_code == 200

    @asyncTimeit
    async def _testAsyncRequest(self, times):
        """
        测试异步请求性能

        :param times: 测试请求次数
        :return:
        """
        task_list = list()
        for x in range(times):
            req = self._request()
            if sys.version_info < (3, 7):
                task = asyncio.ensure_future(req)
            else:
                task = asyncio.create_task(req)
            task_list.append(task)
        await asyncio.gather(*task_list)

    def _verify(self):
        console.info("这是在_verify中输出的INFO信息,即将跳转至_exploit执行。")
        return self._exploit()

    def _exploit(self):
        # 在模块中使用统一的消息输出
        console.info("测试INFO级别消息输出")
        console.debug("测试 [bold green]DEBUG[bold green] 级别消息输出")
        console.warning("测试 [bold yellow]WARNING[/bold yellow] 级别消息输出")
        try:
            1 / 0
        except Exception as e:
            console.exception("测试 [bold red]EXCEPTION[/bold red] 级别消息输出:{0}".format(e.args[0]))
        with Progress() as progress:
            task = progress.add_task(formatPgString("测试 [green]PROGRESS[green] 级别消息输出..."), total=5)
            for i in range(5):
                progress.print(formatPgString("progress {0} done.".format(i)))
                progress.update(task, advance=1)
                time.sleep(1)

        # 在模块中使用统一的数据输入
        choose = ''
        while choose.lower() != 'y' and choose.lower() != 'n':
            choose = console.input("[bold yellow]是否继续演示其他示例?[bold yellow] [bold green]Y/N:[/bold green]")
        if choose == 'n':
            self.result.fail("用户选择终止执行!")
            return

        console.info("example 将继续演示其他示例")

        # HTTP 请求测试
        console.info("正在请求:" + str(self.request.base_url) + "tongda.ico")
        response = self.request.get("/tongda.ico")
        if response.status_code == 200:
            console.info({"status": response.status_code,
                          "md5": response.md5sum,
                          "hash": response.hash,
                          "server": response.server,
                          "base64": response.base64})

        # HTTP 异步请求测试
        console.info("正在执行异步请求测试...")
        loop = None
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError as e:
            if "There is no current event loop in thread" in str(e):
                loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        asyncio.get_event_loop().run_until_complete(self._testAsyncRequest(1000))

        # 指纹识别测试
        response = self.request.get("")
        console.info("被动指纹匹配结果: ")
        console.info(self.fpMatches(response, "PASS"))
        console.info("当前模块指纹匹配结果:")
        console.info(self.fingerprint.Matches(self, response))

        # 执行结果
        self.result.success({"shell": "http://www.target.com/shell.jsp"})