Post

IronCTF2024 web/Loan App

My solution for IronCTF2024 web/Loan App challenge

Challenge overview

Loan App

The Loan App challenge is a web application that allowed users to register, login, and submit loan requests.

Application structure

Flask-based Web Application
The app is build using Flask, interacting with a MongoDB instance via Flask-PyMongo. Key features included registration, login, loan request submission, and an admin approval endpoint.

Key components
Users register using a UUID-based username and password. Credentials are hashed using bcrypt and stored in the MongoDB database. Authenticated users can submit loan requests, which are stored with a “pending” status. An admin endpoint exists (/admin/loan/<loan_id>) to approve loans. Approving a loan added a flag to the loan record.

Analysis

  • Registration and login mechanism
    Registration required both username and password to be valid UUIDv4 strings, and bcrypt is used for hashing. Both credentials are verified during login, and a session is created to manage the user’s login state.

  • Loan request and admin approvals
    After submitting a loan request, an authenticated user receives a loan_id (a MongoDB ObjectId). The /admin endpoint allow updating the loan status and adding a secret message (the flag). The /admin/loan/<loan_id> route require a POST request.

  • Admin URL protection
    The admin URL can be bypass using URL encoding (%61dmin).

Identifying the vulnerabilities

  1. HAProxy bypass
    HAProxy is used to route traffic, but it can be bypassed with %61dmin.

  2. Direct access to Admin endpoint
    The application lack proper authentication or authorization checks on the admin endpoint (/admin/loan/<loan_id>). This allow any user who know the loan_id to directly interact with the endpoint.

Crafting the exploit

Register an account
Use Python’s uuid library to generate valid username and password values:

1
2
3
import uuid
username = str(uuid.uuid4())
password = str(uuid.uuid4())

Register with these credentials to meet the UUIDv4 requirement.

Login and submit loan request
Log in with the registered credentials and submit a loan request to receive a loan_id.

Exploit Admin endpoint
The admin loan approval endpoint can be accessed directly by bypassing HAProxy using a crafted request:

1
curl -X POST http://loanapp.1nf1n1ty.team/%61dmin/loan/OUR_LOAN_ID

Replace OUR_LOAN_ID with the loan_id received in the response from submitting a loan request. Upon successful execution, the response returns “OK”. After refreshing the dashboard we should see the flag.

Flag:ironCTF{L04n_4ppr0v3d_f0r_H4ck3r$!!}

Conclusion

The vulnerability lay in the lack of authentication checks on the admin endpoint. Bypassing the HAProxy routing and crafting a direct curl request led to the approval of the loan and subsequently revealed the flag.

Key takeaways

  • Authorization checks are crucial: Always implement strong authentication and authorization checks on sensitive endpoints, especially those with elevated privileges.
  • Server-side validation: Ensure that all endpoints, especially administrative ones, are protected against unauthorized access.
This post is licensed under CC BY 4.0 by the author.