Arbitrary Command execution in Privacy Disclaimer page of a very popular organization

I found that ‘security and privacy’ section of this company’s website was vulnerable to command execution. I informed them about this issue and their security team was able to confirm it. They added me to their hall of fame and were able to fix the issue quickly. My overall experience of working with them was very pleasant.

One fine evening, while exploring an organization’s ‘Security and Privacy’ page, I don’t remember how I came across a java stack trace. The last paragraph, after the stack trace caught my attention. It said –
“You are seeing this page because development mode is enabled. To disable this mode, set struts.devmode=false”.

I googled the error message but could not find anything relevant. Then, I searched for “struts dev mode” and somehow, landed at Pwntester’s insightful blog on OGNL Injection via struts dev mode, (as well as a few other links on the command execution capability of the dev mode setting).

OGNL is an expression language for Java which allows getting and setting JavaBeans properties, on the fly (using java reflection). It also allows execution of methods of Java classes.

Struts2 comes with an inbuilt OGNL debug console named as dev mode, to help developers with more verbose logs. This can also be used in testing OGNL expressions. Dev mode is disabled by default. If enabled, this setting uses debugging interceptor and supports four types of debug parameters.

  • debug = console
    (non-intrusive way to confirm if devMode setting is enabled. If enabled, a new window with webconsole will open with a black background which can be used for further OGNL expression testing.)
  • debug = browser
    (non-intrusive way to confirm if devMode is enabled. This will show all properties of the specified object value e.g. debug=browser&object=%23parameters)
  • debug = xml
  • debug = command
    (this is used to execute the intended OGNL payload.)

By using parameter debug=command and passing the specially crafted OGNL payload as ‘expression‘ parameter, a command execution can be achieved. e.g. As shown in the below URL, debug and expression parameters are passed to a Struts Action, HelloWorld.action.

http://<target>/struts2-blank/example/HelloWorld.action?debug=command&expression=1%2b1

Mitigation and Remediation:

Always disable devMode in production. Apache also mentions this in their security tips. Best way is to ensure the following setting is applied to your struts.xml in production:

<constant name ="struts.devMode" value="false" />

While by-default devMode is set to ‘False’, many applications enable this setting in their non-prod environment for verbose logs and forget to disable it when deploying to Prod.

Timeline:
8/26/2018 – Reported the issue to this organization
8/28/2018 – They acknowledged the report and confirmed that it was a valid issue and was not previously reported either internally or externally.
10/08/2018 – They fixed the issue and asked me to validate it.
10/08/2018 – They added me to their security hall of fame list.
05/02/2019 – Draft blog post shared with them
05/03/2019 – Organization said they need time to review it
06/20/2019 – Followed up with the them
06/25/2019 – They wrote that they were still reviewing the post
07/11/2019 – Followed up with the organization, received no response
07/22/2019 – Followed up with the organization, received no response
08/16/2019 – Followed up with the organization, received no response
08/22/2019 – Followed up with the organization, received no response
11/13/2019 – Followed up with the organization, no response from their side
11/16/2019 – Published this post but without any name.

References: 
1) http://www.pwntester.com/blog/2014/01/21/struts-2-devmode-an-ognl-backdoor/
2) https://www.cvedetails.com/cve/cve-2012-0394
3) https://struts.apache.org/security/
3) https://www.rapid7.com/db/modules/exploit/multi/http/struts_dev_mode
4) https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/struts2-development-mode-enabled/
5) https://gist.github.com/mgeeky/5ba0170a5fd0171eb91bc1fd0f2618b7
6) https://issues.apache.org/jira/browse/WW-4348

 

Tale of a Cross-Site Scripting vulnerability in ICICI Bank Website

If you’re teaching reflected cross-site scripting to a newbie, what could be a classic example?

A search page taking search keyword as input and reflecting it back on the result page, along with the search results.

I logged into ICICI Bank website after ages and noticed a new search page on my dashboard. Out of curiosity, I just wanted to check if they were encoding the input properly. I entered a few special characters in the search field and right clicked on the result page to view the HTML source but an alert popped up stating that ‘Due to security reason, right click is not allowed’. It is generally very trivial to bypass such client side restrictions and I don’t think any site needs to do that as a security control.

I just added ‘view-source:’ before the URL and was able to see the generated HTML source. After looking at the HTML source, I worked on the XSS payload and below payload successfully popped up an alert, confirming the presence of Cross-Site Scripting vulnerability.

xxx')</script>alert("XSS")

Timeline:

07/31/2016 – Reported this issue to ICICI’s anti-phishing email and whatever other emails I was able to find. Also shared the screenshot and steps to reproduce the issue.
08/02/2016 – Received a generic reply from their customer care asking for my account details and phone number to help me further.
08/02/2016 – Requested them to forward that email to their IT Security team or to anyone responsible for the IT department.
08/26/2016 – Asked for an acknowledgement or an update. Received a generic email from someone in customer care department.
03/05/2017 – Requested for an update.
01/18/2018 – After some good time, when I logged in to the ICICI site, I noticed that XSS was fixed. Emailed them again to confirm if it was fixed.
01/25/2018 – Received a generic email again from the customer care department asking for my account details and phone number to help me further.
09/21/2019 – As I never received an official response, my understanding is that this issue has been resolved. I’m writing this blog post for the general security awareness of my blog readers.

Popping up an XSS alert via a field which does not accept more than 20 characters

While testing an app, a text field was not accepting more than 20 characters (server side validation). I inserted following piece of code to check XSS (From RSnake’s XSS cheat sheet):

'';!--"<XSS>=&{()}

and verified the HTML source for the encoded characters . As < was in the HTML source,  the input field was seem to be missing output encoding and hence was vulnerable to cross site scripting.

Now, I just needed a popup to conclude this theory. I started looking for a smaller script. I tried to create/find some payloads which were less than 20 characters but I was unable to find anything. At that point of time, a random question came to my mind that, what is the smallest possible payload to pop up an alert. I know it was not needed to prove the XSS or missing output encoding but just a random question.
Here are some possible payloads compiled from my own answer and a few others:

<a href=http://a.by>
<a onclick=alert(2)>
<b onclick=alert(2)>
<script src=//h4k.me

Update (7th March, 2019)- This is very old post and may be obsolete now. I guess as someone replied to that question in 2017, following may be the smallest payload to pop up an alert now. I need to check.

<svg/onload=alert()>