Wednesday, 27 September 2023

[Tips & Tricks] Docker FTW. Showing the POC using Docker.

 Using Docker to create your POC

Many times during our pentest engagements, we identified several issues related to the outdated software in used or a non-default misconfiguration that could lead to a significant impact. However, we could not able to create the proof-of-concept (POC) on the environment provided to us due to the following reasons, but not limited to:

  1. We have no direct access to the target as the exploit required access to the host. As an example, local privilege escalation exploit or it is just a host review assessment.
  2. There is a prerequisite in order to ensure the exploit works and we have no visibility on the configuration. As an example, a remote code execution (RCE) when a certain module is enabled.
  3. The customer is concern with the changes that might occur if the exploit is taking place.

The background

In a recent host review assessment we carried out for our first-time customer, we noticed that the host in-scope pretty much well-hardened even though the OS was quite old. From a discussion we had, the host has been repeatedly reviewed every year and it makes sense to see the current state of it looked pretty good.

However, there was something that caught our attention during the review. The kernel.yama.ptrace_scope was found to be set as 0.

At REHACK, we generally utilise several tools to perform the host review assessment. One of them is lynis. The tool identified the misconfiguration of the ptrace_scope:

- kernel.sysrq (exp: 0)       [ OK ]
- kernel.yama.ptrace_scope (exp: 1 2 3)      [ DIFFERENT ]
- net.ipv4.conf.all.accept_redirects (exp: 0)   [ OK ]

This misconfiguration could be neglected if the person conducted the review relies on the automatic scanning results as it does not show the result as a ‘vulnerability’ or similar. Hence, this kind of misconfiguration generally be ignored with the assumption that it is just a ‘best practice’ setting.

A quick Google search led us to these resources:

From the reading, the misconfiguration could allow privilege escalation by injecting process into the sudo tokens. The prerequisite for it to happen:

  • kernel.yama.ptrace_scope = 0
  • low privilege user is in sudoers and has password
  • gdb is enabled

All there requirements were there at time we reviewed the host!

The exploit looked promising at that time hence we informed to the customer. They were quite concern with the outcome of the exploit, hence we need to create our own environment to convince them and their management team.

The options

Now from our experience, we have the following options:

  1. Directly exploit the host > no permission from the customer.
  2. Boot up our virtual machine > possible, but may be time consuming
  3. Boot up from our Digital Ocean > possible, but may be time consuming and have cost
  4. Docker ftw!! > quick, easy to find images and disposable

Docker FTW!

We were glad that previously we had a read about tips and tricks using Docker for pentesters. One of the best reference that we read was from this blog by @ropnop:
https://blog.ropnop.com/docker-for-pentesters/

In the blog, he shared a quick way to find image and run it in an interactive shell. The commands were presented in aliases as the following:

alias dockershell="docker run --rm -i -t --entrypoint=/bin/bash"
alias dockershellsh="docker run --rm -i -t --entrypoint=/bin/sh"

function dockershellhere() {
    dirname=${PWD##*/}
    docker run --rm -it --entrypoint=/bin/bash -v `pwd`:/${dirname} -w /${dirname} "$@"
}
function dockershellshhere() {
    dirname=${PWD##*/}
    docker run --rm -it --entrypoint=/bin/sh -v `pwd`:/${dirname} -w /${dirname} "$@"
}

So, with the above aliases that already included in our shell, we simply located and enabled the Operating System similar to our target which was Ubuntu 18.04.

dockershell ubuntu:18.04

Once downloaded, we verified the version and added a new low privilege user, lowpriv

Next we installed the gdb tool and ensured the misconfiguration was similar.


With all the setup in place, now assuming an attacker able to access to this host as the lowpriv user (potentially via vulnerable application or other ways), the attacker could escalate the privilege into root without knowing the lowpriv's password.

Using the exploit from https://github.com/nongiach/sudo_inject, we demonstrated that to our customer.

Perfect. We got root :)

Explanation

When we showed this to the customer, they quite shocked with it and immediately wanted to plan for an urgent fix. But wait!! We explained to them correctly what actually happened.

The exploit could only works when the attacker could access the shell as the user with sudo access. Other than requiring gdb enabled, another important requirement for it to success is the user must performed the sudo something-something action first as to allow their session be stored temporarily.

At REHACK, we take consideration of the likelihood of the attack to happen before concluding the final risk of the issue. In this case, while the impact looks “Significant”, the likelihood probably “Rare” or “Complex”. We concluded this issue as “Medium”. It was fun considering this issue was previously ignored by the previous tests and we able to highlight the risk to the customer.

By default ptrace_scope is set as 1. We assumed that the setting was previously changed for some purposes which it was not been reverted back to 1. Some other suggestions also have been shared with them and they are happy with the end result.

References:

Bonus

Another issue that was also neglected was the sudo version used on the host. Most of the hosts that we reviewed, if the customers totally rely on their Linux’s package management tool, the sudo on their hosts potentially outdated. Give some times to review the version and see what exploits available for that version :)

Be thorough. RE:HACK.

Share:

Wednesday, 13 September 2023

Introduction to SQL Injection

We noticed that our old post (see here) created by one of the students through the re:educate program was broken. As a result, Alysha, our new team member, gives this topic a fresh perspective. During the course of her research, she will provide more information on SQL Injection in our blog.

Introduction to SQL Injection

Summary
SQL Injection (SQLi) is generally rated as a severe vulnerability in web applications as it allows attackers to execute malicious queries that can compromise both web application and database security. It is one of the oldest and dangerous vulnerabilities.


What is SQL database?
SQL database is a type of relational database management system used for storing and managing data. It utilises SQL language to define, manipulate and query data, organising it into tables composed of rows and columns.


What is SQL?
Structured Query Language (SQL) is a versatile and case-insensitive language for querying databases, commonly used for selecting, inserting, updating and deleting data. While syntax may vary between different databases, this explanation focuses on MySQL.

Assume that we have created a table called staff in the database.

For a better illustration, we can use SQL Fiddle to show the queries and the outputs.

  1. INSERT
    INSERT clause is used to add data into the database.

    Example:
    INSERT INTO staff (username, password) VALUES ('user', 'user123');
    The query inserts a new record into table staff with username user and password user123.

  2. SELECT
    SELECT clause is used to retrieve data from the database.

    Examples:
    SELECT * FROM staff;
    The asterisk * indicates that we request for all data in the table staff.

    SELECT * FROM staff LIMIT 1,2;
    The LIMIT 1,2 clause restricts the database to skip the first row and return just two rows of data.

    SELECT * FROM staff WHERE username != 'vendor';
    The WHERE clause is used to specify specific conditions. The != 'vendor' instructs the database to retrieve data that the username is NOT equal to vendor.

    SELECT * FROM staff WHERE username = 'admin' OR username = 'administrator';
    The OR operator specifies that the data returned must match either admin or administrator.

    SELECT * FROM staff WHERE username = 'rehack' AND password = 'reh4ckisc00l';
    The AND operator specifies that the data returned must match both rehack and reh4ckisc00l.

    SELECT * FROM staff WHERE username LIKE 'v%';
    The LIKE 'v%' clause allows us to retrieve data that starts with the letter 'v'. The % symbol acts as a wildcard, matching any characters.

    SELECT * FROM staffs WHERE username LIKE '%a%';
    The LIKE '%a%' clause allows us to retrieve data containing 'a' in it.

  3. UPDATE
    UPDATE clause is used to modify data in the database.

    Example:
    UPDATE staff SET password = 'isnotmyname' WHERE username = 'user';
    The query updates the password of user to isnotmyname.

  4. DELETE
    DELETE clause is used to remove data from the database.

    Examples:
    DELETE FROM staff WHERE username = 'vendor';
    The query removes a row with username vendor.

    DELETE FROM staff;
    If we omit the WHERE clause, all data in the table will be deleted. Do note that the record count is 0, meaning there are zero data remaining in the table.

  5. UNION
    UNION clause is used to combine data from multiple SELECT queries.

    Example:
    Assume that we have two tables of different departments.

    Table 1 - english

    Table 2 - history

    SELECT staff_name, dept_id FROM english UNION SELECT staff_name, dept_id FROM history;
    The query combines and retrieves staff_name and dept_id from two tables. Do note that there are no duplicate data in the output.


Now that we have covered some SQL basics, let’s explore SQL injection.

What is SQL injection?
SQL injection is a hacking technique in which attackers exploit weak input validation in web applications to inject malicious SQL queries into database. This allows for unauthorised access, data manipulation or data theft, posing a significant threat to application and database security.


What does SQL injection look like?
Let’s explore with a simple SQL injection scenario from PortSwigger Academy.
Resources: PortSwigger: SQL Injection - Login Bypass

Scenario:
SQL injection vulnerability allowing login bypass.

This lab contains a SQL injection vulnerability in the login function.
To solve the lab, perform a SQL injection attack that logs in to the application as the administrator user.

After gaining access to the lab, we will be greeted with an e-commerce website.

To access the login page, click on ‘My Account,’ where we will find the login form.

Considering the vulnerability exists on the login form, we will assume the SQL query used might look like this:
SELECT * FROM users WHERE username = '$username' AND password = '$password';

To bypass the login as administrator, we can inject the username field with administrator' -- and random input for the password field.

After injecting administrator' -- into the username field, the SQL query becomes:
SELECT * FROM users WHERE username = ' administrator' --' AND password = 'random';

In SQL, the -- functions as a comment, causing the rest of queries to be ignored.

As a result, we successfully bypassed the password check with the SQL query:
SELECT * FROM users WHERE username = 'administrator' --

Upon clicking the ‘Login’, observe that we are now login as the administrator.


How to detect SQL injection vulnerabilties?

  1. Error-based testing
    Submit a single quote ' character into input fields or URLs and check for error messages or unusual behavior. If the application mishandles this input, it might be vulnerable to SQL injection. This generally possible when the application enables the debug messages.

    Example:
    Inject ' into URL like http://web.abc/event.php?id=1 and see if there error messages like 'You have an error in your SQL syntax; ~.

  2. Boolean-based testing
    Test Boolean conditions like OR 1=1 and OR 1=2 within input fields and observe any differences in the application’s response. If the application behaves differently for these conditions, it may indicate a potential vulnerability. Do note that, whenever possible avoid using OR 1=1 on sensitive forms such as Login or Reset Password pages. As this may creates unncessary changes in the database if the application is poorly coded. You may use AND 1=1 as an alternative.

    Example:
    Inject 'OR 1=1 -- in a login field and see if it grants access without valid credentials.

  3. Time-based testing
    Submit a payload designed to trigger time delays and monitor the application’s response times for variations. If there are significant delays, it could suggest an SQL injection vulnerability.

    Example:
    Inject SLEEP(5) into the database and see if there’s a delay of 5 seconds before the application responds.


How to prevent from SQL injection?

  1. Prepared statements
    Prepared statements also known as parameterised queries, involving predefined SQL query and adding user inputs as separate parameters. This method safeguards the SQL query’s structure and improves security.

    Example:

    $stmt = $conn -> prepare("INSERT INTO users (username, password, email) VALUES (?, ?, ?)");
    $stmt -> bind_param("sss", $username, $password, $email);
    
    
  2. Escaping user input
    Escaping user input involves adding a backslash () to special characters to treat them as regular strings, preventing them from breaking SQL queries or being used in injection attacks. There are cases where a bypass may exist on a certain condition. Hence, this approach may not very reliable, depending on how the application is coded.

    Example:
    We can use 'mysqli_real_escape_strings' function in PHP to escape any special character.

  3. Input validation
    Input validation restricts user input to predefined values or patterns. An allowlist can be used to only accept specific strings.

    Example:
    We can use filter_var($email, FILTER_VALIDATE_EMAIL) function in PHP to validate e-mail address


References


Author: Alysha from RE:HACK

Share: