Esempio n. 1
0
async def test_false_positive():
    # Test for false positive
    respx.route(host="raw.githubusercontent.com").pass_through()

    respx.get("http://perdu.com/").mock(return_value=httpx.Response(
        200,
        text=
        "<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1> \
            <h2>Pas de panique, on va vous aider</h2> \
            <strong><pre>    * <----- vous &ecirc;tes ici</pre></strong></body></html>"
    ))

    persister = FakePersister()

    request = Request("http://perdu.com/")
    request.path_id = 1

    crawler = AsyncCrawler("http://perdu.com/")
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_wapp(crawler, persister, logger, options, Event())
    module.verbose = 2

    await module.attack(request)

    assert not persister.additionals
    await crawler.close()
Esempio n. 2
0
async def test_false_positive():
    # Test for false positive
    respx.route(host="raw.githubusercontent.com").pass_through()

    respx.get("http://perdu.com/").mock(return_value=httpx.Response(
        200,
        text=
        "<html><head><title>Vous Etes Perdu ?</title></head><body><h1>Perdu sur l'Internet ?</h1> \
            <h2>Pas de panique, on va vous aider</h2> \
            <strong><pre>    * <----- vous &ecirc;tes ici</pre></strong></body></html>"
    ))

    persister = AsyncMock()
    home_dir = os.getenv("HOME") or os.getenv("USERPROFILE")
    base_dir = os.path.join(home_dir, ".wapiti")
    persister.CONFIG_DIR = os.path.join(base_dir, "config")

    request = Request("http://perdu.com/")
    request.path_id = 1

    crawler = AsyncCrawler("http://perdu.com/")
    options = {"timeout": 10, "level": 2}

    module = ModuleWapp(crawler, persister, options, Event())

    await module.attack(request)

    assert not persister.add_payload.call_count
    await crawler.close()
Esempio n. 3
0
async def test_unregistered_cname():
    # Test attacking all kind of parameter without crashing
    respx.route(host="perdu.com").mock(return_value=httpx.Response(200, text="Hello there"))

    async def resolve(qname, rdtype, raise_on_no_answer: bool = False):
        if qname.startswith("supercalifragilisticexpialidocious."):
            # No wildcard responses
            return []
        if qname.startswith("admin.") and rdtype == "CNAME":
            return make_cname_answer("perdu.com", "unregistered.com")
        raise dns.resolver.NXDOMAIN("Yolo")

    with patch("wapitiCore.attack.mod_takeover.dns.asyncresolver.resolve") as mocked_resolve_:
        with patch("wapitiCore.attack.mod_takeover.dns.asyncresolver.Resolver.resolve") as mocked_resolve:
            mocked_resolve.side_effect = resolve
            mocked_resolve_.side_effect = resolve
            persister = AsyncMock()
            all_requests = []

            request = Request("http://perdu.com/")
            request.path_id = 1
            all_requests.append(request)

            crawler = AsyncCrawler("http://perdu.com/", timeout=1)
            options = {"timeout": 10, "level": 2}

            module = ModuleTakeover(crawler, persister, options, Event())

            for request in all_requests:
                await module.attack(request)

            assert persister.add_payload.call_args_list[0][1]["request"].hostname == "admin.perdu.com"
            assert "unregistered.com" in persister.add_payload.call_args_list[0][1]["info"]

            await crawler.close()
Esempio n. 4
0
async def test_direct_upload():
    respx.route(host="127.0.0.1").pass_through()
    persister = AsyncMock()
    request = Request("http://127.0.0.1:65084/xxe/outofband/upload.php",
                      file_params=[[
                          "foo",
                          ("bar.xml", "<xml>test</xml>", "application/xml")
                      ],
                                   [
                                       "calendar",
                                       ("calendar.xml", "<xml>test</xml>",
                                        "application/xml")
                                   ]])
    request.path_id = 8
    persister.get_path_by_id.return_value = request
    crawler = AsyncCrawler("http://127.0.0.1:65084/")
    options = {
        "timeout": 10,
        "level": 1,
        "external_endpoint": "http://wapiti3.ovh/",
        "internal_endpoint": "http://wapiti3.ovh/"
    }
    logger = Mock()

    module = mod_xxe(crawler, persister, logger, options, Event())

    await module.attack(request)

    respx.get(
        "http://wapiti3.ovh/get_xxe.php?session_id=" + module._session_id
    ).mock(return_value=httpx.Response(
        200,
        json={
            "8": {
                "63616c656e646172": [{
                    "date": "2019-08-17T16:52:41+00:00",
                    "url":
                    "https://wapiti3.ovh/xxe_data/yolo/8/63616c656e646172/31337-0-192.168.2.1.txt",
                    "ip": "192.168.2.1",
                    "size": 999,
                    "payload": "linux2"
                }]
            }
        }))

    assert not persister.add_payload.call_count
    await module.finish()

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1][
        "parameter"] == "calendar"
    await crawler.close()
Esempio n. 5
0
async def test_false_positives():
    respx.route(host="raw.githubusercontent.com").pass_through()

    # This one trigger a match based on content
    respx.get("http://perdu.com/opendir.php?/etc/passwd").mock(
        return_value=httpx.Response(200, text="root:0:0:")
    )
    # A lot of cases will trigger because HTTP 200 is returned instead of 404 but false positive check should block them
    respx.route(host="perdu.com").mock(
        return_value=httpx.Response(200, text="Hello there")
    )

    persister = AsyncMock()
    home_dir = os.getenv("HOME") or os.getenv("USERPROFILE")
    base_dir = os.path.join(home_dir, ".wapiti")
    persister.CONFIG_DIR = os.path.join(base_dir, "config")

    temp_nikto_db = os.path.join(persister.CONFIG_DIR, "temp_nikto_db")
    with open(temp_nikto_db, "w") as fd:
        fd.writelines(
            [
                "003270,539,d,/catinfo,GET,200,,,,,May be vulnerable to a buffer overflow. Request '/catinfo?',,\n",
                "003271,5407,a,/soap/servlet/soaprouter,GET,200,,,,,Oracle 9iAS SOAP components allow anonymous,,\n",
                "003272,543,7,/opendir.php?/etc/passwd,GET,root:,,,,,This PHP-Nuke CGI allows attackers to read,,\n"
            ]
        )

    request = Request("http://perdu.com/")
    request.path_id = 1
    request.status = 200
    request.set_headers({"content-type": "text/html"})
    persister.get_links.return_value = chain([request])

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2, "tasks": 20}

    module = ModuleNikto(crawler, persister, options, Event())
    module.do_get = True
    module.NIKTO_DB = "temp_nikto_db"
    await module.attack(request)
    os.unlink(temp_nikto_db)

    assert persister.add_payload.call_count == 1
    assert persister.add_payload.call_args_list[0][1]["module"] == "nikto"
    assert persister.add_payload.call_args_list[0][1]["category"] == _("Potentially dangerous file")
    assert persister.add_payload.call_args_list[0][1]["request"].url == (
        "http://perdu.com/opendir.php?%2Fetc%2Fpasswd"
    )
    assert (
               "This PHP-Nuke CGI allows attackers to read"
           ) in persister.add_payload.call_args_list[0][1]["info"]
    await crawler.close()
Esempio n. 6
0
async def test_out_of_band_body():
    respx.route(host="127.0.0.1").pass_through()

    persister = AsyncMock()
    request = Request("http://127.0.0.1:65084/xxe/outofband/body.php",
                      method="POST",
                      post_params=[["placeholder", "yolo"]])
    request.path_id = 42
    persister.get_path_by_id.return_value = request

    persister.requests.append(request)
    crawler = AsyncCrawler("http://127.0.0.1:65084/")
    options = {
        "timeout": 10,
        "level": 1,
        "external_endpoint": "http://wapiti3.ovh/",
        "internal_endpoint": "http://wapiti3.ovh/"
    }
    logger = Mock()

    module = mod_xxe(crawler, persister, logger, options, Event())

    respx.get(
        "http://wapiti3.ovh/get_xxe.php?session_id=" + module._session_id
    ).mock(return_value=httpx.Response(
        200,
        json={
            "42": {
                "72617720626f6479": [{
                    "date": "2019-08-17T16:52:41+00:00",
                    "url":
                    "https://wapiti3.ovh/xxe_data/yolo/3/72617720626f6479/31337-0-192.168.2.1.txt",
                    "ip": "192.168.2.1",
                    "size": 999,
                    "payload": "linux2"
                }]
            }
        }))

    module.do_post = False
    await module.attack(request)

    assert not persister.add_payload.call_count
    await module.finish()
    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1][
        "parameter"] == "raw body"
    assert "linux2" in persister.add_payload.call_args_list[0][1][
        "request"].post_params
    await crawler.close()
Esempio n. 7
0
async def make_request(method='get',
                       api_url='',
                       api_key='',
                       data={},
                       retries=0):
    """
    Make call to external urls using python request
    :param method: get|post (str)
    :param api_url:
    :param api_key:
    :param data: data to send in the request (dict)
    :param retries:
    :return:
    """
    headers = {'content-type': 'application/json'}
    if api_key and isinstance(data, dict):
        data['api_key'] = api_key
    method = method.upper()
    respx.route(method=method, path=api_url).mock(return_value=httpx.Response(
        status_code=MOCK_URLS[api_url]['status_code'],
        json=MOCK_URLS[api_url]['data']))
    event_hooks = {}
    if DEBUG_MODE:
        event_hooks = {'request': [log_request], 'response': [log_response]}
    async with httpx.AsyncClient(event_hooks=event_hooks) as client:
        try:
            async for attempt in AsyncRetrying(
                    stop=stop_after_attempt(retries), wait=wait_fixed(2)):
                with attempt:
                    if method == httpretty.GET:
                        response = await client.get(api_url,
                                                    params=data,
                                                    headers=headers)
                    elif method == httpretty.POST:
                        response = await client.post(
                            api_url,
                            data=json.dumps(data,
                                            default=date_time_json_serialize),
                            headers=headers)
                    if response.status_code in STATUS_FORCE_LIST:
                        response.raise_for_status()
                    return {
                        'status_code': response.status_code,
                        'data': response.json()
                    }
        except RetryError:
            return {
                'status_code': INTERNAL_SERVER_STATUS_CODE,
                'data': INTERNAL_SERVER_ERROR_MESSAGE
            }
Esempio n. 8
0
async def test_hmac_signature() -> None:
    webhook = Webhook(url="http://localhost:8080/webhook", events="after:measure", secret="testing")
    config = WebhooksConfiguration(__root__=[webhook])
    connector = WebhooksConnector(config=config)
    await connector.startup()

    info = {}
    def match_and_mock(request):
        if request.method != "POST":
            return None

        if "x-servo-signature" in request.headers:
            signature = request.headers["x-servo-signature"]
            body = request.read()
            info.update(dict(signature=signature, body=body))

        return httpx.Response(204)

    webhook_request = respx.route().mock(side_effect=match_and_mock)
    await connector.dispatch_event("measure")
    assert webhook_request.called

    expected_signature = info["signature"]
    signature = str(hmac.new("testing".encode(), info["body"], hashlib.sha1).hexdigest())
    assert signature == expected_signature
Esempio n. 9
0
async def test_get_cashback_total_server_error(client: AsyncClient,
                                               access_token):
    response = {"statusCode": 500, "body": {"credit": 1993}}
    respx.route(host="localhost").pass_through()
    respx.get(
        "https://mdaqk8ek5j.execute-api.us-east-1.amazonaws.com/v1/cashback",
        params={
            "cpf": "12312312323"
        },
    ).mock(return_value=Response(500, json=response))
    r = await client.get(
        f"{settings.API_V1_STR}/cashbacks/me",
        headers={"Authorization": f"Bearer {access_token}"},
    )
    assert r.status_code == 500
    assert respx.calls.called
Esempio n. 10
0
async def test_out_of_band_param():
    respx.route(host="127.0.0.1").pass_through()

    persister = AsyncMock()
    request = Request(
        "http://127.0.0.1:65084/xxe/outofband/param.php?foo=bar&vuln=yolo")
    request.path_id = 7
    persister.get_path_by_id.return_value = request
    crawler = AsyncCrawler("http://127.0.0.1:65084/")
    options = {
        "timeout": 10,
        "level": 1,
        "external_endpoint": "http://wapiti3.ovh/",
        "internal_endpoint": "http://wapiti3.ovh/"
    }
    logger = Mock()

    module = mod_xxe(crawler, persister, logger, options, Event())

    respx.get(
        "http://wapiti3.ovh/get_xxe.php?session_id=" + module._session_id
    ).mock(return_value=httpx.Response(
        200,
        json={
            "7": {
                "76756c6e": [{
                    "date": "2019-08-17T16:52:41+00:00",
                    "url":
                    "https://wapiti3.ovh/xxe_data/yolo/7/76756c6e/31337-0-192.168.2.1.txt",
                    "ip": "192.168.2.1",
                    "size": 999,
                    "payload": "linux2"
                }]
            }
        }))

    module.do_post = False
    await module.attack(request)

    assert not persister.add_payload.call_count
    await module.finish()
    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "vuln"
    assert "linux2" in dict(persister.add_payload.call_args_list[0][1]
                            ["request"].get_params)["vuln"]
    await crawler.close()
Esempio n. 11
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.get("http://perdu.com/").mock(
        return_value=httpx.Response(200, text="Default page"))

    respx.get("http://perdu.com/admin/").mock(
        return_value=httpx.Response(401, text="Private section"))

    respx.route(method="ABC", host="perdu.com", path="/admin/").mock(
        return_value=httpx.Response(200, text="Hello there"))

    persister = AsyncMock()
    all_requests = []

    request = Request("http://perdu.com/")
    request.path_id = 1
    request.status = 200
    request.set_headers({"content-type": "text/html"})
    all_requests.append(request)

    request = Request("http://perdu.com/admin/")
    request.path_id = 2
    request.status = 401
    request.set_headers({"content-type": "text/html"})
    all_requests.append(request)

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_htaccess(crawler, persister, logger, options, Event())
    module.verbose = 2
    module.do_get = True
    for request in all_requests:
        if await module.must_attack(request):
            await module.attack(request)
        else:
            assert request.path_id == 1

    assert persister.add_payload.call_count == 1
    assert persister.add_payload.call_args_list[0][1]["module"] == "htaccess"
    assert persister.add_payload.call_args_list[0][1]["category"] == _(
        "Htaccess Bypass")
    assert persister.add_payload.call_args_list[0][1][
        "request"].url == "http://perdu.com/admin/"
    await crawler.close()
Esempio n. 12
0
async def test_out_of_band_query_string():
    respx.route(host="127.0.0.1").pass_through()

    persister = AsyncMock()
    request = Request("http://127.0.0.1:65084/xxe/outofband/qs.php")
    request.path_id = 4
    persister.get_path_by_id.return_value = request
    crawler = AsyncCrawler("http://127.0.0.1:65084/")
    options = {
        "timeout": 10,
        "level": 2,
        "external_endpoint": "http://wapiti3.ovh/",
        "internal_endpoint": "http://wapiti3.ovh/"
    }
    logger = Mock()

    module = mod_xxe(crawler, persister, logger, options, Event())
    module.do_post = False
    await module.attack(request)

    respx.get(
        "http://wapiti3.ovh/get_xxe.php?session_id=" + module._session_id
    ).mock(return_value=httpx.Response(
        200,
        json={
            "4": {
                "51554552595f535452494e47": [{
                    "date": "2019-08-17T16:52:41+00:00",
                    "url":
                    "https://wapiti3.ovh/xxe_data/yolo/4/51554552595f535452494e47/31337-0-192.168.2.1.txt",
                    "ip": "192.168.2.1",
                    "size": 999,
                    "payload": "linux2"
                }]
            }
        }))

    assert not persister.add_payload.call_count
    await module.finish()

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1][
        "parameter"] == "QUERY_STRING"
    await crawler.close()
Esempio n. 13
0
def test_sync_app_route(using):
    from flask import Flask

    app = Flask("foobar")

    @app.route("/baz/")
    def baz():
        return {"ham": "spam"}

    with respx.mock(using=using, base_url="https://foo.bar/") as respx_mock:
        app_route = respx_mock.route().mock(side_effect=WSGIHandler(app))
        response = httpx.get("https://foo.bar/baz/")
        assert response.json() == {"ham": "spam"}
        assert app_route.called

    with respx.mock:
        respx.route(host="foo.bar").mock(side_effect=WSGIHandler(app))
        response = httpx.get("https://foo.bar/baz/")
        assert response.json() == {"ham": "spam"}
Esempio n. 14
0
async def test_decorating_test(client):
    assert respx.calls.call_count == 0
    respx.calls.assert_not_called()
    request = respx.route(url="https://foo.bar/", name="home").respond(202)
    response = await client.get("https://foo.bar/")
    assert request.called is True
    assert response.status_code == 202
    assert respx.calls.call_count == 1
    assert respx.routes["home"].call_count == 1
    respx.calls.assert_called_once()
    respx.routes["home"].calls.assert_called_once()
Esempio n. 15
0
async def test_async_app_route(client, using):
    from starlette.applications import Starlette
    from starlette.responses import JSONResponse
    from starlette.routing import Route

    async def baz(request):
        return JSONResponse({"ham": "spam"})

    app = Starlette(routes=[Route("/baz/", baz)])

    async with respx.mock(using=using, base_url="https://foo.bar/") as respx_mock:
        app_route = respx_mock.route().mock(side_effect=ASGIHandler(app))
        response = await client.get("https://foo.bar/baz/")
        assert response.json() == {"ham": "spam"}
        assert app_route.called

    async with respx.mock:
        respx.route(host="foo.bar").mock(side_effect=ASGIHandler(app))
        response = await client.get("https://foo.bar/baz/")
        assert response.json() == {"ham": "spam"}
Esempio n. 16
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.route(host="raw.githubusercontent.com").pass_through()

    respx.get("http://perdu.com/cgi-bin/a1disp3.cgi?../../../../../../../../../../etc/passwd").mock(
        return_value=httpx.Response(200, text="root:0:0:")
    )

    respx.route(host="perdu.com").mock(
        return_value=httpx.Response(404, text="Not found")
    )

    persister = AsyncMock()
    home_dir = os.getenv("HOME") or os.getenv("USERPROFILE")
    base_dir = os.path.join(home_dir, ".wapiti")
    persister.CONFIG_DIR = os.path.join(base_dir, "config")

    request = Request("http://perdu.com/")
    request.path_id = 1
    request.status = 200
    request.set_headers({"content-type": "text/html"})
    persister.get_links.return_value = chain([request])

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}

    module = mod_nikto(crawler, persister, options, Event())
    module.verbose = 2
    module.do_get = True
    await module.attack(request)

    assert persister.add_payload.call_count == 1
    assert persister.add_payload.call_args_list[0][1]["module"] == "nikto"
    assert persister.add_payload.call_args_list[0][1]["category"] == _("Potentially dangerous file")
    assert persister.add_payload.call_args_list[0][1]["request"].url == (
        "http://perdu.com/cgi-bin/a1disp3.cgi?..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd"
    )
    assert (
               "This CGI allows attackers read arbitrary files on the host"
           ) in persister.add_payload.call_args_list[0][1]["info"]
    await crawler.close()
Esempio n. 17
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.get("http://perdu.com/").mock(
        return_value=httpx.Response(200, text="Default page"))

    respx.get("http://perdu.com/admin/").mock(
        return_value=httpx.Response(401, text="Private section"))

    respx.route(method="ABC", host="perdu.com", path="/admin/").mock(
        return_value=httpx.Response(200, text="Hello there"))

    persister = FakePersister()

    request = Request("http://perdu.com/")
    request.path_id = 1
    request.status = 200
    request.set_headers({"content-type": "text/html"})
    persister.requests.append(request)

    request = Request("http://perdu.com/admin/")
    request.path_id = 2
    request.status = 401
    request.set_headers({"content-type": "text/html"})
    persister.requests.append(request)

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_htaccess(crawler, persister, logger, options, Event())
    module.verbose = 2
    module.do_get = True
    for request in persister.requests:
        if module.must_attack(request):
            await module.attack(request)
        else:
            assert request.path_id == 1

    assert persister.vulnerabilities
    assert persister.vulnerabilities[0].url == "http://perdu.com/admin/"
    await crawler.close()
Esempio n. 18
0
async def test_no_ports(ports):
    """Test that no ports also work."""
    route = respx.route(
        url__startswith=f"http://{HOST}/axis-cgi/param.cgi").respond(
            text="",
            headers={"Content-Type": "text/plain"},
        )

    await ports.update()

    assert route.call_count == 3
    assert len(ports.values()) == 0
Esempio n. 19
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.route(url__regex=r"http://perdu.com/.*").mock(
        return_value=httpx.Response(200, text="Hello there"))

    persister = AsyncMock()
    all_requests = []

    request = Request("http://perdu.com/")
    request.path_id = 1
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar")
    request.path_id = 2
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar",
                      post_params=[["a", "b"]],
                      file_params=[[
                          "file",
                          ("calendar.xml", "<xml>Hello there</xml",
                           "application/xml")
                      ]])
    request.path_id = 3
    all_requests.append(request)

    crawler = AsyncCrawler("http://perdu.com/", timeout=1)
    options = {"timeout": 10, "level": 2}
    logger = Mock()

    module = mod_redirect(crawler, persister, logger, options, Event())
    module.verbose = 2
    module.do_post = True
    for request in all_requests:
        await module.attack(request)

    assert True
    await crawler.close()
Esempio n. 20
0
async def test_whole_stuff():
    # Test attacking all kind of parameter without crashing
    respx.route(host="perdu.com").mock(
        return_value=httpx.Response(200, text="Hello there"))

    persister = AsyncMock()
    all_requests = []

    request = Request("http://perdu.com/")
    request.path_id = 1
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar")
    request.path_id = 2
    all_requests.append(request)

    request = Request("http://perdu.com/?foo=bar",
                      post_params=[["a", "b"]],
                      file_params=[[
                          "file",
                          ("calendar.xml", b"<xml>Hello there</xml",
                           "application/xml")
                      ]])
    request.path_id = 3
    all_requests.append(request)

    def get_path_by_id(request_id):
        for req in all_requests:
            if req.path_id == int(request_id):
                return req
        return None

    persister.get_path_by_id.side_effect = get_path_by_id

    crawler = AsyncCrawler(Request("http://perdu.com/"), timeout=1)
    options = {"timeout": 10, "level": 2}

    module = ModuleSsrf(crawler, persister, options, Event())
    module.do_post = True

    respx.get(
        "https://wapiti3.ovh/get_ssrf.php?session_id=" + module._session_id
    ).mock(return_value=httpx.Response(
        200,
        json={
            "3": {
                "66696c65": [{
                    "date": "2019-08-17T16:52:41+00:00",
                    "url":
                    "https://wapiti3.ovh/ssrf_data/yolo/3/66696c65/31337-0-192.168.2.1.txt",
                    "ip": "192.168.2.1",
                    "method": "GET"
                }]
            }
        }))

    for request in all_requests:
        await module.attack(request)

    assert not persister.add_payload.call_count
    # We must trigger finish() normally called by wapiti.py
    await module.finish()

    assert persister.add_payload.call_count
    assert persister.add_payload.call_args_list[0][1]["module"] == "ssrf"
    assert persister.add_payload.call_args_list[0][1]["category"] == _(
        "Server Side Request Forgery")
    assert persister.add_payload.call_args_list[0][1]["parameter"] == "file"
    assert persister.add_payload.call_args_list[0][1][
        "request"].file_params == [[
            'file',
            ('http://external.url/page', b'<xml>Hello there</xml',
             'application/xml')
        ]]
    await crawler.close()
Esempio n. 21
0
 def respx_add_empty_msg_pack(self, url, method='GET'):
     respx.route(method=method, url=url).return_value = Response(
         status_code=200,
         headers={'content-type': 'application/x-msgpack'},
         content=msgpack.packb({}))
Esempio n. 22
0
async def test_ports(ports):
    """Test that different types of ports work."""
    update_ports_route = respx.route(
        url__startswith=f"http://{HOST}/axis-cgi/param.cgi").respond(
            text="""root.Input.NbrOfInputs=3
root.IOPort.I0.Direction=input
root.IOPort.I0.Usage=Button
root.IOPort.I1.Configurable=no
root.IOPort.I1.Direction=input
root.IOPort.I1.Input.Name=PIR sensor
root.IOPort.I1.Input.Trig=closed
root.IOPort.I2.Direction=input
root.IOPort.I2.Usage=
root.IOPort.I2.Output.Active=closed
root.IOPort.I2.Output.Button=none
root.IOPort.I2.Output.DelayTime=0
root.IOPort.I2.Output.Mode=bistable
root.IOPort.I2.Output.Name=Output 2
root.IOPort.I2.Output.PulseTime=0
root.IOPort.I3.Direction=output
root.IOPort.I3.Usage=Tampering
root.IOPort.I3.Output.Active=open
root.IOPort.I3.Output.Button=none
root.IOPort.I3.Output.DelayTime=0
root.IOPort.I3.Output.Mode=bistable
root.IOPort.I3.Output.Name=Tampering
root.IOPort.I3.Output.PulseTime=0
root.Output.NbrOfOutputs=1
""",
            headers={"Content-Type": "text/plain"},
        )

    action_low_route = respx.get(
        f"http://{HOST}:80/axis-cgi/io/port.cgi?action=4%3A%2F")
    action_high_route = respx.get(
        f"http://{HOST}:80/axis-cgi/io/port.cgi?action=4%3A%5C")

    await ports.update()

    assert update_ports_route.call_count == 3

    assert ports["0"].id == "0"
    assert ports["0"].configurable is False
    assert ports["0"].direction == "input"
    assert ports["0"].name == ""

    await ports["0"].action(action=ACTION_LOW)

    assert not action_low_route.called

    assert ports["1"].id == "1"
    assert ports["1"].configurable is False
    assert ports["1"].direction == "input"
    assert ports["1"].name == "PIR sensor"
    assert ports["1"].input_trig == "closed"

    assert ports["2"].id == "2"
    assert ports["2"].configurable is False
    assert ports["2"].direction == "input"
    assert ports["2"].name == ""
    assert ports["2"].output_active == "closed"

    assert ports["3"].id == "3"
    assert ports["3"].configurable is False
    assert ports["3"].direction == "output"
    assert ports["3"].name == "Tampering"
    assert ports["3"].output_active == "open"

    await ports["3"].close()

    assert action_low_route.called
    assert action_low_route.calls.last.request.method == "GET"
    assert action_low_route.calls.last.request.url.path == "/axis-cgi/io/port.cgi"
    assert action_low_route.calls.last.request.url.query.decode(
    ) == "action=4%3A%2F"

    await ports["3"].open()
    assert action_high_route.called
    assert action_high_route.calls.last.request.method == "GET"
    assert action_high_route.calls.last.request.url.path == "/axis-cgi/io/port.cgi"
    assert action_high_route.calls.last.request.url.query.decode(
    ) == "action=4%3A%5C"