Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

grep whole server for shell hacks/malware

We host 1000s of domains on multiple servers. We have problems with massive amount of malware and phpshell's. The usage of many scanners had no effect in taking them down. maybe we got 10/20 vague results from those scanners

so i build my own little bash file to find those scripts. It found 148 phpshells this weekend ( im not that good at creating .SH files).



My question The grep is terrible slow, it will run for days. how can i make this script more efficient?

array=(
    "base64_decode(" 
    "substr(md5(strrev(" 
    "cwd = @getcwd();" 
    "chr((ord(" 
    "gzinflate(base64_decode(" 
    "php_uname()" "] = chr(ord(" 
    "cwd[strlen($cwd)" 
    "ini_get('safe_mode');" 
    "=\"\x62\"" 
    "\"+ r + \"&r=\" + document.referrer;\"" 
    "if(strtoupper(substr(PHP_OS, 0, 3) ) == \"WIN\")" 
    "window.top.location.href=\"http://" 
    "@ini_get(\"disable_functions\")" 
    "$g3='';$g3.=$r;$g3.=$h;$g3.=$y"
    "hacked"
)

for value in "${array[@]}"
do
    printf "\n[$value] [start => $(date +"%T")]\n"
        grep -l -inr "$value" "/home/"
    printf "\n[end => $(date +"%T")]\n"
done



FINAL RESULT

#!/bin/bash
LC_ALL=C grep -F -n -r -f /root/scanner/pattern.txt "/home/"

Pattern.txt

eval($___($__));
eval(stripslashes(@$_POST[
eval(stripslashes(array_pop(
eval(base64_decode(
eval(gzinflate(str_rot13(base64_decode(
gzinflate(base64_decode(
Array(base64_decode(
sha1(base64_decode(
print(base64_decode(
wsoScandir($dir)
substr(current(array_keys(
cwd = @getcwd();
$OOO000000=urldecode(
$l___l_='base'.(32*2)
substr(md5(strrev(
cwd[strlen($cwd)
="x62
+ r + "&r=" + document.referrer;
if(strtoupper(substr(PHP_OS, 0, 3) ) == "WIN")
){if(@copy(
copy("endless.html
system("wget
symlink("/","sym/root");
@copy($_FILES['file']['tmp_name']
error_reporting(0);if(
x6C\x28\x67\x7A\x69
"/.*/e","\x28\x65\x76\x61
preg_replace("/.*/e",
Windows-1251";preg_replace(
); exit(); } if(isset(
system("$cmd"); die;}
rtrim($security_code, "/");
like image 695
SinisterGlitch Avatar asked Apr 07 '14 07:04

SinisterGlitch


1 Answers

Store your search strings as a single multiline string, and run fgrep once instead of in a loop:

values="eval(base64_decode(
gzinflate(base64_decode(
cwd = @getcwd();
chr((ord(
substr(md5(strrev(
chr(ord(
cwd[strlen(\$cwd)
ini_get('safe_mode');
=\"\x62\"
\"+ r + \"&r=\" + document.referrer;\"
if(strtoupper(substr(PHP_OS, 0, 3) ) == \"WIN\")
window.top.location.href=\"http://
@ini_get(\"disable_functions\")
){if(@copy(
eval(\$___(\$__));
copy(\"endless.html\"
system(\"wget
symlink(\"/\",\"sym/root\");
@copy(\$_FILES['file']['tmp_name']
error_reporting(0);if(
x6C\x28\x67\x7A\x69\x6E\x66\x6C\x61\x74
hacked"

LC_ALL=C fgrep -nr --include  \*.php "$values" *

This version runs 22x faster than the original (0.535s vs 11.817s on one fairly large site). Noncoincidentally, you have 22 search strings.

PS: Don't forget to \ your $ inside of "", or you won't find your 15th and 19th search strings. I would create a test file that has all the strings you're searching for, and verify that the fgrep "$values" successfully matches each of them.

like image 170
webb Avatar answered Sep 23 '22 08:09

webb