Advertisement
Googleinurl

[+] WebShell Scanner LookForBadGuys

Aug 31st, 2012
805
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.92 KB | None | 0 0
  1. <?php
  2. /*
  3. Créditos: http://www.pearsonified.com
  4.     lookforbadguys.php   3-10-2011
  5. --Purpose: iterate through server files looking for hacker code snippets, backdoor scripts,
  6. .htaccess redirects, and suspicious file names.
  7. -- Caveats: Not all things it finds are hacks. Not all hacks are found.
  8. --You should look also for weird files (such as .php files) in your image directories, especially
  9. if your .htaccess has redirects or was made executable.
  10. --Some searches are commented out because they can give too many false positives.
  11. --This script should work the same on a Linux or Windows server.
  12. It runs fast in Linux/Apache/PHP, and very slowly in Windows/Apache/PHP.
  13.  
  14. */
  15. ?>
  16. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  17. <head>
  18. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  19. <meta http-equiv="Content-Language" content="en-us">
  20. <title>Looking for bad guys</title>
  21. </head>
  22.  
  23. <body>
  24. <p>Looking for bad guys. </p>
  25. <p>This script looks for traces of malicious code including code injections,
  26. modified .htaccess that makes images executable, and so on.</p>
  27. <p>
  28.  
  29. <?php
  30. // SET MAXIMUM EXECUTION TIME TO UNLIMITED (0) BECAUSE THE SCRIPT CAN TAKE A WHILE.
  31. // YOU COULD USE A MORE CONSERVATIVE TIME LIMIT SUCH AS 1 HOUR (3600 SECONDS), JUST IN CASE.
  32. // THESE HAVE NO EFFECT IF YOU RUN PHP IN "SAFE MODE" (SAFE MODE IS USUALLY UNDESIRABLE ANYWAY).
  33. ini_set('max_execution_time', '0');
  34. ini_set('set_time_limit', '0');
  35.  
  36. // --------------------------------------------------------------------------------
  37. // UTILITY FUNCTIONS.
  38. // OUTPUT TEXT IN SPECIFIED COLOR, CLEANING IT WITH HTMLENTITIES().
  39. function CleanColorText($text, $color)
  40. {
  41. $outputcolor = 'black';
  42. $color = trim($color);
  43. if(preg_match('/^(red|blue|green|black)$/i', $color))
  44. $outputcolor = $color;
  45. return '<span style="color:' . $outputcolor . ';">' . htmlentities($text, ENT_QUOTES) . '</span>';
  46. }
  47.  
  48. // --------------------------------------------------------------------------------
  49. // THIS FUNCTION RECURSIVELY FINDS FILES AND PROCESSES THEM THROUGH THE SPECIFIED CALLBACK FUNCTION.
  50. // DIFFERENT TYPES OF FILES NEED TO BE HANDLED BY DIFFERENT CALLBACK FUNCTIONS.
  51.  
  52. function find_files($path, $pattern, $callback)
  53. {
  54. // CHANGE BACKSLASHES TO FORWARD, WHICH IS OK IN PHP, EVEN IN WINDOWS.
  55. // REMOVE ANY TRAILING SLASHES, THEN ADD EXACTLY ONE.
  56. $path = rtrim(str_replace("\", "/", $path), '/') . '/';
  57. if(!is_readable($path))
  58. {
  59. echo "Warning: Unable to open and enter directory " . CleanColorText($path, 'blue') .
  60. ". Check its owner/group permissions.<br>";
  61. return;
  62. }
  63. $dir = dir($path);
  64. $entries = array();
  65. while(($entry = $dir->read()) !== FALSE)
  66. $entries[] = $entry;
  67. $dir->close();
  68. foreach($entries as $entry)
  69. {
  70. $fullname = $path . $entry;
  71. if(($entry !== '.') && ($entry !== '..') && is_dir($fullname))
  72. find_files($fullname, $pattern, $callback);
  73. else
  74. if(is_file($fullname) && preg_match($pattern, $entry))
  75. call_user_func($callback, $fullname);
  76. }
  77. }
  78.  
  79. // --------------------------------------------------------------------------------
  80. // CALLBACK FUNCTIONS.
  81. // CALLBACK FUNCTION TO LOOK FOR MALICIOUS CODE - YOU COULD ADD ANY OTHER MALICIOUS CODE SNIPPETS YOU KNOW OF.
  82. function maliciouscodesnippets($filename)
  83. {
  84. if(stripos($filename, "lookforbadguys.php")) // DON'T FLAG THIS FILE WHICH I CALLED lookforbadguys.php
  85. return;
  86.  
  87. if(!is_readable($filename))
  88. {
  89. echo "Warning: Unable to read " . CleanColorText($filename, 'blue') .
  90. ". Check it manually and check its access permissions.<br>";
  91. return;
  92. }
  93. $file = file_get_contents($filename); //READ THE FILE
  94.  
  95. // PRINTING EVERY FILENAME GENERATES A LOT OF OUTPUT.
  96. //echo CleanColorText($filename, 'green') . " is being examined.<br>";
  97.  
  98. // TEXT FILES WILL BE SEARCHED FOR THESE SNIPPETS OF SUSPICIOUS TEXT.
  99. // THESE ARE REGULAR EXPRESSIONS WITH THE REQUIRED /DELIMITERS/ AND WITH SPECIAL CHARACTERS ESCAPED.
  100. // /i AT THE END MEANS CASE INSENSITIVE.
  101. $SuspiciousSnippets = array
  102. (
  103. // POTENTIALLY SUSPICIOUS PHP CODE
  104. '/edoced_46esab/i',
  105. '/passthru *\(/i',
  106. '/shell_exec *\(/i',
  107. '/document\.write *\(unescape *\(/i',
  108.  
  109. // THESE CAN GIVE MANY FALSE POSITIVES WHEN CHECKING WORDPRESS AND OTHER CMS.
  110. // NONETHELESS, THEY CAN BE IMPORTANT TO FIND, ESPECIALLY BASE64_DECODE.
  111. '/base64_decode *\(/i',
  112. '/system *\(/i',   
  113. '/`.+`/',    // BACKTICK OPERATOR INVOKES SYSTEM FUNCTIONS, SAME AS system()
  114. //   '/phpinfo *\(/i',
  115. //   '/chmod *\(/i',
  116. //   '/mkdir *\(/i',
  117. //   '/fopen *\(/i',
  118. //   '/fclose *\(/i',
  119. //   '/readfile *\(/i',
  120.  
  121. // SUSPICIOUS NAMES. SOME HACKERS SIGN THEIR SCRIPTS. MANY NAMES COULD GO HERE,
  122. // HERE IS A GENERIC EXAMPLE. YOU CAN FILL IN WHATEVER NAMES YOU WANT.
  123. '/hacked by /i',
  124.  
  125. // OTHER SUSPICIOUS TEXT STRINGS
  126. '/web[\s-]*shell/i',    // TO FIND BACKDOOR WEB SHELL SCRIPTS.
  127. '/c99/i',    // THE NAMES OF TWO POPULAR WEB SHELLS.
  128. '/r57/i',
  129.  
  130. // YOU COULD ADD IN THE SPACE BELOW SOME REGULAR EXPRESSIONS TO MATCH THE NAMES OF MALICIOUS DOMAINS
  131. // AND IP ADDRESSES MENTIONED IN YOUR GOOGLE SAFEBROWSING DIAGNOSTIC REPORT. SOME EXAMPLES:
  132. '/gumblar\.cn/i',
  133. '/martuz\.cn/i',
  134. '/beladen\.net/i',
  135. '/gooqle/i',     // NOTE THIS HAS A Q IN IT.
  136.  
  137. // THESE 2 ARE THE WORDPRESS CODE INJECTION IN FRONT OF EVERY INDEX.PHP AND SOME OTHERS
  138. '/_analist/i',
  139. '/anaiytics/i'   // THE LAST ENTRY IN THE LIST MUST HAVE NO COMMA AFTER IT.
  140. );
  141.  
  142. foreach($SuspiciousSnippets as $i)
  143. {
  144. // STRPOS/STRIPOS WERE A LITTLE FASTER BUT LESS FLEXIBLE
  145. if(preg_match($i, $file))  
  146. echo CleanColorText($filename, 'blue') . ' MATCHES REGEX: ' . CleanColorText($i, 'red') . '<br>';
  147. }
  148.  
  149. if(!strpos($filename,"network.php") && !strpos($filename,"rewrite.php") && stripos($file,"RewriteRule"))
  150. echo CleanColorText($filename, 'blue') . " contains " . CleanColorText("RewriteRule", 'red') .
  151. " - check it manually for malicious redirects.<br>";
  152.  
  153. /*
  154. // THIS FINDS ALL JAVASCRIPT CODE. IF ENABLED, IT WILL GIVE *MANY* FALSE POSITIVES IN MOST WEBSITES.
  155. if($p = stripos($file, "<script "))
  156. echo CleanColorText($filename, 'blue') . ' contains SCRIPT:<br>' .
  157. CleanColorText(substr($file, $p, 100), 'red') . '<br><br>';
  158. */
  159. /*
  160. // THIS FINDS ALL IFRAMES. IF ENABLED, IT CAN GIVE MANY FALSE POSITIVES IN SOME WEBSITES.
  161. if($p = stripos($file, "<iframe "))
  162. echo CleanColorText($filename, 'blue') . ' contains IFRAME:<br>' .
  163. CleanColorText(substr($file, $p, 100), 'red') . '<br><br>';
  164. */
  165.  
  166. if(stripos($file, "AddHandler"))
  167. {
  168. // THIS IS HOW THEY MAKE THE IMAGE FILES EXECUTABLE.
  169. echo CleanColorText($filename, 'blue') . " contains " . CleanColorText('AddHandler', 'red') .
  170. " - make sure it does not make ordinary files like images executable.<br>";
  171. // IF YOU FIND NINE ZILLION OF THESE, UNCOMMENT IT BECAUSE IT IS A PAIN TO DELETE THEM BY HAND.
  172. // BUT CHECK THE LIST CAREFULLY FIRST TO MAKE SURE YOU REALLY WANT TO DELETE
  173. // ALL THE FILES AND NONE OF THEM ARE FALSE POSITIVES.
  174. //unlink($filename); // THIS DELETES THE FILE WITHOUT GIVING YOU THE OPTION OF EXAMINING IT!
  175. }
  176. }
  177.  
  178. // CALLBACK FUNCTION TO REPORT PHARMA LINK HACKS.
  179. function pharma($filename)
  180. {
  181. echo CleanColorText($filename, 'blue') . " is most likely a " . CleanColorText('pharma hack', 'red') . ".<br>";
  182. }
  183.  
  184. // CALLBACK FUNCTION TO REPORT FILES WHOSE NAMES ARE SUSPICIOUS.
  185. function badnames($filename)
  186. {
  187. echo CleanColorText($filename, 'blue') . " is a " . CleanColorText('suspicious file name', 'red') . ".<br>";
  188. }
  189.  
  190. // --------------------------------------------------------------------------------
  191. // SET UP THE SEARCH CRITERIA.
  192.  
  193. // SEARCHES WILL BE DONE IN THIS DIRECTORY AND ALL DIRS INSIDE IT.
  194. // './' MEANS CURRENT DIRECTORY, WHERE THIS SCRIPT IS NOW.
  195. // THUS, TO SEARCH EVERYTHING INSIDE PUBLIC_HTML, THAT'S WHERE THIS FILE SHOULD BE PUT.
  196. // TO SEARCH OUTSIDE PUBLIC_HTML, OR TO SEARCH A FOLDER OTHER THAN WHERE THIS SCRIPT IS STORED,
  197. // CHANGE THIS TO THE FULL PATHNAME, SUCH AS /home/userid/ OR /home/userid/public_html/somefolder/
  198. // USE FORWARD SLASHES FOR PATH. WINDOWS EXAMPLE: C:/wamp/apache2/htdocs/test/
  199. $StartPath = './';
  200.  
  201. // ENTRIES IN THE FOLLOWING 3 ARRAYS ARE REGULAR EXPRESSIONS, WHICH IS THE REASON FOR THE /DELIMITERS/.
  202. // FILES WHOSE NAMES MATCH THESE REGEXES WILL HAVE THEIR TEXT SEARCHED FOR MALICIOUS CODE.
  203. $FiletypesToSearch = array
  204. (
  205. '/\.htaccess$/i',
  206. '/\.php[45]?$/i',
  207. '/\.html?$/i',
  208. '/\.aspx?$/i',
  209. '/\.inc$/i',
  210. '/\.cfm$/i',
  211. '/\.js$/i',
  212. '/\.css$/i'
  213. );
  214.  
  215. // FILES OR FOLDERS WITH THESE STRINGS IN THEIR *NAMES* WILL BE REPORTED AS SUSPICIOUS.
  216. $SuspiciousFileAndPathNames = array
  217. (
  218. //  '/root/i',
  219. //  '/kit/i',
  220. '/c99/i',
  221. '/r57/i',
  222. '/gifimg/i'
  223. );
  224.  
  225. // FILENAMES RELATED TO WORDPRESS PHARMA HACK, USING THE NAMING CONVENTIONS
  226. // DESCRIBED AT http://www.pearsonified.com/2010/04/wordpress-pharma-hack.php
  227. // FILES MATCHING THESE NAMES WILL BE REPORTED AS POSSIBLE PHARMA HACK FILES.
  228. $PharmaFilenames = array
  229. (
  230. '/^\..*(cache|bak|old)\.php/i', // HIDDEN FILES WITH PSEUDO-EXTENSIONS IN THE MIDDLE OF THE FILENAME
  231. '/^db-.*\.php/i',
  232.  
  233. // PERMIT THE STANDARD WORDPRESS FILES THAT START WITH CLASS-, BUT FLAG ALL OTHERS AS SUSPICIOUS.
  234. // THE (?!) IS CALLED A NEGATIVE LOOKAHEAD ASSERTION. IT MEANS "NOT FOLLOWED BY..."
  235.  
  236. '/^class-(?!snoopy|smtp|feed|pop3|IXR|phpmailer|json|simplepie|phpass|http|oembed|ftp-pure|wp-filesystem-ssh2|wp-filesystem-ftpsockets|ftp|wp-filesystem-ftpext|pclzip|wp-importer|wp-upgrader|wp-filesystem-base|ftp-sockets|wp-filesystem-direct)\.php/i'
  237. );
  238.  
  239. // --------------------------------------------------------------------------------
  240. // FINALLY, DO THE SEARCHES, USING THE ABOVE ARRAYS AS THE STRING DATA SOURCES.
  241.  
  242. // REPORT FILES WITH SUSPICIOUS NAMES
  243. foreach($SuspiciousFileAndPathNames as $i)
  244. find_files($StartPath, $i, 'badnames');
  245.  
  246. // REPORT FILES WITH SUSPICIOUS PHARMA-RELATED NAMES
  247. foreach($PharmaFilenames as $i)
  248. find_files($StartPath, $i, 'pharma');
  249.  
  250. // REPORT FILES CONTAINING SUSPICIOUS CODE OR TEXT
  251. foreach($FiletypesToSearch as $i)
  252. find_files($StartPath, $i, 'maliciouscodesnippets');
  253.  
  254. echo "<br>Done<br>";
  255.  
  256. ?>
  257.  
  258. </p>
  259. </body>
  260. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement