# WCTF 2020 - thymeleaf

## Challenge

In Nov. 2020, Balsn was invited to participate in WCTF - a CTF event that only invited 10 world’s best CTF teams.

The most special part of this event is that each team needs to design 2 challenges for the other teams.

thymeleaf is a windows challenge designed by r3kapig.

• Type: Web
• Solved: 5/9
• Author: r3kapig

## Solution

### Recon

In the beginning, we found several pages like /login, /swagger-ui.html, /v2/api-docs by dirsearch.

However, the APIs found in /swagger-ui.html could not be used in terms of the lack of permission. After checking, I noticed that the authentication is based on JWT in cookie.

### JWT

JSON Web Token is a signed message to maintain the integrity of the message. That is to say, we trust the message is correct based on the signature of JWT.

Because the content of JWT is just encoded plaintext, we can see the following message after decoding :

Generally, I would not like to try to brute force in an international CTF competition. However, we have no more clue, which forced me to try all the tricks about JWT.

In Founding and Trials, I'd like to share some common JWT tricks.

After brute force, we retrieved the secret of the JWT (admin). Therefore, we can sign all the content we give and access this website with proper permission.

However, for most of the APIs, we can do nothing except to the DELETE /auth/user/someone with special behavior. To be more specific, the server would render the path in the error page when we send the following request:

From this behavior, we learned that we need to reach RCE by SSTI.

### SSTI

After furthermore survey and examination, we found that the server is based on the thymeleaf (same as the name of this challenge).

With the following request, we can reach a simple SSTI.

The response would be like Error resolving template [auth/user/8] .

The next step is to craft a payload without " and '. With payload (0).toString().charAt(0).toChars(105)%5b0%5d.toString() => 'I', we can create strings with no " or ' . Until now, we can reach RCE on the server.

### RCE on Windows

After we can RCE on the server, we didn't obtain the flag immediately. The problem was that the environment was on Windows rather than Linux, and it took a lot of time to check and craft our payload.

We took almost 2 hours in this step and missed the first blood QQQ.

## Founding and Trials

### JWT attacks

JWT is JSON Web Token. It uses a signature to make sure about the integrity of data. Commonly, people use JWT to reach Authentication.

JWT can resolve the sharing problem between multiple backend servers and decrease the cost of storing data on the server-side.

A JWT contains 3 parts:

1. header: records type and algo
2. payload: records the data itself
3. signed: the signature of both of the above data

Here are some common JWT attacks:

1. Brute Force

It just keep trying the possible keys. Though it is not a fancy attack, JWT is a friendly authentication for brute force.

2. alter the algo

Because a server just resigns and compare with the received signature, we can reach forgery the JWT via alternating the algo and making sure that we can sign a valid signed. It is noticeable that the algo we assigned should be supported by the server.

1. none (CVE-2015-9235): with "algo": "none", we don't need any signed.
2. RS256 $\to$ HS256 (CVE-2016-10555): alternating the asymmetric algorithm to symmetric one, we can sign the signed by the public key we have already known.
3. JWKS Injection (CVE-2018-0114):

Some libraries can accept the public key from a client. As a result, we can insert a public key into payload and sign it with the corresponding private key.

4. Null Signature Attack (CVE-2020-28042)

Exploiting the Logic Flaws, when the signed  is null, it could bypass the validation.

5. "kid" Injection

If the server does not properly deal with the kid, it might conduct read files or even SQLi, cmdi attacks.

6. JWKS Spoofing

Editing the jku in the header to a URL that directs to our crafted JWKS file, the server might use the assigned key in JWKS file to validate.