把Apache ModSecurity的攻击日志存储到MySQL。 查看mod_security文件类型的日志,确实太麻烦了。国内资料居然没有百度到,找到了一篇英文文章,并且php都是写好的。
httpd.conf
<IfModule security2_module>
Include conf/modsecurity-crs/crs-setup.conf
Include conf/modsecurity-crs/rules/*.conf
# mlogc.exe 配置文件
SecDataDir logs
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4\d[^4])"
SecAuditLogType Concurrent
SecAuditLogParts ABCDEFGHZ
SecAuditLogStorageDir logs/mod_security/
SecAuditLog "|${SRVROOT}/bin/mlogc.exe d:/ap/apache/conf/mlogc.conf"
# SecAuditLog "|${SRVROOT}/bin/mlogc.exe"
</IfModule>
mlogc.conf
CollectorRoot "d:/ap/apache/logs"
ConsoleURI "http://localhost:9001/test/mlogc.php"
SensorUsername "USERNAME"
SensorPassword "PASSWORD"
LogStorageDir "mod_security"
TransactionLog "mlogc-transaction.log"
QueuePath "mlogc-queue.log"
ErrorLog "mlogc-error.log"
LockFile "mlogc.lck"
KeepEntries 0
ErrorLogLevel 2
MaxConnections 10
MaxWorkerRequests 1000
TransactionDelay 50
StartupDelay 5000
CheckpointInterval 15
ServerErrorTimeout 60
数据库脚本
CREATE DATABASE IF NOT EXISTS `mlogc` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `mlogc`;
CREATE TABLE IF NOT EXISTS `data` (
`ID` int(11) NOT NULL,
`Continuation` int(1) NOT NULL,
`PartA` mediumtext NOT NULL,
`PartB` mediumtext,
`PartC` mediumtext,
`PartD` mediumtext,
`PartE` mediumtext,
`PartF` mediumtext,
`PartG` mediumtext,
`PartH` mediumtext,
`PartI` mediumtext,
`PartJ` mediumtext,
`PartK` mediumtext,
`PartZ` mediumtext NOT NULL,
`RawText` mediumblob NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `data`
ADD PRIMARY KEY (`ID`);
ALTER TABLE `data`
MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT;
PHP脚本
<?php
if($_SERVER['REQUEST_METHOD'] == 'PUT') {
// The username and password setup in mlogc.conf
$username = "admin";
$password = "password";
// The DB username and password
$dbUname = "USERNAME";
$dbPasswd = "PASSWORD";
if($username !== $_SERVER['PHP_AUTH_USER'] or $password !== $_SERVER['PHP_AUTH_PW']){
error_log("Failed Login Attempt to MLogc PHP Console - Username:" . $_SERVER['PHP_AUTH_USER'], 0);
die("The username or password was incorrect");
}
$dsn = 'mysql:host=localhost;dbname=mlogc';
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
$dbh = new PDO($dsn, $dbUname, $dbPasswd, $options);
$putdata = fopen("php://input", "r");
$continuation = 0;
// This may take at most 16MB, we are just being safe
while ($data = fread($putdata, 15360)){
$lookup = array("A","B","C","D","E","F","G","H","I","J","K","Z");
$audit_parts = array_fill(0,sizeof($lookup),"NULL");
// Analyze data to make sure its of the expected format
$audit_log = explode("\n", $data);
$current = 0;
foreach ($audit_log as $line){
// If we are at the beginning
if(substr($line,0,2) === "--" && substr(str_replace(array("\r", "\n"), '', $line),-2,2) == "--"){
$current = array_search(substr(str_replace(array("\r", "\n"), '', $line),-3,1),$lookup);
// We are unable to find the key
if($current === false){
error_log("An invalid Audit Log Part was specified",0);
die("An invalid audit log part was specified this will not be saved");
}
$audit_parts[$current] = $line;
}else{
$audit_parts[$current] = $audit_parts[$current] . '\n' . $line;
}
}
if($audit_parts[11] === "NULL"){
error_log("The format received does not appear correct",0);
die("The format received does not appear correct");
}
$stmt = $dbh->prepare("INSERT INTO data (Continuation,PartA,PartB,PartC,PartD,PartE,PartF,PartG,PartH,PartI,PartJ,PartK,PartZ,RawText) VALUES (:continue,:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:z,:data)");
$stmt->bindParam(':a', $audit_parts[0]);
$stmt->bindParam(':b', $audit_parts[1]);
$stmt->bindParam(':c', $audit_parts[2]);
$stmt->bindParam(':d', $audit_parts[3]);
$stmt->bindParam(':e', $audit_parts[4]);
$stmt->bindParam(':f', $audit_parts[5]);
$stmt->bindParam(':g', $audit_parts[6]);
$stmt->bindParam(':h', $audit_parts[7]);
$stmt->bindParam(':i', $audit_parts[8]);
$stmt->bindParam(':j', $audit_parts[9]);
$stmt->bindParam(':k', $audit_parts[10]);
$stmt->bindParam(':z', $audit_parts[11]);
$stmt->bindParam(':data', $data);
$stmt->bindParam(':continue',$continuation);
$stmt->execute();
// If we need to run through again, its a continuation
$continuation = 1;
}
fclose($putdata);
}else{
die("This application does not respond to such requests");
}
?>
参考:
https://www.trustwave.com/Resources/SpiderLabs-Blog/Sending-ModSecurity-Logs-to-MySQL/
https://www.feistyduck.com/library/modsecurity-handbook-free/online/ch04-logging.html
https://sourceforge.net/p/mod-security/mailman/mod-security-users/?viewmonth=200901
声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。