commit
5b4f296b5b
@ -0,0 +1,15 @@
|
|||||||
|
# evtx2sql scripts
|
||||||
|
|
||||||
|
Simple scripts to import Windows Event Files into a mysql database.
|
||||||
|
Highly experimental stuff.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
The scripts will have to placed somewhere like /usr/local/bin
|
||||||
|
|
||||||
|
'evtx2sql-checknewfiles.sh' will check for new files in a data dir
|
||||||
|
'evtx2sql-import.sh' will handle the little import steps
|
||||||
|
'evtx2sql-convert2sql.php' is converting the xml file into an sql file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# please create the following directorys in the ROOTDIR
|
||||||
|
# in, process and backup
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
ROOTDIR=/tmp
|
||||||
|
PROCESSDIR=$ROOTDIR/process
|
||||||
|
LOCKFILE=$PROCESSDIR/checkfornewfiles.lock
|
||||||
|
INDIR=$ROOTDIR/in
|
||||||
|
BACKUPDIR=$ROOTDIR/backup
|
||||||
|
LOGFILE=$PROCESSDIR/debug.log
|
||||||
|
|
||||||
|
|
||||||
|
log () {
|
||||||
|
echo $1
|
||||||
|
echo $1 >> $LOGFILE
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
checkdir () {
|
||||||
|
if [ ! -d $1 ]; then
|
||||||
|
echo "`date` create dir $1"
|
||||||
|
mkdir $1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log "`date` Startet"
|
||||||
|
checkdir $PROCESSDIR
|
||||||
|
checkdir $INDIR
|
||||||
|
checkdir $BACKUPDIR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# check for look file in indir
|
||||||
|
#
|
||||||
|
for f in $INDIR/*.lock
|
||||||
|
do
|
||||||
|
if [ -f $f ]; then
|
||||||
|
log "`date` found lockfile $f abort"
|
||||||
|
exit;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# check for own lock file
|
||||||
|
#
|
||||||
|
if [ -f $LOCKFILE ]; then
|
||||||
|
log "`date` found lockfile $LOCKFILE abort"
|
||||||
|
exit;
|
||||||
|
fi
|
||||||
|
touch $LOCKFILE
|
||||||
|
|
||||||
|
#
|
||||||
|
# check for temp and import file
|
||||||
|
#
|
||||||
|
for f in $INDIR/*.import
|
||||||
|
do
|
||||||
|
if [ -f $f ]; then
|
||||||
|
log "`date` found temp file needed to rename and import ($(basename -- $f)"
|
||||||
|
FNAME=${f%.*}
|
||||||
|
if [ -f $FNAME.temp ]; then
|
||||||
|
mv $FNAME.temp $FNAME.evtx
|
||||||
|
fi;
|
||||||
|
rm -f $f
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# check for evtx files to import
|
||||||
|
#
|
||||||
|
for f in $INDIR/*.evtx
|
||||||
|
do
|
||||||
|
if [ -f $f ]; then
|
||||||
|
FNAME=$(basename -- $f)
|
||||||
|
log "`date` found evtx file needed to import ($FNAME)"
|
||||||
|
mv $f $PROCESSDIR/
|
||||||
|
evtx2sql-import.sh $PROCESSDIR/$FNAME
|
||||||
|
mv $PROCESSDIR/$FNAME $BACKUPDIR/
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rm $LOCKFILE
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,206 @@
|
|||||||
|
#!/bin/php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
global $xmlelement;
|
||||||
|
global $isevent;
|
||||||
|
global $edataarray;
|
||||||
|
global $edataelement;
|
||||||
|
global $emeta;
|
||||||
|
global $infile;
|
||||||
|
global $configfile;
|
||||||
|
global $argv;
|
||||||
|
global $argc;
|
||||||
|
|
||||||
|
class EventMeta {
|
||||||
|
public $eventrecordid;
|
||||||
|
public $time;
|
||||||
|
public $eventid;
|
||||||
|
public $task;
|
||||||
|
public $level;
|
||||||
|
public $keywords;
|
||||||
|
public $computer;
|
||||||
|
public $server;
|
||||||
|
public $username;
|
||||||
|
public $domainname;
|
||||||
|
public $servicename;
|
||||||
|
public $data;
|
||||||
|
public $status;
|
||||||
|
public $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventData {
|
||||||
|
public $name;
|
||||||
|
public $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xmlelement = "";
|
||||||
|
$isevent = false;
|
||||||
|
$edataelement = new EventData();
|
||||||
|
$edataarray = array();
|
||||||
|
$emeta = new EventMeta();
|
||||||
|
$infile = "";
|
||||||
|
|
||||||
|
|
||||||
|
function sql_addmeta ($data, $darray) {
|
||||||
|
$data->status = 0;
|
||||||
|
$data->result = 0;
|
||||||
|
|
||||||
|
if ($data->eventid == 0) {
|
||||||
|
// do something
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// default
|
||||||
|
if (isset ($darray['IpAddress'])) $data->server = $darray['IpAddress'];
|
||||||
|
if (isset ($darray['TargetUserName'])) $data->username = $darray['TargetUserName'];
|
||||||
|
if (isset ($darray['TargetDomainName'])) $data->domainname = $darray['TargetDomainName'];
|
||||||
|
if (isset ($darray['ServiceName'])) $data->servicename = $darray['ServiceName'];
|
||||||
|
if (isset ($darray['Status'])) $data->status = $darray['Status'];
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("INSERT INTO tbl_EventMeta (eventrecordid, time, eventid, task, level, keywords, computer, server, username, domainname, servicename, data, status) VALUES('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s');\n",
|
||||||
|
$data->eventrecordid,
|
||||||
|
$data->time,
|
||||||
|
$data->eventid,
|
||||||
|
$data->task,
|
||||||
|
$data->level,
|
||||||
|
$data->keywords,
|
||||||
|
$data->computer,
|
||||||
|
$data->server,
|
||||||
|
$data->username,
|
||||||
|
$data->domainname,
|
||||||
|
$data->servicename,
|
||||||
|
$data->data,
|
||||||
|
$data->status
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function xmlstarthandler($parser, $name, $attribs) {
|
||||||
|
global $xmlelement;
|
||||||
|
global $edataelement;
|
||||||
|
global $emeta;
|
||||||
|
|
||||||
|
$xmlelement = $xmlelement . "\t" . $name;
|
||||||
|
|
||||||
|
if (count($attribs)) {
|
||||||
|
foreach ($attribs as $k => $v) {
|
||||||
|
if (strstr($xmlelement, "EVENT\tEVENTDATA\tDATA") <> false && strstr($k, "NAME") <> false) {
|
||||||
|
$edataelement->name = $v;
|
||||||
|
$edataelement->value = "";
|
||||||
|
}
|
||||||
|
else if (strstr($xmlelement, "EVENT\tSYSTEM\tTIMECREATED") <> false && strstr($k, "SYSTEMTIME") <> false) {
|
||||||
|
$v[strpos($v,'T')] = ' ';
|
||||||
|
$v[strpos($v,'Z')] = ' ';
|
||||||
|
$emeta->time = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function xmlendhandler($parser, $name) {
|
||||||
|
global $xmlelement;
|
||||||
|
global $emeta;
|
||||||
|
global $edataelement;
|
||||||
|
global $edataarray;
|
||||||
|
|
||||||
|
if (strstr($xmlelement, "EVENT\tSYSTEM") <> false && strstr($name, "SYSTEM") <> false) {
|
||||||
|
sql_addmeta ($emeta, $edataarray);
|
||||||
|
$edataarray = array();
|
||||||
|
$emata = new EventMeta();
|
||||||
|
}
|
||||||
|
if (strstr($xmlelement, "EVENT\tEVENTDATA\tDATA") <> false && strstr($name, "DATA") <> false) {
|
||||||
|
printf ("******************* %s %s %s\n", $name, $edataelement->name, $edataelement->value);
|
||||||
|
$edataarray[$edataelement->name] = $edataelement->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pos = strrpos ($xmlelement, "\t");
|
||||||
|
if ($pos == false) $xmlelement = "";
|
||||||
|
else $xmlelement = substr($xmlelement, 0, $pos);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function filterunsafetext($text) {
|
||||||
|
$tmp = "";
|
||||||
|
$i = 0;
|
||||||
|
for ($i = 0; $i < strlen($text); $i++) {
|
||||||
|
if ($text[$i] == " " && strlen($tmp) > 0) $tmp = $tmp.$text[$i];
|
||||||
|
else if ($text[$i] == "\n") $tmp = $tmp . " ";
|
||||||
|
else if (($text[$i] >= "a" && $text[$i] <= "z") ||
|
||||||
|
($text[$i] >= "A" && $text[$i] <= "Z") ||
|
||||||
|
($text[$i] >= "0" && $text[$i] <= "9") ||
|
||||||
|
$text[$i] == "&" || $text[$i] == "%" || $text[$i] == "/" ||
|
||||||
|
$text[$i] == "{" || $text[$i] == "}" || $text[$i] == "#" ||
|
||||||
|
$text[$i] == "." || $text[$i] == "," || $text[$i] == "\\" ||
|
||||||
|
$text[$i] == "_" || $text[$i] == "*" || $text[$i] == ":" ||
|
||||||
|
$text[$i] == "&" || $text[$i] == "%" || $text[$i] == "@" ||
|
||||||
|
$text[$i] == "+" || $text[$i] == "-" ) $tmp = $tmp.$text[$i];
|
||||||
|
}
|
||||||
|
return $tmp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function xmldefaulthandler($parser, $data) {
|
||||||
|
global $emeta;
|
||||||
|
global $edataelement;
|
||||||
|
global $edataelement;
|
||||||
|
global $xmlelement;
|
||||||
|
|
||||||
|
if (strstr($xmlelement, "EVENT\tEVENTDATA\tDATA") <> false) {
|
||||||
|
$edataelement->eventrecordid = $emeta->eventrecordid;
|
||||||
|
$edataelement->value = $edataelement->value.filterunsafetext($data);
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tEVENTID") <> false) {
|
||||||
|
$emeta->eventid = $data;
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tEVENTRECORDID") <> false) {
|
||||||
|
$emeta->eventrecordid = $data;
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tKEYWORD") <> false) {
|
||||||
|
$emeta->keyword = $data;
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tLEVEL") <> false) {
|
||||||
|
$emeta->level = $data;
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tCOMPUTER") <> false) {
|
||||||
|
$emeta->computer = $data;
|
||||||
|
} else if (strstr($xmlelement, "EVENT\tSYSTEM\tTASK") <> false) {
|
||||||
|
$emeta->task = $data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function errorexit($text) {
|
||||||
|
printf ("%s", $text);
|
||||||
|
exit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
if (isset ($argv) && isset ($argc)) {
|
||||||
|
global $infile;
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($argv); $i++) {
|
||||||
|
if (strstr($argv[$i], "-in") <> false) {
|
||||||
|
$i++;
|
||||||
|
if ($i >= $argc) ErrorExit ("filename missing\n");
|
||||||
|
$infile = $argv[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($infile == "") {
|
||||||
|
printf ("Parameters:\n");
|
||||||
|
printf (" -in INPUTFILE\n");
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stream = fopen($infile, 'r');
|
||||||
|
$parser = xml_parser_create();
|
||||||
|
xml_set_element_handler($parser, "xmlstarthandler", "xmlendhandler");
|
||||||
|
xml_set_default_handler($parser, "xmldefaulthandler");
|
||||||
|
while (($data = fread($stream, 16384))) {
|
||||||
|
xml_parse($parser, $data); // parse the current chunk
|
||||||
|
}
|
||||||
|
xml_parse($parser, '', true); // finalize parsing
|
||||||
|
xml_parser_free($parser);
|
||||||
|
fclose($stream);
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# parameter 1: source file
|
||||||
|
|
||||||
|
if [ -z "$1" ]; then
|
||||||
|
echo "Source File not defined"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
TEMPFILE=`mktemp`
|
||||||
|
TEMPSQL=`mktemp`
|
||||||
|
SQLDB=EventData
|
||||||
|
|
||||||
|
echo "Source File: $1"
|
||||||
|
echo "Temporary File: $TEMPFILE"
|
||||||
|
echo "Destination File: $2"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
date
|
||||||
|
echo "Reading input file to temp.xml"
|
||||||
|
|
||||||
|
echo "<xml>" > $TEMPFILE
|
||||||
|
evtxexport $1 -t security -f xml | tail -n +2 >> $TEMPFILE
|
||||||
|
echo "</xml>" >> $TEMPFILE
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
date
|
||||||
|
echo "Converting temp.xml to output SQL file"
|
||||||
|
|
||||||
|
evtx2sql-convert2sql.php -in $TEMPFILE | grep INSERT > $TEMPSQL
|
||||||
|
|
||||||
|
rm -f $TEMPFILE
|
||||||
|
|
||||||
|
date
|
||||||
|
echo ""
|
||||||
|
echo "Importing Data into SQL Database"
|
||||||
|
echo "
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS tbl_EventMeta (
|
||||||
|
eventrecordid INT,
|
||||||
|
time DATETIME(6) NOT NULL,
|
||||||
|
eventid INT NULL,
|
||||||
|
task INT NULL,
|
||||||
|
level INT NULL,
|
||||||
|
keywords VARCHAR(32),
|
||||||
|
computer VARCHAR(64) DEFAULT NULL,
|
||||||
|
server VARCHAR(64) DEFAULT NULL,
|
||||||
|
username VARCHAR(64) DEFAULT NULL,
|
||||||
|
domainname VARCHAR(64) DEFAULT NULL,
|
||||||
|
servicename VARCHAR(64) DEFAULT NULL,
|
||||||
|
data VARCHAR(64) DEFAULT NULL,
|
||||||
|
status VARCHAR(16)
|
||||||
|
);
|
||||||
|
" | mysql $SQLDB
|
||||||
|
mysql $SQLDB < $TEMPSQL
|
||||||
|
|
||||||
|
rm -f $TEMPSQL
|
||||||
|
|
||||||
|
date
|
||||||
|
echo "Finished"
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in new issue