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 bothusername
andpassword
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 aloan_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 aPOST
request.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_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.