Trustwave SpiderLabs Uncovers Unique Cybersecurity Risks in Today's Tech Landscape. Learn More

Trustwave SpiderLabs Uncovers Unique Cybersecurity Risks in Today's Tech Landscape. Learn More

Services
Capture
Managed Detection & Response

Eliminate active threats with 24/7 threat detection, investigation, and response.

twi-managed-portal-color
Co-Managed SOC (SIEM)

Maximize your SIEM investment, stop alert fatigue, and enhance your team with hybrid security operations support.

twi-briefcase-color-svg
Advisory & Diagnostics

Advance your cybersecurity program and get expert guidance where you need it most.

tw-laptop-data
Penetration Testing

Test your physical locations and IT infrastructure to shore up weaknesses before exploitation.

twi-database-color-svg
Database Security

Prevent unauthorized access and exceed compliance requirements.

twi-email-color-svg
Email Security

Stop email threats others miss and secure your organization against the #1 ransomware attack vector.

tw-officer
Digital Forensics & Incident Response

Prepare for the inevitable with 24/7 global breach response in-region and available on-site.

tw-network
Firewall & Technology Management

Mitigate risk of a cyberattack with 24/7 incident and health monitoring and the latest threat intelligence.

Solutions
BY TOPIC
Microsoft Exchange Server Attacks
Stay protected against emerging threats
Rapidly Secure New Environments
Security for rapid response situations
Securing the Cloud
Safely navigate and stay protected
Securing the IoT Landscape
Test, monitor and secure network objects
Why Trustwave
About Us
Awards and Accolades
Trustwave SpiderLabs Team
Trustwave Fusion Security Operations Platform
Trustwave Security Colony
Partners
Technology Alliance Partners
Key alliances who align and support our ecosystem of security offerings
Trustwave PartnerOne Program
Join forces with Trustwave to protect against the most advance cybersecurity threats
SpiderLabs Blog

Reducing web application attack surface

For as long as companies rely on web sites to do business with their customers and partners, attackers will keep targeting these web applications searching for new (and old) vulnerabilities and trying to exploit them. Reducing the attack surface has been a good practice for quite some time, hardening applications and web servers usually accomplishes this. In this blogpost we are presenting a Hmac-Based protocol that can be implemented in order to reduce the attack surface with minimum impact to the users and zero changes on the web application itself. Basically, the proposed method consists in parsing HTTP Response data sent by the web application server and signing HTML elements of this response before it is sent back to the client browser, from that point on, the integrity of the communication between the client and the web application will be checked using the protected Request Header or Request Body fields. With this mechanism, no modifications are allowed during a new HTTP Request using the signed elements, reducing quite a number of known web application attacks.

The recent version of ModSecurity 2.7 has some interesting new features that allow people to protect initially a few web resources :

<a href=value_protected> </a>

<frame src=value_protected> </frame>

<iframe src=value_protected> </iframe>

<form action=value_protected> </form>

Location Response Header

Also it is possible to protect additional resources like "inputhidden fields" using the @rsub operator and Lua. We will show how can you use it later in this post.

For both methods content injection and stream variables must be enabled. Just add the following directives in your main configuration file:

SecContentInjection On

SecStreamOutBodyInspection On

SecDisableBackendCompression On

We are not presenting here all possibilities to use this new feature. Please check the ModSecurity reference manual available in www.modsecurity.org for additional information.

Method #1: Built-in Directives

For the first method we are going to use some new built-in Modsecurity directives. Below we have a few ones to protect "href" elements as an example.

For this demonstration we have a sample html file containing an href element

10543_8e97e38d-80df-439f-93c7-c926a5f8a3e8Figure 1. HTML file with unprotected href.

Let's turn on the authentication

SecEncryptionEngine On #Encryption engine is enabled

SecEncryptionParam "hmac" #Modsecurity will add a new hmac parameter

SecEncryptionKey "rand" "KeyOnly" #Modsecurity will for us a password

SecEncryptionMethodrx "HashHref" "product_id" #Let's protect href Fields that contains the word product_id

11413_b7bf2f96-e03e-46c3-b3f0-2d89b9fdda2eFigure 2. HTML file with protected href.

This is still not enough, attackers can still manipulate it. So we need to enforce the HMAC token. Enforcement means:

- HMAC token is present ?

- HMAC value is correct ?

To accomplish that we need to create a SecRule within a new operator, protecting the REQUEST_URI containing "product_id" word.

SecRule REQUEST_URI "@validateEncryption product_id" "phase:2,id:1001,deny"

11542_be1564de-ea1b-4625-9bff-158ad6cd6435Figure 3. Injecting code into protected href.

In this example we tried to inject a code into a parameter, since the HMAC didn't match ModSecurity blocked it.

 

Method #2 : Rsub operator + Lua

For the second method we are going to use the rsub ModSecurity operator + Lua scripts. This possibility was first demonstrated by Josh Zlatin. Some portions of the scripts were based on Josh's work.

The HMAC algorithm used into our scripts for this example is written in pure Lua and can downloaded from : http://regex.info/code/sha1.lua.

For this demonstration we have a sample html file containing a hidden field we want to protect its value

10700_953a116c-2c41-4406-961c-ca11f6ef0630Figure 4. HTML file with unprotected hidden field.

Let's turn on the authentication

SecRule RESPONSE_BODY "name=\"price\" value=\"([\d]+)" "phase:4,chain,id:125,pass,capture,exec:/etc/modsecurity/CreateHMAC.lua"

SecRule STREAM_OUTPUT_BODY "@rsub s/name=\"price\" value=\"[\d]+\">/name=\"price\" value=\"%{TX.1}\"><input type=\"hidden\" name=\"priceHmac\" value=\"%{TX.priceHmac}\">|00|/d"

This is a chain of rules. The first rule will capture the value we want to protect, then store it into a TX variable used by the CreateHMAC script that compute the hmac value and store it into a new variable called TX.priceHmac. The second rule will replace the response body inserting a new hidden field called priceHmac.

BSL_8377_26740385-d3c0-48cb-882c-35dd4b7f18deFigure 5. HTML file with protected hidden field.

As described in method we also need to enforce the protected fields:

SecRule &ARGS:price "@ge 1" "phase:2,id:1000,t:none,chain,deny,log,msg:'Missing priceHmac parameter'"

SecRule &ARGS:priceHmac "!@ge 1"

SecRule &ARGS:price "@ge 1" "phase:2,id:1001,t:none,chain,nolog,exec:/etc/ modsecurity/VerifyHMAC.lua"

SecRule &ARGS:priceHmac "@ge 1"

SecRule &TX:block "@gt 0" "phase:2,id:1002,log,msg:'Invalid HMAC submitted',deny"

The first chain of rules consists of checking the presence of hmac hidden field if the price parameter is present. The second chain of rules checks the hmac value itself. The last rule work together with the last chain, if the hmac value doesn't match a variable TX.block is set and ModSecurity will deny the transaction.

10821_9b5b8f65-5bf3-448b-b68f-066b38c2a5acFigure 6. Injecting code into protected hidden field.

HackMe Test

Now let's evaluate this feature against a real vulnerable web application. To do this we select a "HackMe" like app and setup ModSecurity in front of it as a proxy.

We executed some tests against www.webscantest.com using WebSecurity Scanner. The tests were executed twice, before enabling encryption features and after it.

Below we provide all configuration options and rules we used to protect the WebScanTest page:

SecEncryptionEngine On

SecEncryptionParam "hmac"

SecEncryptionKey "rand" "IpAddress"

SecEncryptionMethodpm "HashHref" "search_get_by_name search_get_by_id redir blockedbyns aboutyou2 search_by_id search_by_name rfplaces search_single_by_name search_double_by_name"

SecEncryptionMethodpm "HashFormAction" "aboutyou2 search_by_id search_by_name rfplaces search_single_by_name search_double_by_name"

SecRule REQUEST_URI "@validateEncryption search_get_by_name|search_get_by_id|redir|blockedbyns|aboutyou2|search_by_id|search_by_name|rfplaces|search_single_by_name|search_double_by_name" "phase:1,id:1,deny"

SecRule RESPONSE_BODY "name=\"id\" value=\"([\d]+)" "phase:4,chain,id:2,pass,capture,exec:/etc/apache2/modsecurity/CreateHMACid.lua"
SecRule STREAM_OUTPUT_BODY "@rsub s/name=\"id\" value=\"[\d]+\">/name=\"id\" value=\"%{TX.1}\"><input type=\"hidden\" name=\"idHmac\" value=\"%{TX.IdHmac}\">|00|/d"

SecRule &ARGS:id "@ge 1" "phase:2,id:3,t:none,chain,nolog,exec:/etc/apache2/modsecurity/VerifyHMACid.lua"
SecRule &ARGS:idHmac "@ge 1"

SecRule &ARGS:id "@ge 1" "phase:2,id:4,t:none,chain,deny,log,msg:'Missing IdHmac parameter'"
SecRule &ARGS:idHmac "!@ge 1"

SecRule &TX:block "@gt 0" "phase:2,id:5,log,msg:'Invalid HMAC submitted',deny,status:403"

SecRule RESPONSE_BODY "name=\"name\" value=\"([a-zA-Z]+)" "phase:4,chain,id:6,pass,capture,exec:/etc/apache2/modsecurity/CreateHMACname.lua"
SecRule STREAM_OUTPUT_BODY "@rsub s/name=\"name\" value=\"[a-zA-Z]+\">/name=\"name\" value=\"%{TX.1}\"><input type=\"hidden\" name=\"nameHmac\" value=\"%{TX.nameHmac}\">|00|/d"

SecRule &ARGS:name "@ge 1" "phase:2,id:7,t:none,chain,nolog,exec:/etc/apache2/modsecurity/VerifyHMACname.lua"
SecRule &ARGS:nameHmac "@ge 1"

SecRule &ARGS:name "@ge 1" "phase:2,id:8,t:none,chain,deny,log,msg:'Missing nameHmac parameter'"
SecRule &ARGS:nameHmac "!@ge 1"

SecRule &TX:block "@gt 0" "phase:2,id:9,log,msg:'Invalid HMAC submitted',deny,status:403"

11014_a441a065-5a03-4081-94b6-46361da35673Figure 7. Result from security scanning.

We can conclude from the report that at least this new feature was be able to add a good layer of protection, with a few rules and directives.

We hadn't success to eliminate all XSS vulnerabilities because the case present into http://www.webscantest.com/crosstraining/aboutyou2.php url is an input type without pre-defined value:

<form method="POST" name="xsswideopen2">

Tell us a little about yourself<br/><br/>

<input type="hidden" name="returnto" value="aboutyou2.php" />

First Name: <input name="fname"><br/>

Nick Name: <textarea name="nick"></textarea><br/>

Last Name: <input name="lname"><br/>

<input type="submit" name="submit" value="submit" />

</form>

It's important to mention that no rules were enabled, except the encryption ones.

Protocol Limitations

The Idea described on this post has some limitations. There are situations you cannot use it for protection:

- Client-side generated resources (ie: URLs).

- Input fields or resources without a value.

- Still cannot protect cookies.

That being said, we do not expect that this feature alone will solve all problems because by design it cannot do that. However we know it can be used as a extra security layer to reduce the attack surface.

Conclusion

In this research, we developed a new security feature for ModSecurity Web Application Firewall, which the goal is to reduce the attack surface of a web application, by authentication and data checking integrity of HTML input vectors.

The implementation experience, described during this post, in a vulnerable environment demonstrated how simple it was to add this new feature to protect almost an entire web application with a few options and rules.

Finally, the performed security tests gave us an idea of how efficient the solution is, reducing the vulnerability detection and attacks, even if the attacker happens to use bypassing methods, like code obfuscation.

Resources

CreateHmac.lua

#!/usr/bin/lua

require "Hmac"

function main()
local id = m.getvar("TX.1", "none");
local secret = "MyPassword";
hmac = hmac_sha1(secret,id);
m.setvar("TX.priceHmac", hmac);
return 1;
end

VerifyHmac.lua

!/usr/bin/lua

require "Hmac"
function main()
local price = m.getvars("ARGS.price", "none");
local pricehmac = m.getvars("ARGS.priceHmac", "none");
local secret = "MyPassword";

if price ~= null then
for i = 1, #price do
for i = 1, #pricehmac do
hmac = hmac_sha1(secret, price[i].value);
m.log(3, "Price: " .. price[i].value .. " hmac: " .. hmac .." priceHmac: " .. pricehmac[i].value);
if hmac ~= pricehmac[i].value then
m.setvar("TX.block", 1);
end
end
end
end
return 0;

CreateHMACid.lua

#!/usr/bin/lua

require "Hmac"

function main()
local id = m.getvar("TX.1", "none");
local secret = "MyPassword";
hmac = hmac_sha1(secret,id);
m.log(3, "ID: " .. id);
m.setvar("TX.IdHmac", hmac);
return 1;
end

VerifyHMACid.lua

#!/usr/bin/lua

require "Hmac"

function main()
local id = m.getvars("ARGS.id", "none");
local idhmac = m.getvars("ARGS.idHmac", "none");
local secret = "MyPassword";
if id ~= null then
for i = 1, #id do
for i = 1, #idhmac do
hmac = hmac_sha1(secret, id[i].value);
m.log(3, "ID: " .. id[i].value .. " hmac: " .. hmac .. " IdHmac: " .. idhmac[i].value);
if hmac ~= idhmac[i].value then
m.setvar("TX.block", 1);
end
end
end
end
return 0;
end

CreateHMACname.lua

#!/usr/bin/lua

require "Hmac"

function main()
local name = m.getvar("TX.1", "none");
local secret = "MyPassword";
hmac = hmac_sha1(secret,name);
m.log(3, "Name: " .. name);
m.setvar("TX.nameHmac", hmac);
return 1
end

VerifyHMACname.lua

#!/usr/bin/lua

require "Hmac"

function main()
local name = m.getvars("ARGS.name", "none");
local namehmac = m.getvars("ARGS.nameHmac", "none");
local secret = "MyPassword";

if name ~= null then
for i = 1, #name do
for i = 1, #namehmac do
hmac = hmac_sha1(secret, name[i].value);
m.log(3, "Name: " .. name[i].value .. " hmac: " .. hmac .." NameHmac: " .. namehmac[i].value);
if hmac ~= namehmac[i].value then
m.setvar("TX.block", 1);
end
end
end
end
return 0;
end

Latest SpiderLabs Blogs

Why We Should Probably Stop Visually Verifying Checksums

Hello there! Thanks for stopping by. Let me get straight into it and start things off with what a checksum is to be inclusive of all audiences here, from Wikipedia [1]:

Read More

Agent Tesla's New Ride: The Rise of a Novel Loader

Malware loaders, critical for deploying malware, enable threat actors to deliver and execute malicious payloads, facilitating criminal activities like data theft and ransomware. Utilizing advanced...

Read More

Evaluating Your Security Posture: Security Assessment Basics

This is Part 4 in my ongoing project to cover 30 cybersecurity topics in 30 weekly blog posts. The full series can be found here.

Read More