commit 5b4f296b5bc26aa566db18b32af9438075d9fb07 Author: Steffen Pohle Date: Thu May 5 19:54:53 2022 +0200 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b6f95b --- /dev/null +++ b/README.md @@ -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 + + + diff --git a/evtx2sql-checknewfiles.sh b/evtx2sql-checknewfiles.sh new file mode 100755 index 0000000..777288c --- /dev/null +++ b/evtx2sql-checknewfiles.sh @@ -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 + + diff --git a/evtx2sql-convert2sql.php b/evtx2sql-convert2sql.php new file mode 100755 index 0000000..d635a7c --- /dev/null +++ b/evtx2sql-convert2sql.php @@ -0,0 +1,206 @@ +#!/bin/php +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); + + diff --git a/evtx2sql-import.sh b/evtx2sql-import.sh new file mode 100755 index 0000000..af78850 --- /dev/null +++ b/evtx2sql-import.sh @@ -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 "" > $TEMPFILE +evtxexport $1 -t security -f xml | tail -n +2 >> $TEMPFILE +echo "" >> $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" + +