Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 50

Executing Multiple SQL Statements with Stacked Queries

Recommended resources

Welcome back. In our previous lesson, we delved into the meticulous process of blind SQL injection, learning how to extract data one character at a time by interpreting subtle application responses or time delays. This method, while powerful, is inherently indirect and laborious. Now, we shift our focus to a far more direct and potentially devastating technique.

This lesson introduces stacked queries. You will learn how, under certain conditions, you can append entirely new SQL commands to a vulnerable query. Instead of just asking questions, you'll be able to issue direct orders to the database, such as UPDATE or DELETE. By the end of this lesson, you will understand the mechanics of stacked queries, the conditions under which they are possible, and how to use them to modify data and escalate privileges within a target application.

From Inference to Direct Command

Stacked queries, also known as batched queries, represent a fundamental shift from the injection types we've covered so far. Instead of manipulating a single query to return extra data (UNION injection) or behave differently (blind injection), this technique involves executing additional, distinct queries. The semicolon (;) acts as a command separator in most SQL dialects, allowing an attacker to terminate the original, legitimate query and start a new one of their own.

To begin, let's establish a clear definition of this attack and see a classic example.

What is Stacked Queries SQL Injection? Attack Explained

This article from Aptive provides a concise and clear explanation of the core concept behind stacked query injection.

Please read the following three parts of the article: Start with the section defining the attack. Next, read how the vulnerability arises from improper input handling. Finally, study the concrete example of a destructive DROP TABLE command. This illustrates the high-impact potential of this technique.


When Can You Stack Queries? Conditions and Limitations

The DROP TABLE example you just saw is severe, but it's important to understand that this attack isn't universally possible. Its success depends heavily on the database technology and the specific API the application uses to interact with it.

Many modern database APIs, for security reasons, only allow a single query to be executed at a time, ignoring anything after the first semicolon. However, some combinations of languages and database drivers still permit multiple statements.

The following resource provides a quick reference for which common database systems support batched queries. More importantly, it highlights a critical limitation you must remember.

SQL injection cheat sheet | Web Security Academy

This cheat sheet from PortSwigger's Web Security Academy provides essential, condensed information on various injection techniques.

In this resource, focus on the section for Batched (or stacked) queries. Pay close attention to two key details: The list of database systems that support this syntax (e.g., Microsoft SQL Server, PostgreSQL). The crucial note that "the results are not returned to the application." This second point is what defines the use case for stacked queries. You cannot use a stacked SELECT statement to see data in the response, as you would with a UNION attack. Therefore, this technique is primarily used for two purposes: Blind Actions: Executing commands that cause a verifiable side effect, like a time delay (WAITFOR DELAY or pg_sleep) to confirm the vulnerability. Destructive/Modifying Actions: Executing "fire-and-forget" commands that alter the state of the database, such as INSERT, UPDATE, or DELETE. Practical Exploitation: A Step-by-Step Account Takeover Now let's move from theory to a practical demonstration. The following video walks through a full attack on a Drupal CMS, from discovery to a complete account takeover, all using stacked queries. Given your background as a security analyst, you'll appreciate the methodical progression. Step 1: Discovering the Vulnerability The first step in any attack is finding a flaw. The presenter begins by probing the application's login form. Instead of a simple ' OR 1=1, they use a more nuanced approach by manipulating the parameter name itself, which reveals a different, more interesting error message.

This second point is what defines the use case for stacked queries. You cannot use a stacked SELECT statement to see data in the response, as you would with a UNION attack. Therefore, this technique is primarily used for two purposes:

  • Blind Actions: Executing commands that cause a verifiable side effect, like a time delay (WAITFOR DELAY or pg_sleep) to confirm the vulnerability.
  • Destructive/Modifying Actions: Executing "fire-and-forget" commands that alter the state of the database, such as INSERT, UPDATE, or DELETE.

Practical Exploitation: A Step-by-Step Account Takeover

Now let's move from theory to a practical demonstration. The following video walks through a full attack on a Drupal CMS, from discovery to a complete account takeover, all using stacked queries. Given your background as a security analyst, you'll appreciate the methodical progression.

Step 1: Discovering the Vulnerability

The first step in any attack is finding a flaw. The presenter begins by probing the application's login form. Instead of a simple ' OR 1=1, they use a more nuanced approach by manipulating the parameter name itself, which reveals a different, more interesting error message.

advanced SQL injection

This first segment from Loi Liang Yang demonstrates how to identify a potential vulnerability that might support stacked queries.

Watch the video from the discovery process. The presenter changes the name parameter in the login form to name[0], effectively sending it as an array. The server responds with an "unexpected error" and a specific "Illegal string offset" message, which is a much stronger indicator of an underlying code-level issue than a generic "wrong password" response.

Step 2: Modifying Page Content

With a potential vulnerability identified, the next step is to confirm it and demonstrate control. Since stacked queries don't return data, a common proof-of-concept is to change something visible on the site.

In this part of the video, the attacker crafts a stacked query payload to inject an UPDATE statement and change the title of a blog post.

advanced SQL injection

This segment shows the first successful exploitation, modifying data in the database.

Watch from where the page title is modified. The payload is constructed by editing the HTML of the login form and looks similar to this: name[0;UPDATE node_revision SET title='hacked by me' WHERE nid=1;-- ] Here's a breakdown: name[... ]: The parameter name that was found to be vulnerable. 0;: A placeholder value followed by the crucial semicolon to terminate the intended query. UPDATE ...;: The malicious SQL statement to change the data. --: A comment to nullify the rest of the original query. The successful change of the page title provides undeniable proof of code execution. Step 3: Escalation to Account Takeover Changing a page title is a good proof-of-concept, but the ultimate goal is often to gain privileged access. This final segment demonstrates how to use the same vulnerability to change a user's password. This is a more complex attack as it requires understanding how the application (Drupal) stores passwords.

Here's a breakdown:

  • name[... ]: The parameter name that was found to be vulnerable.
  • 0;: A placeholder value followed by the crucial semicolon to terminate the intended query.
  • UPDATE ...;: The malicious SQL statement to change the data.
  • --: A comment to nullify the rest of the original query.

The successful change of the page title provides undeniable proof of code execution.

Step 3: Escalation to Account Takeover

Changing a page title is a good proof-of-concept, but the ultimate goal is often to gain privileged access. This final segment demonstrates how to use the same vulnerability to change a user's password. This is a more complex attack as it requires understanding how the application (Drupal) stores passwords.

advanced SQL injection

This final part of the video demonstrates a full account takeover by updating a password hash in the database.

Watch from the password update attack. This attack involves two key phases: Generate a valid hash: The attacker uses a script provided by Drupal (password-hash.sh) to generate a password hash in the correct format. Simply inserting a plaintext password would not work. Inject the UPDATE query: A new payload is crafted to update the pass field in the users table with the newly generated hash.

After the payload is sent, the attacker can log in as the targeted user with the new password, completing the account takeover.


Conclusion

In this lesson, you have learned how to leverage stacked queries to move beyond data retrieval and directly execute arbitrary commands on a vulnerable database. This is a powerful technique that, when available, can be significantly more efficient than blind injection for causing a change in the system's state.

Key Takeaways:

  • Direct Command Execution: Stacked queries use a delimiter (typically ;) to execute one or more additional SQL statements after the original one.
  • No Data Return: The results of these additional queries are not returned to the application. This makes the technique unsuitable for SELECT-based data exfiltration but ideal for actions like UPDATE, INSERT, and DELETE.
  • Dependency on Backend: The viability of stacked query injection is highly dependent on the database management system and the server-side API used to execute queries.
  • High Impact: Successful exploitation can lead to unauthorized data modification, deletion, or, as we saw, complete user account takeover.

So far, our injection payloads have triggered an immediate effect. In our next lesson, we will explore second-order SQL injection, a more subtle and patient attack where a malicious payload is stored in the database and executed at a later time, often in a completely different part of the application.