IronCTF2024 web/Loan App
My solution for IronCTF2024 web/Loan App challenge
Challenge overview
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 bothusernameandpasswordto 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 aloan_id(a MongoDB ObjectId). The/adminendpoint allow updating the loan status and adding a secret message (the flag). The/admin/loan/<loan_id>route require aPOSTrequest.Admin URL protection
The admin URL can be bypass using URL encoding (%61dmin).
Identifying the vulnerabilities
HAProxy bypass
HAProxy is used to route traffic, but it can be bypassed with%61dmin.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 theloan_idto 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.
