xmendez / wfuzz

Web application fuzzer
http://wfuzz.io
GNU General Public License v2.0
5.86k stars 1.35k forks source link

Accessing and overwriting arbitrary attributes #359

Open Abdulrah33m opened 9 months ago

Abdulrah33m commented 9 months ago

Issue template

Context

Please check:

Please describe your local environment:

Wfuzz version: Output of wfuzz --version 3.1.0 Python version: Output of python --version Python 3.11.6 OS: Ubuntu 23.10

Report

What is the current behavior?

Wfuzz --filter, --prefilter and --efield options do not perform enough validation on the user's input, which allows us to recursively get and set attributes of various objects that are accessible from the original objects/filters. This is due to rsetattr and rgetattr functions of obj_dyn.py relying on regex to validate the user's input which still can be leveraged to access various attributes and objects that shouldn't be accessible. We can leverage Python special attributes such as __base__, __class__, __globals__, etc. to disclose information (locally) or result in unexpected behavior.

What is the expected or desired behavior?

While this shows a very limited attack vector since this runs locally, Wfuzz should use a white-list approach to prevent accessing arbitrary objects and attributes.

Please provide steps to reproduce, including exact wfuzz command executed and output:

There are different ways we can leverage this, either by using --filter and --prefilter to set attributes of an object or --efield to access arbitrary attributes.

Accessing __globals__ attribute:

abdulrah33m@ubuntu:~$ wfuzz -z range,0-0 --efield "r.__init__.__globals__" https://www.google.com/FUZZ
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://www.google.com/FUZZ
Total requests: 1

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                 
=====================================================================

000000001:   404        11 L     72 W       1558 Ch     "0 | {'__name__': 'wfuzz.fuzzrequest', '__doc__': None, '__package__': 'wfuzz', '__loader__': <_frozen_importlib_externa
                                                        l.SourceFileLoader object at 0x7f125720ba50>, '__spec__': ModuleSpec(name='wfuzz.fuzzrequest', loader=<_frozen_importlib
                                                        _external.SourceFileLoader object at 0x7f125720ba50>, 
<REDACTED>

Manipulating the actual URL using --prefilter option:

abdulrah33m@ubuntu:~$ wfuzz -z list,blahblah --prefilter "r._request.completeUrl:='https://github.com'" --efield "r.url" https://www.google.com/FUZZ
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://www.google.com/FUZZ
Total requests: 1

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                 
=====================================================================

000000001:   301        0 L      0 W        0 Ch        "blahblah | https://github.com/"                                                                                        

Total time: 0.118809
Processed Requests: 1
Filtered Requests: 0
Requests/sec.: 8.416854

Other relevant information:

During my recent research Prototype Pollution in Python, I was looking for open-source projects that allow users to recursively get/set attributes of Python objects to show real-case scenarios for how this attack might exist. This is when I came across rsetattr and rgetattr functions and how they allow us to manipulate objects.