WHMCS uses Smarty for it's template system, though a great template system it has a flaw, the {php}
tags. These tags allow smarty to interpret PHP code directly in the template, or in this case through the ticket system when a new ticket is created. This hack happens all the time to WHMCS systems, you can try blocking the code in WHMCS through block text option in configuration. But most of the time this doesn't work.
What happens is that WHMCS accepts the ticket and the hacker added the following to the ticket message:
{php}eval(base64_decode(encoded message));{\php}
So smarty sees the {php}
part and immediately let's PHP run that command. So it first decodes the PHP encoded in base64. This will bring out some PHP function/script that the hacker is trying to run.
Then eval takes over and actually evaluates the PHP code and runs it on server side.
A lot of hackers get in this way, they run codes that they know will work in WHMCS that then grab Database information and echo it to a file. Then they just grab this file through the browser URL and get the information they wanted.
This works on only some WHMCS install's, though WHMCS says that the most recent version doesn't allow this and {php} is disabled in Smarty, at times the hacker's do find a way to get around that and eval
their code.
This is actually a very simple hack to fix using mod_security. First off find where your mod_security config file is located, this all depends on your install of mod_security and OS but it's normally called modsec.conf
or modsec2.conf
, sometimes security.conf
but very seldom.
You can find it using the locate
command, if installed, on most linux systems.
sudo updatedb
locate modsec.conf
or
locate modsec2.conf
If you don't have locate
your going to need to go to the /
directory and just run find
, this will take some time but sometimes panels install it in weird places not just in /etc
.
cd /
find . -type f -iname 'modsec*.conf'
Either way will work to find the config file. Once found use your favorite editor to edit the file and go to the very bottom and add the following:
SecRuleEngine On
SecRule ARGS {php} "severity:4,log,deny"
SecRule ARGS eval "severity:4,log,deny"
SecRule ARGS base64_decode "severity:4,log,deny"
Basically your telling it to filter arguments in GET
and POST
. That's it, restart apache now:
CentOS:
service httpd restart
Ubuntu:
service apache2 restart
Now you might be thinking this will block you from using those commands in scripts, not at all. That only blocks those words from being sent over GET
or POST
. If someone tries they get a Not Acceptable
error and it just doesn't work at all.
This saves you from having to block a bunch of IP's from your firewall or WHMCS and potential customer's.