Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RuntimeError in mod_xxe #483

Open
devl00p opened this issue Aug 12, 2023 · 3 comments
Open

RuntimeError in mod_xxe #483

devl00p opened this issue Aug 12, 2023 · 3 comments

Comments

@devl00p
Copy link
Contributor

devl00p commented Aug 12, 2023

Stumbled into this today:

[*] Launching module xxe
Traceback (most recent call last):
  File "wapitiCore/attack/mod_xxe.py", line 394, in finish
    mutated_request, __, __ = next(mutator.mutate(original_request, [used_payload]))
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "bin/wapiti", line 34, in <module>
    wapiti_asyncio_wrapper()
  File "wapitiCore/main/wapiti.py", line 395, in wapiti_asyncio_wrapper
    asyncio.run(wapiti_main())
  File "/home/devloop/.pyenv/versions/3.9.15/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/home/devloop/.pyenv/versions/3.9.15/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "wapitiCore/main/wapiti.py", line 382, in wapiti_main
    await wap.attack(global_stop_event)
  File "wapitiCore/controller/wapiti.py", line 536, in attack
    await attack_module.finish()
RuntimeError: coroutine raised StopIteration

It looks like the call to next returned nothing while it was expected.

The bug appeared while scanning a Wordpress install with the plugin "addonify-quick-view" but maybe it is possible to spot the bug just by looking at the Wapiti code.

@bretfourbe
Copy link
Collaborator

Is it possible to enter in the else case in finish method where XXEUploadMutator is called even if there is no file_params ?

else:
mutator = XXEUploadMutator(
parameters=[parameter_name],
skip=self.options.get("skipped_parameters")
)
mutated_request, __, __ = next(mutator.mutate(original_request, [used_payload]))

In this specific case, mutate will yield nothing.
def mutate(self, request: Request, payloads: PayloadSource) -> Iterator[Tuple[Request, Parameter, PayloadInfo]]:
get_params = request.get_params
post_params = request.post_params
referer = request.referer
for i in range(len(request.file_params)):
new_params = request.file_params
param_name = new_params[i][0]

@devl00p
Copy link
Contributor Author

devl00p commented Aug 13, 2023

Indeed and XXEUploadMutator is used if the form have the enctype multipart/form-data which can happen even if no file upload field is present.

However if we crashed in finish it looks like something was triggered so an investigation would be helpful.

Let's keep the issue open till we find a way to reproduce

@Darkiros
Copy link
Collaborator

Darkiros commented Sep 7, 2023

I've found a way to reproduce.
It seems happen when you have only one file_params in the request and you put the --skip option on that param.
Then, the for is passed and the yield is never triggered.

for i in range(len(request.file_params)):
new_params = request.file_params
param_name = new_params[i][0]
if self._skip_list and param_name in self._skip_list:
continue
if self._parameters and param_name not in self._parameters:
continue

image

Test done with out of band payloads only and this php file where the calendar input file is vulnerable :

<?php
if (isset($_FILES["calendar"])) {
    libxml_disable_entity_loader(false);
    $dom = new DOMDocument();
    move_uploaded_file($_FILES["calendar"]["tmp_name"], "/dev/shm/wapiti.xml");
    $calendar = file_get_contents("/dev/shm/wapiti.xml");
    $dom->loadXML($calendar, LIBXML_NOENT | LIBXML_DTDLOAD);
    $output = simplexml_import_dom($dom);
    echo "Data loaded.";
} else {
?>
    <form method="POST" enctype="multipart/form-data">
        Please send your xml calendar: <input type="file" name="calendar"/ >
        <input type="submit" value="Submit" />
    </form>
<?php
}
?>

Command : wapiti -u http://127.0.0.1/upload.php -m xxe --skip calendar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants