Skip to content

Latest commit

 

History

History
128 lines (77 loc) · 4.77 KB

README.md

File metadata and controls

128 lines (77 loc) · 4.77 KB

HauntMart

Write-up author: jon-brandy

Lessons Learned:

  • Source Code Review.
  • Bypassing SSRF Filter (filter for localhost IP usage).
  • Execute Server-Side Request Forgery.

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?.

HINT:

  • NONE

STEPS:

  1. In this challenge we're given the source code of the webapp.

WEBAPP

image

  1. 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.
  2. Upon registering an account, we're redirected to /home endpoint.

image

  1. After clicking every available feature, turns out only one feature accessible. The sell product.

image

  1. Interesting! Let's review the source code handling the logic behind this endpoint.

image

  1. The first step involves employing the @isAuthenticated middleware, followed by an endpoint that anticipates a JSON body containing specific keys.
  2. Subsequently, the downloadManual function is invoked, taking the manualUrl value from the JSON body as an argument.
  3. Should this call yield a False result, the request is halted with a status of 400.
  4. 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.
  5. Let's review the @isAuthenticated middleware code.

image

  1. Based from 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.
  2. Next, let's review the downloadManual function.

image

  1. This code, checks whether the url does contain a blocked host, then it returns false. Otherwrise, it makes a request to the specified url.
  2. Let's review the isSafeUrl function.

image

  1. It filtered for localhost, interesting.
  2. 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 /home endpoint.
  3. The /addAdmin endpoint should be our interest.

image

  1. Noticed there is a middleware called --> @isFromLocalhost, which handle that the /addAdmin endpoint is only reachable from localhost request.
  2. However, noticing there is a filter which blocks several localhost form, it's not quite robust. We can easily bypass it using 0.
  3. 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=vreshco

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

image

image

EXECUTION

image

  1. Great! Now logout then login again, our user account shall upgraded to admin.

image

  1. Got the flag!

FLAG

HTB{s5rf_m4d3_m3_w3t_my_p4nts!}