Paranormal Log Parser На днях понадобилось просканить логи на предмет всяких иньектов, хсс и так далее. Вобщем на паранормальное содержимое . Это не мега крутой инструмент, а тулза которая бывает иногда полезной. Пример: http://nfdesign.org.ua/achat/parser/parser.php Просьба в демо не пихать большиг логов, и так фрихост. Скрипт парсит логи апача такого плана: Code: 127.0.0.1 - - [01/Jan/2009:00:00:00 -0001] "GET /sscript.php?param=val HTTP/1.1" 200 13236 "http://127.0.0.1/sscript.php?param=val" "Opera/10.0 (Windows NT 5.1; U; ua)" Download: http://nfdesign.org.ua/achat/parser/parser.phps OR Attach
Потому, что это раздел для проявления активности, знаний, релизов полезных для групы. Думаю некоторым пригодится. Хотя я совсем не против чтобы перенесли в паблик
честно говоря, если уж начал как говорится, доводи до ума. 1.Паттерн который парсит лог, думаю вообще стоит убрать и глядеть на всю строку в целом.(мало ли как у кого настроен веб сервер) 2. добавать регулярки для ../ , system, eval, passthru, exec, assert, =http , =ftp, пробелANDпробел, пробелORпробел, --, /* Но всё это будет работать только если уязвимость была эксплуатирована через GET. так что юзаем только POST)))
А я активирую mod_security и буду парсить его логи, включая POST. Генерит он их немерянно Только регулярочки бы действительно поменять Вещь нужная, но пока что сыровато. +1 за всю строку в целом, там как раз на каждый запрос новая строчка в логах. Вот её и надо анализировать. + не забываем за всякие интересные случаи с mod_rewrite + Обязательно вылавливать passwd .htpasswd .htaccess.. Дальше уже сами знаете. Не знаю, возможно ли как-то учесть/оптимизировать или может портирует кто на другой язык.. У меня есть парочка сайтов, там размеры логов двух гигов достигают. Можно конечно немного обстругать и PHP-скрипт из командной строки вызвать, но хотелось бы и чтобы наглядно, и без подвисаний/отваливаний/InternalServerError/дополнительного редактирования конфигов и прочее. ЗЫ. Отличный дипломный проект может получиться..
PHP: $sqlinj = array('/(\%27)*(\')|(union)*select[\+\/**\ %]/i',"/substring/i","/(order|group)*by/i"); Оу в регулярке *, это спец. символ - "0 и более раз", если работает, то еще повезло... PHP: $logs = explode( "\n", file_get_contents($logfile)); Если файл на 100 мегабайт, то представляешь какого размера будет массив? Читай построчно fgets(), выделение памяти очень маленькое будет, грузить всего лишь по строке и сверять с регуляркой... а не всем файлом сразу. Оптимизируйте код, товаришь
Переделал. Парсит теперь через fgets, анализ всей строки. Изменены регулярки. PHP: <?php error_reporting(0); ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=windows-1251"> <meta name="author" content=""> <title>Paranormal Log Detecter</title> <style> body { background-color:#333; color:yellowgreen; font-family:Verdana, Arial; font-size:10px; padding:0px; margin:0px; } table { font-family:Verdana, Arial; font-size:10px; border:1px solid #444; } form { padding:0px; margin:0px; } input, select { background:#292929; padding:2px; font-size:10px; border:1px solid #444; font-family:Verdana; color:#888; } textarea { background:#292929; padding:10px; font-size:10px; border:1px solid #444; font-family:Verdana; color:#888; } a { font-size:10px; font-family:Verdana; color:#999; font-weight:bold; text-decoration:none; } a:hover { color:yellowgreen; } table { border-spacing: 0; margin:0 auto; border-collapse: 0; } td:hover { background:#4D525C; } tr:hover td { background:#4D525C; } td { padding:3px; text-align:center; font-size:12px; color:#B9B9BD; background:#363940; } td b { color:#ccc; } </style> </head> <body> <? /** * @author Dimi4 * @copyright 2009 * @ParanormalLogParser * @v.2 */ $logfile = "test.txt"; $numline = 1; //POSIBLE SIGNATURES // $xss = array('/(\w+script:|@import[^\w]|;base64|base64,)|(\w+\s*\([\w\s]+,[\w\s]+,[\w\s]+,[\w\s]+,[\w\s]+,[\w\s]+\))/i','/(\<\w*\s([^\>]*)t(?!rong))|(\<scri)|(<\w+\w+)/i'); $shell = array("/.act=ls/i",'/c99shell/i','/madshell/i','/r57shell/i','/(([;]+|(<[?%](php)?)).*(define|eval|file_get_contents|include|require|require_once|set|shell_exec|phpinfo|system|passthru|preg_\w+|execute)\s*["(@])/'); $sqlinj = array('/(\%27)*(\')|(union)*select[\+\/**\ %]/i',"/substring/i","/(order|group)*by/i"); $include = array('/\.\.\//i','/(home|conf|usr|etc|proc|opt|local|dev|tmp|kern|sys|system|windows|winnt|program)\/\W*[a-z]/i'); $nullbyte = array('/(\\x[01FE]\w)|(%[01FE]\w)|(&#[01FE]\w)|(\\[01FE][0-9a-f])|(&#x[01FE]\w)/i'); //POSiBLE SIGNATURES // /*********************/ echo("<div align='center'><h2>Результат проверки - ".htmlspecialchars($logfile)."</h2></div> <table width='100%'>"); echo("<tr><th>Line #</th><th>Date</th><th>IP</th><th>Request, User-Agent</th><th>Alert</th></tr>"); $handle = fopen($logfile, "r"); while (!feof($handle)) { $buffer = fgets($handle, 4096); $numline++; $pattern = '/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) (.*) (.*) (\[.*\]) (".*") (\d\d\d) (.*) (".*") (".*")/U'; preg_match( $pattern, $buffer, $entries ); list( $match, $log['ip'], $log['id'], $log['user'], $log['date'], $log['request'], $log['response-code'], $log['bytes-sent'], $log['referrer'], $log['agent'] ) = $entries; //Sql-inj for($i=0; $i<count($sqlinj); $i++) { if(preg_match("$sqlinj[$i]",$buffer)) { $buffer=htmlspecialchars($buffer); $atempt .= "<tr><td>".$numline."</td><td>".$log['date']."</td><td>".$log['ip']."</td><td><textarea cols='45'>".$log['request']."\nUser-agent:\n".$log['agent']."</textarea></td> <td><strong>Возможно, найдена SQL-injection</strong></td></tr>"; print_r($atempt); unset($atempt); } } ///Sql-inj //PHP-include for($i=0; $i<count($include); $i++) { if(preg_match("$include[$i]",$buffer)) { $buffer=htmlspecialchars($buffer); $atempt .= "<tr><td>".$numline."</td><td>".$log['date']."</td><td>".$log['ip']."</td><td><textarea cols='45'>".$log['request']."\nUser-agent:\n".$log['agent']."</textarea></td> <td><strong>Возможно, найден Include</strong></td>"; print_r($atempt); unset($atempt); } } ///PHP-include //Shell for($i=0; $i<count($shell); $i++) { if(preg_match("$shell[$i]",$buffer)) { $buffer=htmlspecialchars($buffer); $atempt .= "<tr><td>".$numline."</td><td>".$log['date']."</td><td>".$log['ip']."</td><td><textarea cols='45'>".$log['request']."\nUser-agent:\n".$log['agent']."</textarea></td> <td><strong>Возможно, найден Shell</strong></td>"; print_r($atempt); unset($atempt); } } ///Shell //XSS $tempval = explode(":", $buffer); for($i=0; $i<count($xss); $i++) { if (preg_match($xss[$i],$buffer)) { $atempt .= "<tr><td>".$numline."</td><td>".$log['date']."</td><td>".$log['ip']."</td><td><textarea cols='45'>".$log['request']."\nUser-agent:\n".$log['agent']."</textarea></td> <td><strong>Возможно, найдена XSS</strong></td>"; print_r($atempt); unset($atempt); } } ///XSS //Null-byte for($i=0; $i<count($nullbyte); $i++) { if(preg_match("$nullbyte[$i]",$buffer)) { $atempt .= "<tr><td>".$numline."</td><td>".$log['date']."</td><td>".$log['ip']."</td><td><textarea cols='45'>".$log['request']."\nUser-agent:\n".$log['agent']."</textarea></td> <td><strong>Возможно, найден nullbyte</strong></td>"; print_r($atempt); unset($atempt); } } ///Null-byte } echo("</table>"); fclose($handle); ?>