Tips to Prevent Heart Diseases By the Best Cardiologist in Delhi

Heart Disease is one of the common causes of death. There are so many other causes like diabetes, and liver and kidney diseases that can lead to heart diseases. Thus, it’s really important to not…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Arbitrary file read tricks with headless browsers

Last time we’ve set up a test environment to play around with Playwright. This time I would like to give a walkthrough of a few challenges when pushing arbitrary file reads (throughfile://) with headless browsers (screen empty for directory listing, file being downloaded instead of shown).

Although I’m using Playwright it is only one example, it could be Selenium, Puppeteer or any other framework to test apps with headless browsers.

I’m gonna give you a symptom and the solutions which I found (if you have any thoughts on how to improve, please don’t hold yourself back) considering two threat vectors:

So in the previous post you’ve seen how a headless chromium (and actually chrome) is giving an empty screen for file:///. I have to admit that in the heat of a bugbounty I didn’t realize that this was not due to some sophisticated configuration / input validation and that it simply could be resolved by using view-source:file:/// .

Directory listing visible on Chromium with view-source

If input sanitization on the target app is messed up, this can work even when you only control the page to be loaded by playwright. And to be honest when input sanitization allows the file:/// protocol to be used, it most likely will allow view-source:file:/// as well ;)

So when I wanted to get a specific configuration file (let’s call it config.yml) on Chrome I bumped into an empty screenshot again (both directly attempting to access it and through view-source). Although I should’ve thought about it immediately I again needed a few extra local clicks in my browser to realize that Chrome (and for that matter Firefox neither) will not render yaml files by default but will “download” them when opened through file. OK, so what can we do?

If I only had control over the page loaded by playwright I couldn’t find a decent way to overcome this obstacle, however with control over the test specification I just got access to almost all the things a browser can do. Including opening a page with a file upload function.

My first quick & dirty approach was to have a form with a filepicker served through ngrok & python, open that page, pick that config.yml with playwright’s help and submit the form.

The HTML is super simple:

Let’s have something quickly to serve it (no, don’t put anything else into that folder and shut down things as soon as you don’t need them):

And the Playwright test doing the actual file upload:

In this case the screenshot’s results are not too useful (one about the upload page and another one with a 501 error response as the python http.server right now doesn’t handle POST requests, but in ngrok’s web UI we can catch that the contents of the file indeed were sent to us:

Content`s of a local yaml file finally visible

However there are some “files” that can’t be properly retrieved with this super simple html upload due to their content… for example trying to retrieve /proc/net/tcp will leave us with the following error message in the ngrok web UI:

OK… do we really need that POST for every file? It is handy… especially when the other end is not just a stupid ngrok, but actually gathers the files nicely organized based on any additional metadata available. BUT we can also simply use FileReader to actually read the files as text and write them to the DOM (or send them off to ourselves to store & organize it nicely… but that might be a different post about scaling this whole thing up).

So let’s open stackoverflow for the rescue and have a different version for this approach (js-fileread.html):

And a minor tweak on the playwright test itself (no need to actually submit anything):

And here comes /proc/net/tcp as well

As I said, I personally prefer to get that data not as screenshots so this is what I ended up with for handling the file select:

And I removed creating the screenshots from the test spec.

File name and content both nicely visible

Of course there are a ton of ways to further improve this whole thing:

OK, so now we have a decent way to retrieve multiple files reliably. What should you get by default?

I would go with something like this:

And to do a bit of recon on the running processes (bruteforcing the first 100 pids, but ofc you could increase it way more…):

And this would be really just the first step giving some ideas about the environment… I also would create a short Playwright test to gather the directory listing recursively on the whole disk (maybe next time?).

And then the most important part: understand the target by thoroughly analyzing the results and look for anything that might actually contain sensitive information (duh).

As you can see it is absolutely no rocket science to read files when you have a chance to play around with playwright / puppeteer but there are a few issues that need a bit of care and automating all the above can significantly increase your speed on pentests / bugbounties.

Add a comment

Related posts:

Are We As Mankind At The End Of Times?

Time itself is fading, not in a sense of speed but rather a sense of coming to a complete stop. There is no hope for a better future when the corruption of our world has taken a global turn for the…