예제 #1
0
def get_bwapp_cookies(cont_ip):
    """Log in to bWAPP and return valid cookie."""
    install_url = 'http://' + cont_ip + '/install.php?install=yes'
    helper.HTTPSession(install_url)
    login_url = 'http://' + cont_ip + '/login.php'
    http_session = helper.HTTPSession(login_url)

    http_session.data = 'login=bee&password=bug&security_level=0&form=submit'

    successful_text = 'Welcome Bee'
    http_session.formauth_by_response(successful_text)

    if not http_session.is_auth:
        return {}
    return http_session.cookies
예제 #2
0
파일: ssl.py 프로젝트: jvasque6/asserts
def has_breach(site: str, port: int = PORT) -> bool:
    """
    Check if BREACH is present.

    :param site: Address to connect to.
    :param port: If necessary, specify port to connect to.
    """
    url = 'https://{}:{}'.format(site, port)
    common_compressors = [
        'compress', 'exi', 'gzip', 'identity', 'pack200-gzip', 'br', 'bzip2',
        'lzma', 'peerdist', 'sdch', 'xpress', 'xz'
    ]

    for compression in common_compressors:
        header = {'Accept-Encoding': '{},deflate'.format(compression)}
        try:
            sess = http.HTTPSession(url, headers=header)
            fingerprint = sess.get_fingerprint()
            if 'Content-Encoding' in sess.response.headers:
                if compression in sess.response.headers['Content-Encoding']:
                    show_open('Site vulnerable to BREACH attack',
                              details=dict(site=site,
                                           port=port,
                                           compression=compression,
                                           fingerprint=fingerprint))
                    return True
        except http.ConnError as exc:
            show_unknown('Could not connect',
                         details=dict(site=site, port=port, error=str(exc)))
            return False
    show_close('Site not vulnerable to BREACH attack',
               details=dict(site=site, port=port))
    return False
예제 #3
0
파일: sca.py 프로젝트: jvasque6/asserts
def get_vulns_ossindex(package_manager: str, package: str,
                       version: str) -> tuple:
    """
    Search vulnerabilities on given package_manager/package/version.

    :param package_manager: Package manager.
    :param package: Package name.
    :param version: Package version.
    """
    if version:
        url = 'https://ossindex.net/v2.0/package/{}/{}/{}'.format(
            _url_encode(package_manager),
            _url_encode(package),
            _url_encode(version))
    else:
        url = 'https://ossindex.net/v2.0/package/{}/{}'.format(
            _url_encode(package_manager),
            _url_encode(package))
    try:
        sess = http.HTTPSession(url)
        resp = json.loads(sess.response.text)[0]
        vuln_titles = tuple()
        if resp['id'] == 0:
            return vuln_titles
        if int(resp['vulnerability-matches']) > 0:
            vulns = resp['vulnerabilities']
            vuln_titles = tuple([x['title'], ", ".join(x['versions'])]
                                for x in vulns)
            vuln_titles = tuple(reduce(
                lambda l, x: l.append(x) or l if x not in l else l,
                vuln_titles, []))
        return vuln_titles
    except http.ConnError:
        raise ConnError
예제 #4
0
def is_insecure_in_url(image_url: str, expected_text: str, *args,
                       **kwargs) -> bool:
    r"""
    Check if the image in the URL is an insecure CAPTCHA.

    The check is performed by converting the image to text and
    comparing with the given expected text.

    :param image_url: Path to the image to be tested.
    :param expected_text: Text the image might contain.
    :param \*args: Optional positional arguments for
        :class:`~fluidasserts.helper.http.HTTPSession`.
    :param \*\*kwargs: Optional keyword arguments for
        :class:`~fluidasserts.helper.http.HTTPSession`.
    """
    session = http.HTTPSession(image_url, stream=True, *args, **kwargs)
    fingerprint = session.get_fingerprint()
    image = session.response.raw
    result = pytesseract.image_to_string(Image.open(image))
    if result == expected_text:
        show_open('Captcha is insecure',
                  details=dict(expected=expected_text,
                               reversed=result,
                               fingerprint=fingerprint))
        return True
    show_close('Captcha is secure',
               details=dict(expected=expected_text,
                            reversed=result,
                            fingerprint=fingerprint))
    return False
예제 #5
0
def accepts_insecure_accept_header(url: str, *args, **kwargs) -> bool:
    r"""
    Check if given URL accepts insecure Accept request header value.

    :param url: URL to test.
    :param \*args: Optional arguments for :class:`HTTPSession`.
    :param \*\*kwargs: Optional arguments for :class:`HTTPSession`.
    """
    expected_codes = [406, 415]
    if 'headers' in kwargs:
        kwargs['headers'].update({'Accept': '*/*'})
    elif kwargs:
        kwargs['headers'] = {'Accept': '*/*'}
    else:
        kwargs = {'headers': {'Accept': '*/*'}}
    try:
        session = http.HTTPSession(url, *args, **kwargs)
    except http.ConnError as exc:
        show_unknown('URL {} returned error'.format(url),
                     details=dict(error=str(exc).replace(':', ',')))
        return False

    if session.response.status_code not in expected_codes:
        show_open(
            'URL {} accepts insecure Accept request header value'.format(url))
        return True
    show_close(
        'URL {} rejects insecure Accept request header value'.format(url))
    return False
예제 #6
0
def test_has_not_secure_in_cookiejar_close():
    """Cookiejar has secure attribute?."""
    url = '%s/http/cookies/secure/ok' % (MOCK_SERVICE)
    cookie_name = 'JSESSID'
    sess = http.HTTPSession(url)
    assert not cookie.has_not_secure_in_cookiejar(cookie_name, sess.cookies)
    assert not cookie.has_not_secure_in_cookiejar(cookie_name, None)
    assert not cookie.has_not_secure_in_cookiejar(None, sess.cookies)
예제 #7
0
def is_header_hsts_missing(url: str, *args, **kwargs) -> bool:
    r"""
    Check if Strict-Transport-Security HTTP header is properly set.

    :param url: URL to test.
    :param \*args: Optional arguments for :class:`.HTTPSession`.
    :param \*\*kwargs: Optional arguments for :class:`.HTTPSession`.
    """
    result = True
    try:
        http_session = http.HTTPSession(url, *args, **kwargs)
        headers_info = http_session.response.headers
        fingerprint = http_session.get_fingerprint()
    except http.ConnError as exc:
        show_unknown('Could not connnect',
                     details=dict(url=url, error=str(exc).replace(':', ',')))
        return False
    except http.ParameterError as exc:
        show_unknown('An invalid parameter was passed',
                     details=dict(url=url, error=str(exc).replace(':', ',')))
        return False

    header = 'Strict-Transport-Security'
    if header in headers_info:
        value = headers_info[header]
        if re.match(HDR_RGX[header.lower()], value, re.IGNORECASE):
            hdr_attrs = value.split(';')
            max_age = list(filter(lambda x: x.startswith('max-age'),
                                  hdr_attrs))[0]
            max_age_val = max_age.split('=')[1]
            if int(max_age_val) >= 31536000:
                show_close('HTTP header {} is secure'.format(header),
                           details=dict(url=url,
                                        header=header,
                                        value=value,
                                        fingerprint=fingerprint))
                result = False
            else:
                show_open('{} HTTP header is insecure'.format(header),
                          details=dict(url=url,
                                       header=header,
                                       value=value,
                                       fingerprint=fingerprint))
                result = True
        else:
            show_open('{} HTTP header is insecure'.format(header),
                      details=dict(url=url,
                                   header=header,
                                   value=value,
                                   fingerprint=fingerprint))
            result = True
    return result
예제 #8
0
def polycom_phone_has_default_credentials(hostname: str,
                                          proto: str = 'https',
                                          port: int = '443',
                                          password: str = '456') -> bool:
    """
    Check if Polycom SoundStation IP 6000 has default credentials.

    :param hostname: IP or host of phone.
    :param password: Default password.
    """
    try:
        url = '{}://{}:{}/login.htm'.format(proto, hostname, port)
        sess = http.HTTPSession(url)
        if 'Polycom Web Configuration Utility' not in sess.response.text:
            show_unknown('Resources not found. Is it a valid phone version?',
                         details=dict(host=hostname, url=url,
                                      status_code=sess.response.status_code))
            return False
        creds = 'Polycom:{}'.format(password)
        encoded = base64.b64encode(creds.encode())

        sess.headers.update({'X-Requested-With': 'XMLHttpRequest'})
        sess.headers.update({'Authorization': 'Basic {}'
                                              .format(encoded.decode())})
        sess.url = '{}://{}:{}/auth.htm?\
t=Tue,%2020%20Nov%202018%2019:48:43%20GMT'.format(proto, hostname, port)
        sess.do_request()
    except http.ConnError as exc:
        show_unknown('Could not connect',
                     details=dict(hostname=hostname, url=url,
                                  reason=str(exc).replace(':', ',')))
        return False
    expected = "SoundStation IP 6000"

    if sess.response.status_code > 401:
        show_unknown('Resources not found. Is it a valid phone version?',
                     details=dict(host=hostname, url=url,
                                  status_code=sess.response.status_code))
        return False
    if expected in sess.response.text:
        show_open('Phone has default credentials',
                  details=dict(host=hostname, username='******',
                               password=password))
        result = True
    else:
        show_close('Phone has not default credentials',
                   details=dict(host=hostname, username='******',
                                password=password))
        result = False
    return result
예제 #9
0
def has_access(url: str, *args, **kwargs) -> bool:
    r"""
    Check if HTTP access to given URL is possible (i.e. response 200 OK).

    :param url: URL to test.
    :param \*args: Optional arguments for :class:`HTTPSession`.
    :param \*\*kwargs: Optional arguments for :class:`HTTPSession`.
    """
    http_session = http.HTTPSession(url, *args, **kwargs)
    ok_access_list = [200, 202, 204, 301, 302, 307]
    if http_session.response.status_code in ok_access_list:
        show_open('Access available to {}'.format(url))
        return True
    show_close('Access not available to {}'.format(url))
    return False
예제 #10
0
def unify_phone_has_default_credentials(hostname: str,
                                        proto: str = 'https',
                                        port: int = '443',
                                        password: str = '123456') -> bool:
    """
    Check if Unify OpenScape Desk Phone IP 55G has default credentials.

    :param hostname: IP or host of phone.
    :param password: Default password.
    """
    try:
        url = '{}://{}:{}/index.cmd?user=Admin'.format(proto, hostname, port)
        sess = http.HTTPSession(url)

        if 'OpenScape Desk Phone IP Admin' not in sess.response.text:
            show_unknown('Resources not found. Is it a valid phone version?',
                         details=dict(host=hostname, url=url,
                                      status_code=sess.response.status_code))
            return False

        sess.data = 'page_submit=WEBMp_Admin_Login&lang=es&AdminPassword={}'\
            .format(password)
        sess.url = '{}://{}:{}/page.cmd'.format(proto, hostname, port)
        sess.do_request()
    except http.ConnError as exc:
        show_unknown('Could not connect',
                     details=dict(hostname=hostname, url=url,
                                  reason=str(exc).replace(':', ',')))
        return False

    failed = "action='./page.cmd'"

    if sess.response.status_code > 400:
        show_unknown('Resources not found. Is it a valid phone version?',
                     details=dict(host=hostname, url=url,
                                  status_code=sess.response.status_code))
        return False
    if failed not in sess.response.text:
        show_open('Phone has default credentials',
                  details=dict(host=hostname, username='******',
                               password=password))
        result = True
    else:
        show_close('Phone has not default credentials',
                   details=dict(host=hostname, username='******',
                                password=password))
        result = False
    return result
예제 #11
0
파일: cookie.py 프로젝트: jvasque6/asserts
def _has_not_same_site(cookie_name: str, url: Optional[str],
                       cookie_jar: Optional[dict], *args, **kwargs) -> bool:
    r"""
    Check if a cookie has the ``samesite`` attribute.

    :param cookie_name: Name of the cookie to test.
    Exactly one of the following has to be ``None``.
    :param url: URL to get cookies.
    :param cookie_jar: Dict-like collection of cookies
                       as returned by ``requests.cookies``.
    :param \*args: Optional positional arguments for
                   :class:`~fluidasserts.helper.http.HTTPSession`.
    :param \*\*kwargs: Optional keyword arguments for
                       :class:`~fluidasserts.helper.http.HTTPSession`.
    """
    fingerprint = None
    if url is not None:
        try:
            sess = http.HTTPSession(url, *args, **kwargs)
            cookielist = sess.cookies
            fingerprint = sess.get_fingerprint()
        except http.ConnError:
            show_unknown('Could not connect', details=dict(url=url))
            return False
    else:
        cookielist = cookie_jar
    if cookielist is None:
        show_unknown('{} Cookies not present'.format(cookie_name),
                     details=dict(url=url, fingerprint=fingerprint))
        return False
    for cookie in cookielist:
        if cookie.name == cookie_name:
            if cookie.has_nonstandard_attr('SameSite'):
                if cookie.get_nonstandard_attr('SameSite') == 'Strict':
                    show_close('SameSite is set to Strict',
                               details=dict(url=url,
                                            cookie=cookie_name,
                                            fingerprint=fingerprint))
                    return False
            show_open('Cookie SameSite not present or Lax',
                      details=dict(url=url,
                                   cookie=cookie_name,
                                   fingerprint=fingerprint))
            return True
    show_unknown('Cookie "{}" not found'.format(cookie_name),
                 details=dict(url=url, fingerprint=fingerprint))
    return False
예제 #12
0
파일: sca.py 프로젝트: jvasque6/asserts
def get_vulns_snyk(package_manager: str, package: str, version: str) -> tuple:
    """
    Search vulnerabilities on given package_manager/package/version.

    :param package_manager: Package manager.
    :param package: Package name.
    :param version: Package version.
    """
    if version:
        url = 'https://snyk.io/vuln/{}:{}@{}'.format(
            _url_encode(package_manager),
            _url_encode(package),
            _url_encode(version))
    else:
        url = 'https://snyk.io/vuln/{}:{}'.format(
            _url_encode(package_manager),
            _url_encode(package))
    try:
        sess = http.HTTPSession(url, timeout=20)
        return _parse_snyk_vulns(sess.response.text)
    except http.ConnError:
        raise ConnError
예제 #13
0
def accepts_empty_content_type(url: str, *args, **kwargs) -> bool:
    r"""
    Check if given URL accepts empty Content-Type requests.

    :param url: URL to test.
    :param \*args: Optional arguments for :class:`HTTPSession`.
    :param \*\*kwargs: Optional arguments for :class:`HTTPSession`.
    """
    if 'headers' in kwargs:
        if 'Content-Type' in kwargs['headers']:
            kwargs['headers'].pop('Content-Type', None)
    expected_codes = [406, 415]
    try:
        session = http.HTTPSession(url, *args, **kwargs)
    except http.ConnError as exc:
        show_unknown('URL {} returned error'.format(url),
                     details=dict(error=str(exc).replace(':', ',')))
        return False

    if session.response.status_code not in expected_codes:
        show_open('URL {} accepts empty Content-Type requests'.format(url))
        return True
    show_close('URL {} rejects empty Content-Type requests'.format(url))
    return False
예제 #14
0
 def __init__(self, url) -> None:
     """Build a new Service object."""
     self.url = url
     self.sess = http.HTTPSession(self.url)
예제 #15
0
def test_has_not_httponly_in_cookiejar_open():
    """Cookiejar has http-only attribute?."""
    url = '%s/http/cookies/http_only/fail' % (MOCK_SERVICE)
    cookie_name = 'JSESSID'
    sess = http.HTTPSession(url)
    assert cookie.has_not_httponly_in_cookiejar(cookie_name, sess.cookies)