2020 ddctf web check-in problem solution

Solution of Web check-in problem in DDCTF in 2020. (web 🐶 Only work out this problem. I have something to do the next day)

web check in question

Step 1: JWT bypass

Figure 1: accident conditions given by the title.

Send a request to the api and get the following response. The data format of data is similar to jwt, which is guessed to be bypassed by jwt.

	"code": 0,
	"message": "success",
	"data": 		"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6InN0ciIsInB3ZCI6InN0ciIsInVzZXJSb2xlIjoiR1VFU1QiLCJleHAiOjE1OTkyODY0NzB9.z-i_zjudu5yejiFbCnE9P5NIjOJE61Bzpw75OX1SHmg"

I only did the problem bypassed by JWT once, and I had a bad habit of taking notes at that time, which I had long forgotten. So I first inquired about the relevant principles and basic steps of JWT, and briefly guided that the vulnerability can be attacked in five ways. Consider starting with the simplest brute force cracking key and using Junay boss blog Recommended tool Try to blast out the password as str (different people may have different passwords), and then go to https://jwt.io/ Forge jwt, send the forged jwt to auth interface and get the client download link.

Figure 2: password obtained by blasting

Step 2: reverse bypass client

After obtaining the client, other leaders in the team will conduct reverse analysis and make tools to simulate the client.

# -*- coding: utf-8 -*-
from base64 import b64encode
import hmac
import hashlib
from time import time
import requests
import json
from pprint import pprint

while True:
    cmd = input()  # Commands sent

    appkey = "DDCTFWithYou"
    time_stamp = str(int(time()))
    strToSign = cmd + '|' + time_stamp

    # hmac_sha256 encryption
    sha = hmac.new(
        bytes(appkey, encoding='utf-8'),
        bytes(strToSign, encoding='utf-8'),
    sign = bytes.decode(

    # Initiate POST request
    url = ""
    data = {
        "signature": sign,
        "command": cmd,
        "timestamp": time_stamp
    res = requests.post(

Step 3: command execution

Judge the back-end language and construct payload. First, use the operators of the language to test whether it is executed, summarize which operators exist, and then test the string. You can use the length function to guess that the language may be an "object-oriented language", from the logical operator= And the length function guess may be Java derived language (enter the command to # define the variable, which can be tested with #a=1)—— ****Groovy**** , but it never matches perfectly. Finally in an article Blog Find a breakthrough point. Many scenarios in the article are in line with the topic. Test Java lang.String. class. When forname ("Java. Lang. runtime"), command is evil appears, and it is determined to be Groovy. So we began to look for Java command injection code, Most commands on the Internet are executed Most of them use the Runtime class or Processbuider class, but they are in the form of multiple lines of code, exploit of CVE-2015-1427 It cannot be executed. There is only one line command for online naming. We guess that it can be echoed in the way of garbled code, then decoded locally, and then automatically complete from IDEA to find the readAllBytes function to read out the data. Then decode the read data with Base64 to get the result of command execution.

Figure 3: programming language classification

code: some key tests

1 == true
#a = 1
'12 '.trim()
new ProcessBuilder("ls").start().getInputStream().readAllBytes()

Figure 4: reading data using readAllBytes

Use base64 to unlock the read data.

If there is an error 🙅, Welcome to correct. you share rose get fun.

Welcome to My blog , I will post some thoughts on my study and life on my blog.

Tags: security Information Security

Posted by ego0 on Tue, 17 May 2022 16:51:44 +0300