test1

The Context

Going into the website at 88.198.219.20:26879, you can see that it spits out javascript.

const bodyParser = require("body-parser")
const express = require("express")
const fs = require("fs")
const customhash = require("./customhash")

const app = express()
app.use(bodyParser.json())

const port = 3000
const flag = "flag"
const secret_key = "Y0ure_g01nG_t0_h4v3_t0_go_1nto_h4rdc0r3_h4ck1ng_m0d3"

app.get('/', (req, res) => {
    console.log("[-] Source view")
    res.type("text")
    return fs.readFile("index.js", (err,data) => res.send(data.toString().replace(flag, "flag")))
})

app.post('/getflag', (req, res) => {
    console.log("[-] Getflag post")
    if (!req.body) {return res.send("400")}
    let one = req.body.one
    let two = req.body.two
    console.log(req.body)
    if (!one || !two) {
        return res.send("400")
    }
    if ((one.length !== two.length) || (one === two)) {
        return res.send("Strings are either too different or not different enough")
    }
    one = customhash.hash(secret_key + one)
    two = customhash.hash(secret_key + two)
    if (one == two) {
        console.log("[*] Flag get!")
        return res.send(flag)
    } else {
        return res.send(`${one} did not match ${two}!`)
    }
})

app.listen(port, () => console.log(`Listening on port ${port}`))

The modules:

Looking closer at the code, you can see that it’s importing a module called, body-parser, express, and fs.

  • It looks like fs replaces, the variable, flag with flag.
  • Express is a javascript web framework.
  • Body-Parser is an addon to express

App logic

When the server receives an HTTP GET request, it spits out a file called index.js. That explains why javascript is present when you connect to the CTF. It’s showing the backend code.

On top of that, you can see how the server reacts when it receives a post request at (/getflag). It makes the variables one and two. They both are a property of an object called req.body.

What is req.body.whatever? ()

Looking at the documentation for express.js, you can see that the req.body

“Contains key-value pairs of data submitted in the request body” -ExpressJS

So that means req.body.one/two are like dictionary. They use key-value system.

Key-Value Things?

An HTTP request consists of three things,

  1. Request Type/URL
  2. Header
  3. Body

I spent a couple of hours, thinking the key-value was Headers/Body. Instead, it was talking about JSON. It makes sense because the server was using bodyparser.json.

So what does it do?

In the code, it compares the variables one and two.

if (!one || !two) {
	return res.send("400")
}

In the first if statement, it checks if one and two are false. If so, it returns as a 400. You can guess that it’s making sure that the one and two are there.

if ((one.length !== two.length) || (one === two)) {
	return res.send("Strings are either too different or not different enough")
}

Later in the second if statement, it checks if they are the same length and are ====

What does it mean by one.length? In javascript, a string/array has a property called length. It tells you how many characters in the string there are or it tells you how many items in the array they are.

What does === mean? It checks if they are the same type and the same thing

After the requirement checks, it creates two hashes. Then checks if the two hashes are the same. If they are, it returns the flag. If not, it returns ${one} did not match ${two}!

Problem

The beginning checks are to make sure that the two values were giving arn’t the same. The requirement to getting the flag is that the two hashes need to be the same.

The hashes are made using the two values were giving. If they can’t be the same, how are you supposed to get the flag?

Image of burp proxy to repeater

The Input

I captured a get request in burp and sent it to a repeater. Then I changed it to a post request pointing to /getflag. The message header had a content-type header of JSON. Stuff I did

Failures

Knowing all that, I spent the next few hours trying numbers. I knew that the length property of a number would return undefined. Hence the first requirement. Additionally, they couldn’t be the same if they were technically different types. Like how an integer is different from a float.

The crash

I tried 0.00 and 000. Later I noticed that javascript simplifies floats to decimals. So everything became 0 and was picked up by the if statements. After failing, I tried hexadecimal. Then I got a javascript error. Looking this up, I found out that JSON can’t have hexadecimal. Rather it follows the guidelines on this website(https://www.json.org/json-en.html). That ruled out numbers.

What I should’ve done at this point. I should’ve tried every datatype. Instead, I tried more numbers.

The Solution

The solution.

After a few hours, I came back to the .length property. I thought what else had it. An Array. I quickly came back to burp and put an array as a value for the key one. Then I did the same array for the key two.