WU_DOJO36_YesWeHack(SQLI->Command Injection)

- 7 mins read

DESCRIPTION

In an SQL Injection (SQLi) vulnerability within a Python application, an attacker can manipulate unfiltered user inputs in SQL queries to gain unauthorized access to user accounts and escalate privileges. By compromising an ‘dev’ account, the attacker can then exploit a command injection vulnerability, often found in poorly sanitized functions like os.system or subprocess. This allows arbitrary commands to be executed on the server, leading to full system compromise, access to sensitive files, or remote code execution.

EXPLOITATION

This Python application executes system commands based on the user’s role (either production or pre-production) while applying custom sanitization to prevent command injections. It uses an SQLite database to authenticate users via a token and dynamically renders responses using Jinja2 templates.

Code analysis - Part 1 : Database

You can see here a database sqlite3 connected to the database.db file, then who all users is. (dev;test)
Pasted image 20241015113437 1.png

Code analysis - Part 2 : User privilege

This is a key condition that highlights the “dev” user, a privileged user with additional rights compared to others. If the authenticated user is identified as “dev”, a different sanitation method is applied before executing the command. This user, therefore, becomes a primary target for a SQLi attack, as they receive specific, potentially vulnerable treatments.

Once the command is sanitized, it is executed via subprocess.run, using /bin/ash with the -c option to run a shell command, in this case, a ping: ping -c 1 {cmd_sanitize}. If the command execution is successful (return code 0), the standard output (stdout) is returned; otherwise, the error (stderr) is returned.

Thus, the “dev” user, with their special rights and treatments, becomes a prime target for exploitation.

Pasted image 20241017140027.png

Code analysis - Part 3 : Filter

Pasted image 20241017141024.png

This method applies a standard filter using shlex.quote(), which automatically adds quotes around the string passed as a parameter. This ensures that the string is safe to use in a shell by escaping special characters, thus preventing command injections.
Pasted image 20241015113551.png
This method uses a custom filter to check if the string contains allowed characters via a regular expression (re.search(r'[a-zA-Z_*^@%+=:,./-]', s)). If no dangerous characters are found, the string is returned as-is. Otherwise, the string is:
Encapsulated in single quotes (' + s + ').
Any single quotes within the string are replaced by the safe sequence "'\"'\"'" using s.replace("'", "'\"'\"'").

This process ensures that the string is sanitized, preventing command injection by making sure the shell does not misinterpret single quotes or other characters as part of a command.

Code analysis - Part 4 : Input

Pasted image 20241015113609.png
This code shows two inputs: cmd = unquote("output: ") and token = unquote("token: "). For the cmd input, you can insert a command injection, and for the token input, you can provide an SQL injection to identify the user as “dev”.

Code analysis - Part 5 : SQL token

Pasted image 20241015160343.png

The code executes an SQL query to retrieve a user based on a token, using LIKE: r = cursor.execute('SELECT username FROM users WHERE token LIKE ?', (token,)). The vulnerability arises from the use of LIKE, which allows partial matches. An attacker can inject %d% as a token to match any user with “d” in their token, including privileged users like “dev”. For instance, with %d%, the query becomes: SELECT username FROM users WHERE token LIKE '%d%'. This injection allows the attacker to bypass restrictions and authenticate as a “dev” user, gaining access to privileged functionalities.

payload TOKEN : %d%

POC SQLI user “dev”

Then, you simply need to inject %d% into your input to select the “dev” user from the database, gaining elevated privileges. This allows you to execute a command injection in subsequent steps with higher access rights.
Pasted image 20241015111640.png
Pasted image 20241015162708.png

In SQL, the % symbol is used with the LIKE operator to perform pattern-based searches in strings. For example, if we are looking for the user “dev”, we could use %d%, which would capture any strings containing the letter “d”, regardless of the characters that come before or after it.

POC Command Injection bypass WAF

Initially, I was able to execute a ping because the second input CMD = unquote("0"), triggers the execution of the ping command. By passing “0” as input, it performs a ping to the IP address specified in the CMD. Furthermore, the concept of command injection is to exploit the ability to execute additional commands on the server. For instance, after the ping, it’s possible to inject a Linux command by separating it from the initial one, allowing movement within the server to read the “flag.txt” file.

Pasted image 20241018124104.png
Pasted image 20241018124125.png
Next, I focused on command injection by using a classic separation with “;” followed by “cat flag.txt.” However, this resulted in a “WAF TRIGGERED” message because a regex filter is implemented in the code to block specific characters.
Pasted image 20241018125725.png
Pasted image 20241018125712.png
After examining the regex, I became interested in character encoding, and through a GitHub repository, I discovered that command injection can be done using octal encoding, just like a simple ping detection. So, I explored the octal approach by performing a ping with “0” using {#}, which is a binary conversion that gives “0”, and {##} equals “1”. This allowed me to successfully perform a ping by injecting ${#}, which executed the ping command as expected.

///Note ! : Octal is a base-8 numbering system that uses digits from 0 to 7. Each digit in octal represents three bits in binary. It is commonly used in computing to simplify the representation of file permissions in Unix/Linux systems, or in certain character encoding methods, particularly for command injections or other security exploits.

Pasted image 20241015161905.png
After that, I was able to test command separation using ";" and "$", followed by my payload enclosed in quotes to insert an ls command. This allowed me to check if I could list the files in the directory, which would confirm whether the server is executing my request. I injected the payload ${#};$'\154\163\12' to see if it works.

To complete the process, our payload must include two separators: one for the cat command and another for accessing the file path. This requires using the "$" symbol twice. The command structure would look like ${#};$cat $/tmp/flag.txt, where ${#} handles binary conversion and $ is used to execute the commands. By encoding both the cat command and the file path /tmp/flag.txt in octal, the final payload would look like ${#};$'\143\141\164' $'\057\164\155\160\057\146\154\141\147\056\164\170\164'. This approach allows us to perform command injection while bypassing filters, enabling the server to execute the command and access the contents of the target file.
payload CMD : ${#};$'\143\141\164' $'\057\164\155\160\057\146\154\141\147\056\164\170\164'
Pasted image 20241015111603.png

The FLAG : FLAG{W3lc0me_T0_Th3_Oth3r_S1de!}

Screenshot from 2024-10-15 11-17-14.png
Pasted image 20241015111512.png

RISK

  • Command injection and SQLI (SQL injection) vulnerabilities pose significant security risks to web applications. Command injection allows attackers to bypass input validation and execute system commands on the server, such as accessing sensitive files or gaining control of the system. By exploiting separators like ; or using special encodings, an attacker can inject Linux commands to manipulate the server.

  • SQLI, on the other hand, enables the injection of malicious SQL queries into input fields, granting access to sensitive data or bypassing authentication. By manipulating the LIKE operator with wildcards like %, attackers can retrieve unauthorized information.

These vulnerabilities compromise the integrity, confidentiality, and availability of systems, exposing servers to takeovers or data breaches.

Remediation

To protect against command injection and SQL injection vulnerabilities, we recommend the following actions:

  1. Validate and sanitize user inputs:

    • Always validate user inputs by allowing only expected values (e.g., alphanumeric characters). If possible, use a whitelist to ensure only safe inputs are processed.
    • For SQL, use parameterized queries to prevent user inputs from being directly embedded in SQL commands, stopping SQL injection attacks.
  2. Secure command execution:

    • Avoid directly passing user inputs into system commands. Use functions like shlex.quote to escape inputs properly and prevent command injection.
    • Implement a whitelist of allowed commands to control what can be executed, and avoid shell command execution unless absolutely necessary.
  3. Restrict privileges:

    • Ensure the user executing system commands or accessing the database has the least amount of privileges needed to perform their tasks. This limits the damage in case of an attack.

By applying these steps, you can effectively reduce the risk of both command and SQL injection vulnerabilities.

References

https://owasp.org/www-community/attacks/Command_Injection
https://portswigger.net/web-security/os-command-injection
https://github.com/RodricBr/Bash-Command-Injection
https://owasp.org/www-community/attacks/SQL_Injection
https://sql.sh/cours/where/like