Peak from #glacierctf was a challenge with three ingredients: (1) An XSS vulnerability, but with (2) a strict CSP that made it impossible to include external JS scripts, and (3) a bullet-proof implementation of an image upload contact form. We hacked it anyway. Read on.
The XSS vulnerability allowed us to post content with <script> tags on that PHP site. But this was the CSP:
Content-Security-Policy: script-src 'self'
So we can't embed an external script that would steal user cookies. But what about uploading a file to their server?
Sadly, the file uploader implementation followed all the best practices: It checked file extensions, it checked MIME type, it gave uploads a new random name, it didn't allow for path traversal attacks, and it even loads the image to see if it can get its dimensions.
We had no clue for hours until we stumbled upon a great article by @gaz from Dec 2016 on bypassing CSP using polyglot JPEGs. We expected that this 7+ year old trick to not work anymore in modern browsers, but it totally did! Thanks Gareth! https://portswigger.net/research/bypassing-csp-using-polyglot-jpegs
Here is the write-up of the full exploit - explaining the XSS vulnerability, the CSP bypass with a JPEG/JS polyglot, stealing browser cookies, and finally exploiting an XXE in the admin panel to read arbitrary files from the victim server: https://sigflag.at/blog/2023/writeup-glacierctf23-peak/
