MyBB <= 1.8.31: Remote Code Execution Chain

Author

Web Application Security Expert

MyBB is one seriously popular type of open-source forum software. However, even a popular tool can contain bugs or even bug chains that can lead to the compromise of an entire system. In this article, we’ll go over one such chain that we found.

Visual editor persistent XSS

CVE-2022-43707 (HIGH RISK)

Some time ago, my colleague Igor Sak-Sakovskiy published an article: Fuzzing for XSS via nested parsers condition. In it, he gives multiple examples of XSS attacks, one of which is in MyBB. The payload given by Igor has been fixed by the MyBB team in version 1.8.25. But I didn’t stop there — I went ahead and started fuzzing the fix!

Firstly, a registered user with low privileges edits his signature in the settings. The following payload is inserted into the editor in the “View Source” mode:

[email][email= onpointerover=alert()//]text[/email]
Inserting the payload with xss into a user signature

After updating the signature, the link has a new onpointerover event handler with the value alert();//. When you hover over the rendered text with the mouse cursor, the embedded JavaScript code is executed.

Execution of the embedded javascript code in the user signature when hover over the mouse cursor

Therefore, if a user belonging to the “Moderator” or “Administrator” group enters the profile of the user who implemented the above payload in the signatures section, then, when that user hovers over the rendered text with the mouse cursor, the embedded JavaScript code will also be executed.

Execution of the embedded javascript code when editing the user signature by the administrator when hover over the mouse cursor

ACP User SQL Injection

CVE-2022-43709 (MEDIUM RISK)

A user who is in the “Administrator” group has the ability to perform an SQL Injection when searching for users via Admin CP: /admin/index.php?module=user-users&action=search.

            By default, custom fields are vulnerable to an SQL Injection: Location, Bio, Gender

Custom fields when searching for users

To demonstrate the vulnerability, a search will be performed on the custom Bio field. To do this, a user needs to add text to the custom Bio field in order for the search to return at least one record.

Here the value My biography is added to the custom Bio field for the user who is in the “Administrator” group.

Filling in the custom Bio field

A request is made to search for users by the custom field Bio with the value My biography, which is intercepted using a proxy, for example, BurpSuite.

Search for users by the custom bio field

The user search query is intercepted by the custom Bio field.

The user search request intercepted via proxy

A vulnerable place for an SQL Injection is the key of the profile_fields array.

profile_fields[fid2]=My biography

If you add a single quotation mark after fid2, the server returns the error “HTTP/1.1 503 Service Temporarily Unavailable“.

Adding the single quotation mark to the key of the custom Bio field in the user search request intercepted through a proxy

The SQL Injection occurred due to the fact that the data transmitted from the user is not fully controlled/escaped. The root of the problem is the file admin/modules/user/users.php, namely how the value of the $column variable is handled. The value of this $column variable should either be framed with double quotes or checked for a valid value.

Insufficient escaping of user data leading to a SQL Injection

Due to the lack of checking which values of the $column variable are allowed, it is possible to implement the SQL Injection with the condition that special characters will not be used, which will be escaped by the $db->escape_string method.

' AND '.$db->escape_string($column)."

A payload for the SQL Injection that delays query execution by 5 seconds:

profile_fields[(select pg_sleep(5))::text = $quote$$quote$ and fid2]=My biography

The SQL Injection, which causes the execute SQL query to fall asleep for an additional 5 seconds

Remote code execution via SQL injection

With the help of the SQL Injection found, it is possible to escalate the problem. This will happen if a Database Engine that supports multiple queries is selected when installing MyBB.

During installation, it is necessary to select, for example, PostgreSQL.

When installing the forum engine, the PostgreSQL is selected in the database configuration

When using the PostgreSQL database engine, the SQL Injection found will be executed via the native pg_send_query function in the file inc/db_pgsql.php.

Calling the native function pg_send_query when using the Postgresql

According to the official PHP documentation, the pg_send_query function can execute multiple queries at a time.

The official documentation for the native pg_send_query function

Now let’s talk about how to create and edit templates in MyBB.

The functionality of template editing

The image above shows editing form of the template member_profile_signature.

When creating or editing a template, it is also possible to insert variable values, for example, {$lang→users_signature}, {$memprofile['signature']}.

The template is saved in the database in the mybb_templates table. In this case, the edited template member_profile_signature has tid = 240.

The user signature template stored in the database

In the file member.php, the template member_profile_signature is taken from the database in line 2158 and passed to the eval function.

Executing code on the server using a user signature template

One might think that when creating/editing a template, the construction ";${system('id')} may be injected in the eval function (line 2158 of member.php) and will represent a separate instruction that will also be executed.

However, this is not possible. Before saving the template in the database, the check_template function will be called in admin/modules/style/templates.php on line 536.

When saving a template, the check_template function is called

The purpose of the check_template function is to check the template passed by the user for the presence of structures that allow arbitrary code to be executed in the system through the eval function.

The check_template function is a sandbox that protects against the introduction of dangerous constructions in the template

If the check_template function finds a dangerous construction when checking, it returns true and a saving error occurs.

The result of the check_template function is a security error

If you manage to somehow embed the construction ";${system('id')} into the template, bypassing the check_template function, you will be able to execute arbitrary code on the server.

Now we go back to the SQL Injection found in MyBB, which uses PostgreSQL with the ability to conduct multi-queries. Using single or double quotes during SQL Injection will lead to their escaping:

' AND '.$db->escape_string($column)."

The SQL query that will rewrite the required construct to the member_profile_signature template without using single quotes:

update mybb_templates set template = (select concat((select template from mybb_templates mt  where mt.tid = 240),(select CHR(34)||CHR(59)||CHR(36)||CHR(123)||CHR(115)||CHR(121)||CHR(115)||CHR(116)||CHR(101)||CHR(109)||CHR(40)||CHR(39)||CHR(105)||CHR(100)||CHR(39)||CHR(41)||CHR(125)))) where tid = 240;

Then, the final SQL Injection will have the form that will lead to the execution of arbitrary code in the system.

Executing the SQL Injection in multi query mode, where the second query overwrites the user signature template and injects malicious code

The result will be the execution of the system('id') command.

The RCE on the server via SQL Injection bypassing the template sandbox function

Vulnerability fixes can be found on the official website of MyBB.

To sum up

I’d like to thank the team at MyBB for fixing the vulnerabilities quickly. As for users, I recommend that they update their software as soon as possible.