Exemple #1
0
def processStructured(report: ReportWrapper, token: str='') -> VulnTestInfo:
    """ Process the given report into a AutoTriageUtils.VulnTestInfo named
        tuple given that it contains structured data """
    info = extractJson(report.getLatestActivity())
    if info is None:
        return VulnTestInfo(reproduced=False,
                            message=('Failed to parse JSON! Please try again.'),
                            type='XSS',
                            info={'report': report.getLatestActivity()})

    # Pass it off to a helper that can try to handle any inconsistencies
    url, cookies, type, data = extractDataFromJson(info)

    if not AutoTriageUtils.isProgramURL(url):
        return VulnTestInfo(reproduced=False,
                            message=('The url provided (`%s`) is not a program URL!') % url,
                            type='XSS',
                            info={'src': url,
                                  'method': 'structured'})

    if type.lower() == 'post':
        results = testPOSTXSS(url, cookies, data)
    elif type.lower() == 'get':
        results = testGETXSS(url, cookies)
    else:
        return VulnTestInfo(reproduced=False,
                            message='Found an invalid value "type"=%s in the JSON blob!' % type,
                            type='XSS',
                            info={'src': url,
                                  'method': 'structured'})

    reproduced, alertBox, message, confirmedBrowsers, alertBrowsers = makeMarkdownTable(results, token)
    if reproduced:
        return VulnTestInfo(reproduced=True,
                            message='Successfully found and confirmed an XSS at `%s`!\n'
                                    '\n\n%s\n\n'
                                    'Metadata: {"vulnDomain": "%s"}' %
                                    (url, message, urlparse(url).hostname),
                            type='XSS',
                            info={'src': url,
                                  'method': 'unstructured',
                                  'confirmedBrowsers': confirmedBrowsers,
                                  'alertBrowsers': alertBrowsers,
                                  'httpType': type,
                                  'cookies': cookies})  # noqa
    elif alertBox:
        return VulnTestInfo(reproduced=False,
                            message=('Failed to confirm the vulnerability! Detected an alert box '
                                     'but the token: `"%s"` was not found!'
                                     '\n\n%s\n\n') % (token, message),
                            type='XSS',
                            info={'src': url,
                                  'method': 'unstructured'})
    else:
        return VulnTestInfo(reproduced=False,
                            message=("Failed to validate XSS at `%s` via structured data. Either try "
                                     "again or wait for manual review of your bug.") % url,
                            type='XSS',
                            info={'method': 'structured'})
Exemple #2
0
def processStructured(report: ReportWrapper, token: str='') -> VulnTestInfo:
    """ Process the given report into a VulnTestInfo named tuple given that it contains structured data """
    info = extractJson(report.getLatestActivity())
    if info is None:
        return VulnTestInfo(reproduced=False,
                            message=('Failed to parse JSON! Please try again.'),
                            type='Open Redirect',
                            info={'report': report.getLatestActivity()})

    # Pass it off to a helper that can try to handle any inconsistencies
    url, cookies, type, data = extractDataFromJson(info)

    if not isProgramURL(url):
        return VulnTestInfo(reproduced=False,
                            message=('The url provided (`%s`) is not a program URL!') % url,
                            type='Open Redirect',
                            info={'src': url,
                                  'method': 'structured'})

    if type.lower() == 'post':
        res = testPOSTOpenRedirect(url, cookies, data)
    elif type.lower() == 'get':
        res = testGETOpenRedirect(url, cookies)
    else:
        return VulnTestInfo(reproduced=False,
                            message='Found an invalid value "type"=%s in the JSON blob!' % type,
                            type='Open Redirect',
                            info={'src': url,
                                  'method': 'structured'})

    if res and token.lower() in urlparse(res).hostname.lower():
        return VulnTestInfo(reproduced=True,
                            message=('Successfully found and confirmed an open redirect from `%s` to `%s`!\n'
                                     'Metadata: {"vulnDomain": "%s"}') % (url, res, urlparse(url).hostname),
                            type='Open Redirect',
                            info={'src': url,
                                  'redirect': res,
                                  'method': 'structured',
                                  'httpType': type,
                                  'cookies': cookies})
    elif res:
        return VulnTestInfo(reproduced=False,
                            message=tokenNotFoundMessage % (url, res, token, token),
                            type='Open Redirect',
                            info={'src': url,
                                  'redirect': res,
                                  'method': 'structured'})
    else:
        return VulnTestInfo(reproduced=False,
                            message=("Failed to validate open redirect at `%s` via structured data. Either try again "
                                     "or wait for manual review of your bug.") % url,
                            type='Open Redirect',
                            info={'method': 'structured'})
Exemple #3
0
def process(report: ReportWrapper) -> Optional[VulnTestInfo]:
    """ Process the given report into a VulnTestInfo named tuple """
    # If the user has not yet been prompted for automatic triaging
    if not report.botHasCommented():
        token = AutoTriageUtils.generateToken()
        return VulnTestInfo(reproduced=False,
                            message=constants.initialMessage(token, 'redirect to a domain', 'Open Redirect'),
                            type='Open Redirect',
                            info={})
    elif report.shouldBackoff():
        if not report.hasPostedBackoffComment():
            addFailureToDB(report.getReporterUsername(), report.getReportID())
            return VulnTestInfo(reproduced=False,
                                message=('Automatic verification of vulnerability has failed, Backing off! Falling '
                                         'back to human verification. '),
                                type='Open Redirect',
                                info={})
        else:
            return None
    elif report.isVerified():
        return None
    try:
        if isStructured(report.getLatestActivity()):
            return processStructured(report, token=report.getToken())
        else:
            return processUnstructured(report, token=report.getToken())
    except Exception as e:
        print("Caught exception: %s" % str(e))
        traceback.print_exc()
        print("+" * 80)
        return VulnTestInfo(reproduced=False,
                            message=('Internal error detected! Backing off...'),
                            type='Open Redirect',
                            info={})
Exemple #4
0
def processUnstructured(report: ReportWrapper,
                        token: str = '') -> VulnTestInfo:
    """ Process the given report into a VulnTestInfo named tuple given that it doesn't contain structured data """
    urls = extractURLs(report.getLatestActivity())
    if config.DEBUG:
        print("URLs=%s" % str(urls))
    if len(urls) > 5:
        if config.DEBUG:
            print("User submitted %s URLs. Skipping...")
        return VulnTestInfo(
            reproduced=False,
            message='Found %s URLs. Please resubmit with a single URL to test.',
            type='SQLi',
            info={
                'URLs': str(urls),
                'method': 'structured'
            })
    testedURLs = []
    for url in urls:
        if isProgramURL(url):
            # Unstructured reports are treated as a GET
            delay = testGETSQLDelay(url, {})
            if delay and abs(delay - int(token)) < maxTimeDiff:
                return VulnTestInfo(
                    reproduced=True,
                    message=('Successfully found and confirmed SQLi at `%s`!\n'
                             'Metadata: {"vulnDomain": "%s"}') %
                    (url, urlparse(url).hostname),
                    type='SQLi',
                    info={
                        'src': url,
                        'method': 'unstructured',
                        'delay': int(delay),
                        'httpType': 'GET',
                        'cookies': {}
                    })
            elif delay:
                return VulnTestInfo(reproduced=False,
                                    message=wrongDelayMessage %
                                    (str(int(delay)), token, token),
                                    type='SQLi',
                                    info={
                                        'src': url,
                                        'method': 'unstructured'
                                    })
            else:
                testedURLs.append(url)
    if len(testedURLs) > 0:
        return VulnTestInfo(reproduced=False,
                            message=constants.structuredDataMessage % ('SQLi'),
                            type='SQLi',
                            info={'method': 'unstructured'})
    else:
        return VulnTestInfo(reproduced=False,
                            message=constants.failedToFindURLsMessage,
                            type='SQLi',
                            info={'method': 'unstructured'})
Exemple #5
0
def test_ReportWrapperGetters():
    r = ReportWrapper(openRedirectReproJson)
    assert r.getReportID() == '239981'
    assert r.getLatestActivity() == ("blah open_redirect\n\n[some](http://example.com/redir.php?QUERY_STRING="
                                     "https://google.com)")
    assert r.getReportBody() == ("blah open_redirect\n\n[some](http://example.com/redir.php?QUERY_STRING="
                                 "https://google.com)")
    assert r.getReportWeakness() == "Open Redirect"
    assert r.getReportTitle() == "open redirect"
    assert r.getVulnDomains() == ['example.com']
    r = ReportWrapper(openRedirectUnreproJson)
    assert r.getReportID() == '240035'
    assert r.getLatestActivity() == ("this is detected as an open redirect but there is no markdown link to it\n\n"
                                     "https://example.com/redir.php?QUERY_STRING=https://google.com")
    assert r.getReportBody() == ("this is detected as an open redirect but there is no markdown link to it\n\n"
                                 "https://example.com/redir.php?QUERY_STRING=https://google.com")
    assert r.getReportWeakness() == "Open Redirect"
    assert r.getReportTitle() == "malformed open redirect"
    assert r.getVulnDomains() == ['example.com']
Exemple #6
0
def processUnstructured(report: ReportWrapper, token: str='') -> AutoTriageUtils.VulnTestInfo:
    """ Process the given report into a AutoTriageUtils.VulnTestInfo named tuple
        given that it doesn't contain structured data """
    urls = extractURLs(report.getLatestActivity())
    if config.DEBUG:
        print("URLs=%s" % str(urls))
    if len(urls) > 5:
        if config.DEBUG:
            print("User submitted %s URLs. Skipping...")
        return VulnTestInfo(reproduced=False,
                            message='Found %s URLs. Please resubmit with a single URL to test.',
                            type='XSS',
                            info={'URLs': str(urls),
                                  'method': 'structured'})
    testedURLs = []
    for url in urls:
        if AutoTriageUtils.isProgramURL(url):
            testedURLs.append(url)
            results = testGETXSS(url, {})
            reproduced, alertBox, message, confirmedBrowsers, alertBrowsers = makeMarkdownTable(results, token)
            if reproduced:
                return VulnTestInfo(reproduced=True,
                                    message=('Successfully found and confirmed an XSS at `%s`!\n'
                                             '\n\n%s\n\n'
                                             'Metadata: {"vulnDomain": "%s"}') %
                                            (url, message, urlparse(url).hostname),
                                    type='XSS',
                                    info={'src': url,
                                          'method': 'unstructured',
                                          'confirmedBrowsers': confirmedBrowsers,
                                          'alertBrowsers': alertBrowsers,
                                          'httpType': 'GET',
                                          'cookies': {}})
            elif alertBox:
                return VulnTestInfo(reproduced=False,
                                    message=('Failed to confirm the vulnerability! Detected an alert '
                                             'box but the token: `"%s"` was not found!'
                                             '\n\n%s\n\n') % (token, message),
                                    type='XSS',
                                    info={'src': url,
                                          'method': 'unstructured'})
    if len(testedURLs) > 0:
        return VulnTestInfo(reproduced=False,
                            message=constants.structuredDataMessage % 'XSS',
                            type='XSS',
                            info={'method': 'unstructured'})
    else:
        return VulnTestInfo(reproduced=False,
                            message=constants.failedToFindURLsMessage,
                            type='XSS',
                            info={'method': 'unstructured'})
Exemple #7
0
def processUnstructured(report: ReportWrapper, token: str='') -> VulnTestInfo:
    """ Process the given report into a VulnTestInfo named tuple given that it doesn't contain structured data """
    urls = extractURLs(report.getLatestActivity())
    if config.DEBUG:
        print("URLs=%s" % str(urls))
    if len(urls) > 5:
        if config.DEBUG:
            print("User submitted %s URLs. Skipping...")
        return VulnTestInfo(reproduced=False,
                            message=('Found %s URLs. Please resubmit with a single URL to test.'),
                            type='Open Redirect',
                            info={'URLs': str(urls),
                                  'method': 'structured'})
    testedURLs = []
    for url in urls:
        if isProgramURL(url):
            res = testGETOpenRedirect(url, {})
            print("res=%s" % str(urlparse(res).hostname))
            if res and token.lower() in urlparse(res).hostname.lower():
                return VulnTestInfo(reproduced=True,
                                    message=('Successfully found and confirmed an open redirect from `%s` to `%s`!\n'
                                             'Metadata: {"vulnDomain": "%s"}') % (url, res, urlparse(url).hostname),
                                    type='Open Redirect',
                                    info={'src': url,
                                          'redirect': res,
                                          'method': 'unstructured',
                                          'httpType': 'GET',
                                          'cookies': {}})  # nopep8
            elif res:
                return VulnTestInfo(reproduced=False,
                                    message=tokenNotFoundMessage % (url, res, token, token),
                                    type='Open Redirect',
                                    info={'src': url,
                                          'redirect': res,
                                          'method': 'unstructured'})
            else:
                testedURLs.append(url)
    if len(testedURLs) > 0:
        return VulnTestInfo(reproduced=False,
                            message=constants.structuredDataMessage % 'open redirect',
                            type='Open Redirect',
                            info={'method': 'unstructured'})
    else:
        return VulnTestInfo(reproduced=False,
                            message=constants.failedToFindURLsMessage,
                            type='Open Redirect',
                            info={'method': 'unstructured'})
Exemple #8
0
def processStructured(report: ReportWrapper, token: str = '') -> VulnTestInfo:
    """ Process the given report into a VulnTestInfo named tuple given that it contains structured data """
    info = extractJson(report.getLatestActivity())
    if info is None:
        return VulnTestInfo(
            reproduced=False,
            message=('Failed to parse JSON! Please try again.'),
            type='SQLi',
            info={'report': report.getLatestActivity()})

    # Pass it off to a helper that can try to handle any inconsistencies
    url, cookies, type, data = extractDataFromJson(info)

    if not isProgramURL(url):
        return VulnTestInfo(
            reproduced=False,
            message=('The url provided (`%s`) is not a program URL!') % url,
            type='SQLi',
            info={
                'src': url,
                'method': 'structured'
            })

    if type.lower() == 'post':
        delay = testPOSTSQLDelay(url, cookies, data)
    elif type.lower() == 'get':
        delay = testGETSQLDelay(url, cookies)
    else:
        return VulnTestInfo(
            reproduced=False,
            message='Found an invalid value "type"=%s in the JSON blob!' %
            type,
            type='SQLi',
            info={
                'src': url,
                'method': 'structured'
            })

    if delay and abs(delay - int(token)) < maxTimeDiff:
        return VulnTestInfo(
            reproduced=True,
            message=('Successfully found and confirmed SQLi at `%s`!\n'
                     'Metadata: {"vulnDomain": "%s"}') %
            (url, urlparse(url).hostname),
            type='SQLi',
            info={
                'src': url,
                'method': 'structured',
                'delay': int(delay),
                'httpType': type,
                'cookies': cookies
            })
    elif delay:
        return VulnTestInfo(reproduced=False,
                            message=wrongDelayMessage %
                            (str(int(delay)), token, token),
                            type='SQLi',
                            info={
                                'src': url,
                                'method': 'structured'
                            })
    else:
        return VulnTestInfo(
            reproduced=False,
            message=
            ("Failed to validate SQLi at `%s` via structured data. Either try again or wait "
             "for manual review of your bug.") % url,
            type='SQLi',
            info={'method': 'structured'})