Congratulations to the CFT Team of TU Delft for winning the SecurityWeek CTF powered by our @LosFuzzys! 💜🍕🏆

The student team joined us for #GSW24 after winning the academic bracket at the #GlacierCTF (hosted by LosFuzzys). Back then, they received the funding to attend our summer school as their prize!

#securitysummerschool #cybersecurity #informationsecurity #technology #tech #engineering #programming #coding #summerschool #ctf

Blocking bad symbols from user input is often done to aid security. Avatar from #glacierctf offers a new example on how to bypass that. Let's write a calculator in Python and pass user input to eval() only allowing these chars:

" ( ) = - + * / > < { } f

Looks safe, right?

It's not. Let's build this from the ground up. We first need some zeros and ones. How about this?

()==()

I am just comparing two empty tuples. That gives me a "True" result ;D Likewise, we can do the following:

()>()

That gives me a "False" result.

Booleans are almost numbers, so let's do some math with them. What's that?

(()==())+(()==())

Just a weird way of encoding the number 2 in Python.

You see where this is going: The first screenshot shows some code to encode each digit with just ( ) = + * > ... cool, right?

There is a cool trick to move from numbers to letters now. Python allows us to format strings with f-strings and there is the {:c} presentation type that converts integers to unicode characters. Here is an example:

f"{100:c}"

That prints the letter with ASCII code 100 "d"

This gives us a method to write arbitrary strings with this minimal set of characters ;) The full write-up explains how we encode our payload, and eventually get a shell without built-in functions. https://sigflag.at/blog/2023/writeup-glacierctf23-avatar/

Write-Up: Avatar from GlacierCTF23 | SIGFLAG

Python sandbox escape with very restrictive whitelist and no built-in functions

SIGFLAG

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/

Bypassing CSP using polyglot JPEGs

James challenged me to see if it was possible to create a polyglot JavaScript/JPEG. Doing so would allow me to bypass CSP on almost any website that hosts user-uploaded images on the same domain. I gl

PortSwigger Research