In Imunify360 v4.2 beta, we introduced “Hooks”, a new way to handle asynchronous events coming from the Imunify agent. It works like a simple event handler. For example, you can create a script that will run when malware is detected (right after the on-demand or background scan is finished).
The updated version of the article came up and all the essentials of using Imunify Hooks are now covered in a short video, check here.
The script is put on the server and registered via the Imunify360 command-line interface. In the script, you can specify a set of actions based on the scanning report received from Imunify360: for example, suspend a user account infected with malware, send out an email notification, or submit a ticket for the client. Hooks are just executables, so they can be written in any language (bash, php, python, etc.).
We’ve had a lot of questions regarding the practical use of hooks. So, we’ve created this article to show you an example of a hook that runs when malware is detected, and suspends the cPanel user account when the number of infected files exceeds three.
Here are the steps to create the hook:
Create a file (e.g. /root/hooks/hook.php
) with the following content:
#!/usr/local/bin/php -q
<?php
define('MAX_ALLOWED_INFECTED_FILES', 3);
stream_set_blocking(STDIN, 0);
$stdin = fopen('php://stdin', 'r');
$data = stream_get_contents($stdin);
$json = json_decode(trim($data), true);
switch ($json['event']) {
case 'malware-detected':
// if it's infection?
if ($json['subtype'] == 'critical') {
// retrieve the scanning report
$report = json_decode(file_get_contents($json['params']['tmp_filename']), true);
$by_users = array();
// combine infected files by users
foreach ($report as $entry) {
if (!isset($by_users[$entry['username']])) {
$by_users[$entry['username']] = array();
}
$by_users[$entry['username']][] = $entry['file'];
}
// suspend all accounts, where number of infected files more than MAX_ALLOWED_INFECTED_FILES
foreach ($by_users as $user => $files) {
if (count($files) > MAX_ALLOWED_INFECTED_FILES) {
exec('/scripts/suspendacct ' . $user . ' "Reason" 1');
}
}
}
break;
}
Make the file executable:
chmod +x /root/hooks/hook.php
The script assumes your PHP interpreter is in /usr/local/bin/php
. If it’s somewhere else (you can find it with which php
), change the path in the first line of the script to match the path to your PHP interpreter.
Use this command to register the script as a handler for the malware-detected
event:
imunify360-agent hook add --event malware-detected --path /root/hooks/hook.php
That’s all. From now on, when an On-Demand or Background scan finishes and malware is detected, the script will run and any account with more than three malicious files will be suspended automatically.
It’s easy to enhance the script to send a message to a user with a list of files detected on his/her account (the variable $by_users[$entry['username']]
will contain those files).
You can do more sophisticated processing based on data received from the agent. Let’s look at the data structures coming from the agent when a malware-detected
event is triggered:
The following JSON data structure is output by the event handler when the hook is triggered (it’s read from STDIN, lines 7–9 of hook.php
):
The ["params]["users"]
field will contain a list of affected users. More interesting is the field ["params"]["tmp_filename"]
. This specifies the path to a temporary file containing the scanning results. The contents can be read and parsed for specific processing of the infection.
This data structure has all necessary fields: account name, infected filename, type/verdict (malware signature id), size, date of creation, etc. (Details of the fields are here.) Please note, the tmp_filename
file is removed after the script is run, so you must read it and store the data somewhere if you need it for further processing.
Lines 19–25 of hook.php
iterate through the files from the report, and combine them by usernames, giving us a list of users and a list of infected files for each account.
Finally, lines 28–31 iterate through the list of users and check the number of infected files on the account. If it exceeds the constant MAX_ALLOWED_INFECTED_FILES
(=3) then the account is suspended. This is how it looks like after detecting malware on the “imunify” account:
If you’re a Plesk user, you must replace the command in exec(...)
with:
plesk bin user --update <...user email...> -status disabled
That’s pretty much everything we’d like to tell you about hooks for today, but you can read more detailed documentation on hooks here.
Imunify360 is a comprehensive security suite for Linux web-servers. Antivirus firewall, WAF, PHP, Security Layer, Patch Management, Domain Reputation with easy UI and advanced automation. Try free to make your websites and server secure now.