HauntMart
HauntMart
Platform: HackTheBox | Category: Web | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
HauntMart, a beloved Halloween webstore, has fallen victim to a curse, bringing its products to life. You must explore its ghostly webpages, and break the enchantment before Halloween night. Can you save Spooky Surprises from its supernatural woes?.
Solution Approach
Core idea: Source Code Review. Bypassing SSRF Filter (filter for localhost IP usage).
Steps
-
In this challenge we're given the source code of the web application.
-
Noticed there's a register option, hence the objective is to not bypass the login page or achieved admin role with bypassing the DB logic.
-
Upon registering an account, we're redirected to
/homeendpoint. -
After clicking every available feature, turns out only one feature accessible. The sell product.
-
Interesting! let us review the source code handling the logic behind this endpoint.
-
The first step involves employing the @isAuthenticated middleware, followed by an endpoint that anticipates a JSON body containing specific keys.
-
Subsequently, the
downloadManualfunction is invoked, taking the manualUrl value from the JSON body as an argument. -
Should this call yield a False result, the request is halted with a status of 400.
-
Conversely, if it returns True, the addProduct function is triggered, accepting parameters such as name, description, and price. Upon successful execution of this function, the request is terminated satisfactorily.
-
Let us review the
@isAuthenticatedmiddleware code. -
Based on the code, the middleware checks if a session token exists. If it does, it verifies it and passes the user information to the decorated function. If it does not exist, it returns a 401 HTTP error indicating unauthorized access.
-
Next, let us review the
downloadManualfunction. -
This code, checks whether the url does contain a blocked host, then it returns false. Otherwrise, it makes a request to the specified url.
-
Let us review the
isSafeUrlfunction. -
It filtered for localhost, interesting.
-
Reviewing the other code, found a code that to make an admin user and seems the flag shall rendered if our role is admin. The flag itself shall rendered at the
/homeendpoint. -
The
/addAdminendpoint should be our interest. -
Noticed there is a middleware called -->
@isFromLocalhost, which handle that the/addAdminendpoint is only reachable from localhost request. -
However, noticing there is a filter which blocks several localhost form, it's not quite robust. We can easily bypass it using
0. -
Seems now we're clear, the objective for this challenge is to do Server-Side Request Forgery.
Manual URL:
http://0:1337/api/addAdmin?username=D3v0o0Nu11
NOTES:
- Remember to use port 1337, based from the Dockerfile, that port is reachable.
Also the run.py code specified that the port for localhost is 1337.
- WHY adding /api/ at the manual URL? Because /addAdmin endpoint is one of api.route.
api = Blueprint('api', __name__)
...
...
...
@api.route('/addAdmin', methods=['GET'])
@isFromLocalhost
def addAdmin():
username = request.args.get('username')
if not username:
return response('Invalid username'), 400
result = makeUserAdmin(username)
if result:
return response('User updated!')
return response('Invalid username'), 400
EXECUTION
-
Now logout then login again, our user account shall upgraded to admin.
-
Got the flag!
Flag
REDACTED
Lessons Learned
- Source Code Review.
- Bypassing SSRF Filter (filter for localhost IP usage).
- Execute Server-Side Request Forgery.