Untitled


SUBMITTED BY: Guest

DATE: Oct. 14, 2024, 2:27 p.m.

FORMAT: Text only

SIZE: 10.5 kB

HITS: 89

  1. <?php
  2. $minute = 15;
  3. $limit = (60 * $minute); // 60 (seconds) = 1 Minutes
  4. ini_set('memory_limit', '-1');
  5. ini_set('max_execution_time', $limit);
  6. set_time_limit($limit);
  7. function recursiveScan($directory, &$entries_array = array())
  8. {
  9. // link can cause endless loop
  10. $handle = @opendir($directory);
  11. if ($handle) {
  12. while (($entry = readdir($handle)) !== false) {
  13. if ($entry == '.' || $entry == '..') {
  14. continue;
  15. }
  16. $entry = $directory . DIRECTORY_SEPARATOR . $entry;
  17. if (is_dir($entry) && is_readable($directory) && !is_link($directory)) {
  18. $entries_array = recursiveScan($entry, $entries_array);
  19. } elseif (is_file($entry) && is_readable($entry)) {
  20. $entries_array['file_writable'][] = $entry;
  21. } else {
  22. $entries_array['file_not_writable'][] = $entry;
  23. }
  24. }
  25. closedir($handle);
  26. }
  27. return $entries_array;
  28. }
  29. /**
  30. *
  31. * Sort array of list file by lastest modified time
  32. *
  33. * @param array $files Array of files
  34. *
  35. * @return array
  36. *
  37. */
  38. function sortByLastModified($files)
  39. {
  40. @array_multisort(array_map('filemtime', $files), SORT_DESC, $files);
  41. return $files;
  42. }
  43. /**
  44. *
  45. * Recurisively list a file by descending modified time
  46. *
  47. * @param string $path
  48. *
  49. * @return array
  50. *
  51. */
  52. function getSortedByTime($path)
  53. {
  54. $result = recursiveScan($path);
  55. $fileWritable = $result['file_writable'];
  56. $fileNotWritable = isset($result['file_not_writable']) ? !$result['file_not_writable'] : false;
  57. $fileWritable = sortByLastModified($fileWritable);
  58. return array(
  59. 'file_writable' => $fileWritable,
  60. 'file_not_writable' => $fileNotWritable
  61. );
  62. }
  63. /**
  64. * Recurisively list a file by array of extension
  65. *
  66. * @param string $path
  67. * @param array $ext
  68. * @return array of files
  69. */
  70. function getSortedByExtension($path, $ext)
  71. {
  72. $result = getSortedByTime($path);
  73. $fileWritable = $result['file_writable'];
  74. isset($result['file_not_writable']) ? $result['file_not_writable'] : false;
  75. foreach ($fileWritable as $entry) {
  76. $pathinfo = pathinfo($entry, PATHINFO_EXTENSION);
  77. $pathinfo = strtolower($pathinfo);
  78. if (in_array($pathinfo, $ext)) {
  79. $sortedWritableFile[] = $entry;
  80. }
  81. }
  82. if (isset($fileNotWritable)) {
  83. foreach ($fileNotWritable as $entry) {
  84. $pathinfo = pathinfo($entry, PATHINFO_EXTENSION);
  85. $pathinfo = strtolower($pathinfo);
  86. if (in_array($pathinfo, $ext)) {
  87. $sortedNotWritableFile[] = $entry;
  88. }
  89. }
  90. } else {
  91. $sortedNotWritableFile = false;
  92. }
  93. return array(
  94. 'file_writable' => $sortedWritableFile,
  95. 'file_not_writable' => $sortedNotWritableFile
  96. );
  97. }
  98. /**
  99. * Get lowercase Array of tokens in a file
  100. *
  101. * @param string $filename
  102. * @return array
  103. */
  104. function getFileTokens($filename)
  105. {
  106. /*
  107. token_get_all() This function not support :
  108. - Old notation : "<? ?>" and "<% %>"
  109. - heredoc syntax
  110. - nowdoc syntax (since PHP 5.3.0)
  111. */
  112. $fileContent = file_get_contents($filename);
  113. $fileContent = preg_replace('/<\?([^p=\w])/m', '<?php ', $fileContent); // replace old php tags
  114. $token = token_get_all($fileContent);
  115. $output = array();
  116. $tokenCount = count($token);
  117. if ($token > 0) {
  118. for ($i = 0; $i < $tokenCount; $i++) {
  119. if (isset($token[$i][1])) {
  120. $output[] .= strtolower($token[$i][1]);
  121. }
  122. }
  123. }
  124. $output = array_values(
  125. array_unique(array_filter(array_map("trim", $output)))
  126. );
  127. return $output;
  128. }
  129. /**
  130. * Compare tokens and return array of matched tokens
  131. *
  132. * @param array $tokenNeedles
  133. * @param array $tokenHaystack
  134. * @return array
  135. */
  136. function compareTokens($tokenNeedles, $tokenHaystack)
  137. {
  138. $output = array();
  139. foreach ($tokenNeedles as $tokenNeedle) {
  140. if (in_array($tokenNeedle, $tokenHaystack)) {
  141. $output[] = $tokenNeedle;
  142. }
  143. }
  144. return $output;
  145. }
  146. $ext = array(
  147. 'php',
  148. 'phps',
  149. 'pht',
  150. 'phpt',
  151. 'phtml',
  152. 'phar',
  153. 'php3',
  154. 'php4',
  155. 'php5',
  156. 'php7',
  157. 'suspected'
  158. );
  159. $tokenNeedles = array(
  160. // Obfuscation
  161. 'base64_decode',
  162. 'rawurldecode',
  163. 'urldecode',
  164. 'gzinflate',
  165. 'gzuncompress',
  166. 'str_rot13',
  167. 'convert_uu',
  168. 'htmlspecialchars_decode',
  169. 'bin2hex',
  170. 'hex2bin',
  171. 'hexdec',
  172. 'chr',
  173. 'strrev',
  174. 'goto',
  175. 'implode',
  176. 'strtr',
  177. 'extract',
  178. 'parse_str', //works like extract if only one argument is given.
  179. 'substr',
  180. 'mb_substr',
  181. 'str_replace',
  182. 'substr_replace',
  183. 'preg_replace', // able to do eval on match
  184. 'exif_read_data',
  185. 'readgzfile',
  186. // Shell / Process
  187. 'eval',
  188. 'exec',
  189. 'shell_exec',
  190. 'system',
  191. 'passthru',
  192. 'pcntl_fork',
  193. 'fsockopen',
  194. 'proc_open',
  195. 'popen ',
  196. 'assert', // identical to eval
  197. 'posix_kill',
  198. 'posix_setpgid',
  199. 'posix_setsid',
  200. 'posix_setuid',
  201. 'proc_nice',
  202. 'proc_close',
  203. 'proc_terminate',
  204. 'apache_child_terminate',
  205. // Server Information
  206. 'posix_getuid',
  207. 'posix_geteuid',
  208. 'posix_getegid',
  209. 'posix_getpwuid',
  210. 'posix_getgrgid',
  211. 'posix_mkfifo',
  212. 'posix_getlogin',
  213. 'posix_ttyname',
  214. 'getenv',
  215. 'proc_get_status',
  216. 'get_cfg_var',
  217. 'disk_free_space',
  218. 'disk_total_space',
  219. 'diskfreespace',
  220. 'getlastmo',
  221. 'getmyinode',
  222. 'getmypid',
  223. 'getmyuid',
  224. 'getmygid',
  225. 'fileowner',
  226. 'filegroup',
  227. 'get_current_user',
  228. 'pathinfo',
  229. 'getcwd',
  230. 'sys_get_temp_dir',
  231. 'basename',
  232. 'phpinfo',
  233. // Database
  234. 'mysql_connect',
  235. 'mysqli_connect',
  236. 'mysqli_query',
  237. 'mysql_query',
  238. // I/O
  239. 'fopen',
  240. 'fsockopen',
  241. 'file_put_contents',
  242. 'file_get_contents',
  243. 'url_get_contents',
  244. 'stream_get_meta_data',
  245. 'move_uploaded_file',
  246. '$_files',
  247. 'copy',
  248. 'include',
  249. 'include_once',
  250. 'require',
  251. 'require_once',
  252. '__file__',
  253. // Miscellaneous
  254. 'mail',
  255. 'putenv',
  256. 'curl_init',
  257. 'tmpfile',
  258. 'allow_url_fopen',
  259. 'ini_set',
  260. 'set_time_limit',
  261. 'session_start',
  262. 'symlink',
  263. '__halt_compiler',
  264. '__compiler_halt_offset__',
  265. 'error_reporting',
  266. 'create_function',
  267. 'get_magic_quotes_gpc',
  268. '$auth_pass',
  269. '$password',
  270. );
  271. ?>
  272. <!DOCTYPE html>
  273. <html lang="en-us">
  274. <head>
  275. <title>Cicak WebSHell Scanner</title>
  276. <style type="text/css">
  277. @import url('https://fonts.googleapis.com/css?family=Ubuntu+Mono&display=swap');
  278. body {
  279. font-family: 'Ubuntu Mono', monospace;
  280. color: #8a8a8a;
  281. }
  282. table {
  283. border-spacing: 0;
  284. padding: 10px;
  285. border-radius: 7px;
  286. border: 3px solid #d6d6d6;
  287. }
  288. tr,
  289. td {
  290. padding: 7px;
  291. }
  292. th {
  293. color: #8a8a8a;
  294. padding: 7px;
  295. font-size: 25px;
  296. }
  297. input[type=submit]:focus {
  298. background: #ff9999;
  299. color: #fff;
  300. border: 3px solid #ff9999;
  301. }
  302. input[type=submit]:hover {
  303. border: 3px solid #ff9999;
  304. cursor: pointer;
  305. }
  306. input[type=text]:hover {
  307. border: 3px solid #ff9999;
  308. }
  309. input {
  310. font-family: 'Ubuntu Mono', monospace;
  311. }
  312. input[type=text] {
  313. border: 3px solid #d6d6d6;
  314. outline: none;
  315. padding: 7px;
  316. color: #8a8a8a;
  317. width: 100%;
  318. border-radius: 7px;
  319. }
  320. input[type=submit] {
  321. color: #8a8a8a;
  322. border: 3px solid #d6d6d6;
  323. outline: none;
  324. background: none;
  325. padding: 7px;
  326. width: 100%;
  327. border-radius: 7px;
  328. }
  329. </style>
  330. </head>
  331. <body>
  332. <script type="text/javascript">
  333. function copytable(el) {var urlField = document.getElementById(el)
  334. var range = document.createRange()
  335. range.selectNode(urlField)
  336. window.getSelection().addRange(range)
  337. document.execCommand('copy')
  338. }
  339. </script>
  340. <form method="post">
  341. <table align="center" width="30%">
  342. <tr>
  343. <th>
  344. Webshell Scanner
  345. </th>
  346. </tr>
  347. <tr>
  348. <td>
  349. <input type="text" name="dir" value="<?= getcwd() ?>">
  350. </td>
  351. </tr>
  352. <tr>
  353. <td>
  354. <input type="submit" name="submit" value="SEARCH">
  355. </td>
  356. </tr>
  357. <?php if (isset($_POST['submit'])) { ?>
  358. <tr>
  359. <td>
  360. <span style="font-weight:bold;font-size:25px;">RESULT</span>
  361. <input type=button value="Copy to Clipboard" onClick="copytable('result')">
  362. </td>
  363. </tr>
  364. </table>
  365. <table id="result" align="center" width="30%">
  366. <?php
  367. $path = $_POST['dir'];
  368. $result = getSortedByExtension($path, $ext);
  369. $fileWritable = $result['file_writable'];
  370. $fileNotWritable = $result['file_not_writable'];
  371. $fileWritable = sortByLastModified($fileWritable);
  372. foreach ($fileWritable as $file) {
  373. $filePath = str_replace('\\', '/', $file);
  374. $tokens = getFileTokens($filePath);
  375. $cmp = compareTokens($tokenNeedles, $tokens);
  376. $cmp = implode(', ', $cmp);
  377. if (!empty($cmp)) {
  378. echo sprintf('<tr><td><span style="color:red;">%s (%s)</span></td></tr>', $filePath, $cmp);
  379. //unlink($filePath);
  380. }
  381. }
  382. }

comments powered by Disqus