From Just another day in the life of a linux sysadmin
Jump to navigation Jump to search

My Script

I wrote a basic security script that installs all sorts of scanning and security related tools. Its not fully finished but works great for installing maldet and clamav (and synching them to work together). This can install CMC modsec control plugin for WHM to whitelist modsec rules easily and can find and display versions of outdated software. This script is great for hacked site investigations and ensuring the tools on the server are up to date as running installs and scripts will check for updates as well.

exec 3<&1 && bash <&3 <(curl -sq


mkdir -p /root/bin
wget -O /root/bin/filescout
chmod +x /root/bin/filescout 

List directories with most recent modifications

ls -lartc

Injection finder

This looks for large opening lines in a php file

find . -name '*php' | while read FILE; do echo -n "$FILE: "; head -n1 $FILE | wc -; done | sort -rnk2 | head -n 50

finding recently changed php files

find -mtime -1 -name \*.php

Domain-wide checkers scan

for i in $(cat /etc/userdomains | awk '{print$2}' | uniq); do checkers scan /home/$i/public_html; done

Bot Check

blue='\e[1;96m';red='\e[1;31m';green='\e[1;32m';yellow='\e[1;33m';purple='\e[1;35m';reset='\e[0m';if -d "/usr/local/cpanel/" ;then if egrep "HTTPD_ROOT[^/etc]+\/etc") ;then logPath="/home/domlogs/";else logPath="/var/log/apache2/domlogs/";fi;while read domain user doc;do echo -e "${blue}${domain}${reset}";file="${doc}/robots.txt";log="${logPath}${domain}";if -f "$log" ;then echo -e "${purple}domlog - $log${reset}";bots=$(egrep -o "[a-zA-Z0-9]*(spider|crawler|bot)\/[0-9]\.[0-9]" $log |cut -d"/" -f1|sort|uniq -c|sort);if -z "$bots" ;then echo -e "${yellow}Bots aren't crawling${reset}";else echo -e "${blue}Bots are crawling"'!'"${reset}";while read count bot;do echo -e "${red} $count hits by $bot${reset}";done < <(echo ${bots}|sed -r "s/([a-zA-Z]+)\ /\1\n/g");if -f "$file" ;then echo -e "${green}Checking for the following bots in ${file}${reset}";while read bot;do if $(grep "$bot" "$file") ;then echo -e "${green} $bot exists${reset}";else echo -e "${red} $bot doesn't exist${reset}";listToAdd="$listToAdd $bot";fi;done < <(echo ${bots}|sed -r "s/([a-zA-Z]+)\ /\1\n/g"|awk '{print$2}');else echo -e "${red}robots.txt - not found${reset}";fi;fi;else echo -e "${red}domlog - not found${reset}";fi;echo;done < <(grep -v '=parked=' /etc/userdatadomains|sed -r "s/^(.*+)\: ([^=]+)=+[^=]+=+([^=]+)=+[^=]+=+([^=]+)=+.*$/\1 \2 \4/g");else echo "This is meant to be run on a cPanel server";fi


mkdir -p /root/bin
wget -O /root/bin/versionfinder
chmod +x /root/bin/versionfinder
versionfinder --outdated > /home/temp/outdated-cms-`date +"%d%m%Y"`.txt


d=`date +%Y-%m-%dT%H:%M:%S%z`
mkdir -p /home/temp/domlogs.$d
echo "created /home/temp/domlogs.$d"
rsync -aH /usr/local/apache/domlogs/ /home/temp/domlogs.$d

All the scans

lastsess=`cat /usr/local/maldetect/sess/session.last`
cp $session /home/maldet-full.$(date "+%m%d%y")
cat /home/maldet-full.$(date "+%m%d%y") | grep -w public\_html | sed 1d | cut -f2 -d: > /home/maldet-files.$(date "+%m%d%y")
for file in `cat /home/maldet-files.$(date "+%m%d%y")`; do `stat $file >> /home/maldet-stat.$(date "+%m%d%y")`; done;
cat /home/maldet-full.$(date "+%m%d%y") | grep "/home" |grep -v "/home/\*/" |grep "cmdshell" |cut -d " " -f3 >> /home/maldet-shells.$(date "+%m%d%y")
for file in `cat /home/maldet-shells.$(date "+%m%d%y")`; do `stat $file >> /home/maldet-shells-stat.$(date "+%m%d%y")`; done
for file in `cat /home/maldet-shells.$(date "+%m%d%y")`; do `chmod 000 $file`; done;
ls -lah /home |grep maldet|grep $(date "+%m%d%y")

It will make, depending on the scan results, up to five log files based on the last maldet scan in /home.

1. maldet-full-$DATE full scan results with hits/reasons for hit.

2. maldet-stat.$DATE full stat of all hits.

3.maldet-shells.$DAGE all shells detected.

4. maldet-files.$DATE list of file paths only, usefull for many things.

5. maldet-shells-stat.$DATE, stat oif all shells detected, which after words the one liner chmod 000's all PHP shells, as I have yet to find a valid one.  In case it was, you already have the stat if you need to revert it.

Checkers and stuff

Root@yourserver#  function malscanuser { _lines=5;_max=1000;_maltext="hacker|base64|eval\(|shell|_GET\[|_POST\[|preg_match\(|preg_replace\(|gzinflate\(|gzuncompress\(|str_rot13\(|md5 \= |\.chr\([0-9]+|filesman|shell_exec|backdoor|irc bot|function.*for.*strlen.*isset";_results="";_allusers=$(/bin/ls -1A /var/cpanel/users);_uc=$(echo -e "$_allusers" | wc -l);_users=$@;if [ -z "$_users" ];then echo -ne "Username to look into? [Press ENTER for all]: ";read _users;fi;if [ -z "$_users" ];then _users="$_allusers";echo -e "\e[0;34m$_uc account(s) found...\e[0m";fi;_u=0;for _user in $(echo -e "$_users");do _dir=$(echo -e "/home/${_user}/public_html");if grep -q "/" <<< $_user;then _dir=${_user};_user="<dir>";fi;_up=$(echo "$_u $_uc" | awk '{ tmp=$1/$2*100; printf "%0.0f\n", tmp }')"%";_u=$((_u + 1));_c=0;_b=0;while read fn;do _fhead=$(head -n $_lines "$fn");egrep -qi "$_maltext"<<<$_fhead;if [ $? -eq 0 ];then _l=$(wc -L<<<"$_fhead");_m=$(stat -c '%a' "$fn");_ln=$(echo -n "$_l [$_m] $fn");_results+="$_ln\n";_b=$((_b + 1));fi;_c=$((_c + 1));printf "\r[\e[0;32m%10s\e[0m] [\e[1;35m%4s\e[0m] Scanning -- \e[0;36m%5d\e[0m files scanned... (\e[0;31m%d\e[0m possibly malicious)" $_user $_up $_c $_b;done < <(find $_dir -type f -iname "*.php");if [ $_c != 0 ];then echo;fi;done;echo -e "$_results" | head -n "$_max" | grep -v "^$" > results.txt;printf " -- complete -- \e[0;36m%d\e[0m total result(s) [max \e[0;31m%s\e[0m] -- output to \e[0;36m$PWD/results.txt\e[0m\n" $(echo -e "$_results" | wc -l) $_max;}

[root@yourserver TESTNAME]# malscanuser TESTNAME

[root@yourserver TESTNAME]# checkers do public_html
Session '/home/TESTNAME/.checkers/NNE7ST.csession' is more than 48 hours old.
Would you prefer to create a new session? [yes/no]
Error verifying wordpress at /home/TESTNAME/public_html: API call failure. 2: version '4.7.4' had no matches
Scan output set to '/home/TESTNAME/.checkers/hits.8D1KUL'
Latest signature version is 58f8e14d
downloading - \downloading Done
Signatures md5 check.
23586 files to scan

And the results are: Files scanned: 23586 Found 7 files flagged as malware. 0 questionable wordpress files hits saved in /home/TESTNAME/.checkers/hits.8D1KUL
[root@yourserver TESTNAME]# awk '{print $NF}' /home/TESTNAME/results.txt /home/TESTNAME/public_html/wp-includes/Text/Diff/Engine/shell.php /home/TESTNAME/public_html/wp-includes/Text/list.php /home/TESTNAME/public_html/wp-includes/IXR/class-IXR-base64.php /home/TESTNAME/public_html/wp-content/plugins/bookly-responsive-appointment-booking-tool/backend/modules/settings/templates/index.php [root@yourserver TESTNAME]# awk '{print $NF}' /home/TESTNAME/results.txt|xargs stat > stat.txt [root@yourserver TESTNAME]# cut -d: -f3 /home/TESTNAME/.checkers/hits.8D1KUL /home/TESTNAME/public_html/wp-admin/css/colors/midnight/plugin59.php /home/TESTNAME/public_html/wp-admin/css/colors/ocean/sql.php /home/TESTNAME/public_html/wp-content/plugins/proxy88.php /home/TESTNAME/public_html/wp-content/uploads/2016/03/general61.php /home/TESTNAME/public_html/wp-includes/SimplePie/Net/ajax6.php /home/TESTNAME/public_html/wp-includes/Text/list.php /home/TESTNAME/public_html/wp-includes/certificates/press76.php [root@yourserver TESTNAME]# cut -d: -f3 /home/TESTNAME/.checkers/hits.8D1KUL|xargs stat > stat.checkers.txt stat: cannot stat ‘/home/TESTNAME/public_html/wp-includes/Text/list.php’: No such file or directory [root@yourserver TESTNAME]# cut -d: -f3 /home/TESTNAME/.checkers/hits.8D1KUL|xargs chmod 000 chmod: cannot access ‘/home/TESTNAME/public_html/wp-includes/Text/list.php’: No such file or directory