Imunify360 Features

External Black/Whitelist Management

To use external files with the list of Black/White IPs, place this list into the following directory:

  • for the White List:
/etc/imunify360/whitelist/*.txt
  • for the Black List:
/etc/imunify360/blacklist/*.txt

The files may have IP addresses or subnet in CIDR notation.

In order to apply the IP lists, run the following command:

imunify360-agent reload-lists

Or restart the agent.

Warning

Specifying IPs in those files will not prevent Imunify from adding the same IPs to dynamic lists (like Gray list), but all White lists always have the priority over Black lists when it comes to actual filtering of requests/packages.

RapidScan

RapidScan feature allows you to increase scanning speed by lower system resource usage and gives you an opportunity to scan more frequently, further hardening your systems’ security posture.

RapidScan techniques

  • Faster File Integrity Checking. File metadata, such as file hashes, are stored locally. This means that unchanged files don't need to be rescanned.
  • Efficient Cloud-assisted Scanning. Imunify360 stores its malicious file hash database in the cloud. We detect malicious files and skip white-listed files. The remaining files are fewer, so the overall scan time is significantly reduced.
  • Optimized Malware Signatures. Our malware signature database continually expands to match the variety of malicious software. While the database becomes more accurate and comprehensive, it also becomes larger and more cumbersome to index. We tackle this by actively curating the database and re-evaluating complex signatures, recasting any that affect scanning performance.

What does it mean to you?

When you first enable the RapidScan feature, the first scan will run as before. But subsequent scans will see a speed improvement, anywhere between 5 to 20 times faster. This is the case for both on-demand and scheduled scans, and means you can afford more scans without affecting system performance.

To take advantage of these new improvements, go to your Imunify360 control panel and enable RapidScan in Settings→Malware Scanner. See details here.

Low Resource Usage mode

This is a special operation mode where Imunify360 consumes less CPU and RAM. It is intended for servers with limited resources.

This mode disables WebShield switching off GrayList and Captcha.

Low Resource Usage mode also enables the Minimized Modsec Ruleset option that disables Imunify WAF rules with a high memory footprint, leaving critical rulesets enabled.

When the Low Resource Usage mode is activated it is reflected on the UI: an Imunify main menu changes color to light green, and an appropriate label appears on the top right.

Exim+Dovecot brute-force attack protection

Note

cPanel only, other panels will be added later

Exim+Dovecot brute-force attack protection is an advanced protection against Dovecot brute-force attacks. PAM module protects against IMAP/POP3 brute-force attack and prevents mail account from being compromised via brute-forcing.

How to enable Dovecot

We recommend using Imunify360 agent config to enable Dovecot because this allows to correctly switch OSSEC rules/configs:

imunify360-agent config update '{"PAM": {"enable": true, "exim_dovecot_protection": true}}'

How to disable Dovecot

To disable all PAM module via config file:

imunify360-agent config update '{"PAM": {"enable": false, "exim_dovecot_protection": false}}'

To disable only Exim+Dovecot via config file:

imunify360-agent config update '{"PAM": {"exim_dovecot_protection": false}}'

The options of the pam_imunufy are placed in the file: /etc/pam_imunify/i360.ini

Values

USER_LOCK_TIMEOUT=5 a period of time during which a user should be blocked (minutes)
USER_LOCK_ATTEMPTS=10 a number of attempts after which a user should be blocked
USER_LOCK_MINUTES=5 a period of time (minutes) during which violation attempts from a user are counted; all attempts earlier than USER_LOCK_MINUTES are not counted
USER_IP_LOCK_TIMEOUT=5 a period of time during which a user + IP should be blocked (minutes)
USER_IP_LOCK_ATTEMPTS=10 a number of attempts after which a user + IP should be blocked
USER_IP_LOCK_MINUTES=5 a period of time (minutes) during which violation attempts from a user + IP are counted; all attempts earlier than USER_IP_LOCK_MINUTES are not counted
IP_LOCK_TIMEOUT=5 a period of time during which an IP should be blocked (minutes)
IP_LOCK_ATTEMPTS=10 a number of attempts after which an IP should be blocked
IP_LOCK_MINUTES=5 a period of time during which violation attempts from an IP are counted; all attempts earlier than IP_LOCK_MINUTES are not counted
rbl=net-brute.rbl.imunify.com. RBL DNS Zone
RBL_timeout=5 this is the wait time for a response from RBL
RBL_nameserver=ns1-rbl.imunify.com:53 NS Server

Notes

Default RBL block time for IP = 4 hours.

How to apply settings

In order to apply new settings in the /etc/pam_imunify/i360.ini, run the following command:

systemctl restart imunify360-pam

How it works

During the last XXX_LOCK_MINUTES we count the number of login failures (unsuccessful login attempts). If the number of attempts exceeds the specified threshold XXX_LOCK_ATTEMPTS, the PAM plugin blocks access for XXX_LOCK_TIMEOUT minutes. After that, the counter is reset and the process repeats. Note that the plugin has three separate counters and a set of settings for USER/IP/USER+IP management regarding brute-force attacks (see the table above).

Notes

  • If a user is blocked by USER_LOCK_ATTEMPTS, then this user will not have access to the server from any IP
  • If a user is blocked by USER_IP_LOCK_ATTEMPTS, then this user will not have access to the server from that specific IP
  • If an IP is blocked by IP_LOCK_ATTEMPTS, then all users will not have access to the server from that specific blocked IP

Hooks

Overview

Hooks are introduced as a script-based interface for various application events. This is a simple and effective way to automate Imunify360 alerts and event processing. For example, an administrator can have Imunify360 calling his own script when malicious files are detected or misconfigurations are detected and perform a custom processing or specific actions, for example, create a ticket. Hooks are available only via CLI.

Requirements

  • You can use any programming language to create a hook script
  • A hook script should be executable
  • For Native hooks, you should use Python 3.5 only

How to start using hooks

Start using hooks with three simple steps:

  1. Create a script to handle an event (a hook handler):

  2. Register your hook handler in Imunify360 agent - use registration command:

imunify360-agent hook add --event <event name> --path </path/to/hook_script>
  1. Once the event added - check results and the log file

Available events and their parameters

agent

  • subtype ( started | misconfig )
    • started - the event is generated each time the Imunify agent is started/restarted

      • params[]
        • version / string / version of agent
      {"version": "4.6.2-2"}
      
    • misconfig - the event is generated when the agent detects agent misconfiguration / broken settings / etc.

      • params[]
        • error / string / error message where / what type of misconfiguration was detected and some details
      {
      "error": "ValidationError({'SMTP_BLOCKING': [{'allow_groups': ['must be of list type']}]},)"
      }
      

malware-scanning

  • subtype ( started | finished )

    • started - the event is generated when the malware scanning process is started (for on-demand and background scans only, yet not the ftp / waf / inotify)

      • params[]
        • scan_id / string / identifier of running scan
        • path / string / path that’s scanning
        • type / string / type of scanning (“on-demand”, “background”, “ftp”, “rescan“)
        • scan_params[] / initial scanning params
          • file_mask / string / file mask to scan
          • follow_symlinks / boolean / shall scanner follow symlinks
          • ignore_mask / string / file mask to ignore
          • intensity / string / intensity type selected (“low”, “moderate”, “high”)
      {
      "scan_id": "dc3c6061c572410a83be19d153809df1",
      "home": "/home/a/abdhf/",
      "user": "abdhf",
      "type": "background",
      "scan_params": {"file_mask": "*", "follow_symlinks": true, "ignore_mask": "", "intensity": "low"}
      }
      
    • finished - the event is generated when the malware scanning process is finished (for on-demand and background scans only, yet not the ftp / waf / inotify)

      • params[]
        • scan_id / string / identifier of running scan
        • path / string / path that’s scanned
        • users[] / string array/ user that’s scanned
        • started / int / unixtime when scan started
        • total_files / int / total number of files that were scanned
        • total_malicious / int / number of detected malicious files
        • errors[] / string / error message if any occurred during scanning
        • status / string / status of scan (“ok”, “has_errors”, “failed”)
        • scan_params[] / initial scanning params
          • file_mask / string / file mask to scan
          • follow_symlinks / boolean / shall scanner follow symlinks
          • ignore_mask / string / file mask to ignore
          • intensity / string / intensity type selected (“low”, “moderate”, “high”)
      {
      "scan_id": "dc3c6061c572410a83be19d153809df1",
      "home": "/home/a/abdhf/",
      "user": "abdhf",
      "started": 1587365282,
      "total_files": 873535,
      "total_malicious": 345,
      "errors": [],
      "status": "ok",
      "type": "background",
      "scan_params": {"file_mask": "*", "follow_symlinks": true, "ignore_mask": "", "intensity": "low"}
      }
      

malware-detected

  • subtype ( critical )
    • critical

      • params[]
        • scan_id / string / unique id of the scan
        • errors[] / string / error strings that happened during the last scan
        • started / int / unixtime when the scan was started
        • path / string / path that was scanned
        • users[] / string array / users that have been scanned (if any)
        • total_files / int / number of files checked within the last scanning
        • total_malicious / int / number of detected malicious files
        • tmp_filename / string / path to a temporary file with a list of detected threads. The list of threads is in the format of the following command: imunify360-agent malware malicious list --by-scan-id=... --json
      {
      "scan_id": "dc3c6061c572410a83be19d153809df1",
      "path": "/home/a/abdhf/",
      "username": ["imunify"],
      "started": 1587365282,
      "total_files": 873535,
      "total_malicious": 345,
      "errors": [],
      "files": [
          {
            "username": "imunify",
            "hash": "17c1dd3659578126a32701bb5eaccecc2a6d8307d8e392f5381b7273bfb8a89d",
            "size": "182",
            "cleaned_at": 1553762878.6882641,
            "extra_data": {
      
      
            },
            "malicious": true,
            "id": 32,
            "status": "cleanup_removed",
            "file": "/home/imunify/public_html/01102018_2.php",
            "type": "SMW-INJ-04174-bkdr",
            "scan_type": "on-demand",
            "Created": 1553002672
          },
          {
            "username": "imunify",
            "hash": "04425f71ae6c3cd04f8a7f156aee57096dd658ce6321c92619a07e122d33bd32",
            "size": "12523",
            "cleaned_at": 1553762878.6882641,
            "extra_data": {
      
      
            },
            "malicious": true,
            "id": 33,
            "status": "cleanup_done",
            "file": "/home/imunify/public_html/22.js",
            "type": "SMW-INJ-04346-js.inj",
            "scan_type": "on-demand",
            "Created": 1553002672
          },
      ...
      
      }
      

Note

All results can be saved in a temporary file before handler invocation and then remove the file after the event is being processed

malware-cleanup

  • subtype ( started | finished )

    • started - the event is generated when the malware cleanup process is started (for on-demand and background cleanup only, background auto-cleanup will be implemented later)

      • params[]
        • cleanup_id / string / unique id of the cleanup
        • started / int / unixtime when the cleanup was started
        • tmp_filename / string / path to a temporary file with a scanning report. The list is in the format of the following command: imunify360-agent malware malicious list --by-scan-id=... --json. See malware-detected hook section for details.
        • total_files / int / number of files that were sent for cleanup
      {
      "scan_id": "dc3c6061c572410a83be19d153809df1",
      "started": 1587365282,
      "total_files": 873535,
      "total_cleaned": 872835,
      "tmp_filename": "/var/imunify/tmp/hooks/tmp_02q648234692834698456728439587245.json",
      "errors": [],
      "status": "ok"
      }
      
    • finished - the event is generated when the malware scanning process is finished (for on-demand and background cleanup only, background auto-cleanup will be implemented later)

      • params[]
        • cleanup_id / string / identifier of running cleanup
        • started / int / unixtime when cleanup started
        • total_files / int / number of files that were sent for cleanup
        • total_cleaned / int / number of files that were successfully cleaned
        • tmp_filename / string / path to a temporary file with a list of results.
        • errors[] / string / error messages if any occurred during cleanup
        • errors[] / string / error messages if any occurred during cleanup
      {
      "scan_id": "dc3c6061c572410a83be19d153809df1",
      "started": 1587365282,
      "total_files": 873535,
      "total_cleaned": 872835,
      "tmp_filename": "/var/imunify/tmp/hooks/tmp_02q648234692834698456728439587245.json",
      "errors": [],
      "status": "ok"
      }
      

license

  • subtype ( expiring | expired | renewed )

    • expiring - the event is generated when license is about to expire, the even should be sent 3 days prior to expiration
      • params[]

        • exp_time / int / unixtime data when the license expired
        {"exp_time": 1587365282}
        
    • expired - the event is generated when license has expired
      • params[]

        • exp_time / int / unixtime data when the license is expired
        {"exp_time": 1587365282}
        
    • renewed - the event is generated when the license is updated (renewed)
      • params[]

        • exp_time / int / unixtime data when the license will expire
        • license / string / license type
        {
          "exp_time": 1587365282,
          "license": "imunify360"
        }
        

CLI

The following CLI command is used to manage hooks:

imunify360-agent hook [command] --event [event_name|all] [--path </path/to/hook_script>]

The following commands are supported:

  • add - register a new event handler
  • delete - unregister existing event handler
  • list - show existing event handlers
  • add-native - register a new native event handler

The third parameter event_name defines a particular event that invokes a registered handler as opposed to all keyword. The fourth parameter /path/to/hook_script shall contain a valid path to a handler of the event, it shall be any executable or Python Native event handlers that agent will run upon a registered event.

Native

Native hook is a script written on Python 3.5 and allows to quickly process events. The Python file should contain only one method that customer would implement:

def im_hook(dict_param):
  …
  pass

where dict_param would hold the same data as JSON that non-Native hook would get.

Log File

You can see all hook data in the log file. It is located at /var/log/imunify360/hook.log . When the event comes, the data is recorded to the log file in the following format:

timestamp event : id : started [native:] name :  subtype : script_path
  • native is prepended for the Native hook implementation
  • id is a unique ID for each event

Once the listener is done, the data is recorded to the log file in the following format:

timestamp event : id : done [native:] script_path [OK|ERROR:code]

In case of an error, you can see the error code you have specified.

Structure and examples of a hook script

Regular (non-native) hook:

#!/bin/bash

data=$(cat)

event=$(jq -r '.event' <<< ${data})
subtype=$(jq -r '.subtype' <<< ${data})

case ${event} in
    malware-scanning)
        case ${subtype} in
            started)
                # do stuff here
            ;;
            *)
                echo "Unhandled subtype: ${subtype}" 1>&2
                exit 1
        esac
        ;;
    *)
        echo "Unhandled event: ${event}/${subtype}" 1>&2
        exit 2
esac

Native hook:

def im_hook(dict_param):
   event = dict_param['event']
   subtype = dict_param['subtype']

   if event == 'malware-scanning':
       if subtype == 'started':
           # do stuff here
           pass
       elif subtype == 'finished':
           # do other stuff here
           pass
       else:
           raise Exception('Unhandled subtype {}'.format(subtype))
   else:
       raise Exception('Unhandled event {}'.format(event))

Malware Database Scanner (MDS) Beta 5.1

Malware Database Scanner (MDS) is designed to solve all malware related problems in the database.

Warning

Version 5.1 of the Imunify360 introduces a CLI tool without the UI. Further versions will be integrated with the Malware Scanner UI.

Warning

For now, Malware Database Scanner (MDS) supports WordPress databases only.

How to use Malware Database Scanner (MDS)

To provide safe work with database MDS supports several methods:

  • --scan - only scan the database, no changes will be applied
  • --clean - scan database and clean-up malicious
  • --restore - restore data affected by clean-up from the backup CSV file

Usage

php /opt/ai-bolit/imunify_dbscan.php [OPTIONS] [PATH]

Options

--host=<host> Database host
--port=<port> Database port
--login=<username> Database username
--password=<password> Database password
--password-from-stdin Get database password from stdin
--database=<db_name> Database name
--prefix=<prefix> Prefix for table
--scan Do scan
--clean Do clean
--report-file=<filepath> Filepath where to put the report
--signature-db=<filepath> Filepath with signatures
--progress=<filepath> Filepath with progress
--shared-mem-progress=<shmem_id> ID of shared memory segment
--create-shared-mem MDS create own shared memory segment
--status=<filepath> Filepath with status for control task
--avdb=<filepath> Filepath with ai-bolit signatures database
--procudb=<filepath> Filepath with procu signatures database
--state-file=<filepath> Filepath with info about state (content: new/working/done/canceled). You can change it on canceled.
--restore=<filepath> Filepath to restore CSV file
-h, --help Display this help and exit
-v, --version Show version

Example of usage

Scan database

# /opt/alt/php74-imunify/usr/bin/php -n -d extension=json.so -d extension=pdo.so -d extension=mysqlnd.so -d extension=nd_mysqli.so /opt/ai-bolit/imunify_dbscan.php --port=3306 --login=user --password-from-stdin --database=$DATABASE --avdb=`pwd`/mds-ai-bolit-hoster.db --report-file=`pwd`/report.json --scan

Scan results will be stored in the results.json.

Scan & Clean-up database

# /opt/alt/php74-imunify/usr/bin/php -n -d extension=json.so -d extension=pdo.so -d extension=mysqlnd.so -d extension=nd_mysqli.so /opt/ai-bolit/imunify_dbscan.php --port=3306 --login=user --password-from-stdin --database=$DATABASE --avdb=`pwd`/mds-ai-bolit-hoster.db --procudb=`pwd`/procu2.php --report-file=`pwd`/report.json --clean

Scan results will be stored in the results.json. Also, backup of the affected data will be created with a filename similar to the mds_backup_1597223818.csv.

Undo changes (restore)

# /opt/alt/php74-imunify/usr/bin/php -n -d extension=json.so -d extension=pdo.so -d extension=mysqlnd.so -d extension=nd_mysqli.so /opt/ai-bolit/imunify_dbscan.php --port=3306 --login=user --password-from-stdin --database=$DATABASE --report-file=$REPORT --restore=`pwd`/mds_backup_1597223818.csv