vBulletin hacked forums: Clean Up Time
Step 4. While forums still closed, it would be a good time to check the extent of the compromise to your vBulletin installs’ files and MySQL database itself. Or you can do Step 9 and restore from backup.
vbplugincheck.sh script
Personally, I like to find out what was compromised before restoring from backups. For VPS or dedicated server users with SSH telnet and root user access to your server, I have written a bash shell script to be able to quickly scan your vBulletin database for potential intrusions or malware embedded into your vBulletin database. The script is called vbplugincheck.sh and was originally written years back just for vBulletin 4 but I have extended it to vBulletin 5 usage as well. The script won’t detect all embedded hacks or malware, but it serves as a good starting point in cleaning up the compromised vBulletin forum. It’s available for download here and assumes you know how to setup a shell script from SSH command line.
mkdir /root/tools cd /root/tools wget -c http://vbtechsupport.com/vbplugincheck/vbplugincheck.sh?nocache -O vbplugincheck.sh chmod 0700 vbplugincheck.sh
Wildcard keyword searches
The script searches for exec, base64, system, pass_thru, iframe functions in common plugin, template, templatehistory, phrase and announcement tables. The search keywords are in wildcard form i.e. %exec%, %base64%, %system% so they results might match against other terms and/or vBulletin itself has valid uses for some of these matched functions. So when I mean potential, the bash shell script will output all matches along with a known list of valid vB matches. Of course you need to check the actual code to be sure as the valid match could have been altered by the hacker. You can of course use manual keyword search for more fine grain control using qkeyword and fkeyword options illustrated further below.
I wrote a bash shell script called phpdfcheck.sh which scans default vBulletin 4.2 and 5.04+ php files for matches against a set of php functions and then lists which php functions are in use. The list output shows valid uses for php functions within vBulletin php files of which some will turn up in vbplugincheck.sh output. So there’s overlap and false positives.
For vB 4.2.1 output of phpdfcheck.sh :
./phpdfcheck.sh --------------------------------------------------- Count number of PHP Files: 1128 Count number of PHP disable_functions listed: 50 --------------------------------------------------- searching PHP files at home/username/public_html/vb421 for disable_functions in use as outlined in script DF variable ... --------------------------------------------------- --------------------------------------------------- PHP disable_functions to check for: system passthru exec popen proc_close proc_get_status proc_nice proc_open proc_terminate highlight_file escapeshellcmd define_syslog_variables posix_uname posix_getpwuid apache_child_terminate posix_kill posix_mkfifo posix_setpgid posix_setsid posix_setuid escapeshellarg posix_uname ftp_exec ftp_connect ftp_login ftp_get ftp_put ftp_nb_fput ftp_raw ftp_rawlist ini_alter ini_restore inject_code syslog openlog define_syslog_variables apache_setenv mysql_pconnect eval phpAds_XmlRpc phpAds_remoteInfo phpAds_xmlrpcEncode phpAds_xmlrpcDecode xmlrpc_entity_decode fp fput shell_exec mail chmod pclose chmod in use escapeshellcmd in use eval in use exec in use fp in use fput in use mail in use mysql_pconnect in use passthru in use shell_exec in use system in use search completed in 46.097250725 seconds
For vB 5.0.4 output of phpdfcheck.sh :
./phpdfcheck.sh --------------------------------------------------- Count number of PHP Files: 1930 Count number of PHP disable_functions listed: 50 --------------------------------------------------- searching PHP files at /home/username/public_html/504 for disable_functions in use as outlined in script DF variable ... --------------------------------------------------- --------------------------------------------------- PHP disable_functions to check for: system passthru exec popen proc_close proc_get_status proc_nice proc_open proc_terminate highlight_file escapeshellcmd define_syslog_variables posix_uname posix_getpwuid apache_child_terminate posix_kill posix_mkfifo posix_setpgid posix_setsid posix_setuid escapeshellarg posix_uname ftp_exec ftp_connect ftp_login ftp_get ftp_put ftp_nb_fput ftp_raw ftp_rawlist ini_alter ini_restore inject_code syslog openlog define_syslog_variables apache_setenv mysql_pconnect eval phpAds_XmlRpc phpAds_remoteInfo phpAds_xmlrpcEncode phpAds_xmlrpcDecode xmlrpc_entity_decode fp fput shell_exec mail chmod pclose chmod in use escapeshellcmd in use eval in use exec in use fp in use fput in use mail in use mysql_pconnect in use openlog in use passthru in use pclose in use popen in use proc_close in use proc_get_status in use proc_open in use shell_exec in use syslog in use system in use search completed in 106.167788862 seconds
Comparing databases against 2nd fresh install copy
To check against valid matches and uses, I suggest you install a 2nd dummy test vBulletin forum of same version as your live compromised vBulletin version. Then you can run this bash shell script against both compromised live vB forum and the 2nd fresh dummy test vB forum. Save output to text files and then you can compare the output of the two runs and work from there. You can use file comparison tools such as BeyondCompare.
vbplugincheck.sh explained
The script is only run via SSH telnet as root user so only applies to VPS or dedicated hosting users. There are a few variables you need to edit in vbplugincheck.sh for the script to work. They have their own brief explanations inline already but I’ll explain them below:
VBVERSION='4' # for vB 4.x or enter '5' for vB 5.x # your mysql server hostname set # in vB config.php # $config['MasterServer']['servername'] = MYSQLHOST='localhost' # mysql username/password MYSQLUSER='yourmysqlusername' MYSQLPASS='yourmysqlpassword' # your database name # vB config.php # $config['Database']['dbname'] = DBNAME='vbdatabasename' # if you set table prefix in vB config.php # $config['Database']['tableprefix'] = DBPREFIX=''
- VBVERSION – set this to 4 or 5 depending on your vBulletin major version i.e. If vB 4.2.1 then set to 4. If vB 5.0.5 then set to 5.
- MYSQLHOST – same as servername in your vB config.php leave at localhost if MySQL is on same server. Only change to IP address if your MySQL server is remotely hosted
- MYSQLUSER – your vBulletin database’s MySQL username
- MYSQLPASS – your vBulletin database’s MySQL username password
- DBNAME – your vBulletin database name
- DBPREFIX – same as tableprefix set in vB config.php. Only needs changing if you set a prefix in your vB config.php
When you run the script at command line without any options, you will get a list of options that are available:
./vbplugincheck.sh
./vbplugincheck.sh quick ./vbplugincheck.sh full ./vbplugincheck.sh quick {dbname} {dbprefix} ./vbplugincheck.sh full {dbname} {dbprefix} ./vbplugincheck.sh adminlogfull ./vbplugincheck.sh adminloguser ./vbplugincheck.sh adminlogtemp ./vbplugincheck.sh adminlogactions ./vbplugincheck.sh adminlogfull {dbname} {dbprefix} ./vbplugincheck.sh adminloguser {dbname} {dbprefix} ./vbplugincheck.sh adminlogtemp {dbname} {dbprefix} ./vbplugincheck.sh adminlogactions {dbname} {dbprefix} ./vbplugincheck.sh qkeyword ./vbplugincheck.sh fkeyword ./vbplugincheck.sh qkeyword {dbname} {dbprefix} ./vbplugincheck.sh fkeyword {dbname} {dbprefix} ./vbplugincheck.sh tempcheck ./vbplugincheck.sh temphistcheck ./vbplugincheck.sh tempcheck {dbname} {dbprefix} ./vbplugincheck.sh temphistcheck {dbname} {dbprefix} ./vbplugincheck.sh usertitle ./vbplugincheck.sh ads ./vbplugincheck.sh usertitle {dbname} {dbprefix} ./vbplugincheck.sh ads {dbname} {dbprefix} ./vbplugincheck.sh ranks ./vbplugincheck.sh ranks {dbname} {dbprefix} ./vbplugincheck.sh setting ./vbplugincheck.sh setting {dbname} {dbprefix} ./vbplugincheck.sh pluginlist ./vbplugincheck.sh pluginlist {dbname} {dbprefix}
Options explained:
Some options can also pass database name and database table prefix on command line if you want to check other vBulletin databases on the server (provided the MySQL username and password you entered into vbplugincheck.sh have permissions to access the other database names). If you don’t have table prefix set, just leave off the {dbprefix} from command line.
./vbplugincheck.sh quick (summary format output of plugin, template, announcement & phrase table matches) ./vbplugincheck.sh full (full format output of plugin, template, announcement & phrase table matches) ./vbplugincheck.sh quick {dbname} {dbprefix} (similar to above except you can specify database name) ./vbplugincheck.sh full {dbname} {dbprefix} (similar to above except you can specify database name) ./vbplugincheck.sh adminlogfull (output full adminlog with human readable dateline) ./vbplugincheck.sh adminloguser (output filter on user.php adminlog human readable dateline) ./vbplugincheck.sh adminlogtemp (output filter on template.php adminlog human readable dateline) ./vbplugincheck.sh adminlogactions (output filter on specific actions i.e. edit, insert, add, modify) ./vbplugincheck.sh adminlogfull {dbname} {dbprefix} ./vbplugincheck.sh adminloguser {dbname} {dbprefix} ./vbplugincheck.sh adminlogtemp {dbname} {dbprefix} ./vbplugincheck.sh adminlogactions {dbname} {dbprefix} ./vbplugincheck.sh qkeyword (manual prompt for search term you enter yourself output quick summary format) ./vbplugincheck.sh fkeyword (manual prompt for search term you enter yourself output full format) ./vbplugincheck.sh qkeyword {dbname} {dbprefix} ./vbplugincheck.sh fkeyword {dbname} {dbprefix} ./vbplugincheck.sh tempcheck {dbname} {dbprefix} (list template table entries by dateline) ./vbplugincheck.sh temphistcheck {dbname} {dbprefix} (list templatehistory table entries by dateline) ./vbplugincheck.sh$ usertitle (list usertitles check for malicious code) ./vbplugincheck.sh$ ads (list ad html snippets check for malicious code) ./vbplugincheck.sh$ usertitle {dbname} {dbprefix} ./vbplugincheck.sh$ ads {dbname} {dbprefix} ./vbplugincheck.sh ranks (list user rank code for html code in ranking field) ./vbplugincheck.sh ranks {dbname} {dbprefix} ./vbplugincheck.sh setting (check setting table value field for code ie. %script% for js scripts) ./vbplugincheck.sh setting {dbname} {dbprefix} ./vbplugincheck.sh pluginlist (output pluginlist code content fully or filtered on keyword at prompt) ./vbplugincheck.sh pluginlist {dbname} {dbprefix}
Output samples:
adminlogactions
For adminlogactions option run against vB 4 database named. The output filters the adminlog table entries by action field for edit, modify, insert, update, add etc and then outputs the log entries with human readable dateline timestamps. Output shows the following fields:
- adminlogid
- userid
- dataline
- script
- action
- extrainfo
- ip addresss
You can use this output as a starting point to see what admin level user actions were logged and by which userid and at what time and the ip address etc. So if you see actions against user.php, template.php, phrase.php, notice.php and announcement.php files, you can look more carefully at the quick option output further below to check against the relevant tables.
./vbplugincheck.sh adminlogactions vb422a1 adminlogid: 12 userid: 1 [Sat Aug 31 10:57:52 2013] script: user.php action: modify extrainfo: [ user id = 2 ] ip: 111.222.333.444 adminlogid: 13 userid: 1 [Sat Aug 31 10:59:51 2013] script: user.php action: modify extrainfo: [ user id = 2 ] ip: 111.222.333.444 adminlogid: 14 userid: 1 [Sat Aug 31 11:00:41 2013] script: user.php action: edit extrainfo: [ user id = 2 ] ip: 111.222.333.444 adminlogid: 15 userid: 1 [Sun Sep 1 16:33:35 2013] script: template.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 16 userid: 1 [Sun Sep 1 16:33:39 2013] script: template.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 17 userid: 1 [Sun Sep 1 16:33:44 2013] script: template.php action: add extrainfo: [ style id = 1 ] ip: 111.222.333.444 adminlogid: 31 userid: 1 [Tue Sep 10 03:13:45 2013] script: cronadmin.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 34 userid: 1 [Fri Sep 20 13:47:39 2013] script: template.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 35 userid: 1 [Fri Sep 20 13:47:47 2013] script: template.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 36 userid: 1 [Fri Sep 20 13:47:52 2013] script: template.php action: add extrainfo: [ style id = 1 ] ip: 111.222.333.444 adminlogid: 37 userid: 1 [Fri Sep 20 13:47:56 2013] script: template.php action: inserttemplate extrainfo: [ style id = 1 ] ip: 111.222.333.444 adminlogid: 38 userid: 1 [Fri Sep 20 13:47:57 2013] script: template.php action: edit extrainfo: [ style id = 0 ] ip: 111.222.333.444 adminlogid: 39 userid: 1 [Fri Sep 20 16:22:30 2013] script: announcement.php action: add extrainfo: [ ] ip: 111.222.333.444 adminlogid: 40 userid: 1 [Fri Sep 20 16:22:44 2013] script: announcement.php action: update extrainfo: [ ] ip: 111.222.333.444 adminlogid: 42 userid: 1 [Fri Sep 20 16:22:50 2013] script: notice.php action: add extrainfo: [ ] ip: 111.222.333.444 adminlogid: 43 userid: 1 [Fri Sep 20 16:23:06 2013] script: notice.php action: update extrainfo: [ ] ip: 111.222.333.444 adminlogid: 50 userid: 1 [Fri Sep 20 16:37:28 2013] script: notice.php action: update extrainfo: [ notice id = 2 ] ip: 111.222.333.444 adminlogid: 53 userid: 1 [Fri Sep 20 16:58:43 2013] script: phrase.php action: modify extrainfo: [ ] ip: 111.222.333.444 adminlogid: 56 userid: 1 [Fri Sep 20 16:59:03 2013] script: phrase.php action: edit extrainfo: [ ] ip: 111.222.333.444
Update: Thought this additional insight would be beneficial to others in the same predicament. Working on one private client’s forums for this where it’s complicated by the fact there are multiple legit administrators and moderators populating the adminlog and there were multiple new administrator user accounts created by the hacker. Fortunately, the moderators were quick to stop the hackers’ administrator accounts from doing much damage and they demoted those new administrator accounts down to normal registered users ASAP.
I was then brought in to clean up the mess. But there was no actual exact record of which usernames and userids were demoted amongst a very actively moderated 120K registered member base vB forum. There were 100s of adminlog entries from various admins and moderators. So tracking down the exact usernames and userids for new users created by the hacker needed a bit more work.
I can find which new administrator accounts were setup if I exclude all known admin and moderator userids (i.e. 1, 2 and 3) from output and filter for whole of 2013 year on vB adminlog and just extract the adminlog’s userids and then lookup the vB database’s user table. Below is an example output where the result showed a new administrator username (username126000) with userid of 126000 was created.
The exact command I used ultilising vbplugincheck.sh script for initial adminlog filtering – replace userids 1, 2, 3 with whatever are your known admin and moderator’s userids and where VBDATABASENAME is the vB database name. Replace mysqlusername with your database’s MySQL username and when prompted enter your MySQL username’s password.
for u in $(./vbplugincheck.sh adminlogactions | grep ' 2013' | egrep -v 'userid: 1|userid: 2|userid: 3' | awk -F ' ' '{print $4}' | sort -u); do echo; echo "adminlog userid: $u"; mysql -u mysqlusername -p -e "SELECT userid, username, email FROM user WHERE userid =${u}\G" VBDATABASENAME; done
Resulting output sample:
adminlog userid: 126000 *************************** 1. row *************************** userid: 126000 username: username126000 email: hackers@emailaddy
Then check if any other user accounts were created with that same email address:
define("DISABLE_HOOKS", true); |
This brought back another 8 new user accounts the hacker had created who originally had administrator usergroup permissions. It’s interesting to note that there was also a 9th user account that was probably a separate hacker’s work about a week prior to this hack. That hacker inserted a malicious plugin which was detected by vbplugincheck.sh tool. But due to moderator’s quick reflexes (prior to me starting on this cleanup), these 8 user accounts had already been demoted back to regular registered users so they didn’t actually turn up any entries in adminlog.
Then you can filter adminlog on userids i.e. 126000 to check for their logged IP addresses
./vbplugincheck.sh adminlogactions | grep ' 2013' | grep '126000'
Then filter adminlog by IP address in adminlog to find all their actions to see what they did i.e. plugin.php, template.php, announcement.php and user.php actions were made.
./vbplugincheck.sh adminlogactions | grep ' 2013' | grep '111.222.333.444'
quick option
For quick option run against vB 4 database named vb422a1. The output while it may seem is quite long is actually a quick summary only. If you use full option, it’s much more verbose !.
- The output first lists all usually valid matches for known vB uses for exec, base64, system, pass_thru, iframe functions in common plugin, template, phrase and announcement tables.
- Then it lists all matches it finds with basic identifiable titles or names.
- If you find unknown or not valid entries, then use the identifiable titles or names to dig deeper into the file or plugin names reported. If you find unknown code, then delete the plugin and/or revert the template or phrases. This is where having a full MySQL database backup of the compromised forums in step 0, comes in handy as if you delete something that shouldn’t be deleted, you can restore to previous compromised state and redo the clean up steps again.
To save quick option output to text file called quickoutput.txt for later comparison type the following. You will find a the text file in same directory as your vbplugincheck.sh script:
./vbplugincheck.sh quick vb422a1 > quickoutput.txt
Note: I removed some of the output below to keep it shorter.
./vbplugincheck.sh quick vb422a1 --------------------------------------------------------------------- %iframe% match should only be in the following templates: --------------------------------------------------------------------- bbcode_video editor-ie.css help_bbcodes humanverify_recaptcha member.css search_common search_common_select_type stylegenerator.css vbcms.css vbulletin.css --------------------------------------------------------------------- --------------------------------------------------------------------- %exec% match should only be in the phrase table varname: --------------------------------------------------------------------- varname: task_blog_cleanup_desc varname: task_blog_pending_desc varname: task_blog_views_desc varname: blog_search_executed varname: widgettype_vbcms_execphp varname: skimlinks_time_limit_note varname: cronadmin_add_edit_active_text varname: diagnostic_text varname: misc_text --------------------------------------------------------------------- --------------------------------------------------------------------- %system% match should only be in the phrase table varname: --------------------------------------------------------------------- varname: blog_admin_tags_tagtext_text varname: options_options_vbblog_tagging_text varname: vbblog_faq varname: convert_blog_attachments_desc varname: featured_entries_warning varname: setting_vbblog_tagcloud_searchhistory_desc varname: setting_vbblog_tagging_desc varname: no_edit_permissions varname: cannot_add_cms --------------------------------------------------------------------- --------------------------------------------------------------------- %iframe% match should only be in the phrase table varname: --------------------------------------------------------------------- fakeobjects.iframe iframe.noUrl iframe.title iframe.toolbar --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for base64 code --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for exec() --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for system() --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for pass_thru() --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for iframe --------------------------------------------------------------------- --------------------------------------------------------------------- check templates for base64 code --------------------------------------------------------------------- --------------------------------------------------------------------- check templates for exec() --------------------------------------------------------------------- templateid: 967 styleid: -1 title: WHOSONLINE templateid: 1018 styleid: -1 title: STANDARD_REDIRECT templateid: 1308 styleid: -2 title: STANDARD_REDIRECT --------------------------------------------------------------------- check templates for system() --------------------------------------------------------------------- templateid: 527 styleid: -1 title: editor_jsoptions_font templateid: 546 styleid: -1 title: FORUMDISPLAY templateid: 550 styleid: -1 title: FORUMHOME templateid: 661 styleid: -1 title: modifyoptions --------------------------------------------------------------------- check templates for pass_thru() --------------------------------------------------------------------- --------------------------------------------------------------------- check templates for iframe --------------------------------------------------------------------- templateid: 1 styleid: -10 title: bbcode_video templateid: 2 styleid: -20 title: bbcode_video templateid: 168 styleid: -1 title: vbcms.css templateid: 477 styleid: -1 title: bbcode_video templateid: 1030 styleid: -1 title: stylegenerator.css templateid: 1054 styleid: -1 title: member.css templateid: 1082 styleid: -2 title: bbcode_video --------------------------------------------------------------------- check templatehistory for base64 code --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for exec() --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for system() --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for pass_thru() --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for iframe --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for base64 code --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for exec() --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for system() --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for pass_thru() --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for iframe --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase table for base64 code --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase tables for exec() --------------------------------------------------------------------- phraseid: 323 languageid: -1 varname: task_blog_cleanup_desc username: freddie dateline: 1178750196 --------------------------------------------------------------------- check phrase tables for system() --------------------------------------------------------------------- phraseid: 95 languageid: -1 varname: blog_admin_tags_tagtext_text username: freddie dateline: 1211320354 --------------------------------------------------------------------- check phrase tables for pass_thru() --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase tables for iframe --------------------------------------------------------------------- phraseid: 6338 languageid: -1 varname: fakeobjects.iframe username: vBulletin Solutions dateline: 1299264962 phraseid: 6417 languageid: -1 varname: iframe.noUrl username: vBulletin Solutions dateline: 1299264962 phraseid: 6419 languageid: -1 varname: iframe.title username: vBulletin Solutions dateline: 1299264962 phraseid: 6420 languageid: -1 varname: iframe.toolbar username: vBulletin Solutions dateline: 1299264962
Rather than match against generic wildcard searches, you can use qkeyword and fkeyword options. Below is example of manual keyword search for %exec(% instead. You could also search for words %refresh etc in case hackers embed refresh command in templates to redirect visitors to malicious web sites.
qkeyword for quick summary output
./vbplugincheck.sh qkeyword vb422a1 Enter keyword to search for i.e. %refresh or %base64% : %exec(% --------------------------------------------------------------------- check templates for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase table for %exec(% code --------------------------------------------------------------------- phraseid: 8793 languageid: -1 varname: php_error_exec_disabled username: vBulletin Solutions dateline: 1212055432 phraseid: 8794 languageid: -1 varname: php_error_unspecified_exec username: vBulletin Solutions dateline: 1212055457 --------------------------------------------------------------------- check plugins for %exec(% code ---------------------------------------------------------------------
fkeyword for full output
./vbplugincheck.sh fkeyword vb422a1 Enter keyword to search for i.e. %refresh or %base64% : %exec(% --------------------------------------------------------------------- check templates for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for %exec(% code --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase table for %exec(% code --------------------------------------------------------------------- *************************** 1. row *************************** phraseid: 8793 languageid: -1 varname: php_error_exec_disabled fieldname: error text: PHP Error: The function exec() has been disabled. product: vbulletin username: vBulletin Solutions dateline: 1212055432 version: 3.7.2 *************************** 2. row *************************** phraseid: 8794 languageid: -1 varname: php_error_unspecified_exec fieldname: error text: PHP Error: Unspecified error in exec(). product: vbulletin username: vBulletin Solutions dateline: 1212055457 version: 3.7.2 --------------------------------------------------------------------- check plugins for %exec(% code ---------------------------------------------------------------------
Here’s a sample from a hacked vB forum with malicious plugin at init_startup hookname reported by qkeyword option when i did a search for %base64%. Checking AdminCP > Plugins & Products > Plugin Manager for the entry definitely showed hacker inserted base64 code.
You can use fkeyword option (./vbplugincheck.sh fkeyword) and search on %base64% to get the actual phpcode output for what the hacker inserted as well.
./vbplugincheck.sh qkeyword Enter keyword to search for i.e. %refresh or %base64% : %base64% --------------------------------------------------------------------- check templates for %base64% code --------------------------------------------------------------------- --------------------------------------------------------------------- check templatehistory for %base64% code --------------------------------------------------------------------- --------------------------------------------------------------------- check announcement tables for %base64% code --------------------------------------------------------------------- --------------------------------------------------------------------- check phrase table for %base64% code --------------------------------------------------------------------- --------------------------------------------------------------------- check plugins for %base64% code --------------------------------------------------------------------- title: vBulletin hookname: init_startup product: vbulletin
If you are saving vbplugincheck.sh output to text files, you can run a check against infected MySQL database and save output. Then run a check against a known clean MySQL database restored backup and then using file comparison tool such as BeyondCompare mentioned above to visually see any differences. You will see something similar to this screenshot where left side has infected MySQL database’s output compared side by side with clean MySQL database’s output.
Using tempcheck and temphistcheck options to output entries from vBulletin template and templatehistory tables ordered by dateline, so you can check to see which templateid or templatehistoryid, styleid, title, username and date of modifications. Note for some templates, vB system my auto regenerate them and they would be listed without a username. For instance bbcode_video titled template as opposed to user edited template which have username attached. In below example username eva2000 edited the header template.
./vbplugincheck.sh tempcheck vb422a1 --------------------------------------------------------------------- Show template table data ordered by dateline --------------------------------------------------------------------- templateid: 2 styleid: -20 title: bbcode_video username: [Sat Aug 31 08:51:57 2013] templateid: 1 styleid: -10 title: bbcode_video username: [Sat Aug 31 08:51:57 2013] templateid: 477 styleid: -1 title: bbcode_video username: [Sat Aug 31 08:53:21 2013] templateid: 1082 styleid: -2 title: bbcode_video username: [Sat Aug 31 08:53:21 2013] templateid: 1314 styleid: 1 title: header username: eva2000 [Fri Sep 20 20:12:32 2013]
In below example username eva2000 saved header template history with comment editted header.
./vbplugincheck.sh temphistcheck vb422a1 --------------------------------------------------------------------- Show templatehistory table data ordered by dateline --------------------------------------------------------------------- templatehistoryid: 1 styleid: 1 title: header username: eva2000 [Fri Sep 20 20:12:32 2013] comment: editted header
Again you can save output to text file again
./vbplugincheck.sh tempcheck vb422a1 > templateoutput.txt
./vbplugincheck.sh temphistcheck vb422a1 > templatehistoryoutput.txt
Checking your usergroup’s usertitle table for malicious html code embedded via the usertitle option. Below I altered the Senior Member title and added an exclamation mark ! as an example.
./vbplugincheck.sh usertitle vb422a1 +-------------+----------+-----------------+ | usertitleid | minposts | title | +-------------+----------+-----------------+ | 1 | 0 | Junior Member | | 2 | 30 | Member | | 3 | 100 | Senior Member ! | +-------------+----------+-----------------+
Check your ad table for managing ads for altered or additional malicious html code in your advertising html snippets. Here I added a test ad titled ‘test ad‘ with snippet of html code. Normally you should see your advertising banner code snippets, check to make sure they are correct for your advertisements.
./vbplugincheck.sh ads vb422a1 *************************** 1. row *************************** adid: 1 title: test ad adlocation: global_below_navbar displayorder: 10 active: 1 snippet: html code
Check user ranks table for malicious html code in ranking field via ranks option. Here I added a new rank with html code text Noob.
./vbplugincheck.sh ranks vb422a1 *************************** 1. row *************************** rankid: 1 minposts: 10 ranklevel: 1 rankimg: Noob usergroupid: 0 type: 1 stack: 0 display: 0
Check vB setting table’s value field for unwanted code i.e. embedded js script %script%. This option prompts for a keyword to search for. In below example looking for < script >
tags embedded in value field i.e. Forum Name I added < script >
to the field in AdminCP. Use wildcard %script% as keyword. (Thanks Lynne for heads up on table to check)
./vbplugincheck.sh setting vb422a1 Enter keyword to search for i.e. %script% or %refresh : %script% --------------------------------------------------------------------- check setting tables value for %script% --------------------------------------------------------------------- varname: bbtitle grouptitle: address value: vB 4.2.2 PHP 5.4 Test Forums<script> defaultvalue: vBulletin Forums displayorder: 10
Check pluginlist field contents for vB datastore table for malicious or hidden code. When pluginlist option is run, you get prompted if you want to filter output code by keyword search (select y) or full unfiltered output (select n). Below example filter on keyword preg_replace commonly used as part of the code for malware (source) or use keywords like %base64%.
./vbplugincheck.sh pluginlist vb422a1 Do you want to do a filtered keyword search [y] or full output of pluginlist [n] ? : y Enter keyword to search for i.e. %base64% or %preg_replace% : preg_replace