An Introduction to Imunify Hooks

IM-Hooks

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 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:

  1. 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;
    }
    
  2. Make the file executable:

    chmod +x /root/hooks/hook.php
    
  3. 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.

  4. 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):

Imunify Hooks 2

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.

Imunify Hooks 3

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:

Imunify Hooks 4

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.

If you have any questions or would like to request a feature, please email us.

Beta: Imunify360 4.2.4 updated
Beta: ImunifyAV 4.2.3 updated
 

Comments

No comments made yet. Be the first to submit a comment
Already Registered? Login Here
Guest
Wednesday, 17 July 2019

Captcha Image