Skip to content

InvalidURL exception #690

@devl00p

Description

@devl00p

Bumped into that error recently:

[¨] GET http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D%3D (0)
InvalidURL
Traceback (most recent call last):

  File "/home/nico/dev/wapiti/./bin/wapiti", line 34, in <module>
    wapiti_asyncio_wrapper()
    └ <function wapiti_asyncio_wrapper at 0x73b8f5f182c0>

  File "/home/nico/dev/wapiti/wapitiCore/main/wapiti.py", line 513, in wapiti_asyncio_wrapper
    asyncio.run(wapiti_main())
    │       │   └ <function wapiti_main at 0x73b8f5f18220>
    │       └ <function run at 0x73b8fb33bce0>
    └ <module 'asyncio' from '/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/__init__.py'>

  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           │      │   └ <coroutine object wapiti_main at 0x73b8f61c5f10>
           │      └ <function Runner.run at 0x73b8fb202b60>
           └ <asyncio.runners.Runner object at 0x73b8fbd0bd40>
  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           │    │     │                  └ <Task pending name='Task-1' coro=<wapiti_main() running at /home/nico/dev/wapiti/wapitiCore/main/wapiti.py:500> wait_for=<Tas...
           │    │     └ <function BaseEventLoop.run_until_complete at 0x73b8fb2007c0>
           │    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
           └ <asyncio.runners.Runner object at 0x73b8fbd0bd40>
  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/base_events.py", line 651, in run_until_complete
    self.run_forever()
    │    └ <function BaseEventLoop.run_forever at 0x73b8fb200720>
    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/base_events.py", line 618, in run_forever
    self._run_once()
    │    └ <function BaseEventLoop._run_once at 0x73b8fb202520>
    └ <_UnixSelectorEventLoop running=True closed=False debug=False>
  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/base_events.py", line 1951, in _run_once
    handle._run()
    │      └ <function Handle._run at 0x73b8fb34cae0>
    └ <Handle <_asyncio.TaskStepMethWrapper object at 0x73b8c5dcf5e0>()>
  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/events.py", line 84, in _run
    self._context.run(self._callback, *self._args)
    │    │            │    │           │    └ <member '_args' of 'Handle' objects>
    │    │            │    │           └ <Handle <_asyncio.TaskStepMethWrapper object at 0x73b8c5dcf5e0>()>
    │    │            │    └ <member '_callback' of 'Handle' objects>
    │    │            └ <Handle <_asyncio.TaskStepMethWrapper object at 0x73b8c5dcf5e0>()>
    │    └ <member '_context' of 'Handle' objects>
    └ <Handle <_asyncio.TaskStepMethWrapper object at 0x73b8c5dcf5e0>()>

  File "/home/nico/dev/wapiti/wapitiCore/attack/active_scanner.py", line 247, in run_attack_module
    await asyncio.wait_for(
          │       └ <function wait_for at 0x73b8fb3f8d60>
          └ <module 'asyncio' from '/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/__init__.py'>

  File "/home/nico/.pyenv/versions/3.12.0/lib/python3.12/asyncio/tasks.py", line 510, in wait_for
    return await fut
                 └ <coroutine object ActiveScanner.load_and_attack at 0x73b8f5ced6c0>

> File "/home/nico/dev/wapiti/wapitiCore/attack/active_scanner.py", line 191, in load_and_attack
    await attack_module.attack(original_request, original_response)
          │             │      │                 └ <wapitiCore.net.response.Response object at 0x73b8c5db3320>
          │             │      └ GET http://angular.testsparker.com/test.php?r=index.html (0)
          │             └ <function ModuleExec.attack at 0x73b8f5f6e7a0>
          └ <wapitiCore.attack.mod_exec.ModuleExec object at 0x73b8c5e86090>

  File "/home/nico/dev/wapiti/wapitiCore/attack/mod_exec.py", line 98, in attack
    response: Response = await self.crawler.async_send(mutated_request)
    │                          │    │       │          └ GET http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D%3D (0)
    │                          │    │       └ <function AsyncCrawler.async_send at 0x73b8f978f100>
    │                          │    └ <wapitiCore.net.crawler.AsyncCrawler object at 0x73b8c5e87f50>
    │                          └ <wapitiCore.attack.mod_exec.ModuleExec object at 0x73b8c5e86090>
    └ <wapitiCore.net.response.Response object at 0x73b8c5dcda90>

  File "/home/nico/dev/wapiti/wapitiCore/net/crawler.py", line 350, in async_send
    return await self.async_get(
                 │    └ <function AsyncCrawler.async_get at 0x73b8f978f240>
                 └ <wapitiCore.net.crawler.AsyncCrawler object at 0x73b8c5e87f50>

  File "/home/nico/dev/wapiti/wapitiCore/net/crawler.py", line 62, in inner_wrapper
    value = await function(*args, **kwargs)
                  │         │       └ {'headers': None, 'follow_redirects': False, 'stream': False, 'timeout': None}
                  │         └ (<wapitiCore.net.crawler.AsyncCrawler object at 0x73b8c5e87f50>, GET http://angular.testsparker.com/test.php?r=data%3A%3Bbase...
                  └ <function AsyncCrawler.async_get at 0x73b8f978f1a0>

  File "/home/nico/dev/wapiti/wapitiCore/net/crawler.py", line 252, in async_get
    response = await self._client.send(
                     │    │       └ <function AsyncClient.send at 0x73b8fa7f19e0>
                     │    └ <httpx.AsyncClient object at 0x73b8c5fdfd40>
                     └ <wapitiCore.net.crawler.AsyncCrawler object at 0x73b8c5e87f50>

  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 1674, in send
    response = await self._send_handling_auth(
                     │    └ <function AsyncClient._send_handling_auth at 0x73b8fa7f1a80>
                     └ <httpx.AsyncClient object at 0x73b8c5fdfd40>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 1702, in _send_handling_auth
    response = await self._send_handling_redirects(
                     │    └ <function AsyncClient._send_handling_redirects at 0x73b8fa7f1b20>
                     └ <httpx.AsyncClient object at 0x73b8c5fdfd40>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 1760, in _send_handling_redirects
    raise exc
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 1749, in _send_handling_redirects
    request = self._build_redirect_request(request, response)
              │    │                       │        └ <Response [302 Found]>
              │    │                       └ <Request('GET', 'http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D...
              │    └ <function BaseClient._build_redirect_request at 0x73b8fa7f0400>
              └ <httpx.AsyncClient object at 0x73b8c5fdfd40>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 461, in _build_redirect_request
    url = self._redirect_url(request, response)
          │    │             │        └ <Response [302 Found]>
          │    │             └ <Request('GET', 'http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D...
          │    └ <function BaseClient._redirect_url at 0x73b8fa7f0540>
          └ <httpx.AsyncClient object at 0x73b8c5fdfd40>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_client.py", line 513, in _redirect_url
    url = url.copy_with(host=request.url.host)
          │   │              │       │   └ <property object at 0x73b8fad45490>
          │   │              │       └ URL('http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D%3D')
          │   │              └ <Request('GET', 'http://angular.testsparker.com/test.php?r=data%3A%3Bbase64%2CPD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA%2FPg%3D...
          │   └ <function URL.copy_with at 0x73b8fad02f20>
          └ URL('data:;base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg==')
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_urls.py", line 356, in copy_with
    return URL(self, **kwargs)
           │   │       └ {'host': 'angular.testsparker.com'}
           │   └ URL('data:;base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg==')
           └ <class 'httpx.URL'>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_urls.py", line 119, in __init__
    self._uri_reference = url._uri_reference.copy_with(**kwargs)
    │                     │   │              │           └ {'host': 'angular.testsparker.com'}
    │                     │   │              └ <function ParseResult.copy_with at 0x73b8fad01a80>
    │                     │   └ ParseResult(scheme='data', userinfo='', host='', port=None, path=';base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg==', quer...
    │                     └ URL('data:;base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg==')
    └ <unprintable URL object>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_urlparse.py", line 137, in copy_with
    return urlparse("", **defaults)
           │              └ {'scheme': 'data', 'authority': '', 'path': ';base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg==', 'query': None, 'fragment'...
           └ <function urlparse at 0x73b8fad018a0>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_urlparse.py", line 266, in urlparse
    validate_path(path, has_scheme=has_scheme, has_authority=has_authority)
    │             │                │                         └ True
    │             │                └ True
    │             └ ';base64,PD9waHAgZWNobyAndzRwMXQxJywnX2V2YWwnOyA/Pg=='
    └ <function validate_path at 0x73b8fad020c0>
  File "/home/nico/dev/wapiti/wapiti3/lib/python3.12/site-packages/httpx/_urlparse.py", line 388, in validate_path
    raise InvalidURL("For absolute URLs, path must be empty or begin with '/'")
          └ <class 'httpx.InvalidURL'>

httpx.InvalidURL: For absolute URLs, path must be empty or begin with '/'
Wapiti 3.2.8. httpx 0.27.2. OS linux
Sending crash report 312a540e-b97d-11f0-af81-a002a5038cbb ... SUCCESS

Here we have a payload reflected in the Location header. Unfortunately httpx attemps to validate that header as an URL and crashes.

I made a MR to fix that encode/httpx#3706

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions