ffuf / ffuf

Fast web fuzzer written in Go
MIT License
12.52k stars 1.29k forks source link

Parsing error in "-mode sniper"; "&" character is getting replaced by letter "Z" #579

Closed mchlstr closed 1 year ago

mchlstr commented 2 years ago

Hi team,

When running the latest (v1.5.0) ffuf, I encountered the following issue.

I am not used to the go language, but I think that an issue lies in the parser. Explicitly while the code is trying to execute this feature as mentioned PR #469:

An array of requests is returned by SniperRequests, with one location specified by the user replaced by FUZZ in each request.

What is happening is that when substituting any but the last parameter & character is getting replaced by Z.

To showcase, I prepared a simple payload file as a word list:

$ cat payloads.txt
payload1
payload2
payload3
$ ffuf -w ./payloads.txt -u "http://127.0.0.1:8000/file?id=§a§&sort=§b§&test=§c§" -mode sniper

And following are the logs from my local web server.

::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=payload2Zsort=b&test=c HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=payload3Zsort=b&test=c HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=payload1Zsort=b&test=c HTTP/1.1" 200 -

::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=payload3Ztest=c HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=payload2Ztest=c HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=payload1Ztest=c HTTP/1.1" 200 -

::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=b&test=payload1 HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=b&test=payload3 HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:01:34] "GET /file?id=a&sort=b&test=payload2 HTTP/1.1" 200 -

As you can see file?id=§a§&sort=§b§&test=§c§ got replaced by file?id=payload2Zsort=b&test=c, making the request invalid.

I also tried an example mentioned by @denandz in Add Sniper Mode #469; however, the result remains the same. It worked better, but the replace mechanism replaced the] character with Z.

$ ffuf -w payloads.txt -u "http://127.0.0.1:8000/file?feature=§aaa§&thingie=§bbb§&array[§0§]=§baz§" --mode sniper

::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=payload1&thingie=bbb&array[0]=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=payload3&thingie=bbb&array[0]=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=payload2&thingie=bbb&array[0]=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=payload1&array[0]=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=payload3&array[0]=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=payload2&array[0]=baz HTTP/1.1" 200 -

::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[payload1Z=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[payload2Z=baz HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[payload3Z=baz HTTP/1.1" 200 -

::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[0]=payload1 HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[0]=payload2 HTTP/1.1" 200 -
::ffff:127.0.0.1 - - [13/Aug/2022 15:02:33] "GET /file?feature=aaa&thingie=bbb&array[0]=payload3 HTTP/1.1" 200 -

I hope it will be fixed because I use ffuf regularly and find sniper integration an ingenious idea.

Thanks and good work!!

denandz commented 2 years ago

Good catch, I think we may be hitting a rune parsing issue in injectKeyword. Thanks for providing test cases, have replicated locally. Will take a look

denandz commented 2 years ago

Got it, the issue was with any single-character payload location between the section signs and the silly string slice logic. Have moved to a dedicated output slice, added in some tests, and opened the PR for the fix.

With the fix:

./ffuf -w ./payloads.txt -u "http://127.0.0.1:8000/file?id=§a§&sort=§b§&test=§c§" -mode sniper
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=payload3&sort=b&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=payload1&sort=b&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=payload2&sort=b&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=payload1&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=payload2&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=payload3&test=c HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=b&test=payload3 HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=b&test=payload2 HTTP/1.1" 404 -
127.0.0.1 - - [14/Aug/2022 11:55:43] code 404, message File not found
127.0.0.1 - - [14/Aug/2022 11:55:43] "GET /file?id=a&sort=b&test=payload1 HTTP/1.1" 404 -
mchlstr commented 2 years ago

Hey Dol!

Thank you for reacting so fast and for working on issue. Glad that it was such a easy fix. And looking forward to test this super handy sniper mode!

Best,