예제 #1
0
    def getRqRx(self, opName):
        """
		Craft and send a test request to the specified operation
		Return: request template + response
		"""
        ret = (None, None)
        try:
            tosend = self.getParamObjs(opName)
            # tosend might be empty, this should be caught by the WebFault exception at retrieval
            getattr(self.ws_client.service, opName)(**tosend)
            ret = (self.ws_client.messages['tx'],
                   self.ws_client.messages['rx'])
        except WebFault as e:
            logger.error("Got WebFault sending request: %s" % e.message)
            ret = (self.ws_client.messages['tx'], str(e.message))
        except TransportError as te:
            logger.error("Got TransportError sending request: %s" % te.message)
        # suds client class may just raise a regular Exception to tell us of HTTP code 401
        except Exception as e:
            txt = self.processException(e)
            ret = (
                self.ws_client.messages['tx'],
                'This is an unsual error. Copy the HTTP packet for this request and investigate using a regular client'
            )
            return ret
        return ret
예제 #2
0
    def customRequest(self, opName, params, payload):
        ret = (None, None)
        res = None
        try:
            if not opName or not params or not payload:
                return None

            tosend = self.getParamObjs(opName)
            for name, elem in self.getParams(opName):
                if name in params:
                    tosend[name] = payload

            res = getattr(self.ws_client.service, opName)(**tosend)
        except WebFault as e:
            logger.error("Got WebFault exception at customRequest: %s" %
                         e.message)
            ret = (str(e.message), res)
        except Exception as e:
            error = self.processException(e)
            if error == 401:
                # How do we stop this mess?
                pass
        else:
            ret = (str(self.ws_client.messages['rx']), res)

        return ret
예제 #3
0
 def refresh(self):
     if self.analyzer:
         global_stats = self.analyzer.getStats()
     else:
         logger.error("Kaput! The analyzer has not calculated statistics yet. Try lowering the number of attacking threads.")
         return False
     self._refreshStatistics(global_stats)    
     self._refreshPlugins(global_stats)  
     self._refreshGraphs(global_stats)
     return True
예제 #4
0
def check_waf():
    """
    发送触发WAF payload
    :return:
    """
    check_waf_payload = " AND 1=1 UNION ALL SELECT 1,NULL,'<script>alert(\"XSS\")</script>',table_name FROM " \
                        "information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell(\'cat ../../../etc/passwd\')#"
    logger.info("正在检查目标是否受到WAF防护")
    try:
        url = conf.TARGET['url'] + check_waf_payload
        count = Request.get_page(url=url)
        check_waf_regex = load_check_waf_json()
        non_blind_check(queries[count]['text'], check_waf_regex)
    except Exception as reason:
        logger.error("连接出错,带有攻击性的请求可能被重置:%s" % reason)
예제 #5
0
 def run(self):
     while True:
         [req_id, (args, payload)] = self.queue.get()
         if payload and args and req_id:
             resp_object = self.wsdl.customRequest(self.op_name, args, payload)
             if resp_object[0]:
                 response = wsResponse(id=req_id, params=args, size=sys.getsizeof(resp_object[0]), response=resp_object, payload=payload, plugin=self.get_plugin(payload))
                 # Report this to the appropiate plugin
                 plugin = response.getPlugin()
                 plugin.reportResult(response)
                 self.out_list.append(response)
             else:
                 self.out_list.append(None)
                 logger.error("Empty response! Error sending request ->  Args are: %s ; Payload is: %s" % (args, payload))
             
         self.queue.task_done()
예제 #6
0
def load_settings():
    """
    加载配置
    :return:
    """
    logger.info("初始化项目配置")
    try:
        with codecs.open(paths.CONFIG_FILE, encoding="utf-8") as config:
            configs = json.loads(config.read())
            parse_result = urlparse(configs.get("target"))

            # 将配置文件写入全局变量
            conf.TARGET = {}
            conf.TARGET['url'] = configs.get("target")
            conf.TARGET['scheme'] = parse_result.scheme
            conf.TARGET['domain'] = parse_result.netloc
            conf.TARGET['path'] = parse_result.path
            conf.TARGET['params'] = parse_result.params
            conf.TARGET['query'] = parse_result.query.split('&')

            conf.TAMPER = configs.get("tamper")
            conf.HOST = configs.get("host")
            conf.HEADER = configs.get("header")
            conf.TECH = configs.get("tech").upper()
            conf.COOKIE = configs.get("cookie")
            conf.CHUNK = configs.get("chunk")
            conf.GZIP_ENCODING = configs.get("gzip_encoding")
            conf.DATA = configs.get("data")
            conf.METHOD = configs.get("method")
            conf.UA = []
            conf.COUNT = 0
            conf.BOUNDARIES = []

            # 初始化全局变量
            byz.dynamic_markings = []
            byz.dynamic_params = []
            byz.injectable_params = []
            byz.original_page = ''

            # 加载随机UA
            with codecs.open(paths.UA_FILES, 'r') as ua_file:
                for line in ua_file.readlines():
                    line = line.strip()
                    conf.UA.append(line)

    except Exception as reason:
        logger.error("加载配置错误:%s" % reason)
예제 #7
0
def check_stable():
    logger.info("正在检查页面稳定性")

    # 进行一定的延时
    delay = 1 - queries['original']['time']
    delay = max(0, min(1, delay))
    time.sleep(delay)

    # 再次请求相同的页面,排除动态页面
    try:
        count = Request.get_page()
        find_dynamic_content(queries['original']['ori_text'],
                             queries[count]['ori_text'])
        byz.original_page = remove_dynamic_content(
            queries['original']['ori_text'])
    except ConnectionError:
        logger.error('页面连接不稳定,请稍后重试')
예제 #8
0
def host_resolv(host):
    """
    根据域名解析DNS
    :param host:
    :return:
    """
    ip = None
    try:
        family, socktype, proto, canonname, sockaddr = socket.getaddrinfo(
            host, 0, socket.AF_UNSPEC, socket.SOCK_STREAM)[0]

        if family == socket.AF_INET:
            ip, port = sockaddr
        elif family == socket.AF_INET6:
            ip, port, flow_info, scope_id = sockaddr
    except Exception as reason:
        logger.error("DNS解析出错,网站连通性可能存在问题:%s" % reason)
        sys.exit()
    return ip
예제 #9
0
def check_connection():
    """
    检查页面连通性
    :return:
    """
    # 对目标域名进行DNS解析
    logger.info("正在解析目标域名")
    ip = host_resolv(conf.TARGET['domain'])

    if conf.HOST:
        if ip != conf.HOST:
            logger.info("域名解析IP与指定IP不同,请注意")

    logger.info("正在检查页面连通性")
    Request.get_page(original=True)
    if queries['original']['code'] != 200 or queries['original']['text']:
        logger.info("页面连通性正常")
    else:
        logger.error("检查页面连通性出错:%s" % conf.TARGET['url'])
        sys.exit()
예제 #10
0
    def processException(self, except_obj):
        """
		All methods interacting with the EndPoint should call this function if they found
		a general Exception. Suds will raise some of these with authentication messages.
		This function will return the HTTP code error int
		"""
        try:
            msg = except_obj.message
            txt = ''
            # HTTP Authentication here
            if u'Unauthorized' in msg[1]:
                # We should probably tell to proj_man here
                logger.error(
                    "Got HTTP code 401, please specify HTTP credentials in the config tab!"
                )
                txt = 'Got a 401 Unauthorized HTTP packet. \nThat means this EndPoint requires protocol authentication.\n\n'
                txt += "Fortunately, you can specify these credentials in the configuration tab."
            elif msg[0] == 404:
                logger.error("Got HTTP code 404, Not Found! Removed??")
                txt = "Got a 404 Not Found HTTP packet. \nThe EndPoint might have changed it's location.\n\nCheck URL!"
            else:
                #print except_obj.__dict__
                #print type(except_obj)
                logger.error(
                    "Unknown exception at processException. Data is: %s" %
                    except_obj.message)

            return txt
        except:
            pass
예제 #11
0
    def get_page(self, **kwargs):
        """
        连接到目标URL并返回内容
        :param kwargs:
        :return:
        """
        url = kwargs.get("url", None) or conf.TARGET['url']
        method = kwargs.get("method", None) or conf.METHOD
        cookie = kwargs.get("cookie", None) or conf.COOKIE
        ua = kwargs.get("ua", None) or random.choice(conf.UA)
        host = kwargs.get("host", None) or conf.HOST
        headers = kwargs.get("headers", None) or conf.HEADER
        chunked = kwargs.get("chunked", False) or conf.CHUNK
        data = kwargs.get("data", False) or conf.DATA
        gzip = kwargs.get("gzip", False) or conf.GZIP_ENCODING
        original = kwargs.get("original", False)

        # 指定随机UA
        headers["User-Agent"] = ua

        # 指定真实IP
        if host:
            url = self.url_re(url, host)
            headers["Host"] = conf.TARGET['domain']

        # 请求页面并返回内容
        if not chunked:
            if not method or method.upper() == 'GET':
                try:
                    result = self.Request.get(url,
                                              headers=headers,
                                              cookies=cookie,
                                              allow_redirects=False,
                                              timeout=(3, 15))
                    self.result_handle(conf.COUNT, result, original)
                    conf.COUNT += 1
                except requests.exceptions.RequestException as e:
                    logger.error("请求超时,正在重试请求:%s" % conf.TARGET['url'])
                    logger.error(e)

            elif method.upper() == 'POST':
                if gzip:
                    headers["Content-Encoding"] = 'gzip'
                    headers["Content-Type"] = 'x-application/x-gzip'

                    def to_gzip_format(post_data):
                        """
                        定义gzip 发包 data 格式
                        :param post_data:
                        :return:
                        """
                        _data = bytes(json.dumps(post_data), 'utf-8')
                        ct = gzip.compress(_data, )
                        return ct

                    try:
                        result = self.Request.post(url=url,
                                                   data=to_gzip_format(data),
                                                   headers=headers,
                                                   cookies=cookie,
                                                   timeout=(3, 15))
                        self.result_handle(conf.COUNT, result, original)
                        conf.COUNT += 1
                    except requests.exceptions.RequestException as e:
                        logger.error("请求超时,正在重试请求:%s" % conf.TARGET['url'])
                        logger.error(e)
                else:
                    try:
                        result = self.Request.post(url=url,
                                                   data=data,
                                                   headers=headers,
                                                   cookies=cookie,
                                                   timeout=(3, 15))
                        self.result_handle(conf.COUNT, result, original)
                        conf.COUNT += 1
                    except requests.exceptions.RequestException as e:
                        logger.error("请求超时,正在重试请求:%s" % conf.TARGET['url'])
                        logger.error(e)

        else:
            pass

        return conf.COUNT - 1
예제 #12
0
    def loadWSDL(self, url):
        """
		This function should be called right after the project_manager has loaded any projects,
		it will query the PM in order to perform authentication tasks before loading the WSDL and
		URL objects used to represent the EndPoint.

		Error handling is a quite a mess here.
		Default HTTP timeout is set from command line or default (100 seconds) if not specified. 
		The url parameter may point to the offline WSDL copy in the filesystem while pm.getURL() will give EndPoint's addr.
		A WSDL file can be loaded from it's offline copy while the document contains _a_ valid EndPoint's IP addr. 

		ServiceDefinition @ client.sd
	        ports = (port, [methods])
        	ports = (port, [(name, [opers])])
	        ports = (port, [name, [(type, name)]])
		"""
        try:
            msg = ''

            # Check for protocol authentication methods
            if self.project_manager.getAuthType() == AUTH_BASIC:
                if self.project_manager.getUsername(
                ) and self.project_manager.getPassword():
                    try:
                        self.ws_client = Client(
                            url,
                            username=self.project_manager.getUsername(),
                            password=self.project_manager.getPassword(),
                            faults=True,
                            prettyxml=True,
                            cache=None)
                        request = self.project_manager.createAuthorizationRequest(
                            self.project_manager.getUsername(),
                            self.project_manager.getPassword(),
                            self.project_manager.getURL(),
                            self.project_manager.getDomain())
                        self.server_client = urllib2.urlopen(request)
                    except URLError as e:
                        try:
                            if e.code == 401:
                                msg = 'Error: Something went wrong while trying to authenticate with saved credentials -> %s' % str(
                                    e)
                                logger.error(
                                    'Credentials %s:%s [Basic] for project %s stopped working'
                                    % (self.project_manager.getUsername(),
                                       self.project_manager.getPassword(),
                                       self.project_manager.getName()))
                                return msg
                        except:
                            msg = "\tWarning:\nWasn't able to connect to target.\nAntares is running in offline mode now."
            elif self.project_manager.getAuthType() == AUTH_WINDOWS:
                # Can we do this?
                try:
                    import ntlm
                    if self.project_manager.getUsername(
                    ) and self.project_manager.getPassword():
                        ntlm_transport = WindowsHttpAuthenticated(
                            username='******' %
                            (self.project_manager.getDomain(),
                             self.project_manager.getUsername()),
                            password=self.project_manager.getPassword())
                        self.server_client = self.project_manager.createNTLMRequest(
                            self.project_manager.getUsername(),
                            self.project_manager.getPassword(),
                            self.project_manager.getURL(),
                            self.project_manager.getDomain())
                        self.ws_client = Client(url,
                                                transport=ntlm_transport,
                                                faults=True,
                                                prettyxml=True,
                                                cache=None)
                except ImportError:
                    msg = "Error: The project you're trying to load uses Windows authentication\n"
                    msg += "but we couldn't load the proxy_ntlm third party package.\n"
                    msg += "Please install it before proceeding. "
                    return msg

                except (antaresWrongCredentialsException, TransportError) as e:
                    msg = 'Error: Something went wrong while trying to authenticate with saved credentials -> %s' % str(
                        e)
                    logger.error(
                        'Credentials %s:%s [NTLM] for project %s stopped working'
                        % (self.project_manager.getUsername(),
                           self.project_manager.getPassword(),
                           self.project_manager.getName()))
                    return msg

            else:
                if self.project_manager.getAuthType() == AUTH_UNKNOWN:
                    msg = "Warning: Antares detected an unknown protocol mechanism for this EndPoint!\n"
                    msg = "We probably won't be able to connect to the service."

                # Or fallback to regular connections
                self.ws_client = Client(url,
                                        faults=True,
                                        prettyxml=True,
                                        cache=None)
                self.server_client = urllib2.urlopen(
                    self.project_manager.getURL())

            self.setup()

            if self.ws_client:
                self.wsdl_desc = WSDLDescription(self.ws_client.sd[0])
                msg = 'OK'
                logger.info("WSDL helper is:\n %s" % self.ws_client)
            if url.startswith('file'):
                logger.info("Loaded wsdl from local path %s" %
                            self.project_manager.getWSDLPath())
            else:
                logger.info("Loaded wsdl from remote path %s" %
                            self.project_manager.getURL())
        except exceptions.ValueError:
            msg = "Error: Malformed URL\n" + url
        except URLError:
            msg = "Error: No route to host\n " + url
        except os.error:
            msg = "Error: Can't read offline WSDL file"
        except SAXParseException as e:
            msg = 'Error: Malformed WSDL. Are you sure you provided the correct WSDL path?'
        except TypeNotFound as e:
            msg = "Error: There is an import problem with this WSDL.\n We hope to add automatic fix for this in the future."
            msg += "\nReference is: https://fedorahosted.org/suds/wiki/TipsAndTricks#Schema-TypeNotFound"
        except TransportError as e:
            msg = 'Error: Something went wrong while trying to authenticate with saved credentials'
            logger.error('Credentials %s:%s for project %s stopped working' %
                         (self.project_manager.getUsername(),
                          self.project_manager.getPassword(),
                          self.project_manager.getName()))
        except Exception as e:
            msg = 'FATAL: unmanaged exception. Check stderr : ' + e.message
            print e.__dict__
            print type(e)
            raise antaresUnknownException(
                "Got unknown exception while loading wsdl at WSDLHelper: %s" %
                str(e))

        # Check how we'll run
        if self.server_client:
            self.is_offline = False
        else:
            logger.error("Running in offline mode on %s" % url)
        return msg