PenLog - Under Construction by HackTheBox

James Fraser · November 5, 2020


Platform: HackTheBox
Difficulty: Medium
Link: Under Construction


Start the challenge instance and download the resource package:


Navigate the browser to http://ip:port/ and enter test as the “Username” and “Password” and click “Register”:

register (Note: My instance was deployed at

Start Burp Suite and configure the browser’s HTTP proxy:

firefox-proxy (Note: My Burp proxy is the default:

With Burp running and intercepting HTTP traffic via the proxy, login to the web app with the registered test account.

“Forward” the initial login request via Burp:


Again, using Burp, send the web app’s redirect request, including the Cookie: session= token to Burp’s “Repeater”:

burp-redirect-request (Note:: Press Ctrl-R to send the request to Burp’s repeater.)

JSON Web Token (JWT)

Perusing the provided expressjs web app’s source code, the above session cookie, or, “token”, is generated and sent as an HTTP redirect response in the route file “routes/index.js”:


The JWTHelper.sign(...) can be traced to the file “helpers/JWTHelper.js” which subsequently includes a requires for jsonwebtoken:


Googling “jsonwebtoken vulnerabilities”, this library is vulnerable to “Authentication Bypass”, as described here.

This vulnerability, known as CVE-2015-9235, describes “JWT HS/RSA key confusion vulnerability” whereby a vulnerable server-side (jsonwebtoken in this case) successfully verifies a token by erroneously:

  1. Expecting “RSA” (public-private key scheme), but instead receiving “HSA256”(symmetric-key scheme); an attacker can easily forge a token with an updated “alg”
  2. Blindly passing the re-purposed public-key as the verification key to the server-side verification method, confusing the known public-key as the verification key for HS256

Copy the JWT token from the session cookie from the request in Burp’s Repeater, and use to decode it. Note the “alg” type “RS256” and that the payload data includes a public key element “pk”:


As shown above, the decoded JWT token’s header designates “RS256” as the algorithm and the payload divulges the server-side public-key - the two requirements for CVE-2015-9235.

Download locally and copy the encoded JWT token from Burp’s repeater to a file for easier management, e.g. “jwt_token_example.txt”. Execute passing in the copied JWT token and registered username “test”:

jwt-forge-keyconfusion-test-1 (Note: I wrote to learn about JWT tokens and solve the “Under Construction” challenge.)

Copy the “forged” token from the terminal output and paste it over the current token in the request in Burp’s Repeater window; send the request to the web app by pressing “Send” and confirm the user is still authenticated as “test”:


SQL Injection (SQLi)

Spending more time reading the source code, there looks to be a simple SQL injection in “helpers/DBHelper.js” which interfaces to an SQLite3 database; the user-supplied input variable ${username} is concatenated with the SQL “SELECT” statement in the DBHelper.getUser(...) helper:


DBHelper.getUser(...), is called via the result of an async call from “middleware/AuthMiddleware.js”’s AuthMiddleware as highlighted in “routes/index.js”:


The provided parameter, susequently passed to the SQLi vulnerability in DBHelper.getUser(...) is the username from the JWT token, extracted as of middleware AuthMiddleware:


Re-forge the last “forged” JWT token using; pass a “UNION” injection to test the SQLi vulnerability:


Again, copy the “forged” JWT token to the same Burp Repeater window and “Send” the request:

union-inject-result (Note: Having the “2” replace “test” as the username - this SQLi is not “blind”.)

With the + Burp Repeater process, inject the follow commands:

SQLite Version

$ python3 $(cat jwt_token_example.txt) \
    "test' and 1=2 UNION SELECT 1,sqlite_version(),3 -- -


Database Table Names

$ python3 $(cat jwt_token_example.txt) \
    "test' and 1=2 UNION SELECT 1,group_concat(tbl_name),3 from sqlite_master -- -"


Database Table SQL

$ python3 $(cat jwt_token_example.txt) \
    "test' and 1=2 UNION SELECT 1,group_concat(sql),3 from sqlite_master -- -"



Perform UNION injection to get the challenge flag and submit!

$ python3 $(cat jwt_token_example.txt) \
    "test' and 1=2 UNION SELECT 1,group_concat(top_secret_flaag),3 from flag_storage -- -"


Twitter, Facebook