skipped 12 lines 13 13 <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-qtip/2.7.1/cytoscape-qtip.js" integrity="sha384-iEsLCgQ6cKWEBnP+3Yd8hsUSvCzDYQU/UUVvXzB10FMtPexDn68x5Sem24bboY4I" crossorigin="anonymous"></script> 14 14 <!-- Neo4j JavaScript Driver --> 15 15 <script src="https://cdn.rawgit.com/neo4j/neo4j-javascript-driver/1.4.1/lib/browser/neo4j-web.min.js" integrity="sha384-xu5q3iV0ueZtK1T6RpPoUqv4VlVuEJpax+yyNmlN6CuOtT+SeUe1dqlI7MHpIN0p" crossorigin="anonymous"></script> 16 + <script src="static/script.js"></script> 16 17 </head> 17 18 18 19 <body> skipped 78 lines 97 98 <hr> 98 99 <a>Graph mode</a><br> 99 100 <div class="btn-group" data-toggle="buttons"> 100 - <label class="btn btn-default active"> 101 + <label class="btn btn-default active">101 102 <input type="radio" id="modeGrid" name="graphmode" checked="checked">grid</label> 102 - <label class="btn btn-default"> 103 + <label class="btn btn-default">103 104 <input type="radio" id="modeCose" name="graphmode">cose</label> 104 105 <label class="btn btn-default"> 105 106 <input type="radio" id="modeCircle" name="graphmode">circle</label> 106 107 </div> 107 108 <hr> 108 109 <a>Timeline</a><br> 109 - <div class="list-group"> 110 - <button type="button" class="list-group-item" onclick="createAlltimeline()">Create All Users</button> 111 - <button type="button" class="list-group-item" onclick="searchTimeline()">Search</button> 112 - </div> 113 - <div class="btn-group"> 114 - <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false"> 115 - Download <span class="caret"></span> 116 - </button> 117 - <ul class="dropdown-menu" role="menu"> 118 - <li role="presentation"><a onclick="downloadSummary()">Summary</a></li> 119 - <li role="presentation"><a onclick="downloadDetail()">Details</a></li> 120 - </ul> 121 - </div> 110 + <button class="btn btn-default" onClick="window.open('timeline')">Create All Users</button> 122 111 <hr> 123 112 <a>Upload</a><br> 124 113 <button class="btn btn-default" data-toggle="modal" data-target="#UploadEVTX">Upload EVTX File</button> skipped 16 lines 141 130 </ul> 142 131 </div> 143 132 </div> 144 - <!-- Upload --> 145 - <div class="modal fade" id="UploadEVTX" tabindex="-1"> 146 - <div class="modal-dialog ">147 - <div class="modal-content ">148 - <div class="modal-header "> 149 - <button type="button" class="close" data-dismiss="modal"><span>×</span></button> 150 - <h4 class="modal-title">Upload EVTX File</h4> 151 - </div> 152 - <div class="modal-body"> 153 - <div id="zoneTime"></div> 154 - <div class="input-group"> 155 - <input multiple id="lefile" type="file" style="display:none"> 156 - <input type="text" id="evtx_name" class="form-control" placeholder="select file (multi files) ..."> 157 - <span class="input-group-btn"><button type="button" class="btn btn-info" onclick="$('input[id=lefile]').click();">Browse</button></span> 158 - </div> 159 - <div id="uploadBar"></div> 160 - <div id="status"></div> 133 + </div> 134 + <!-- Upload --> 135 + <div class="modal fade " id = " UploadEVTX " tabindex = " -1 "> 136 + <div class="modal-dialog "> 137 + <div class="modal-content "> 138 + <div class="modal-header"> 139 + <button type="button" class="close" data-dismiss="modal"><span>×</span></button> 140 + <h4 class="modal-title">Upload EVTX File</h4> 141 + </div> 142 + <div class="modal-body"> 143 + <div id="zoneTime"></div> 144 + <div class="input-group"> 145 + <input multiple id="lefile" type="file" style="display:none"> 146 + <input type="text" id="evtx_name" class="form-control" placeholder="select file (multi files) ..."> 147 + <span class="input-group-btn"><button type="button" class="btn btn-info" onclick="$('input[id=lefile]').click();">Browse</button></span> 161 148 </div> 162 - <div class="modal-footer"> 163 - <button type="submit" class="btn btn-primary" onclick="file_upload()">Upload</button> 164 - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 165 - <a href="log" target="_blank"><button type="button" class="btn btn-default">Log</button></a> 166 - </div> 149 + <div id="uploadBar"></div> 150 + <div id="status"></div> 151 + </div> 152 + <div class="modal-footer"> 153 + <button type="submit" class="btn btn-primary" onclick="file_upload()">Upload</button> 154 + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> 155 + <a href="log" target="_blank"><button type="button" class="btn btn-default">Log</button></a> 167 156 </div> 168 157 </div> 169 158 </div> 170 - <script type="text/javascript"> 171 - var neo = neo4j.default; 172 - //Neo4j access settings 173 - var driver = neo.driver("bolt://{{ server_ip }}", neo.auth.basic("{{ neo4j_user }}", "{{ neo4j_password }}")); 174 - var session = driver.session(); 175 - var cy = cytoscape(); 176 - var rankpageUser = 0 177 - var rankpageHost = 0 159 + </div> 160 + <script type="text/javascript"> 161 + var neo = neo4j.default; 162 + //Neo4j access settings 163 + var driver = neo.driver("bolt://{{ server_ip }}", neo.auth.basic("{{ neo4j_user }}", "{{ neo4j_password }}")); 164 + var session = driver.session(); 165 + var cy = cytoscape(); 166 + var rankpageUser = 0 167 + var rankpageHost = 0 178 168 179 - var userqueryStr = 'MATCH (node:Username) RETURN node'; 180 - var ipqueryStr = 'MATCH (node:IPAddress) RETURN node'; 181 - pagerankQuery(userqueryStr, "User", rankpageUser); 182 - pagerankQuery(ipqueryStr, "Host", rankpageHost); 169 + var userqueryStr = 'MATCH (node:Username) RETURN node'; 170 + var ipqueryStr = 'MATCH (node:IPAddress) RETURN node'; 171 + pagerankQuery(userqueryStr, "User", rankpageUser); 172 + pagerankQuery(ipqueryStr, "Host", rankpageHost); 183 173 184 - var currentNumber = 0; 185 - var ItemField = { 186 - currentNumber: 0, 187 - itemTemplate: '<label class="sr-only" for="InputSelect">select</label>\ 174 + var currentNumber = 0; 175 + var ItemField = { 176 + currentNumber: 0, 177 + itemTemplate: '<label class="sr-only" for="InputSelect">select</label>\ 188 178 <select class="form-control" id="InputSelect_count_">\ 189 179 <option>Username</option><option>Host</option></select>\ 190 180 <input class="form-control" type="text" id="query-input_count_" size="10">\ 191 181 <label class="sr-only" for="InputSelect">select</label>\ 192 182 <select class="form-control" id="InputRule_count_">\ 193 183 <option>OR</option><option>AND</option></select>', 194 - add: function() { 195 - currentNumber++; 196 - if (currentNumber <= 10) { 197 - var new_item = this.itemTemplate.replace(/_count_/mg, currentNumber); 198 - var new_area = document.createElement("div"); 199 - new_area.setAttribute("id", "item" + currentNumber); 200 - var field = document.getElementById('itemForm'); 201 - field.appendChild(new_area); 202 - document.getElementById('item' + currentNumber).innerHTML = new_item; 203 - } 204 - }, 205 - del: function() { 206 - if (currentNumber == 0) { 207 - return; 208 - } 184 + add: function() { 185 + currentNumber++; 186 + if (currentNumber <= 10) { 187 + var new_item = this.itemTemplate.replace(/_count_/mg, currentNumber); 188 + var new_area = document.createElement("div"); 189 + new_area.setAttribute("id", "item" + currentNumber); 209 190 var field = document.getElementById('itemForm'); 210 - field.removeChild(field.lastChild); 211 - currentNumber--; 212 - } 213 - } 214 - 215 - var downMenu = '<div class="col-xs-3"><select class="form-control" id="utcTime"><option>UTC</option>'; 216 - for (i = +14; i >= -12; i--) { 217 - downMenu += '<option>' + i + '</option>'; 218 - } 219 - downMenu += '</select></div>'; 220 - document.getElementById("zoneTime").innerHTML = downMenu; 221 - 222 - function buildGraph(graph, path) { 223 - for (idx in path) { 224 - if (Object.keys(path[idx]).length == 3) { 225 - objid = parseInt(path[idx].identity.low) + 100; 226 - } else { 227 - objid = parseInt(path[idx].identity.low) + 1000; 228 - } 229 - 230 - // Node 231 - if (Object.keys(path[idx]).length == 3) { 232 - var ndupflg = false; 233 - for (nidx in graph.nodes) { 234 - if (graph.nodes[nidx].data.objid == objid) { 235 - ndupflg = true; 236 - } 237 - } 238 - if (ndupflg) { 239 - continue; 240 - } 241 - 242 - if (path[idx].labels[0] == "Username") { 243 - nname = path[idx].properties.user 244 - nfsize = "10" 245 - nshape = "ellipse" 246 - nwidth = "25" 247 - nheight = "25" 248 - ntype = "User" 249 - if (path[idx].properties.rights == "system") { 250 - ncolor = "#ff0000" 251 - nbcolor = "#ffc0cb" 252 - nfcolor = "#ff69b4" 253 - nprivilege = "SYSTEM" 254 - } else { 255 - ncolor = "#0000cd" 256 - nbcolor = "#cee1ff" 257 - nfcolor = "#6da0f2" 258 - nprivilege = "Normal" 259 - } 260 - } 261 - if (path[idx].labels[0] == "IPAddress") { 262 - nname = path[idx].properties.IP 263 - nshape = "diamond" 264 - nwidth = "25" 265 - nheight = "25" 266 - nfsize = "8" 267 - ncolor = "#2e8b57" 268 - nbcolor = "#98fb98" 269 - nfcolor = "#3cb371" 270 - ntype = "Host" 271 - } 272 - graph.nodes.push({ 273 - "data": { 274 - "id": objid, 275 - "objid": objid, 276 - "nlabel": nname, 277 - "ncolor": ncolor, 278 - "nbcolor": nbcolor, 279 - "nfcolor": nfcolor, 280 - "nwidth": nwidth, 281 - "nheight": nheight, 282 - "nfsize": nfsize, 283 - "nshape": nshape, 284 - "label": path[idx].labels[0], 285 - "nprivilege": nprivilege, 286 - "ntype": ntype, 287 - "nsid": path[idx].properties.sid 288 - } 289 - }); 290 - } else { 291 - // Relationship 292 - var ldupflg = false; 293 - var label_count = document.getElementById("label-count").checked; 294 - var label_type = document.getElementById("label-type").checked; 295 - var label_status = document.getElementById("label-status").checked; 296 - var ename = path[idx].properties.id.low; 297 - if (label_count) { 298 - ename += " : " + path[idx].properties.count.low; 299 - } 300 - if (label_type) { 301 - ename += " : " + path[idx].properties.logintype; 302 - } 303 - if (label_status) { 304 - ename += " : " + path[idx].properties.status; 305 - } 306 - for (nidx in graph.edges) { 307 - if (graph.edges[nidx].data.objid == objid) { 308 - ldupflg = true; 309 - } 310 - } 311 - if (ldupflg) { 312 - continue; 313 - } 314 - graph.edges.push({ 315 - "data": { 316 - "id": objid, 317 - "source": parseInt(path[parseInt(idx) - 1].identity.low) + 100, 318 - "target": parseInt(path[parseInt(idx) + 1].identity.low) + 100, 319 - "objid": objid, 320 - "elabel": ename, 321 - "label": path[idx].type, 322 - "distance": 5, 323 - "ntype": "edge", 324 - "eid": path[idx].properties.id.low, 325 - "count": path[idx].properties.count.low, 326 - "logontype": path[idx].properties.logintype, 327 - "status": path[idx].properties.status 328 - } 329 - }); 330 - } 331 - } 332 - 333 - return (graph); 334 - } 335 - 336 - function drawGraph(graph, rootNode) { 337 - var flagGrid = document.getElementById("modeGrid").checked; 338 - var flagCose = document.getElementById("modeCose").checked; 339 - var flagCircle = document.getElementById("modeCircle").checked; 340 - var flagMode = ""; 341 - 342 - if (flagGrid) { 343 - flagMode = "grid"; 344 - } 345 - if (flagCose) { 346 - flagMode = "cose"; 347 - } 348 - if (flagCircle) { 349 - flagMode = "circle"; 350 - } 351 - 352 - cy = cytoscape({ 353 - container: document.getElementById("cy"), 354 - boxSelectionEnabled: false, 355 - style: cytoscape.stylesheet() 356 - .selector('node').css({ 357 - "content": "data(nlabel)", 358 - "width": "data(nwidth)", 359 - "height": "data(nheight)", 360 - "color": "data(ncolor)", 361 - "font-size": "data(nfsize)", 362 - "background-color": "data(nbcolor)", 363 - "border-color": "data(nfcolor)", 364 - "border-style": "solid", 365 - "border-width": 3, 366 - "text-valign": "center", 367 - "text-outline-width": 1, 368 - "text-outline-color": "data(nbcolor)", 369 - "shape": "data(nshape)" 370 - }) 371 - .selector(':selected').css({ 372 - "width": 25, 373 - "height": 25, 374 - "border-width": 4, 375 - "border-color": "#404040" 376 - }) 377 - .selector('edge').css({ 378 - "content": "data(elabel)", 379 - "font-size": "8", 380 - 'curve-style': 'bezier', 381 - 'target-arrow-shape': 'triangle', 382 - 'width': 2, 383 - 'line-color': '#ddd', 384 - 'target-arrow-color': '#ddd' 385 - }) 386 - .selector('.highlighted').css({ 387 - 'background-color': '#61bffc', 388 - 'line-color': '#61bfcc', 389 - 'transition-property': 'background-color, line-color, target-arrow-color', 390 - 'transition-duration': '0.5s' 391 - }), 392 - elements: graph, 393 - layout: { 394 - name: flagMode, 395 - directed: true, 396 - roots: rootNode, 397 - animate: true, 398 - padding: 10 399 - } 400 - }); 401 - 402 - cy.nodes().forEach(function(ele) { 403 - ele.qtip({ 404 - content: { 405 - title: "<b>Node Details</b>", 406 - text: qtipNode(ele) 407 - }, 408 - style: { 409 - classes: 'qtip-bootstrap' 410 - }, 411 - position: { 412 - my: 'top center', 413 - at: 'bottom center', 414 - target: ele 415 - } 416 - }); 417 - }); 418 - 419 - cy.edges().forEach(function(ele) { 420 - ele.qtip({ 421 - content: { 422 - title: "<b>Event Details</b>", 423 - text: qtipEdge(ele) 424 - }, 425 - style: { 426 - classes: 'qtip-bootstrap' 427 - }, 428 - position: { 429 - my: 'top center', 430 - at: 'bottom center', 431 - target: ele 432 - } 433 - }); 434 - }); 435 - } 436 - 437 - function qtipNode(ndata) { 438 - var qtext = 'Name: ' + ndata._private.data["nlabel"]; 439 - if ( ndata._private.data["ntype"] == "User" ) { 440 - qtext += '<br>Privilege: ' + ndata._private.data["nprivilege"]; 441 - qtext += '<br>SID: ' + ndata._private.data["nsid"]; 191 + field.appendChild(new_area); 192 + document.getElementById('item' + currentNumber).innerHTML = new_item; 442 193 } 443 - qtext += '<br><button type="button" class="btn btn-primary btn-xs" onclick="createRankQuery(\'' + ndata._private.data["nlabel"] + '\',\'' + ndata._private.data["ntype"] + '\')">search</button>'; 444 - 445 - return qtext; 446 - } 447 - 448 - function qtipEdge(ndata) { 449 - var qtext = ""; 450 - if ( ndata._private.data["eid"] == 4624 ){ 451 - qtext = "<b>Successful logon</b><br>"; 194 + }, 195 + del: function() { 196 + if (currentNumber == 0) { 197 + return; 452 198 } 453 - if ( ndata._private.data["eid"] == 4625 ){ 454 - qtext = "<b>Logon failure</b><br>"; 455 - } 456 - if ( ndata._private.data["eid"] == 4768 ){ 457 - qtext = "<b>Kerberos Authentication (TGT Request)</b><br>"; 458 - } 459 - if ( ndata._private.data["eid"] == 4769 ){ 460 - qtext = "<b>Kerberos Service Ticket (ST Request)</b><br>"; 461 - } 462 - if ( ndata._private.data["eid"] == 4776 ){ 463 - qtext = "<b>NTLM Authentication</b><br>"; 464 - } 465 - qtext += "Count: " + ndata._private.data["count"]; 466 - qtext += "<br>Logon Type: " + ndata._private.data["logontype"]; 467 - qtext += "<br>Status: " + ndata._private.data["status"]; 468 - return qtext; 199 + var field = document.getElementById('itemForm'); 200 + field.removeChild(field.lastChild); 201 + currentNumber--; 469 202 } 203 + } 470 204 471 - function createAllQuery() { 472 - eidStr = getQueryID(); 473 - eidStr = eidStr.slice(4); 474 - queryStr = 'MATCH (user)-[event]-(ip) WHERE ' + eidStr + ' RETURN user, event, ip'; 475 - //console.log(queryStr); 476 - executeQuery(queryStr); 477 - } 205 + var downMenu = '<div class="col-xs-3"><select class="form-control" id="utcTime"><option>UTC</option>'; 206 + for (i = +14; i >= -12; i--) { 207 + downMenu += '<option>' + i + '</option>'; 208 + } 209 + downMenu += '</select></div>'; 210 + document.getElementById("zoneTime").innerHTML = downMenu; 478 211 479 - function createSystemQuery() { 480 - eidStr = getQueryID(); 481 - queryStr = 'MATCH (user)-[event]-(ip) WHERE user.rights = "system" ' + eidStr + ' RETURN user, event, ip'; 482 - //console.log(queryStr); 483 - executeQuery(queryStr); 484 - } 485 - 486 - function createRDPQuery() { 487 - eidStr = getQueryID(); 488 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.logintype = 10 ' + eidStr + ' RETURN user, event, ip'; 489 - //console.log(queryStr); 490 - executeQuery(queryStr); 491 - } 492 - 493 - function createNetQuery() { 494 - eidStr = getQueryID(); 495 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.logintype = 3 ' + eidStr + ' RETURN user, event, ip'; 496 - //console.log(queryStr); 497 - executeQuery(queryStr); 212 + $('input[id=lefile]').change(function() { 213 + var inFile = ""; 214 + var fileList = document.getElementById("lefile").files; 215 + if (1 < fileList.length) { 216 + inFile += "selected " + fileList.length + " files." 217 + } else { 218 + inFile += fileList[0].name 498 219 } 499 - 500 - function createBatchQuery() { 501 - eidStr = getQueryID(); 502 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.logintype = 4 ' + eidStr + ' RETURN user, event, ip'; 503 - //console.log(queryStr); 504 - executeQuery(queryStr); 505 - } 506 - 507 - function createServiceQuery() { 508 - eidStr = getQueryID(); 509 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.logintype = 5 ' + eidStr + ' RETURN user, event, ip'; 510 - //console.log(queryStr); 511 - executeQuery(queryStr); 512 - } 513 - 514 - function create14068Query() { 515 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.status = "0xf" AND event.id = 4769 RETURN user, event, ip' 516 - //console.log(queryStr); 517 - executeQuery(queryStr); 518 - } 519 - 520 - function createFailQuery() { 521 - queryStr = 'MATCH (user)-[event]-(ip) WHERE event.id = 4625 RETURN user, event, ip' 522 - //console.log(queryStr); 523 - executeQuery(queryStr); 524 - } 525 - 526 - function createRankQuery(setStr, qType) { 527 - if (qType == "User") { 528 - whereStr = 'user.user = "' + setStr + '" '; 529 - } 530 - if (qType == "Host") { 531 - whereStr = 'ip.IP = "' + setStr + '" '; 532 - } 533 - 534 - eidStr = getQueryID() 535 - 536 - queryStr = 'MATCH (user)-[event]-(ip) WHERE (' + whereStr + ') ' + eidStr + ' RETURN user, event, ip'; 537 - //console.log(queryStr); 538 - executeQuery(queryStr); 539 - } 540 - 541 - function getQueryID() { 542 - var id4624Ch = document.getElementById("id4624").checked; 543 - var id4625Ch = document.getElementById("id4625").checked; 544 - var id4768Ch = document.getElementById("id4768").checked; 545 - var id4769Ch = document.getElementById("id4769").checked; 546 - var id4776Ch = document.getElementById("id4776").checked; 547 - var countInt = document.getElementById("count-input").value; 548 - var eidStr = "AND (" 549 - if (id4624Ch) { 550 - eidStr = eidStr + "event.id = 4624 OR "; 551 - } 552 - if (id4625Ch) { 553 - eidStr = eidStr + "event.id = 4625 OR "; 554 - } 555 - if (id4768Ch) { 556 - eidStr = eidStr + "event.id = 4768 OR "; 557 - } 558 - if (id4769Ch) { 559 - eidStr = eidStr + "event.id = 4769 OR "; 560 - } 561 - if (id4776Ch) { 562 - eidStr = eidStr + "event.id = 4776 OR "; 563 - } 564 - eidStr = eidStr.slice(0, -4) + ")"; 565 - eidStr = eidStr + " AND event.count > " + countInt; 566 - 567 - return eidStr; 568 - } 569 - 570 - function createQuery() { 571 - var selectVal = document.getElementById("InputSelect").value; 572 - var setStr = document.getElementById("query-input").value; 573 - 574 - if (selectVal == "Username") { 575 - whereStr = 'user.user =~ "' + setStr + '" '; 576 - } else { 577 - whereStr = 'ip.IP =~ "' + setStr + '" '; 578 - } 579 - 580 - for (i = 1; i <= currentNumber; i++) { 581 - if (document.getElementById("query-input" + i).value) { 582 - ruleStr = document.getElementById("InputRule" + i).value; 583 - if (document.getElementById("InputSelect" + i).value == "Username") { 584 - whereStr += ruleStr + ' user.user =~ "' + document.getElementById("query-input" + i).value + '" '; 585 - } else { 586 - whereStr += ruleStr + ' ip.IP =~ "' + document.getElementById("query-input" + i).value + '" '; 587 - } 588 - } 589 - } 590 - 591 - eidStr = getQueryID() 592 - queryStr = 'MATCH (user)-[event]-(ip) WHERE (' + whereStr + ') ' + eidStr + ' RETURN user, event, ip'; 593 - //console.log(queryStr); 594 - executeQuery(queryStr); 595 - } 596 - 597 - function executeQuery(queryStr) { 598 - var graph = { 599 - "nodes": [], 600 - "edges": [] 601 - }; 602 - 603 - session.run(queryStr) 604 - .subscribe({ 605 - onNext: function(record) { 606 - //console.log(record.get('user'), record.get('event'), record.get('ip')); 607 - graph = buildGraph(graph, [record.get("user"), record.get("event"), record.get("ip")]) 608 - }, 609 - onCompleted: function() { 610 - session.close(); 611 - if (graph.nodes.length == 0) { 612 - searchError(); 613 - } else { 614 - //console.log(graph); 615 - rootNode = graph.nodes[0].id; 616 - drawGraph(graph, rootNode); 617 - } 618 - }, 619 - onError: function(error) { 620 - console.log("Error: ", error); 621 - } 622 - }); 623 - } 624 - 625 - function pruserBack() { 626 - rankpageUser -= 1; 627 - if (rankpageUser < 0) { 628 - rankpageUser = 0; 629 - } 630 - pagerankQuery(userqueryStr, "User", rankpageUser); 631 - } 632 - 633 - function pruserNext() { 634 - rankpageUser += 1; 635 - if (rankpageUser < 0) { 636 - rankpageUser = 0; 637 - } 638 - pagerankQuery(userqueryStr, "User", rankpageUser); 639 - } 640 - 641 - function prhostBack() { 642 - rankpageHost -= 1; 643 - if (rankpageHost < 0) { 644 - rankpageHost = 0; 645 - } 646 - pagerankQuery(ipqueryStr, "Host", rankpageHost); 647 - } 648 - 649 - function prhostNext() { 650 - rankpageHost += 1; 651 - if (rankpageHost < 0) { 652 - rankpageHost = 0; 653 - } 654 - pagerankQuery(ipqueryStr, "Host", rankpageHost); 655 - } 656 - 657 - function pagerankQuery(queryStr, dataType, currentPage) { 658 - var nodes = new Array(); 659 - var html = '<div><table class="table table-striped"><thead><tr class="col-sm-2 col-md-2">\ 660 - <th class="col-sm-1 col-md-1">Rank</th><th class="col-sm-1 col-md-1">' + dataType + 661 - '</th></tr></thead><tbody class="col-sm-2 col-md-2">'; 662 - session.run(queryStr) 663 - .subscribe({ 664 - onNext: function(record) { 665 - nodeData = record.get("node"); 666 - if (dataType == "User") { 667 - nodes.push([nodeData.properties.user, nodeData.properties.rank]); 668 - } 669 - if (dataType == "Host") { 670 - nodes.push([nodeData.properties.IP, nodeData.properties.rank]); 671 - } 672 - }, 673 - onCompleted: function() { 674 - session.close(); 675 - nodes.sort(function(a, b) { 676 - var aa = a[1]; 677 - var bb = b[1]; 678 - if (aa < bb) { 679 - return 1; 680 - } 681 - if (aa > bb) { 682 - return -1; 683 - } 684 - return 0; 685 - }); 686 - for (i = 10 * currentPage; i < nodes.length; i++) { 687 - if (i >= 10 * currentPage + 10) { 688 - break; 689 - } 690 - html += '<tr><td>' + (i + 1) + '</td><td><a onclick="createRankQuery(\'' + nodes[i][0] + '\', \'' + dataType + '\')">' + nodes[i][0] + '</a></td></tr>'; 691 - //console.log(nodes[i][0]); 692 - //console.log(hosts[i][0]); 693 - } 694 - html += '</tbody></table></div>'; 695 - 696 - if (dataType == "User") { 697 - var rankElem = document.getElementById("rankUser"); 698 - } 699 - if (dataType == "Host") { 700 - var rankElem = document.getElementById("rankHost"); 701 - } 702 - rankElem.innerHTML = html; 703 - }, 704 - onError: function(error) { 705 - console.log("Error: ", error); 706 - } 707 - }); 708 - } 709 - 710 - function exportCSV() { 711 - var queryStr = 'MATCH (user:Username)-[event]-(ip:IPAddress) RETURN user, ip, event'; 712 - var events = new Array(); 713 - 714 - session.run(queryStr) 715 - .subscribe({ 716 - onNext: function(record) { 717 - eventData = record.get("event"); 718 - userData = record.get("user"); 719 - ipData = record.get("ip"); 720 - events.push([userData.properties.user, ipData.properties.IP, 721 - eventData.properties.id, eventData.properties.logintype, 722 - eventData.properties.status, eventData.properties.count 723 - ]); 724 - }, 725 - onCompleted: function() { 726 - session.close(); 727 - var rowData = "username,host,id,logontype,status,count\r\n"; 728 - for (i = 0; i < events.length; i++) { 729 - rowData += events[i][0] + ","; 730 - rowData += events[i][1] + ","; 731 - rowData += events[i][2] + ","; 732 - rowData += events[i][3] + ","; 733 - rowData += events[i][4] + ","; 734 - rowData += events[i][5] + "\r\n"; 735 - } 736 - var downLoadLink = document.createElement("a"); 737 - downLoadLink.download = "image.csv"; 738 - downLoadLink.href = URL.createObjectURL(new Blob([rowData], {type: "application.csv"})); 739 - downLoadLink.dataset.downloadurl = ["application/csv", downLoadLink.download, downLoadLink.href].join(":"); 740 - downLoadLink.click(); 741 - }, 742 - onError: function(error) { 743 - console.log("Error: ", error); 744 - } 745 - }); 746 - } 747 - 748 - function exportJSON() { 749 - var jsonData = "data:application/json,"; 750 - jsonData += encodeURIComponent(JSON.stringify(cy.json())); 751 - var exptag = document.getElementById('export-json'); 752 - exptag.href = jsonData; 753 - } 754 - 755 - function exportPNG() { 756 - var png64 = cy.png(); 757 - var exptag = document.getElementById('export-png'); 758 - exptag.href = png64; 759 - } 760 - 761 - function exportJPEG() { 762 - var jpg64 = cy.png(); 763 - var exptag = document.getElementById('export-jpeg'); 764 - exptag.href = jpg64; 765 - } 766 - 767 - function downloadCSV(csvType) { 768 - var queryStr = 'MATCH (date:Date) MATCH (user:Username) RETURN date, user'; 769 - var users = new Array(); 770 - 771 - session.run(queryStr) 772 - .subscribe({ 773 - onNext: function(record) { 774 - nodeData = record.get("user"); 775 - dateData = record.get("date"); 776 - users.push([nodeData.properties.user, nodeData.properties.counts, 777 - nodeData.properties.counts4624, nodeData.properties.counts4625, 778 - nodeData.properties.counts4768, nodeData.properties.counts4769, 779 - nodeData.properties.counts4776 780 - ]); 781 - starttime = dateData.properties.start; 782 - endtime = dateData.properties.end; 783 - }, 784 - onCompleted: function() { 785 - session.close(); 786 - 787 - var startDate = new Date(starttime); 788 - var rangeHours = Math.floor((Date.parse(endtime) - Date.parse(starttime)) / (1000 * 60 * 60)) + 1; 789 - var rawDate = "username,"; 790 - if (csvType == "detail") { 791 - rawDate += "id,"; 792 - } 793 - var countData = ""; 794 - for (i = 0; i < rangeHours; i++) { 795 - rawDate += startDate.toISOString() + ","; 796 - startDate.setHours(startDate.getHours() + 1); 797 - } 798 - 799 - if (csvType == "summary") { 800 - for (i = 0; i < users.length; i++) { 801 - countData += users[i][0] + "," + users[i][1] + "\r\n"; 802 - } 803 - } else if (csvType == "detail") { 804 - for (i = 0; i < users.length; i++) { 805 - countData += users[i][0]; 806 - for (j = 2; j <= 6; j++) { 807 - if (j == 2) { 808 - countData += ",4624," 809 - } else if (j == 3) { 810 - countData += ",4625," 811 - } else if (j == 4) { 812 - countData += ",4768," 813 - } else if (j == 5) { 814 - countData += ",4769," 815 - } else if (j == 6) { 816 - countData += ",4776," 817 - } 818 - countData += users[i][j] + "\r\n"; 819 - } 820 - } 821 - } 822 - 823 - rawDate += "\r\n" + countData 824 - var downLoadLink = document.createElement("a"); 825 - downLoadLink.download = "timeline.csv"; 826 - downLoadLink.href = URL.createObjectURL(new Blob([rawDate], {type: "application.csv"})); 827 - downLoadLink.dataset.downloadurl = ["application/csv", downLoadLink.download, downLoadLink.href].join(":"); 828 - downLoadLink.click(); 829 - }, 830 - onError: function(error) { 831 - console.log("Error: ", error); 832 - } 833 - }); 834 - } 835 - 836 - function downloadSummary() { 837 - downloadCSV("summary") 838 - } 839 - 840 - function downloadDetail() { 841 - downloadCSV("detail") 842 - } 843 - 844 - function createTimeline(queryStr, tableType) { 845 - var users = new Array(); 846 - var starttime = ""; 847 - var endtime = ""; 848 - var weekTbl = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); 849 - var bgcolorTbl = new Array("#ff7f50", "#efefef", "#efefef", "#efefef", "#efefef", "#efefef", "#b0c4de"); 850 - 851 - if (tableType == "all") { 852 - var span = 'rowspan = "4"'; 853 - } 854 - if (tableType == "search") { 855 - var span = 'rowspan = "4" colspan="2"'; 856 - } 857 - var html = '<div class="table-responsive"><table class="table table-bordered table-condensed table-striped" style="background-color:#EEE;"><thead><tr>\ 858 - <th ' + span + '>Username</th>'; 859 - 860 - session.run(queryStr) 861 - .subscribe({ 862 - onNext: function(record) { 863 - dateData = record.get("date"); 864 - nodeData = record.get("user"); 865 - users.push([nodeData.properties.user, nodeData.properties.counts, nodeData.properties.detect, nodeData.properties.rights, nodeData.properties.counts4624, 866 - nodeData.properties.counts4625, nodeData.properties.counts4768, nodeData.properties.counts4769, nodeData.properties.counts4776 867 - ]); 868 - starttime = dateData.properties.start; 869 - endtime = dateData.properties.end; 870 - }, 871 - onCompleted: function() { 872 - session.close(); 873 - var startDate = new Date(starttime); 874 - var rangeHours = Math.floor((Date.parse(endtime) - Date.parse(starttime)) / (1000 * 60 * 60)) + 1; 875 - var thisyear = startDate.getFullYear(); 876 - var thismonth = startDate.getMonth(); 877 - var thisday = startDate.getDate(); 878 - var thishour = startDate.getHours(); 879 - var thisdow = startDate.getDay(); 880 - var nextyear = null; 881 - var nrangeHours = 0; 882 - var weekd = 0; 883 - for (i = 1; i <= rangeHours; i++) { 884 - startDate.setHours(startDate.getHours() + 1); 885 - if (startDate.getFullYear() != thisyear) { 886 - html += '<th colspan="' + (i - nrangeHours) + '">' + thisyear + '</th>'; 887 - thisyear = startDate.getFullYear(); 888 - nrangeHours = i; 889 - } 890 - } 891 - html += '<th colspan="' + (rangeHours - nrangeHours) + '">' + thisyear + '</th></tr><tr>'; 892 - 893 - nrangeHours = 0; 894 - startDate = new Date(starttime); 895 - for (i = 1; i <= rangeHours; i++) { 896 - startDate.setHours(startDate.getHours() + 1); 897 - if (startDate.getMonth() != thismonth) { 898 - html += '<th colspan="' + (i - nrangeHours) + '">' + (thismonth + 1) + '</th>'; 899 - thismonth = startDate.getMonth(); 900 - nrangeHours = i; 901 - } 902 - } 903 - html += '<th colspan="' + (rangeHours - nrangeHours) + '">' + (thismonth + 1) + '</th></tr><tr>'; 904 - 905 - nrangeHours = 0; 906 - startDate = new Date(starttime); 907 - for (i = 1; i <= rangeHours; i++) { 908 - startDate.setHours(startDate.getHours() + 1); 909 - if (startDate.getDate() != thisday) { 910 - html += '<th bgcolor="' + bgcolorTbl[thisdow + weekd] + '" colspan="' + (i - nrangeHours) + '">' + thisday + '(' + weekTbl[thisdow + weekd] + ')</th>'; 911 - if (thisdow + weekd >= 6) { 912 - thisdow = 0 - (weekd + 1); 913 - } 914 - thisday = startDate.getDate(); 915 - nrangeHours = i; 916 - weekd += 1; 917 - } 918 - } 919 - html += '<th bgcolor="' + bgcolorTbl[thisdow + weekd] + '" colspan="' + (rangeHours - nrangeHours) + '">' + thisday + '(' + weekTbl[thisdow + weekd] + ')</th></tr><tr>'; 920 - 921 - for (i = 0; i < rangeHours; i++) { 922 - html += '<th>' + thishour + '</th>'; 923 - thishour += 1; 924 - if (thishour >= 24) { 925 - thishour = 0; 926 - } 927 - } 928 - 929 - html += '</tr></thead><tbody>'; 930 - 931 - if (tableType == "all") { 932 - for (i = 0; i < users.length; i++) { 933 - if (users[i][3] == "system") { 934 - html += '<tr><td><font color="#ff7f50">' + users[i][0] + '</font></td>'; 935 - } else { 936 - html += '<tr><td>' + users[i][0] + '</td>'; 937 - } 938 - rowdata = users[i][1].split(","); 939 - alerts = users[i][2].split(","); 940 - for (j = 0; j < rowdata.length; j++) { 941 - if (alerts[j] > 17) { 942 - html += '<td bgcolor="#ff5aee">' + rowdata[j].split(".")[0] + '</td>'; 943 - } else if (alerts[j] > 16) { 944 - html += '<td bgcolor="#ff8aee">' + rowdata[j].split(".")[0] + '</td>'; 945 - } else if (alerts[j] > 13) { 946 - html += '<td bgcolor="#ffbaee">' + rowdata[j].split(".")[0] + '</td>'; 947 - } else if (alerts[j] > 10) { 948 - html += '<td bgcolor="#ffeaee">' + rowdata[j].split(".")[0] + '</td>'; 949 - } else { 950 - html += '<td>' + rowdata[j].split(".")[0] + '</td>'; 951 - } 952 - } 953 - html += '</tr>'; 954 - } 955 - } 956 - 957 - if (tableType == "search") { 958 - for (i = 0; i < users.length; i++) { 959 - if (users[i][3] == "system") { 960 - html += '<tr><td rowspan = "5"><font color="#ff7f50">' + users[i][0] + '</font></td>'; 961 - } else { 962 - html += '<tr><td rowspan = "5">' + users[i][0] + '</td>'; 963 - } 964 - 965 - for (j = 4; j <= 8; j++) { 966 - rowdata = users[i][j].split(","); 967 - alerts = users[i][2].split(","); 968 - if (j == 4) { 969 - html += '<td>4624</td>'; 970 - } else if (j == 5) { 971 - html += '<td>4625</td>'; 972 - } else if (j == 6) { 973 - html += '<td>4768</td>'; 974 - } else if (j == 7) { 975 - html += '<td>4769</td>'; 976 - } else if (j == 8) { 977 - html += '<td>4776</td>'; 978 - } 979 - for (k = 0; k < rowdata.length; k++) { 980 - if (alerts[k] > 17) { 981 - html += '<td bgcolor="#ff5aee">' + rowdata[k].split(".")[0] + '</td>'; 982 - } else if (alerts[k] > 16) { 983 - html += '<td bgcolor="#ff8aee">' + rowdata[k].split(".")[0] + '</td>'; 984 - } else if (alerts[k] > 13) { 985 - html += '<td bgcolor="#ffbaee">' + rowdata[k].split(".")[0] + '</td>'; 986 - } else if (alerts[k] > 10) { 987 - html += '<td bgcolor="#ffeaee">' + rowdata[k].split(".")[0] + '</td>'; 988 - } else { 989 - html += '<td>' + rowdata[k].split(".")[0] + '</td>'; 990 - } 991 - } 992 - html += '</tr>'; 993 - } 994 - } 995 - } 996 - html += '</tbody></table></div>'; 997 - 998 - var timelineElem = document.getElementById("cy"); 999 - timelineElem.innerHTML = html; 1000 - }, 1001 - onError: function(error) { 1002 - console.log("Error: ", error); 1003 - } 1004 - }); 1005 - } 1006 - 1007 - function createAlltimeline() { 1008 - var queryStr = 'MATCH (date:Date) MATCH (user:Username) RETURN date, user'; 1009 - createTimeline(queryStr, "all"); 1010 - } 1011 - 1012 - function searchTimeline() { 1013 - var selectVal = document.getElementById("InputSelect").value; 1014 - var setStr = document.getElementById("query-input").value; 1015 - 1016 - if (selectVal == "Username") { 1017 - whereStr = 'user.user =~ "' + setStr + '" '; 1018 - } else { 1019 - searchError(); 1020 - } 1021 - 1022 - for (i = 1; i <= currentNumber; i++) { 1023 - if (document.getElementById("query-input" + i).value) { 1024 - ruleStr = document.getElementById("InputRule" + i).value; 1025 - if (document.getElementById("InputSelect" + i).value == "Username") { 1026 - whereStr += ruleStr + ' user.user =~ "' + document.getElementById("query-input" + i).value + '" '; 1027 - } else { 1028 - searchError(); 1029 - } 1030 - } 1031 - } 1032 - var queryStr = 'MATCH (date:Date) MATCH (user:Username) WHERE (' + whereStr + ') RETURN date, user'; 1033 - createTimeline(queryStr, "search"); 1034 - } 1035 - 1036 - function searchError() { 1037 - var elemMsg = document.getElementById("error"); 1038 - elemMsg.innerHTML = 1039 - '<div class="alert alert-warning alert-dismissible" id="alertfadeout" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="close">\ 1040 - <span aria-hidden="true">×</span></button><strong>WARNING</strong>: Search failed!</div>'; 1041 - $(document).ready(function() { 1042 - $('#alertfadeout').fadeIn(2000).delay(4000).fadeOut(2000); 1043 - }); 1044 - } 1045 - 1046 - function file_upload() { 1047 - var upfile = document.getElementById("lefile"); 1048 - var timezone = document.getElementById("utcTime").value; 1049 - document.getElementById("uploadBar").innerHTML = ''; 1050 - document.getElementById("status").innerHTML = ''; 1051 - 1052 - var formData = new FormData(); 1053 - for (var i = 0; i < upfile.files.length; i++) { 1054 - sendFile = "file" + i 1055 - formData.append(sendFile, upfile.files[i]); 1056 - } 1057 - formData.append("timezone", timezone); 1058 - var xmlhttp = new XMLHttpRequest(); 1059 - xmlhttp.upload.addEventListener("progress", progressHandler, false); 1060 - xmlhttp.addEventListener("load", completeHandler, false); 1061 - xmlhttp.addEventListener("error", errorHandler, false); 1062 - xmlhttp.addEventListener("abort", abortHandler, false); 1063 - xmlhttp.open("POST", "upload", true); 1064 - xmlhttp.send(formData); 1065 - } 1066 - 1067 - function progressHandler(event) { 1068 - var percent = (event.loaded / event.total) * 100; 1069 - document.getElementById("uploadBar").innerHTML = '<h4>Upload ...</h4><div class="progress"><div class="progress-bar progress-bar-striped active" role="progressbar" style="width: ' + Math.round(percent) + '%;">' + Math.round(percent) + '%</div></div>'; 1070 - } 1071 - 1072 - var parse_status = false; 1073 - 1074 - function completeHandler(event) { 1075 - if (event.target.responseText == "FAIL") { 1076 - document.getElementById("status").innerHTML = '<div class="alert alert-danger"><strong>ERROR</strong>: Upload Failed!</div>'; 1077 - } 1078 - if (event.target.responseText == "SUCCESS") { 1079 - parse_status = false 1080 - document.getElementById("uploadBar").innerHTML = '<h4>Upload ...</h4><div class="progress"><div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" style="width: 100%;">SUCCESS</div></div>'; 1081 - var loop = function() { 1082 - if (parse_status == false) { 1083 - setTimeout(loop, 2000); 1084 - } 1085 - parseEVTX(); 1086 - } 1087 - loop(); 1088 - } 1089 - } 1090 - 1091 - function errorHandler(event) { 1092 - document.getElementById("status").innerHTML = '<div class="alert alert-danger"><strong>ERROR</strong>: Upload Failed!</div>'; 1093 - } 1094 - 1095 - function abortHandler(event) { 1096 - document.getElementById("status").innerHTML = '<div class="alert alert-info">Upload Aborted</div>'; 1097 - } 1098 - 1099 - $('input[id=lefile]').change(function() { 1100 - var inFile = ""; 1101 - var fileList = document.getElementById("lefile").files; 1102 - if ( 1 < fileList.length) { 1103 - inFile += "selected " + fileList.length + " files." 1104 - } else { 1105 - inFile += fileList[0].name 1106 - } 1107 - $('#evtx_name').val(inFile.replace("C:\\fakepath\\", "")); 1108 - }); 1109 - 1110 - function parseEVTX() { 1111 - var xmlhttp2 = new XMLHttpRequest(); 1112 - xmlhttp2.open("GET", "/log"); 1113 - xmlhttp2.send(); 1114 - xmlhttp2.onreadystatechange = function() { 1115 - if (xmlhttp2.readyState == 4) { 1116 - if (xmlhttp2.status == 200) { 1117 - var logdata = xmlhttp2.responseText.split(/\r\n|\r|\n/); 1118 - var allrecode = logdata[3].split(" ")[5].replace(".", ""); 1119 - var nowdata = logdata[logdata.length - 2]; 1120 - if (nowdata.indexOf("Now loading") != -1) { 1121 - var recordnum = nowdata.split(" ")[3]; 1122 - var percent = (recordnum / allrecode) * 100; 1123 - document.getElementById("uploadBar").innerHTML = '<h4>Parsing ...</h4><div class="progress"><div class="progress-bar progress-bar-striped active" role="progressbar" style="width: ' + Math.round(percent) + '%;">' + Math.round(percent) + '%</div></div>'; 1124 - } else if (nowdata.indexOf("Script end") != -1) { 1125 - document.getElementById("uploadBar").innerHTML = '<h4>Parsing ...</h4><div class="progress"><div class="progress-bar progress-bar-success progress-bar-striped" role="progressbar" style="width: 100%;">SUCCESS</div></div>'; 1126 - document.getElementById("status").innerHTML = '<div class="alert alert-info"><strong>Import Success</strong>: You need to reload the web page.</div>'; 1127 - parse_status = true; 1128 - } else if (nowdata.indexOf("[!]") != -1) { 1129 - document.getElementById("status").innerHTML = '<div class="alert alert-danger"><strong>ERROR</strong>: EVTX parse Failed!</div>'; 1130 - parse_status = true; 1131 - } 1132 - } else { 1133 - document.getElementById("status").innerHTML = '<div class="alert alert-danger"><strong>ERROR</strong>: logontracer.log status = ' + xmlhttp2.status + '</div>'; 1134 - parse_status = true; 1135 - } 1136 - } 1137 - } 1138 - } 1139 - </script> 220 + $('#evtx_name').val(inFile.replace("C:\\fakepath\\", "")); 221 + }); 222 + </script> 1140 223 </body> 1141 224 1142 225 </html> skipped 1 lines