# Copyright 2020 FireEye, Inc. and Citrix Systems, Inc.
# FreeBSD/NetScaler bash doesn't support array declaration shortcut
# so we create the array by hand... I'm sorry.
declare -a ns_content_blacklist;
ns_content_blacklist[0]="template.new";
# don't match "execute" which is found in /netscaler/portal/templates/homepage.html
ns_content_blacklist[1]="exec[^u]";
ns_content_blacklist[2]="\`";
# /netscaler/portal/scripts/subscription.pl contains the line:
# eval(handle_subscriptions());
ns_content_blacklist[3]="eval([^h][^a][^n]";
ns_content_blacklist[4]="bash";
ns_content_blacklist[5]="ns.conf";
ns_content_blacklist[6]="curl";
ns_content_blacklist[7]="wget";
# seen in webshells
ns_content_blacklist[8]="Encode::decode(chr(";
ns_content_blacklist[9]="}exit";
# ref: https://github.com/projectzeroindia/CVE-2019-19781/blob/master/CVE-2019-
19781.sh#L22
ns_content_blacklist[10]="pwnpzi1337";
ns_content_blacklist[11]="test1337";
# ref: https://github.com/trustedsec/cve-2019-19781/blob/master/citrixmash.py
ns_content_blacklist[12]="chr(";
# FireEye has seen actors copying the /flash/nsconfig/ns.conf file to a template so
that it can be fetched remotely.
# Look for the header associated with the ns.conf file, like: `#NS12.1 Build 51.19`
ns_content_blacklist[13]="^\#NS";
# IP of host serving EternalBlue scanner/exploiter
ns_content_blacklist[14]="45.120.53.214";
ns_content_blacklist[15]="eternalblue.replay";
ns_content_blacklist[16]="scan.py";
ns_content_blacklist[17]="x64.dll";
ns_content_blacklist[18]="x86.dll";
ns_content_blacklist[19]="xp_eternalblue.replay";
# match filename `ld.sh` without matching `build.sh`
ns_content_blacklist[20]="[^i]ld.sh";
ns_content_blacklist[21]="piz.Lan";
ns_content_blacklist[22]="de.py";
ns_content_blacklist[23]=".new.zip";
ns_content_blacklist[24]="/tmp/rAgn";
# other activity
ns_content_blacklist[25]="198.44.227.126";
ns_content_blacklist[26]="/tmp/l.sh";
declare -a ns_exploit_dirs;
ns_exploit_dirs[0]="/netscaler/portal/templates/";
ns_exploit_dirs[1]="/netscaler/portal/scripts/";
# ref: https://github.com/x1sec/CVE-2019-19781/blob/master/CVE-2019-19781-DFIR.md
#
# note: this directory is synced between devices in an HA pair setup.
# this means that content dropped here by attackers onto a compromised device may
# be copied to the standby device.
# the standby device was not directly exploited, but does have attacker content.
# this should at least be cleaned, and possibly investigated.
ns_exploit_dirs[2]="/var/vpn/bookmark/";
ns_exploit_dirs[3]="/var/tmp/netscaler/portal/templates/";
# Search the files in the given path for blacklisted terms.
# The blacklist is found above, at `ns_content_blacklist`.
#
# args:
# path - path to search, relative to root.
scan_ns_directory_content() {
local readonly path="$root_directory/$1";
if [ ! -d "$path" ]; then
debug "didn't find directory: $path";
return
fi
local found=false;
for re in "${ns_content_blacklist[@]}"; do
local entries=$(grep -lR "$re" "$path");
if [ -n "$entries" ]; then
found=true;
report_match "blacklisted content '$re'";
report "matches for '$re':";
report "$entries";
fi
done
if [ "$found" != true ]; then
debug "did not find blacklisted or suspicious content in $path";
fi
}
# Search the files in the given path for permissions like 'rw-r--r--' (644).
# It seems that files created during exploitation default to this mask.
#
# args:
# path - path to search, relative to root.
scan_ns_directory_perms() {
local readonly path="$root_directory/$1";
if [ ! -d "$path" ]; then
debug "didn't find directory: $path";
return
fi
# /var/vpn/bookmarks/ contains legit entries with prefix `bm_prefix_`
# on NetScaler versions after 13.0.47.24 (patch)
local entries=$(find "$path" -perm 644 | grep -v "bm_prefix_");
if [ -n "$entries" ]; then
report_match "incorrect file permissions";
report "files with permissions 644:";
report "$entries";
report "Please review the above paths for any unexpected files.";
report "Exploits commonly write to files with these permissions;"
report "however, customization of a Citrix NetScaler environment may cause
false positives in the above list."
report "For example, '/var/vpn/bookmark/[legitimate-username].xml' may be
valid in your environment."
else
debug "did not find incorrect permissions in $path";
fi
}
# Find files created in the templates directory that have been created since Jan 1,
2020.
# This seems to detect lots of activity; however, we're not sure how this interacts
with patches and customizations.
# Disabled for now, with preference towards the permission scanner.
scan_ns_new_templates() {
if [ ! -d "$root_directory/netscaler/portal/templates" ]; then
debug "didn't find templates directory";
return;
fi
local readonly entries=$(find "$root_directory/netscaler/portal/templates/"
-type f -newerct "2020-01-01" -print);
if [ -n "$entries" ]; then
report_match "recently created template";
report "recently created templates:";
report "$entries";
else
debug "did not find new files in /netscaler/portal/templates/.";
fi
}
# Find files created in the scripts directory that have been created since Jan 1,
2020.
# This seems to detect lots of activity; however, we're not sure how this interacts
with patches and customizations.
# Disabled for now, with preference towards the permission scanner.
scan_ns_new_scripts() {
if [ ! -d "$root_directory/netscaler/portal/scripts" ]; then
debug "didn't find scripts directory";
return;
fi
local readonly entries=$(find "$root_directory/netscaler/portal/scripts/" -type
f -newerct "2020-01-01" -print);
if [ -n "$entries" ]; then
report_match "recently created script";
report "recently created scripts:";
report "$entries";
else
debug "did not find new files in /netscaler/portal/scripts/.";
fi
}
scan_netscaler_content() {
for path in "${ns_exploit_dirs[@]}"; do
scan_ns_directory_content "$path";
scan_ns_directory_perms "$path";
done
# disabled, since we're not sure of the interaction with system updates and/or
customizations.
#scan_ns_new_templates;
#scan_ns_new_scripts;
}