Files
zira-etc/cxs/cxs.pod
2021-05-24 22:18:33 +03:00

1559 lines
56 KiB
Plaintext

=head1 ConfigServer eXploit Scanner
B<cxs> - Using ConfigServer eXploit Scanner
=head1 DESCRIPTION
B<cxs> will scan files, directories and user accounts for suspicious files,
potential exploits and viruses.
Note: cxs is B<not> a rootkit scanner, though it can detect rootkits uploaded
to user accounts.
=head1 SYNOPSIS
B<cxs [OPTION]... RESOURCE>
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<not> 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<must> 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<cxs and csf Integration>), 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<not> 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<FTP IP addresses>)
See the section B<cxs and csf Integration> 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<man> pages for B<renice>
and B<ionice> 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<and all its subdirectories>
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<Warning: Using this option will report ALL scripts as suspicious. Be sure
that you understand this before using it.>
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<cxs Watch Daemon>
=item B<--Wstop>
Stops any running cxs Watch daemon, see B<cxs Watch Daemon>
=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 <B--[no]fallback>
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</etc/cxs/install.txt>
The installation document for this application.
=item B</etc/cxs/reference.txt - Exploit Scanning Reference>
The Exploit Scanning Reference document that explains the different exploit
scanning options reported by cxs.
=item B</etc/cxs/cxs.fp>
The database of exploit fingerprints.
The file needs to have world read access (B<644>) to allow Web script file
upload scanning.
=item B</etc/cxs/cxs.defaults>
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</etc/cxs/cxs.disableui>
See also B</etc/cxs/cxs.restricted> 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</etc/cxs/cxs.restricted>
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</etc/init.d/pure-uploadscript>
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>
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<cxs Watch Daemon>
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<Performance and Restrictions>
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<Performance and Restrictions>
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<web script scanning> 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<pure-ftpd file scanner> 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<cxs Watch daemon>. 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<cxs and csf Integration>
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<cPanel/WHM - latest versions>
B<Redhat/CentOS/CloudLinux Linux>
Redhat/CentOSCloudLinux v4/5/6
(Redhat/CentOSCloudLinux v5/6+ OS vendor kernel or custom kernel with inotify
support for cxs Watch)
B<Perl modules>:
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<ClamAV> daemon process for virus scanning
B<ModSecurity v2+> (not supported for litespeed, nginx, etc. - only Apache v2+)
B<Pure-ftpd> compiled with --with-uploadscript for ftp upload scanning
B<Note:> web upload scanning can only be performed on files uploaded via the
HTML ENCTYPE multipart/form-data
B<Note:> 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