=head1 ConfigServer eXploit Scanner B - Using ConfigServer eXploit Scanner =head1 DESCRIPTION B will scan files, directories and user accounts for suspicious files, potential exploits and viruses. Note: cxs is B a rootkit scanner, though it can detect rootkits uploaded to user accounts. =head1 SYNOPSIS B OPTION: -?, --help Display the documentation -V, --version Display the version --terms Display the License Agreement -Z, --quiet Quiet output -U, --upgrade Upgrade to the latest version --mail [email] Send scan report to email address [email] --smtp Send emails via localhost SMTP instead of sendmail --template [file] Use [file] as a template when sending scan reports --report [file] Write scan report to [file] --logfile [file] Append scan report files to [file] -N, --cleanlog Log clean Web script or FTP files with --logfile --[no]virusscan Do [not] perform virus scanning (default:on) --[no]exploitscan Do [not] perform exploit scanning (default:on) --[no]summary Do [not] display scan summary (default:on) --[no]sversionscan Do [not] perform script version scanning -S, --sizemax [bytes] Maximum amount of text to scan (default:500000) -F, --filemax [num] Skip dir if > than [num] resources (default:10000) -H, --timemax [secs] Scan timeout per file in seconds (default:30) --ctime [hours] Ignore files changed more than [hours] ago -C, --clamdsock [sock] Location of the clamd socket --[no]fallback Do [not] use clamscan if clamd errors (default:off) -D, --delete Delete suspicious files --defapache [user] Default apache user --force Force scanning within restricted directories -K, --skipover [user] Start scanning after [user] with --allusers --jumpfrom [user] Start scanning from [user] (incl) with --allusers --jumpto [user] Stop scanning to [user] (incl) with --allusers --ulist [file] Scan users listed in [file] with --allusers --uidmin [uid] Min UID for GENERIC with --allusers (default:1000) --uidmax [uid] Max UID for GENERIC with --allusers (default:65535) -E, --deep Perform a deep scan --debug Print a LOT of debugging information --decode [file] Decode PHP base64/rot13 encoded file --depth [num] Decode to [num] depth for --decode --block Block FTP IP addresses using csf --MD5 Display matched file md5sum --prenice [num] Set process nice priority value --pionice [num] Set process ionice priority value -B, --background Run scan as a background process -T, --throttle [num] Sleep if load is greater than [num] -I, --ignore [file] A file with more resources for scanning to ignore -X, --xtra [file] A file with more resources for scanning to use --script [script] Run [script] if a match is detected --tscripts [list] When using --options [T] only detect these types --www Only scan in public_html subdir (--allusers/--user) --generate Generate --ignore [file] using --report [file] --wttw [file] Report script to ConfigServer --comment "text" Include quoted comment when using --wttw [file] --voptions [mfuhexT] Virus scan specified file types only --doptions [mMfuSGchexTEv] Delete specified file types only (def:Mv) --soptions [ad] Script version scanning options --options [-][mMOLfuSGcChexdnwWTEDZRP] Exploit scan options -Q, --quarantine [dir] Move suspicious files to quarantine [dir] --qoptions [mMfuSGchexTEvB] Quarantine specified file types only (def:Mv) --qcreate Create a cxs quarantine directory --qclean [days] Clean quarantine retaining [days] of files --qlocal Quarantine ModSecurity files locally (mod_ruid2) --qrestore [file] Restore quarantine [file] to original location --qignore [method] Add an ignore entry for [file] into an ignore file --qview [file] View quarantine [file] --[no]bayes Do [not] perform script Bayes classification --breport [level] Min Bayes level to report (default:medium) --baction [level] Min Bayes level to quarantine/delete (default:high) --bget Retrieve the trained master Bayes corpus --blearn [X|C] Add a file to the local corpus --bforget [X|C] Remove a file from the local corpus --Wstart Start the cxs Watch daemon --Wstop Stop the cxs Watch daemon --Wmaxchild [num] The number of Watch child processes (default:3) --Wadd [file] A file with more resources for cxs Watch to scan --Wsleep [secs] Sleep delay (default:3 secs) --Wloglevel [num] cxs Watch daemon log file verbosity [0..2] --Wrefresh [days] Restart cxs Watch daemon every [days] (default:7) --Wrateignore [secs] Ignore excessively updated files (default:0) RESOURCE: [file/directory] A file or directory to scan, or --allusers Scan all user login directories (alphabetical), or --user [user] Scan [user] login directory =head1 OPTIONS =over 8 =item B<--help> Displays this help page =item B<--clamdsock [sock]> This should be the full path to the ClamAV Daemon socket if running. cxs will look for the socket at /tmp/clamd, /var/clamd, /var/run/clamav/clamd.sock and /var/run/clamav/clamd.ctl unless specified with this option. =item B<--[no]fallback> This option is disabled by default. If clamd produces an error or is unavailable after a scan starts, this option will attempt to use clamscan from one of the following locations to scan files until clamd is available again (in order of preference): /usr/local/cpanel/3rdparty/bin/clamscan /usr/local/bin/clamscan /usr/bin/clamscan If clamd is not running prior to the scan starting then this option will not apply as virus scanning will have been disabled. Note: This can impose a significant performance hit during scanning but does mean that clamav scanning will still be performed. =item B<--quiet> Does not display the progress of the requested scan. The progress indicator uses symbols to indicate particular file matches or a dot (.) for every 50 files scanned: m = regex pattern match M = fingerprint match v = virus O = socket L = symlink f = suspicious file u = script in suspicious directory F = skipped directory with too many entries S = SUID file G = GUID file c = core dump file C = core dump file deleted h = suspected exploit file e = Linux binary or executable file x = Windows binary or executable file d = suspicious directory name n = hidden directory owned by apache default user w = world writable directory W = world writable directory - chmod to 755 T = script file - identifies PHP, Perl, and other script files as suspicious E = email script D = Decoded PHP encoded (e.g. base64) file scan match R = Match the PHP decode regex P = Search D/B config files and attempt user login via FTP. Match on success Z = compressed file - scan within zip, tar, tar.gz and tar.bz2 files b = Possible exploit as determined by Bayes B = Possible exploit as determined by Bayes for action (quarantine/delete) s = Old script version installed ! = Scan timeout per file --timemax [Zzzzzzz] = sleeping for 60 seconds as load average is > --throttle [num] =item B<--ignore [file]> [file] points to a file containing resources that the scanning engine should ignore. Each entry in [file] should be on its own line and prefixed with one of the following (no spaces after the : separator): user: - ignore user file: - ignore file dir: - ignore directory sym: - ignore symlink script: - ignore web script (ModSecurity hook) puser: - regex of users to ignore pfile: - regex of files to ignore pdir: - regex of directories to ignore psym: - regex of symlinks to ignore pscript: - regex of web script to ignore (ModSecurity hook) The following do not apply to web script uploads via ModSecurity hook: hfile: - ignore file relative to a users homedir* hdir: - ignore directory relative to a users homedir* hsym: - ignore symlink relative to a users homedir* match: - ignore regex pattern match md5sum: - ignore file md5sum (See --MD5) fp: - ignore fingerprint match (e.g. [P0001]) The following only apply to web and ftp script uploads: ip: - ignore IP address** [*] When --allusers or --user [user] is used [**] This may or may not have any impact on performance with ftp uploads as the IP address will need to be established from the message log for each file You can include additional entries using external files with: Include /path/to/cxs.altignore See /etc/cxs/cxs.ignore.example for examples - this file is overwritten when cxs upgrades, so use a copy of this file [file] needs to have world read access (B<644>) to allow Web script file upload scanning. =item B<--script [script]> During a scan, if a suspicious file or resource is detected, [script] will be executed with the following passed as parameters: filename option triggered message reported account name (if a manual scan and --allusers or --user [user] is used) IP address (Only available via ModSecurity and pure-ftpd hooks) The account name is not passed during cxs Watch scans. [script] must be the full path to the script. The [script] will run under the context cxs is running (e.g. under the root account for manual and ftp scans, the apache default user for ModSecurity scans). The [script] will be run for every hit against a file. The [script] must be chmod +x and have a valid shebang line. For example, [script] could contain code to suspend an account if the options v and M are detected against a file. That script would have to check whether the account has already been suspended (by a previous excecution) and that the context the script is running under has the permissions to suspend the account: /etc/cxs/cpanelsuspend.example.pl Another example provided is /etc/cxs/htaccessdisable.example.pl which disables access via the web server to a directory using a .htaccess file =item B<--tscripts [list]> If B<--options [T]> is used, you can restrict which script types are always detected using [list] as a comma separated list from a selection of the following script types: php,perl,python,ruby,asp,jsp,java,c,other If B<--tscripts [list]> is not used, all types will be detected. To omit one or more types use B<--tscripts [list]> and don't include those that should not be detected in the list. =item B<--xtra [file]> [file] points to a file containing a list of regular expression matches and filenames that cxs will additionally scan for: regall: - regular expression match for all script files regphp: - regular expression match for only php script files regperl: - regular expression match for only perl script files regfile: - regular expression match for a file or directory name file: - file or directory name match (not a regex) md5sum: - md5sum of a file to match as a known exploit (See --MD5) To force quarantine of a file with a matching regex when using quarantine, prefix the regex with quarantine:, e.g.: regall:quarantine:/etc/passwd You can include additional entries using external files with: Include /path/to/cxs.altxtra See /etc/cxs/cxs.xtra.example for examples - this file is overwritten when cxs upgrades, so use a copy of this file [file] needs to have world read access (B<644>) to allow Web script file upload scanning. =item B<--logfile [file]> This will append scan results per item found to [file] If [file] is intended to log web script file uploads it must have appropriate ownership and permissions. It would be best to create [file] in advance, e.g. if the default apache account is "nobody" and the log file is /var/log/cxs.log: touch /var/log/cxs.log chown root:nobody /var/log/cxs.log chmod 630 /var/log/cxs.log This will then only allow appending to [file] by the default apache user. =item B<--template [file]> This identifies an email template file that can be used when report emails are sent. The B<--mail [email]> option must also be specified for this option to be used. An example is provided in /etc/cxs/cxs.template.example - this file is overwritten when cxs upgrades, so use a copy of this file The template file must be chmod B<644> so that it can be read by all users. In the example template you can see how a Linux end-user can be copied (CC:) on the cxs scan report using the [user] text replacement. This is used for: Web script scanning (cxscgi.sh) - user = web script owner FTP script scanning (cxsftp.sh) - user = ftp account owner cxs Watch Daemon scanning (cxswatch.sh) = file owner Using B<--template [file]> with a different template in each of cxscgi.sh, cxsftp.sh and cxswatch.sh each report can be formatted differently. For manual scans using B<--allusers> or B<--user [user]> the template is used to send an email of each users files after the have been processed, with the To: field set to the user. In this case, the [user] text replacement field is ignored. Once the scan completes the email to --mail [email] is sent as normal. Additionally, on cPanel servers, the user email will be sent to the contents of the users .contactemail file. This is not possible under Web script scanning as the ModSecurity process runs under the apache default user account which does not have read access to those files. =item B<--report [file]> This will (re)create [file] and write the full scan report to it. If [file] is intended to log web script file uploads it must have world writable permissions. =item B<--options [-][mMOLfuSGcChexdnwWTEDZRP]> By default B<--exploitscan> will scan for the following default list of options: B<[mMOLfSGchexdnwZDRu]>, B C, W, T, P, and E which need to be specified explicitly using this option. Please read the separate sections for options C, W, T, P and E as these advanced options can be dangerous (change file permissions, delete files or identify innocent files as suspicious) and you should read and understand the documentation before enabling any of them. If you prefix the list of options with a minus (B<->) then all the default list of options above will be used apart from those specified (settings for --options in the cxs.defaults file will be ignored). For example, B<--options -OLSG> will scan using options [mMfchexdnwZDRu], skipping options O, L, S and G. B<[mMOLfuSGcChexdnwWTEDZRP]> represent: m = regex pattern match M = fingerprint match O = socket L = symlink f = suspicious file u = script in suspicious directory S = SUID file G = GUID file c = core dump file C = core dump file deleted h = suspected exploit file e = Linux binary or executable file x = Windows binary or executable file d = suspicious directory name n = hidden directory owned by apache default user w = world writable directory W = world writable directory - chmod to 755 T = script file - identifies all PHP, Perl, and other script files as suspicious E = email script D = Decode PHP encoded (e.g. base64) scripts Z = compressed file - scan within zip, tar, tar.gz and tar.bz2 files R = Match the PHP decode regex P = Search D/B config files and attempt user login via FTP. Match on success (See the Exploit Scanning Reference for a detailed description for each option) This option will only work with B<--exploitscan> enabled. =item B<--voptions [mfuhexT]> By default B<--virusscan> will scan all files. If B<--voptions [mfhexT]> is also used then only the selected file types will be scanned, from a choice of: m = regex pattern match f = suspicious file u = script in suspicious directory h = suspected exploit file e = Linux binary or executable file x = Windows binary or executable file T = script file (See the Exploit Scanning Reference for a detailed description for each option) This option will only work with B<--virusscan> enabled. This option is disabled when scanning uploaded Web script or FTP files as all uploads are virus scanned if B<--virusscan> is enabled. =item B<--qoptions [mMfuSGchexTEvB]> By default B<--qoptions [mMfuSGchexTEvB]> is set to [Mv] if B<--quarantine [dir]> is set. A different list of file types can be chosen from: m = regex pattern match M = fingerprint match f = suspicious file u = script in suspicious directory S = SUID file G = GUID file c = core dump file h = suspected exploit file e = Linux binary or executable file x = Windows binary or executable file T = script file - quarantines all PHP, Perl, and other script files E = email script v = virus B = Possible exploit as determined by Bayes This option will only work with B<--quarantine [dir]> enabled. Care should be taken using this option scanning uploaded Web script or FTP files as any file types omitted by B<--qoptions [mMfuSGchexTEv]> will be allowed. =item B<--delete> This option will delete an uploaded Web script or FTP file that matches an suspected exploit or virus. Caution should be exercised when using this options as it could cause confusion, or damage to user data. In such circumstances it would be better to consider using B<--quarantine [dir]> instead. This option can also be used on manual or scheduled scans, however since the likelihood of a false-positive is relatively high, it is recommended that a strict B<--qoptions [mMfuSGchexTEvB]> is used. Do not use B<--delete> with B<--quarantine [dir]>, the former takes precedence. =item B<--doptions [mMfuSGchexTEvB]> By default B<--doptions [mMfuSGchexTEvB]> is set to [Mv] if B<--delete> is set. A different list of file types can be chosen from: m = regex pattern match M = fingerprint match f = suspicious file u = script in suspicious directory S = SUID file G = GUID file c = core dump file h = suspected exploit file e = Linux binary or executable file x = Windows binary or executable file T = script file - quarantines all PHP, Perl, and other script files E = email script v = virus B = Possible exploit as determined by Bayes This option will only work with B<--delete> enabled. =item B<--[no]sversionscan> Script Version Scanning. This will search for common web script installations and report if older than the latest version on record. The latest version data is obtained on install, upgrade and daily update of cxs if configured. Current web scripts checked: AbanteCart AEF b2evolution v5 ClipBucket v2 CMS Made Simple CodeIgnitor v2 Concrete5 v5 Contao CMS v3 Coppermine Photo Gallery CubeCart v5 Dolphin v7 Dotclear v2 Drupal v7 e107 Elgg Feng Office v2 Gallery v2 v3 HESK v2 Invision Power Board v3 Jcow CE v7 Joomla Advanced Module Manager Ext Joomla Akeeba Joomla AllVideos Joomla Asynchronous Google Analytics Ext Joomla CDN for Joomla Joomla Community Builder Joomla Google Maps Ext Joomla JCE Ext Joomla JEvents Joomla Jomsocial Joomla Joomla LiveHelpNow Chat Ext Joomla K2 Joomla Kunena Joomla Modules Anywhere Ext Joomla Phoca Gallery Joomla RAntiSpam Ext Joomla Rapid Contact Ext Joomla sh404SEF Joomla Simple Image Gallery Joomla Sourcerer Ext Joomla Tabs Ext Joomla v2 v3 Joomla XCloner Ext Joomla Xmap Kayako v4 LimeSurvey v2 Magento Community Edition MediaWiki MODX Evolution MODX Revolution v2 Moodle v2 MyBB v1 Noahs Classifieds v3 Nucleus CMS v3 Open Classifieds v2 OpenCart OpenX Source v2 OSClass v3 osCommerce v2 osTicket ownCloud v4 v5 Oxwall PHP-Fusion v7 phpBB v2 phpList v3 phpMyAdmin v3 v4 phpPgAdmin v5 Piwigo v2 Piwik PrestaShop Roundcube Seo Panel v3 Serendipity SMF v2 SquirrelMail StatusNet SugarCRM Community Edition v6 TomatoCart Typo3 v6.1 v6.0 v4.7 v4.5 vBulletin v3 v4 v5 VirtueMart v2 WebCalendar WHMCS v5 Wordpress v3 WP Akismet Ext WP All In One WP Security & Firewall WP BackUpWordPress WP Better WP Security WP BulletProof Security WP Contact Form 7 WP Facebook WP FD Feedburner WP Google Adsense Plugin WP Google XML Sitemaps WP Jetpack Ext WP NextGEN Gallery Ext WP Seo Ext WP Share This WP Sociable WP UpdraftPlus WP W3 Total Cache WP WooCommerce WP WordPress eShop WP WordPress s2Member WP WordPress Simple Paypal Shopping Cart WP WP Super Cache WP XCloner Ext Xoops v2 Zen Cart ZenPhoto Zikula Note: The checks are not comprehensive and could either mis-identify or fail to identify installations of the above scripts. It also won't be able to necessarily detect patched versions compared to fully upgraded versions. However, it could be a useful tool in helping to identify old installations of those scripts that are detected. By default B<--[no]sversionscan> will report only old versions of scripts it finds. If B<--soptions [a]> is used then all script installed found will be reported, i.e. old, latest and unknown version. By default B<--[no]sversionscan> will report the file that triggered the scan. If B<--soptions [d]> is used then only the directory is reported. Note: This option is disabled for web script scanning (cxscgi.sh). =item B<--[no]bayes> Naive Bayesian probabability scanning of script files. This option uses an enhanced Naive Bayes statistical algorithm to report a probability that a scanned script is an exploit. This is achieved through a trained corpus (database). The probability is further manipulated by other scanning options. The implementation produces three propabilities if a script is identified as more likely to be an exploit compared to a clean script: low - possibly an exploit medium - probably an exploit high - likely an exploit If the probability indicates the script is clean, or if the script has already been detected as a virus or a fingerprint match, nothing will be reported for this option. The B<--[no]bayes> option can only be used if B<--deep> is not enabled, as it is only intended to inspect script files. If B<--deep> is enabled, B<--[no]bayes> will be ignored and no probability calculated. This feature is not currently configurable via the UI. To get started with this option, the bayes corpus needs to be downloaded. This will be done automatically on the first run, or can be downloaded manually using: cxs --bget The minimum level of exploit probability of a script to report can be set to low, medium or high using B<--breport [level]>. The default is medium, i.e. all medium and high exploit probabilities will be reported for the scan. The minimum level of exploit probability of a script to quarantine or delete can also be set to low, medium or high using B<--baction [level]>. The default is high, i.e. only high exploit probabilities. This helps limit false-positive scripts from tbe actioned, allowing for lower probability exploits to be investigated. Impact: This option will increase the time it takes to scan each script file. It will also increase memory use by cxs as it uses the Bayes corpus, which is quite large. Note: This option is not to be seen as a definitive evaluation of a file. It simply provides a probability as to whether a script is an exploit. Since many exploits look like normal scripts, and vice-versa, it will inevitably catagorise incorrectly at times. This is not a fault, it is simply in the nature of the way this type of analysis works. However, it can be a useful indicator so that scripts can be inspected if reported to ensure they are not indeed exploits. Given the above, please do not report any files detected through this option as false-positives. However, if it helps identify exploits that are not otherwise detected, feel free to report them as usual using B<--wttw [script]>. =item B<--blearn [X|C]> This option allows new files to be added to a local bayes corpus. The new file must either be added as an exploit file (X) or as a clean file (C). Adding a file will affect subsequent evaluation of all files. This allows local training of the corpus if you see excessive false-positives. Great care should be taken when adding files to the local corpus as this can greatly affect the effectiveness of the bayes feature. Adding significant numbers of files to a local corpus will affect the performance of the bayes feature. You can specify either a single file, a user account or a full directory path. The latter two will categorise all script file found within the account or path based on the category specified in B<--blearn [X|C]>. You must ensure that only scripts of the specified category lie within the path otherwise the effectiveness of the corpus will be weakened. =item B<--forget [X|C]> This option allows existing files that have previously been added to the local bayes corpus using B<--blearn [X|C]> to be removed. The new file must either be removed from the same category as when it was added, that is as an exploit file (X) or as a clean file (C). =item B<--ctime [hours]> If you run regular full system scans then you can use B<--ctime [hours]> to only scan files changed in the intervening hours. This can speed up scan times dramatically. On a daily scan we would suggest using 25 hours to ensure resources are not missed. A weekly or monthly scan should also be run without --ctime [hours] so that all files are rescanned in case of new scanning techniques and exploit signatures and fingerprints. This option should not be used in cxswatch.sh, cxscgi.sh or cxsftp.sh =item B<--force> If B<--force> is not used then cxs will refuse to scan within the following directories: /usr /var /bin /lib /lib64 /boot /etc /proc /sys /opt =item B<--jumpfrom [user]>, B<--jumpto [user]> With these options a start and end [user] can be specified for a scan used with B<--allusers> to only scan those users between the two specified. The scan includes the start and end [user]. Additionally, a special value can be used for the from and to [user] using a single letter then a plus sign to scan those users whose name begins with the letter specified (not case sensitive). Again, this is inclusive. For example, to scan all accounts beginning with k through to g use B<--jumpfrom k+> B<--jumpto g+> =item B<--generate> This is a special option that requires the options B<--report [file]> and B<--ignore [file]>, where B<--report [file]> is taken as input and cxs will append ignore rules to B<--ignore [file]> When a cxs report is first run it is likely to show some false-positives. If you do not want to see those same files in subsequent reports, you can ignore them by adding appropriate records to an ignore file and using the B<--ignore [file]> option with that file. To help create such an ignore file from a report containing a large number of false-positives, you can use this B<--generate> option which takes the report file as input and cxs will append correctly specified ignore rules to the ignore file listed. Subsequent scans using that ignore file will then ignore those listed files. =item B<--wttw [file]> This option is available for submitting exploits to ConfigServer if cxs fails to detect it. The file is sent as an attachment via email. It will veryify that the script isn't normally detected as a Virus or Fingerprint. If you want to include a short comment with the submission you can use the B<--comment "text"> option. The text B by enclosed by either single or double quotes, otherwise the comment will be lost. If you are submitting a false-positive for a fingerprint match, you must use B<--force> to skip the scan check. Please do NOT: 1. Send exploits that are detected by cxs using the default options 2. Send exploits that are detected by ClamAV 3. Send excessive numbers of exploit examples 4. Send HTML defacement injections (e.g. iframe injections) 5. Send files unless you are sure they are exploits 6. Send files with --force unless it is a false-positive Failure to adhere to the above will result in your submissions being blocked. =item B<--quarantine [dir]> This option will move an uploaded Web script or user file that matches an exploit or virus to [dir]. To create a quarantine directory use the B<--qcreate [dir]> option. This option can also be used on manual or scheduled scans, however since the likelihood of a false-positive is relatively high, it is recommended that a strict B<--qoptions [mMfuSGchexTEv]> is used. FTP files, cxs Watch and manual scan files are moved to: /[dir]/cxsuser/{username}/{file}.{timestamp} Web script files are moved to: /[dir]/cxscgi/{file}.{timestamp} A restore file is also created in the same directory as the quarantined file for use through the UI as {file}.{timestamp}.restore4 To restore files from quarantine you must use either the cxs UI through either the installed control panel or via csf (see B), or, use the B<--qrestore [file]> option. It is not possible to restore a file for a web script as the destination filename is not known. Note: Do B place the quarantine directory within a user account. It must be created in a location accessible to all user accounts, e.g. /home, /backup =item B<--qcreate [dir]> Use this option together with B<--quarantine [dir]> to create a cxs compatible quarantine directory structure. This will create the following structure: /[dir]/ - owned by root:root, chmod 0755 /[dir]/cxscgi/ - owned by root:[defapache user], chmod 0730 /[dir]/cxsuser/ - owned by root:root, chmod 0600 =item B<--qlocal> When using the ModSecurity hook and running Apache under mod_ruid2, ModSecurity runs under the user account that owns a script, rather than the standard apache account (e.g. "nobody" on cPanel servers). This prevents cxs accessing a globally defined quarantine directory due to security constraints. To work around this issue, you can use the B<--qlocal> option on the cxs command in /etc/cxs/cxscgi.sh. This will instruct cxs to use a directory in the local user account called .quarantine, e.g. /home/someuser/.quarantine/ cxs will create this directory as needed and store quarantine files for ModSecurity in this directory. Caveats: 1. You must still specify a valid global --quarantine [dir] option on the command line in /etc/cxs/cxscgi.sh 2. You will not be able to view the quarantined files within the /home/someuser/.quarantine/ directory through the cxs UI 3. To view those quarantine files you must use the --qview [file] command from the root shell 4. You cannot use --qclean [days] on the local quarantine directories =item B<--qrestore [file]> Use this option to restore a quarantine file (as reported in the quarantine email or report) to the original file location. A file must not exist at the original location, i.e. this option will not overwrite a file that has been created since it was placed in quarantine. =item B<--qignore [method]> Use this option when restoring a quarantine file using B<--qrestore [file]> to add an ignore entry to a specified B<--ignore [file]> before the file is restored. The available ignore entries for the restored file can be made using the following [method] values: MD5 - creates an md5sum: entry in the ignore file FILE - creates a file: entry in the ignore file It is recommended to use the MD5 method to uniquely identify the ignore file incase the restored file becomes exploited in the future. =item B<--qview [file]> Use this option to view a quarantine file (as reported in the quarantine email or report). Alternatively, if you view [file].restore4 then you can see the details of the quarantined file along with the reason for quarantine (similar to the UI). =item B<--deep> This option will scan all text files for all regex and fingerprint matches which will obviously take longer. The default, without B<--deep>, checks for php and perl file extensions and file types (using file magic) and scans each appropriately. =item B<--defapache [user]> This is the default account under which apache runs. This will be set to "apache" by default except on cPanel servers where it is set to "nobody" by default. If a different default apache user is being used, then this option should be set appropriately on all cxs commands. This is the account under which ModSecurity runs. =item B<--decode [file]> This option will attempt to recursively decode PHP [file] which contains base64 or rot13 encoded data that is passed through the eval() statement and display the result. This is not a foolproof option and it may not produce meaningful results. An additional option B<--depth [num]> is included so that the final result can be stopped at a specific depth level rather than recursing to the end. Once decoding is complete cxs will run a deep scan against the result. =item B<--block> This option will enable cxs to block FTP connections uploading suspicious files. Careful consideration should be made before using this option in cxsftp.sh as there is a significant risk of false-positives with using this option for two reasons: 1. It's relatively easy for an innocent user to upload a file that could trigger one of the scan results 2. The FTP IP address isn't completely reliable (see B) See the section B below. =item B<--MD5> This option will display the md5sum of a file that obtains a hit when B<--options [m]> triggers a match during a scan. Under those circumstances, an md5sum: entry in a B<--ignore [file]> will ignore the file. An md5sum: entry in a B<--xtra [file> will match the file as a known exploit, i.e. as an B<--options [M]> hit. =item B<--prenice [num]> B<--pionice [num]> These options allow you to control the nice and ionice priorities of the running process. This can, for example, help even out the load on heavy IO servers, increase the speed of the scan on busy servers, help avoid conflicts with backups. You must have a kernel that supports ionice and have the renice and ionice binaries installed to use this feature. The renice value must be a whole number between -20 and 20, the ionice must be a whole number between 0 and 7. See the individual B pages for B and B to understand what the values mean and what effect they have on the running process. The ionice scheduling class is set to "Best effort". =item B<--background> This option will force cxs to run as a detached background process. For this reason you must specify either B<--report [file]> or B<--mail [email]> when using this option otherwise you won't see any results. The option can be used with interactive, cron or FTP upload scans, but not with web upload scans. Note: If you use this option in cxsftp.sh it may help ftp performance, but it will likely add significant load to the server with high ftp throughput as scans will no longer be queued by the pure-uploadscript process. =item B<--throttle [num]> This option will force cxs to sleep for 60 seconds if the one minute load average is greater than [num]. cxs performs the load check every 60 seconds. If the load average on the server is continuously high when cxs is running the process will take much longer to complete, so care should be taken when specifying this option. =item B<--sizemax [bytes]> This option will restrict scanning for regex matches in script files to only the initial [bytes] of text. This does not apply to virus scanning. Compressed archives > [bytes] in size will be ignored. =item B<--timemax [secs]> Scan timeout per file in seconds, default is 30 seconds. this value cannot be set lower than 20 seconds to allow for effective php decoding. =item B<--filemax [num]> This option will prevent scanning of a directory B if there are more than [num] resources contained within this directory level. Set this value to 0 to not skip based on this setting. =item B<--[no]summary> If you want to disable summary statistics then use B<--nosummary>. Doing so will also force cxs to only report accounts with suspicious files when using the B<--allusers> and B<--mail [email]> options. However, B<--report [file]> will still display a full report. =item B<--upgrade> If cxs is scheduled, via cron, to check for a new version daily, an additional check for new Exploit Fingerprints released since the last cxs version is performed. These will be downloaded and used on subsequent scans. If the upgrade needs to be redone B<--force> can also be used. =item B<--options [T]> If you do not want to allow any script uploading via web scripts include this option which will identify: PHP, Perl, C and other scripts that use a shebang (#!) Note: This could cause problems for people using a CMS to manage their site You could also use this option when scanning vulnerable directories such as /tmp or /dev/shm B If you want to only detect some script types, use the B<--tscripts [list]> option. =item B<--options [E]> This option will match scripts that send out email using sendmail, exim or via SMTP. This option requires that B<--options [m]> is also specified. =item B<--options [W]> This option will chmod all world writable directories found to 755. Use this option with care as it could prevent web scripts from functioning on non-suPHP or non-SUEXEC enabled systems. In cxs Watch, only new directories immediately chmod to 777 will be detected. Old directories or new ones that have already been scanned will not be scanned for this option. You should use a daily manual scan to check for such directories. =item B<--options [D]> This is an option that puts any PHP scripts containing a eval() function that decodes base64/rot13 information through the B<--decode [file]> option during a scan. This will then highlight the decoded result if it hits any regex, fingerprint or virus scan matches. This option will add a performance and time overhead to any scans, which could be significant. However, it does make cxs much more effective. See also the B<--decode [file]> description. =item B<--options [R]> This option will trigger a match for the inbuilt regex used by B<--options [D]> when decoding PHP encoded (base64, etc.) scripts =item B<--options [P]> This option will search standard web application configuration files for MySQL database passwords. It will then attempt to login via FTP on localhost with the username of the account being processed and the detected password (it will attempt up to two password hits per configuration file). If the login is successful, the option will trigger a match. The intention of this option is to help prevent exploitation of the server by uploaded exploits that trawl through web application configuration files for passwords that match user accounts and then gain access to that account via FTP or the server Control Panel. Any matches should prompt you to have the user change either their database or Control Panel/user account password so that they are different to avoid this common exploitation method. This option will use additional resources during the scan process as it tries FTP logins for config file matches. This option can only be used with the B<--allusers> or B<--user [user]> options. =item B<--Wstart> Starts the cxs Watch daemon, see B =item B<--Wstop> Stops any running cxs Watch daemon, see B =item B<--Wadd [file]> To add additional resources to watch you can specifically list them within [file] and the will be included when the cxs Watch daemon starts. If the file is changed, the cxs Watch daemon must be restarted. For example, to scan files in /dev/shm add that to a file (e.g. /etc/cxs/cxs.wadd) and then use the B<--Wadd [file]> option to also scan them (--Wadd /etc/cxs/cxs.wadd). =item B<--Wchildren [num]> Use this option to increase the number of child processes started by the cxs Watch daemon to scan files. On a server with mostly static pages and little activity, you could reduce the number. On a very active server, increasing the number will mean that files are processed more quickly. =item B<--Wsleep [num]> Wsleep forces the cxs Watch daemon to go to sleep for the number of specified seconds after each process run of modified files. A value of 0 means that files will be processed as soon as they have been modified. This is good because any suspicious files will be processed immediately. However, on a very busy server with a lot of continuous file updates, this would mean that files may be processed multiple times per second. In this case, it may be a good idea to set this value higher (e.g. 5) to allow file updates to accumulate before they are processed. Additionally the B<--throttle [num]> option can be used for the daemon process to help alleviate additional load if desired. However, this in turn can cause a backlog of files to scan. =item B<--Wloglevel [num]> The higher the value of [num] the more verbose the log file information will be for the cxs Watch daemon in /var/log/cxswatch.log. By default the value is set to 0. For more detailed information, set to 1. For maximum detail set to 2. Be aware that a log level of 2 will provide a great deal of information and the log file will grow in size rapidly on evenr the quietest of systems. So this setting is best set to 2 only for short periods. =item B<--Wrefresh [days]> To keep the cxs Watch daemon up to date, it will restart every 7 days by default. To change this interval, you can set B<--Wrefresh [days]>. =item B<--Wrateignore [secs]> If a file is scanned more then (2 * B<--Wsleep [num]>) times in (10 * B<--Wsleep [num]>) seconds then a warning is logged. This is to help identify frequently scanned files that you might want to ignore (e.g. if they are very frequently updated log files). To help prevent excessive resource usage, cxs Watch will ignore files for [secs] seconds if the warning above is issued. Scanning will then resume. Set this to 0 to disable the ignore feature. Ignored resources are rescanned once [sec] expires. If B<--Wsleep [num]> is set to 0, then the trigger values will be more than 2 times in 10 seconds. =back =head1 UNDOCUMENTED/UNSUPPORTED OPTIONS No support is provided for cxs, including submission of undetected exploits, if any of these options are used. These options may be removed at any time which will, for example, break scheduled cron jobs if they are used. =over 8 =item B<--YSKIPREG> Ignore inbuilt regex matching when using B<--options [m]>, B<--xtra [file]> contents will still match. =item B<--YSKIPMD5> Ignore all inbuilt fingerprint matching when using B<--options [M]>, B<--xtra [file]> contents will still match. =item B<--YSKIPFPREGEX> Ignore inbuilt fingerprint regex matching when using B<--options [M]>, B<--xtra [file]> contents will still match. =item B<--YCMD> Print the intended complete CLI command and do not execute. =item B<--YCLAMSCAN> Alternative to the pre-configured paths for clamscan and the option. This should be the full path to the clamscan binary, e.g.: --YCLAMSCAN /opt/bin/clamscan =item B<--YCONREP [file]> Same as B<--report [file]> except console ASCII colour-coded output to [file] =item B<--YSKIPWMAIL> If --options [W] or --options [wW] is triggered, then the directory will be chmod as normal but no email will be sent. If any other option is triggered for the same scan, the email will still be sent. This option only applies to cxs Watch. =item B<--YRATECNT [num]> and B<--YRATESEC [secs]> To manually set the detection rate for B<--Wrateignore [secs]> these values can be set such that: If a file is scanned more then B<--YRATECNT [num]> times in B<--YRATESEC [secs]> seconds then a warning is logged. The file will then be ignored for B<--Wrateignore [secs]>. Note: If either is set, both must be set to more than 0 otherwise both settings will be ignored. =back =head1 OTHER FILES & INFORMATION =over 2 =item B The installation document for this application. =item B The Exploit Scanning Reference document that explains the different exploit scanning options reported by cxs. =item B The database of exploit fingerprints. The file needs to have world read access (B<644>) to allow Web script file upload scanning. =item B If you create this file you can add default options for cxs. For example, you might want cxs to always use --clamdsock /some/other/path/to/socket The file is a simple list of option=value statements, e.g.: clamdsock=/some/other/path/to/clamd.socket ignore=/etc/cxs/cxs.ignore virusscan=0 The file needs to have world read access (B<644>) to allow Web script file upload scanning. Note: Options used on the command line will override the default settings. =item B See also B below. Create this as an empty file if you want to completely disable access to the User Interface, e.g.: touch /etc/cxs/cxs.disableui =item B This disables features in the UI that could allow abritrary commands to be run as root and system files to be overwritten. Create this as an empty file if you want to enable Restricted Mode access to the User Interface, e.g.: touch /etc/cxs/cxs.restricted =item B Controls the startup of the daemon process that handles the socket interface between pure-ftpd and cxs. If either of the following files exists the process will not start: /etc/ftpdisable /etc/cxs/ftpddisable If you have problems with FTP access with this enabled, you need to restart pure-ftpd through this script using: service pure-uploadscript restart This will recreate the socket that pure-ftpd uses to communicate with the pure-uploadscript process. =item B FTP IP addresses are determined by scanning the relevant pure-ftpd log for the IP address, first by trying to find an account and file match, if not found the last successful login via pure-ftpd for the affected account. This could lead to false-positives, so care should be taken before blocking the IP addresses reported by cxs. =item B This is an alternative to ftp and web script upload scanning. The cxs Watch daemon uses a separate process to constantly watch entire user accounts for new and modified files and scans them immediately. The scanning children use up significantly fewer resources than the ftp and web script upload scanning methods. This feature requires: Redhat/CentOS v5+ (i.e. a kernel that supports inotify) Linux::Inotify2 Perl module Systems that do not meet these requirements can continue to use the ftp and web script upload scanning methods. See the documentation for more information about this new option. To use B<--Wstart> and start the daemon you need to use it as if performing a normal cxs scan but include this option, e.g.: cxs --Wstart --www --allusers However, it is recommened that instead of doing this directly, you should use the provided /etc/cxs/cxswatch.sh script to configure the cxs Watch daemon and the /etc/init.d/cxswatch (or systemctl on systemd) init script to control it. This is so you do not forget what options you use every time you start the daemon. You should edit /etc/cxs/cxswatch.sh and change the command line to suit your requirements and then you can: 1. Enable the init script so that cxswatch starts at boot time: chkconfig cxswatch on 2. Start the daemon: /etc/init.d/cxswatch start If using systemd: 1. Enable the service so that cxswatch starts at boot time: systemctl enable cxswatch.service 2. Start the daemon: systemctl start cxswatch.service You can only have one cxs Watch daemon running at a time. If you make configuration changes you will need to restart the daemon, e.g.: /etc/init.d/cxswatch restart Or on systemd: systemctl restart cxswatch.service To disable the cxswatch daemon after enabling it through the init script: chkconfig cxswatch off /etc/init.d/cxswatch stop Or on systemd: systemctl stop cxswatch.service systemctl disable cxswatch.service All of the relevant cxs scanning commands apply to the CLI for this option. See the limitations of the cxs Watch daemon in the B section. The cxs Watch daemon logs scanning activity to /var/log/cxswatch.log To enable monitoring the cxswatch daemon in cPanel servers, you should go into WHM > Service Manager > and tick both boxes for cxswatch, then Save. The cPanel tailwatchd daemon will then restart cxswatch if it is not running. On cPanel servers, cxswatch will automatically start watching the directories of newly created accounts when using B<--allusers>. On other platforms, if you want to automatically have the cxs Watch daemon add new accounts when using B<--allusers> you need to create an empty file in /etc/cxs/newuser with the username of the new account. cxs Watch scans that directory and on finding a new account name will start monitoring it. For example, to add a new account that has already been generated called "iamnew", you could use: touch /etc/cxs/newusers/iamnew If cxs is upgraded to a new version and the cxs Watch daemon is running it will be automatically restarted with the same command. If an ignore file us used with cxs Watch daemon and the ignore file is modified, cxs Watch will reload the ignore file and restart the child processes. However, after making a large number of changes to the ignore file or if adding puser: or user: to the ignore file, the cxs Watch daemon should be manually restarted. =item B We would recommend using B<--virusscan> for the PHP, CGI and FTP uploads. There can be a performance overhead using ClamAV for multiple files which means that the scan will run for longer using more resources when performing user and large directory scans. For this reason it might be sensible to use B<--voptions [options]> for such scans. On systems where users store large amounts of email, it might also be sensible to use the example mail ignore regex provided in /etc/cxs/cxs.ignore.example for user scans. PHP and Perl CGI B is performed on the temporary file created before the data is passed back to the initiating web script. This means that cxs cannot determine what the destination file will be as it is up to the calling script to determine that. This means that you will not be notified of the actual file that a web script creates with the data from the uploaded file. For this reason it would be sensible to enable the B<--delete> or B<--quarantine [dir]> option in /etc/cxs/cxscgi.sh. It is also for this reason it isn't possible to restore such files from quarantine. The B scans files after they have been uploaded via FTP. This means that if the --delete option is used, the end user will not know that the uploaded file has been removed during the FTP session. It also means that cxs is deleting a file within the users account and so great care should be used when considering use of the --delete option here. Since in this case the destination file is known it may not be sensible to enable --delete in /etc/cxs/cxsftp.sh, though using B<--quarantine [dir]> is a good idea. You can restore such files from quarantine through the UI. A much more efficient way to use cxs is via the B. This daemon process is able to perform file scanning using fewer server resources, more quickly and more comprehensively, and can process and remove all suspicious files regardless of how they are uploaded. The main disadvantages of this method are: inotify must be enabled for every directory being watched which could be a very IO intensive operation when starting the daemon and could take some time on servers with large amounts of data and/or large numbers of user accounts; there will be no feedback to the end-user with file uploads being quarantined or deleted (much the same as the ftp method); there is no way to block IP addresses; homedir ignore settings will not work for any files not owner by the user (e.g. the apache default user); the additional server requirements. =item B If the server running cxs doesn't have a supported UI through a control panel, the cxs UI can be used through the csf Integrated User Interface. To do this, enable the option UI_CXS after having configured the csf UI. If you want to block web script upload IP addresses, use the LF_CXS option in csf. If you want to block FTP upload IP addresses use the B<--block> option in cxs, but be aware of the limitations of this option mentioned in B<--block>. =back =head1 REQUIREMENTS =over 2 B B Redhat/CentOSCloudLinux v4/5/6 (Redhat/CentOSCloudLinux v5/6+ OS vendor kernel or custom kernel with inotify support for cxs Watch) B: Archive::Tar Archive::Zip Digest::MD5 File::Basename File::Copy File::Find File::stat Getopt::Long IO::Socket::UNIX IPC::Open3 Linux::Inotify2 LWP::Protocol::https LWP::UserAgent MIME::Base64 Net::FTP Net::SMTP Pod::Usage Storable Time::HiRes B daemon process for virus scanning B (not supported for litespeed, nginx, etc. - only Apache v2+) B compiled with --with-uploadscript for ftp upload scanning B web upload scanning can only be performed on files uploaded via the HTML ENCTYPE multipart/form-data B ModSecurity and pure-ftpd are not required if using the cxs Watch daemon. See alternative requirements for this method above). =back =head1 RECOMMENDATIONS =over 2 1. Create a quarantine location, e.g.: cxs --qcreate --quarantine /home/quarantine 2. Use the example ignore file provided and amend to your needs: cp /etc/cxs/cxs.ignore.example /etc/cxs/cxs.ignore 3. Create a daily cron job to check for cxs updates and new Exploit Fingerprints and to tidy up the quarantine directory, e.g.: ln -s /etc/cxs/cxsdaily.sh /etc/cron.daily/ 4. Create a daily and weekly cron job to scan all user accounts e.g. create /etc/cron.d/cxs-cron and add: @daily root /usr/sbin/cxs --report /root/scan.log --www --mail root --virusscan --voptions fmMhexT --quarantine /home/quarantine --qoptions Mv --ignore /etc/cxs/cxs.ignore --options OLfmMChexdDZRP --ctime 25 --all @weekly root /usr/sbin/cxs --report /root/scan.log --www --mail root --virusscan --voptions fmMhexT --quarantine /home/quarantine --qoptions Mv --ignore /etc/cxs/cxs.ignore --options OLfmMChexdDZRP --all 5. Enable ModSecurity cxs scanning (see install.txt) via /etc/cxs/cxscgi.sh 6. If on a supported platform, run the cxs Watch daemon on all user web scripts (see install.txt) via /etc/cxs/cxswatch.sh 7. If not on a supported platform for cxs Watch, or if preferred, enable pure-ftpd cxs scanning (see install.txt) via /etc/cxs/cxsftp.sh 8. Run a manual scan: /usr/sbin/cxs --report /root/scan.log --www --mail root --virusscan --voptions fmMhexT --ignore /etc/cxs/cxs.ignore --options OLfmMChexdDZRP --all 9. We strongly recommend that you subscribe via RSS to our blog to stay informed of updates to cxs and our other applications: ConfigServer Blog: http://blog.configserver.com =back =head1 EXAMPLES =over 2 These are examples of how you can run cxs on the command line with an explanation of what each example does: 1. Create a report file; do not virus scan; use the ignore file; only do selected scan options; scan all users: cxs --report /root/scan.log --novirusscan --ignore /etc/cxs/cxs.ignore \ --options OLmMfuSGChexdR --allusers 2. Create a report file; use the ignore file; only do selected scan options; only virus scan selected file types; scan all users: cxs --report /root/scan.log --ignore /etc/cxs/cxs.ignore --options \ mMfuhexdR --virusscan --voptions mfuhexT --allusers 3. Email scan report to root; use all scan options including "no scripts"; scan directory /tmp: cxs --mail root --options mMOLfSGcChexdnwDZRT /tmp 4. Process /root/scan.log and append to ignore file /etc/cxs/cxs.ignore cxs --generate --report /root/scan.log --ignore /etc/cxs/cxs.ignore =back =head1 AUTHOR =over 2 Copyright 2009-2016, Way to the Web Limited URL: http://www.configserver.com Email: sales@waytotheweb.com =back =cut