This story starts with a head-hunter offering me a job for a major company. No need to say I always screen the employer as I expect they would do to me. If we add the fact that I was a little bored, I ended up finding a 0-day in a WordPress plugin used in one of their servers.
Even not a being security company they take it very seriously. Kudos for their security team as they managed it blazingly fast.
Let’s take a look at this vulnerability found on the plugin ‘Quick Chat’ for WordPress.
SQL Injection 1 (CVE-2018-12535)
Status: still not patched
The plugin is subject to SQL injections through the ajax call quick-chat-ajax-username-check. As we may appreciate in this vulnerable code:
The function like_escape() is not meant to act as security measure against SQL injections. In fact, it only escapes special characters related to the LIKE statement. Even the newer wpdb::esc_like is not safe as stated on the official documentation: “The output is not SQL safe.”
The vulnerable parameter is username_check as we can appreciate on the following POC where the SQL injection is Blind Boolean Based.
Note: if “no_participation” is set to 1, login is required to proceed with the injection.
Even if the best way to mitigate SQL injection is to use wpdb::prepare(), in this case esc_sql() may be used as it escapes values to be included in strings in the query.
On line 399:
$sql = 'SELECT COUNT(*) FROM '.$quick_chat_users_table_name.' WHERE alias like "%' . like_escape($_POST['username_check']) . '";';
$sql = 'SELECT COUNT(*) FROM '.$quick_chat_users_table_name.' WHERE alias like "%' . esc_sql(like_escape($_POST['username_check'])) . '";';
SQL Injection 2 (CVE-2018-12534)
Status: patched on version 4.0
The plugin was subject to SQL injections through the ajax call. This SQLi can be found on the to_delete_ids parameter when using the action quick-chat-ajax-delete.
Proof of concept to get the current database name using an error based technique:
action=quick-chat-ajax-delete&to_delete_ids=666,(select 1 from(select count(*),concat((select (select concat(0x7e,0x27,Hex(cast(database() as char)),0x27,0x7e)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)