Projects STRLCPY LogonTracer Commits dbb1addc
🤬
  • images/diff_panel.png
  • images/filter_panel.png
  • images/nav_bar.png
  • images/sample.png
  • images/sample_dark.png
  • ■ ■ ■ ■ ■
    logontracer.py
    skipped 7 lines
    8 8  import os
    9 9  import sys
    10 10  import re
     11 +import pickle
     12 +import shutil
    11 13  import argparse
    12 14  import datetime
    13 15  import subprocess
    skipped 183 lines
    197 199   help="Parse Security Event log from this time. (for example: 20170101000000)")
    198 200  parser.add_argument("-t", "--to", dest="todate", action="store", type=str, metavar="DATE",
    199 201   help="Parse Security Event log to this time. (for example: 20170228235959)")
     202 +parser.add_argument("--add", action="store_true", default=False,
     203 + help="Add additional data to Neo4j database. (default: False)")
    200 204  parser.add_argument("--delete", action="store_true", default=False,
    201 205   help="Delete all nodes and relationships from this Neo4j database. (default: False)")
    202 206  args = parser.parse_args()
    skipped 100 lines
    303 307   try:
    304 308   timezone = request.form["timezone"]
    305 309   logtype = request.form["logtype"]
     310 + addlog = request.form["addlog"]
    306 311   for i in range(0, len(request.files)):
    307 312   loadfile = "file" + str(i)
    308 313   file = request.files[loadfile]
    skipped 14 lines
    323 328   return "FAIL"
    324 329   if not re.search(r"\A-{0,1}[0-9]{1,2}\Z", timezone):
    325 330   return "FAIL"
     331 + if addlog in "true":
     332 + log_option = "--add"
     333 + else:
     334 + log_option = "--delete"
    326 335   
    327  - parse_command = "nohup python3 " + FPATH + "/logontracer.py --delete -z " + timezone + logoption + filelist + " -u " + NEO4J_USER + " -p " + NEO4J_PASSWORD + " > " + FPATH + "/static/logontracer.log 2>&1 &"
     336 + parse_command = "nohup python3 " + FPATH + "/logontracer.py " + log_option + " -z " + timezone + logoption + filelist + " -u " + NEO4J_USER + " -p " + NEO4J_PASSWORD + " > " + FPATH + "/static/logontracer.log 2>&1 &"
    328 337   subprocess.call("rm -f " + FPATH + "/static/logontracer.log > /dev/null", shell=True)
    329 338   subprocess.call(parse_command, shell=True)
    330 339   # parse_evtx(filename)
    skipped 222 lines
    553 562   
    554 563  # Parse the EVTX file
    555 564  def parse_evtx(evtx_list):
    556  - event_set = pd.DataFrame(index=[], columns=["eventid", "ipaddress", "username", "logintype", "status", "authname", "date"])
    557  - count_set = pd.DataFrame(index=[], columns=["dates", "eventid", "username"])
    558  - ml_frame = pd.DataFrame(index=[], columns=["date", "user", "host", "id"])
    559  - username_set = []
    560  - domain_set = []
    561  - admins = []
    562  - domains = []
    563  - ntmlauth = []
    564  - deletelog = []
    565  - policylist = []
    566  - addusers = {}
    567  - delusers = {}
    568  - addgroups = {}
    569  - removegroups = {}
    570  - sids = {}
    571  - hosts = {}
     565 + cache_dir = os.path.join(FPATH, 'cache')
     566 + 
     567 + # Load cache files
     568 + if args.add and os.path.exists(cache_dir) and len(os.listdir(cache_dir)):
     569 + print("[+] Load cashe files.")
     570 + event_set = pd.read_pickle(os.path.join(cache_dir, "event_set.pkl"))
     571 + count_set = pd.read_pickle(os.path.join(cache_dir, "count_set.pkl"))
     572 + ml_frame = pd.read_pickle(os.path.join(cache_dir, "ml_frame.pkl"))
     573 + with open(os.path.join(cache_dir, "username_set.pkl"), "rb") as f:
     574 + username_set = pickle.load(f)
     575 + with open(os.path.join(cache_dir, "domain_set.pkl"), "rb") as f:
     576 + domain_set = pickle.load(f)
     577 + with open(os.path.join(cache_dir, "admins.pkl"), "rb") as f:
     578 + admins = pickle.load(f)
     579 + with open(os.path.join(cache_dir, "domains.pkl"), "rb") as f:
     580 + domains = pickle.load(f)
     581 + with open(os.path.join(cache_dir, "ntmlauth.pkl"), "rb") as f:
     582 + ntmlauth = pickle.load(f)
     583 + with open(os.path.join(cache_dir, "deletelog.pkl"), "rb") as f:
     584 + deletelog = pickle.load(f)
     585 + with open(os.path.join(cache_dir, "policylist.pkl"), "rb") as f:
     586 + policylist = pickle.load(f)
     587 + with open(os.path.join(cache_dir, "addusers.pkl"), "rb") as f:
     588 + addusers = pickle.load(f)
     589 + with open(os.path.join(cache_dir, "delusers.pkl"), "rb") as f:
     590 + delusers = pickle.load(f)
     591 + with open(os.path.join(cache_dir, "addgroups.pkl"), "rb") as f:
     592 + addgroups = pickle.load(f)
     593 + with open(os.path.join(cache_dir, "removegroups.pkl"), "rb") as f:
     594 + removegroups = pickle.load(f)
     595 + with open(os.path.join(cache_dir, "sids.pkl"), "rb") as f:
     596 + sids = pickle.load(f)
     597 + with open(os.path.join(cache_dir, "hosts.pkl"), "rb") as f:
     598 + hosts = pickle.load(f)
     599 + with open(os.path.join(cache_dir, "dcsync.pkl"), "rb") as f:
     600 + dcsync = pickle.load(f)
     601 + with open(os.path.join(cache_dir, "dcshadow.pkl"), "rb") as f:
     602 + dcshadow = pickle.load(f)
     603 + with open(os.path.join(cache_dir, "date.pkl"), "rb") as f:
     604 + starttime, endtime = pickle.load(f)
     605 + else:
     606 + event_set = pd.DataFrame(index=[], columns=["eventid", "ipaddress", "username", "logintype", "status", "authname", "date"])
     607 + count_set = pd.DataFrame(index=[], columns=["dates", "eventid", "username"])
     608 + ml_frame = pd.DataFrame(index=[], columns=["date", "user", "host", "id"])
     609 + username_set = []
     610 + domain_set = []
     611 + admins = []
     612 + domains = []
     613 + ntmlauth = []
     614 + deletelog = []
     615 + policylist = []
     616 + addusers = {}
     617 + delusers = {}
     618 + addgroups = {}
     619 + removegroups = {}
     620 + sids = {}
     621 + hosts = {}
     622 + dcsync = {}
     623 + dcshadow = {}
     624 + starttime = None
     625 + endtime = None
     626 + 
    572 627   dcsync_count = {}
    573  - dcsync = {}
    574 628   dcshadow_check = []
    575  - dcshadow = {}
    576 629   count = 0
    577 630   record_sum = 0
    578  - starttime = None
    579  - endtime = None
     631 + 
     632 + if os.path.exists(cache_dir) is False:
     633 + os.mkdir(cache_dir)
     634 + print("[+] make cache folder %s." % cache_dir)
    580 635   
    581 636   if args.timezone:
    582 637   try:
    skipped 323 lines
    906 961   
    907 962   tohours = int((endtime - starttime).total_seconds() / 3600)
    908 963   
     964 + # Create Event log cache files
     965 + print("[+] Create cache files.")
     966 + pd.to_pickle(event_set, os.path.join(cache_dir, "event_set.pkl"))
     967 + pd.to_pickle(count_set, os.path.join(cache_dir, "count_set.pkl"))
     968 + pd.to_pickle(ml_frame, os.path.join(cache_dir, "ml_frame.pkl"))
     969 + with open(os.path.join(cache_dir, "username_set.pkl"), "wb") as f:
     970 + pickle.dump(username_set, f)
     971 + with open(os.path.join(cache_dir, "domain_set.pkl"), "wb") as f:
     972 + pickle.dump(domain_set, f)
     973 + with open(os.path.join(cache_dir, "admins.pkl"), "wb") as f:
     974 + pickle.dump(admins, f)
     975 + with open(os.path.join(cache_dir, "domains.pkl"), "wb") as f:
     976 + pickle.dump(domains, f)
     977 + with open(os.path.join(cache_dir, "ntmlauth.pkl"), "wb") as f:
     978 + pickle.dump(ntmlauth, f)
     979 + with open(os.path.join(cache_dir, "deletelog.pkl"), "wb") as f:
     980 + pickle.dump(deletelog, f)
     981 + with open(os.path.join(cache_dir, "policylist.pkl"), "wb") as f:
     982 + pickle.dump(policylist, f)
     983 + with open(os.path.join(cache_dir, "addusers.pkl"), "wb") as f:
     984 + pickle.dump(addusers, f)
     985 + with open(os.path.join(cache_dir, "delusers.pkl"), "wb") as f:
     986 + pickle.dump(delusers, f)
     987 + with open(os.path.join(cache_dir, "addgroups.pkl"), "wb") as f:
     988 + pickle.dump(addgroups, f)
     989 + with open(os.path.join(cache_dir, "removegroups.pkl"), "wb") as f:
     990 + pickle.dump(removegroups, f)
     991 + with open(os.path.join(cache_dir, "sids.pkl"), "wb") as f:
     992 + pickle.dump(sids, f)
     993 + with open(os.path.join(cache_dir, "hosts.pkl"), "wb") as f:
     994 + pickle.dump(hosts, f)
     995 + with open(os.path.join(cache_dir, "dcsync.pkl"), "wb") as f:
     996 + pickle.dump(dcsync, f)
     997 + with open(os.path.join(cache_dir, "dcshadow.pkl"), "wb") as f:
     998 + pickle.dump(dcshadow, f)
     999 + with open(os.path.join(cache_dir, "date.pkl"), "wb") as f:
     1000 + pickle.dump([starttime, endtime], f)
     1001 + 
    909 1002   if hosts:
    910 1003   event_set = event_set.replace(hosts)
     1004 + 
    911 1005   event_set_bydate = event_set
    912 1006   event_set_bydate["count"] = event_set_bydate.groupby(["eventid", "ipaddress", "username", "logintype", "status", "authname", "date"])["eventid"].transform("count")
    913 1007   event_set_bydate = event_set_bydate.drop_duplicates()
    skipped 167 lines
    1081 1175   if args.delete:
    1082 1176   GRAPH.delete_all()
    1083 1177   print("[+] Delete all nodes and relationships from this Neo4j database.")
     1178 + 
     1179 + cache_dir = os.path.join(FPATH, 'cache')
     1180 + if os.path.exists(cache_dir):
     1181 + shutil.rmtree(cache_dir)
     1182 + print("[+] Delete cache folder %s." % cache_dir)
    1084 1183   
    1085 1184   if args.evtx:
    1086 1185   for evtx_file in args.evtx:
    skipped 16 lines
  • ■ ■ ■ ■ ■ ■
    static/css/dark-mode.css
     1 +[data-theme="dark"] {
     2 + background-color: #202020;
     3 + color: #eee;
     4 +}
     5 + 
     6 +[data-theme="dark"] .bg-light {
     7 + background-color: #292929 !important;
     8 +}
     9 + 
     10 +[data-theme="dark"] .bg-white {
     11 + background-color: #000;
     12 +}
     13 + 
     14 +[data-theme="dark"] .bg-black {
     15 + background-color: #eee;
     16 +}
     17 + 
     18 +[data-theme="dark"] .list-group-item-light.list-group-item-action:focus {
     19 + color: WHITE;
     20 + background-color: #6c757d;
     21 +}
     22 + 
     23 +[data-theme="dark"] .list-group-item-light.list-group-item-action:hover {
     24 + color: WHITE;
     25 + background-color: #6c757d;
     26 +}
     27 + 
     28 +[data-theme="dark"] .list-group-item-light {
     29 + color: WHITE;
     30 + background-color: #202020;
     31 + border: 1px solid WHITE;
     32 +}
     33 + 
     34 +[data-theme="dark"] .my_svg {
     35 + fill: WHITE;
     36 + stroke: WHITE;
     37 + height: 50px;
     38 + width: 190px;
     39 +}
     40 + 
     41 +[data-theme="dark"] .table {
     42 + color: WHITE;
     43 + background-color: #202020;
     44 +}
     45 + 
     46 +[data-theme="dark"] .tbody {
     47 + color: WHITE;
     48 + background-image: none;
     49 + border-color: WHITE;
     50 +}
     51 + 
     52 +[data-theme="dark"] .table .thead-light th {
     53 + color: WHITE;
     54 + background-color: #202020;
     55 + border-color: WHITE;
     56 +}
     57 + 
     58 +[data-theme="dark"] .table tr {
     59 + background-color: #202020;
     60 +}
     61 + 
     62 +[data-theme="dark"] .table tr:hover {
     63 + color: WHITE;
     64 + background-color: #6c757d;
     65 + transition: background-color .3s;
     66 +}
     67 + 
     68 +[data-theme="dark"] .table-striped tbody tr {
     69 + background-color: #202020;
     70 +}
     71 + 
     72 +[data-theme="dark"] .table-striped tbody tr:hover {
     73 + color: WHITE;
     74 + background-color: #6c757d;
     75 + transition: background-color .3s;
     76 +}
     77 + 
     78 +[data-theme="dark"] .btn-primary {
     79 + color: WHITE;
     80 + background-color: #6c757d;
     81 + border-color: #6c757d;
     82 +}
     83 + 
     84 +[data-theme="dark"] .btn-primary:hover {
     85 + color: WHITE;
     86 + background-color: #545b62;
     87 + border-color: #545b62;
     88 + transition: background-color .3s;
     89 +}
     90 + 
     91 +[data-theme="dark"] .btn-outline-primary {
     92 + color: WHITE;
     93 + background-color: transparent;
     94 + background-image: none;
     95 + border-color: WHITE;
     96 +}
     97 + 
     98 +[data-theme="dark"] .btn-outline-primary:hover {
     99 + color: WHITE;
     100 + background-color: #6c757d;
     101 + border-color: #ccc;
     102 + transition: background-color .3s;
     103 +}
     104 + 
     105 +[data-theme="dark"] .btn-outline-secondary {
     106 + color: WHITE;
     107 + background-color: #202020;
     108 + background-image: none;
     109 + border-color: WHITE;
     110 +}
     111 + 
     112 +[data-theme="dark"] .btn-outline-secondary:hover {
     113 + color: WHITE;
     114 + background-color: #6c757d;
     115 + border-color: #ccc;
     116 + transition: background-color .3s;
     117 +}
     118 + 
     119 +[data-theme="dark"] .btn-outline-secondary:focus, .btn-outline-secondary.focus {
     120 + color: WHITE;
     121 + background-color: #6c757d;
     122 + border-color: #ccc;
     123 +}
     124 + 
     125 +[data-theme="dark"] .modal-content {
     126 + background-color: #222;
     127 +}
     128 + 
     129 +[data-theme="dark"] .page-link {
     130 + color: WHITE;
     131 + background-color: transparent;
     132 + border: 1px solid WHITE;
     133 +}
     134 + 
     135 +[data-theme="dark"] .page-link:hover {
     136 + background-color: #6c757d;
     137 + transition: background-color .3s;
     138 +}
     139 + 
     140 +[data-theme="dark"] .bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before {
     141 + border-top-color: #444;
     142 +}
     143 + 
     144 +[data-theme="dark"] .bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
     145 + border-bottom-color: #444;
     146 +}
     147 + 
     148 +[data-theme="dark"] .tooltip-inner {
     149 + background-color: #444;
     150 +}
     151 + 
     152 +[data-theme="dark"] .fa-refresh {
     153 + color: WHITE;
     154 +}
     155 + 
     156 +[data-theme="dark"] .fa-times {
     157 + color: WHITE;
     158 +}
     159 + 
     160 +[data-theme="dark"] .dropdown-menu {
     161 + color: WHITE;
     162 + background-color: #202020;
     163 +}
     164 + 
     165 +[data-theme="dark"] .dropdown-item {
     166 + color: WHITE;
     167 +}
     168 + 
     169 +[data-theme="dark"] .dropdown-item:hover {
     170 + color: Black;
     171 +}
     172 + 
     173 +[data-theme="dark"] .dropdown-item:active {
     174 + color: Black;
     175 +}
     176 + 
  • ■ ■ ■ ■ ■ ■
    static/css/style.css
    skipped 22 lines
    23 23   z-index: 10000;
    24 24  }
    25 25   
     26 +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
     27 + background-color:blue;
     28 +}
     29 + 
     30 +.my_svg {
     31 + height: 50px;
     32 + width: 190px;
     33 +}
     34 + 
  • static/images/logo_timeline.svg
  • static/images/logo_top.svg
  • ■ ■ ■ ■ ■
    static/js/dark-mode-switch.min.js
     1 +const darkSwitch=document.getElementById("darkSwitch");function initTheme(){const e=null!==localStorage.getItem("darkSwitch")&&"dark"===localStorage.getItem("darkSwitch");darkSwitch.checked=e,e?document.body.setAttribute("data-theme","dark"):document.body.removeAttribute("data-theme")}function resetTheme(){darkSwitch.checked?(document.body.setAttribute("data-theme","dark"),localStorage.setItem("darkSwitch","dark")):(document.body.removeAttribute("data-theme"),localStorage.removeItem("darkSwitch"))}window.addEventListener("load",()=>{darkSwitch&&(initTheme(),darkSwitch.addEventListener("change",()=>{resetTheme()}))});
  • ■ ■ ■ ■ ■ ■
    static/js/script.js
    1 1  function buildGraph(graph, path, root) {
    2 2   var objidList = []
     3 + var darkSwitch = document.getElementById("darkSwitch").checked;
     4 + 
     5 + if (darkSwitch) {
     6 + ncolor_sys = "#FF5917"
     7 + nbcolor_sys = "#000000"
     8 + nfcolor_sys = "#FF5917"
     9 + ncolor_user = "#5D86FF"
     10 + nbcolor_user = "#000000"
     11 + nfcolor_user = "#5D86FF"
     12 + ncolor_chenge = "#B59658"
     13 + nfcolor_root = "#ADADAD"
     14 + ncolor_host = "#44D37E"
     15 + nbcolor_host = "#000000"
     16 + nfcolor_host = "#44D37E"
     17 + ncolor_domain = "#9573FF"
     18 + nbcolor_domain = "#000000"
     19 + nfcolor_domain = "#9573FF"
     20 + ncolor_id = "#F9D46B"
     21 + nbcolor_id = "#000000"
     22 + nfcolor_id = "#F9D46B"
     23 + edge_color = "#007b7d"
     24 + ecolor = "#FAFAFA"
     25 + } else {
     26 + ncolor_sys = "#ff0000"
     27 + nbcolor_sys = "#ffc0cb"
     28 + nfcolor_sys = "#ff69b4"
     29 + ncolor_user = "#0000cd"
     30 + nbcolor_user = "#cee1ff"
     31 + nfcolor_user = "#6da0f2"
     32 + ncolor_chenge = "#404040"
     33 + nfcolor_root = "#404040"
     34 + ncolor_host = "#2e8b57"
     35 + nbcolor_host = "#98fb98"
     36 + nfcolor_host = "#3cb371"
     37 + ncolor_domain = "#8b2e86"
     38 + nbcolor_domain = "#fa98ef"
     39 + nfcolor_domain = "#b23aa2"
     40 + ncolor_id = "#8b6f2e"
     41 + nbcolor_id = "#f9d897"
     42 + nfcolor_id = "#b28539"
     43 + edge_color = "#CCCCCC"
     44 + ecolor = "#333333"
     45 + }
     46 + 
    3 47   for (idx in path) {
    4 48   if (Object.keys(path[idx]).length == 3) {
    5 49   objid = parseInt(path[idx].identity.low) + 100;
    skipped 28 lines
    34 78   nshape = "ellipse"
    35 79   ntype = "User"
    36 80   if (path[idx].properties.rights == "system") {
    37  - ncolor = "#ff0000"
    38  - nbcolor = "#ffc0cb"
    39  - nfcolor = "#ff69b4"
     81 + ncolor = ncolor_sys
     82 + nbcolor = nbcolor_sys
     83 + nfcolor = nfcolor_sys
    40 84   nprivilege = "SYSTEM"
    41 85   } else {
    42  - ncolor = "#0000cd"
    43  - nbcolor = "#cee1ff"
    44  - nfcolor = "#6da0f2"
     86 + ncolor = ncolor_user
     87 + nbcolor = nbcolor_user
     88 + nfcolor = nfcolor_user
    45 89   nprivilege = "Normal"
    46 90   }
    47 91   if (path[idx].properties.status != "-") {
    48  - ncolor = "#404040"
     92 + ncolor = ncolor_chenge
    49 93   nshape = "octagon"
    50 94   }
    51 95   if (root == path[idx].properties.user) {
    52  - nfcolor = "#404040"
     96 + nfcolor = nfcolor_root
    53 97   }
    54 98   }
    55 99   if (path[idx].labels[0] == "IPAddress") {
    skipped 2 lines
    58 102   nwidth = "25"
    59 103   nheight = "25"
    60 104   nfsize = "8"
    61  - ncolor = "#2e8b57"
    62  - nbcolor = "#98fb98"
    63  - nfcolor = "#3cb371"
     105 + ncolor = ncolor_host
     106 + nbcolor = nbcolor_host
     107 + nfcolor = nfcolor_host
    64 108   ntype = "Host"
    65 109   if (root == path[idx].properties.IP) {
    66  - nfcolor = "#404040"
     110 + nfcolor = nfcolor_root
    67 111   }
    68 112   }
    69 113   if (path[idx].labels[0] == "Domain") {
    skipped 2 lines
    72 116   nwidth = "25"
    73 117   nheight = "25"
    74 118   nfsize = "10"
    75  - ncolor = "#8b2e86"
    76  - nbcolor = "#fa98ef"
    77  - nfcolor = "#b23aa2"
     119 + ncolor = ncolor_domain
     120 + nbcolor = nbcolor_domain
     121 + nfcolor = nfcolor_domain
    78 122   ntype = "Domain"
    79 123   }
    80 124   if (path[idx].labels[0] == "ID") {
    skipped 5 lines
    86 130   nwidth = "25"
    87 131   nheight = "25"
    88 132   nfsize = "10"
    89  - ncolor = "#8b6f2e"
    90  - nbcolor = "#f9d897"
    91  - nfcolor = "#b28539"
     133 + ncolor = ncolor_id
     134 + nbcolor = nbcolor_id
     135 + nfcolor = nfcolor_id
    92 136   ntype = "Policy"
    93 137   }
    94 138   graph.nodes.push({
    skipped 76 lines
    171 215   "count": ecount,
    172 216   "logontype": String(path[idx].properties.logintype),
    173 217   "status": path[idx].properties.status,
    174  - "authname": path[idx].properties.authname
     218 + "authname": path[idx].properties.authname,
     219 + "edge_color": edge_color,
     220 + "ecolor": ecolor
    175 221   }
    176 222   });
    177 223   } else {
    skipped 61 lines
    239 285   "curve-style": "bezier",
    240 286   "target-arrow-shape": "triangle",
    241 287   "width": 2,
    242  - "line-color": "#ddd",
    243  - "target-arrow-color": "#ddd"
     288 + "line-color": "data(edge_color)",
     289 + "target-arrow-color": "data(edge_color)",
     290 + "color": "data(ecolor)",
    244 291   })
    245 292   .selector('.highlighted').css({
    246 293   "background-color": "#61bffc",
    skipped 595 lines
    842 889   
    843 890  function pagerankQuery(queryStr, dataType, currentPage) {
    844 891   var nodes = new Array();
    845  - var html = '<div><table class="table table-striped"><thead><tr class="col-sm-2 col-md-2">\
     892 + var html = '<div><table class="table table-hover"><thead class="thead-light"><tr class="col-sm-2 col-md-2">\
    846 893   <th class="col-sm-1 col-md-1">Rank</th><th class="col-sm-1 col-md-1">' + dataType +
    847 894   '</th></tr></thead><tbody class="col-sm-2 col-md-2">';
    848 895   var startRunk = currentPage * 10;
    skipped 185 lines
    1034 1081   if (tableType == "search") {
    1035 1082   var span = 'rowspan = "4" colspan="2"';
    1036 1083   }
    1037  - var html = '<div class="table-responsive"><table class="table table-bordered table-condensed table-striped table-wrapper" style="background-color:#EEE;"><thead><tr>\
     1084 + var html = '<div class="table-responsive"><table class="table table-hover table-bordered table-sm table-striped table-wrapper" style="background-color:#EEE;"><thead class="thead-light"><tr>\
    1038 1085   <th ' + span + '>Username</th>';
    1039 1086   
    1040 1087   for (i = 0; i < chartArray.length; i++) {
    skipped 25 lines
    1066 1113   var nextyear = null;
    1067 1114   var nrangeHours = 0;
    1068 1115   var weekd = 0;
     1116 + 
     1117 + if (darkSwitch) {
     1118 + normal_color = "#4d0715"
     1119 + low_color = "#800b23"
     1120 + mid_color = "#b31031"
     1121 + high_color = "#dc143c"
     1122 + } else {
     1123 + normal_color = "#ffeaee"
     1124 + low_color = "#ffbaee"
     1125 + mid_color = "#ff8aee"
     1126 + high_color = "#ff5aee"
     1127 + }
     1128 + 
    1069 1129   for (i = 1; i <= rangeHours; i++) {
    1070 1130   startDate.setHours(startDate.getHours() + 1);
    1071 1131   if (startDate.getFullYear() != thisyear) {
    skipped 53 lines
    1125 1185   alerts = users[i][2].split(",");
    1126 1186   for (j = 0; j < rowdata.length; j++) {
    1127 1187   if (alerts[j] > 17) {
    1128  - html += '<td bgcolor="#ff5aee">' + rowdata[j].split(".")[0] + '</td>';
     1188 + html += '<td bgcolor="' + high_color + '">' + rowdata[j].split(".")[0] + '</td>';
    1129 1189   } else if (alerts[j] > 16) {
    1130  - html += '<td bgcolor="#ff8aee">' + rowdata[j].split(".")[0] + '</td>';
     1190 + html += '<td bgcolor="' + mid_color + '">' + rowdata[j].split(".")[0] + '</td>';
    1131 1191   } else if (alerts[j] > 13) {
    1132  - html += '<td bgcolor="#ffbaee">' + rowdata[j].split(".")[0] + '</td>';
     1192 + html += '<td bgcolor="' + low_color + '">' + rowdata[j].split(".")[0] + '</td>';
    1133 1193   } else if (alerts[j] > 10) {
    1134  - html += '<td bgcolor="#ffeaee">' + rowdata[j].split(".")[0] + '</td>';
     1194 + html += '<td bgcolor="' + normal_color + '">' + rowdata[j].split(".")[0] + '</td>';
    1135 1195   } else {
    1136 1196   html += '<td>' + rowdata[j].split(".")[0] + '</td>';
    1137 1197   }
    skipped 26 lines
    1164 1224   }
    1165 1225   for (k = 0; k < rowdata.length; k++) {
    1166 1226   if (alerts[k] > 17) {
    1167  - html += '<td bgcolor="#ff5aee">' + rowdata[k].split(".")[0] + '</td>';
     1227 + html += '<td bgcolor="' + high_color + '">' + rowdata[k].split(".")[0] + '</td>';
    1168 1228   } else if (alerts[k] > 16) {
    1169  - html += '<td bgcolor="#ff8aee">' + rowdata[k].split(".")[0] + '</td>';
     1229 + html += '<td bgcolor="' + mid_color + '">' + rowdata[k].split(".")[0] + '</td>';
    1170 1230   } else if (alerts[k] > 13) {
    1171  - html += '<td bgcolor="#ffbaee">' + rowdata[k].split(".")[0] + '</td>';
     1231 + html += '<td bgcolor="' + low_color + '">' + rowdata[k].split(".")[0] + '</td>';
    1172 1232   } else if (alerts[k] > 10) {
    1173  - html += '<td bgcolor="#ffeaee">' + rowdata[k].split(".")[0] + '</td>';
     1233 + html += '<td bgcolor="' + normal_color + '">' + rowdata[k].split(".")[0] + '</td>';
    1174 1234   } else {
    1175 1235   html += '<td>' + rowdata[k].split(".")[0] + '</td>';
    1176 1236   }
    skipped 272 lines
    1449 1509   
    1450 1510   var elemMsg = document.getElementById("error");
    1451 1511   elemMsg.innerHTML =
    1452  - '<div class="alert alert-danger alert-dismissible" id="alertfadeout" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="close">\
     1512 + '<div class="alert alert-danger alert-dismissible mt-3" id="alertfadeout" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="close">\
    1453 1513   <span aria-hidden="true">×</span></button><strong>IMPORTANT</strong>: Delete Event Log has detected! If you have not deleted the event log, the attacker may have deleted it.\
    1454 1514   <br>DATE: ' + delDate + ' DOMAIN: ' + delDomain + ' USERNAME: ' + delUser + '</div>';
    1455 1515   }
    skipped 11 lines
    1467 1527  function searchError() {
    1468 1528   var elemMsg = document.getElementById("error");
    1469 1529   elemMsg.innerHTML =
    1470  - '<div class="alert alert-warning alert-dismissible" id="alertfadeout" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="close">\
     1530 + '<div class="alert alert-warning alert-dismissible mt-3" id="alertfadeout" role="alert"><button type="button" class="close" data-dismiss="alert" aria-label="close">\
    1471 1531   <span aria-hidden="true">×</span></button><strong>WARNING</strong>: Search failed!</div>';
    1472 1532   $(document).ready(function() {
    1473 1533   $('#alertfadeout').fadeIn(2000).delay(4000).fadeOut(2000);
    skipped 8 lines
    1482 1542   var upfile = document.getElementById("lefile");
    1483 1543   var timezone = document.getElementById("utcTime").value;
    1484 1544   var logtype = document.getElementById("logType").value;
     1545 + var addlog = document.getElementById("add_log").checked;
    1485 1546   
    1486 1547   if (timezone == "Time Zone") {
    1487 1548   document.getElementById("status").innerHTML = '<div class="alert alert-danger"><strong>ERROR</strong>: Please set the time zone of the event logs.</div>';
    skipped 8 lines
    1496 1557   }
    1497 1558   formData.append("timezone", timezone);
    1498 1559   formData.append("logtype", logtype);
     1560 + formData.append("addlog", addlog);
    1499 1561   var xmlhttp = new XMLHttpRequest();
    1500 1562   xmlhttp.upload.addEventListener("progress", progressHandler, false);
    1501 1563   xmlhttp.addEventListener("load", completeHandler, false);
    skipped 48 lines
    1550 1612   if (xmlhttp2.readyState == 4) {
    1551 1613   if (xmlhttp2.status == 200) {
    1552 1614   var logdata = xmlhttp2.responseText.split(/\r\n|\r|\n/);
    1553  - var allrecode = logdata[4].split(" ")[5].replace(".", "");
     1615 + for (i = 0; i < logdata.length; i++) {
     1616 + if (logdata[i].indexOf("Last record number") != -1) {
     1617 + var allrecode = logdata[i].split(" ")[5].replace(".", "");
     1618 + break;
     1619 + }
     1620 + }
    1554 1621   var nowdata = logdata[logdata.length - 2];
    1555 1622   if (nowdata.indexOf("Now loading") != -1) {
    1556 1623   var recordnum = nowdata.split(" ")[3];
    skipped 97 lines
  • ■ ■ ■ ■ ■ ■
    templates/index.html
    skipped 3 lines
    4 4  <head>
    5 5   <meta charset="utf-8">
    6 6   <title>LogonTracer</title>
    7  - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
     7 + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    8 8   <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/jquery.qtip.css" integrity="sha384-EG4MkHYaMXjB6f2q1t0Jfs+W6DpGsGZls4D6PYHr9yhXwZf27Z10ReappeV2ZXcU" crossorigin="anonymous">
    9  - <link rel="stylesheet" href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" integrity="sha384-yBEPaZw444dClEfen526Q6x4nwuzGO6PreKpbRVSLFCci3oYGE5DnD1pNsubCxYW" crossorigin="anonymous">
     9 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" integrity="sha384-yakM86Cz9KJ6CeFVbopALOEQGGvyBFdmA4oHMiYuHcd9L59pLkCEFSlr6M9m434E" crossorigin="anonymous">
    10 10   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" integrity="sha384-CmLV3WR+cw/TcN50vJSYAs2EAzhDD77tQvGcmoZ1KEzxtpl2K5xkrpFz9N2H9ClN" crossorigin="anonymous">
    11  - <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.css" integrity="sha384-BxjoNa5Gy6HWpewxZeRKXOU9soDrevzGlc0x2UrFD5yPVuBIz/3YUxvzchy7Q1+k" crossorigin="anonymous">
     11 + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.0.1/css/tempusdominus-bootstrap-4.min.css" integrity="sha384-8wYGNo4TwC9xzqNRdt7OUN789eBPzNQlO/sxIKaJR1gkX0+Ok1kXxhHR4pZU+gP2" crossorigin="anonymous">
     12 + <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.11.2/css/all.css" integrity="sha384-KA6wR/X5RY4zFAHpv/CnoG2UW1uogYfdnP67Uv7eULvTveboZJg0qUpmJZb5VqzN" crossorigin="anonymous">
    12 13   <link rel="stylesheet" href="static/css/style.css">
     14 + <link rel="stylesheet" href="static/css/dark-mode.css">
    13 15   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
    14 16   <script src="https://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.1/jquery.qtip.js" integrity="sha384-6pAYkjo39N26cI9QEzy7zTD9xr9XzSnaWywG02LeFyoJnBEyYvWvqomLU+uGAlaw" crossorigin="anonymous"></script>
    15  - <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js" integrity="sha384-cd07Jx5KAMCf7qM+DveFKIzHXeCSYUrai+VWCPIXbYL7JraHMFL/IXaCKbLtsxyB" crossorigin="anonymous"></script>
    16  - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
     17 + <script src="https://cdn.jsdelivr.net/gh/gitbrent/[email protected]/js/bootstrap4-toggle.min.js" integrity="sha384-Q9RsZ4GMzjlu4FFkJw4No9Hvvm958HqHmXI9nqo5Np2dA/uOVBvKVxAvlBQrDhk4" crossorigin="anonymous"></script>
     18 + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.15.0/umd/popper.min.js" integrity="sha384-L2pyEeut/H3mtgCBaUNw7KWzp5n9+4pDQiExs933/5QfaTh8YStYFFkOzSoXjlTb" crossorigin="anonymous"></script>
     19 + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    17 20   <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cytoscape.min.js" integrity="sha384-vTbGUxFr0qyAqYeS+nIqQ6Row8uIp1PgvAWiA4GuEtdkD8scsArkL9QgZHWaHuv5" crossorigin="anonymous"></script>
    18 21   <script src="https://cdn.jsdelivr.net/npm/[email protected]/cytoscape-qtip.min.js" integrity="sha384-0S5MX36ySZW8tkZEooDZdxYdGvtwdVxA/1bl0U0zoqsrHBJbv4LxKxc8Hp8LpxlE" crossorigin="anonymous"></script>
    19 22   <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js" integrity="sha384-sIzeKWIAHvT0Vm8QbfLCqZwBG0WMCkWVAOYd/330YSNeeQ1Y57N3T9lQz5Ry/EHH" crossorigin="anonymous"></script>
    20  - <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js" integrity="sha384-eRwUWQDbnWMRrNpCKFsqmkfL7PMM8a4uUw5AvjTuLRoYFfozRz7g9BS696LvdNrE" crossorigin="anonymous"></script>
     23 + <script src="https://cdnjs.cloudflare.com/ajax/libs/tempusdominus-bootstrap-4/5.0.1/js/tempusdominus-bootstrap-4.min.js" integrity="sha384-hzexvprs0k2Q/IHSJOfegsjdg6kTcTTVxQdgHiB4+I/915hcvse9v42LLVVM5K4e" crossorigin="anonymous"></script>
     24 + <script src="https://cdn.jsdelivr.net/npm/[email protected]/desvg.min.js" integrity="sha384-J1rV4940pYhBtFhx6SqDEMJP35rgSVSVx+44+TPf67jyXL8dsBtYMZeBCNLf/2zk" crossorigin="anonymous"></script>
    21 25   <!-- Neo4j JavaScript Driver -->
    22  - <script src="https://cdn.jsdelivr.net/npm/[email protected].3/lib/browser/neo4j-web.min.js" integrity="sha384-XVrDQNh79isRQKoUzX8pCHmnP2HmtLQJTDMfzI5/4gxbjqz7mHlGjTKyQxVGKR7k" crossorigin="anonymous"></script>
     26 + <script src="https://cdn.jsdelivr.net/npm/[email protected].6/lib/browser/neo4j-web.min.js" integrity="sha384-VaW5fiy/7vrN4S7dr0pOBxTer8CLIPL86Br0V7QmvA0AhwjWAL+emVM8Hp1WUFP4" crossorigin="anonymous"></script>
    23 27   <script src="static/js/script.js"></script>
    24 28  </head>
    25 29   
    26 30  <body>
    27  - <nav class="navbar navbar-default">
    28  - <div class="container-fluid">
    29  - <a class="navbar-brand" href="#"><img src="static/images/logo_top.svg" alt="top" width="190" style="margin-top: -5px"></a>
     31 + <nav class="navbar navbar-expand-lg navbar-light bg-light p-1 shadow">
     32 + <a class="navbar-brand" href="#"><img class="my_svg" src="static/images/logo_top.svg" alt="top" width="190"></a>
    30 33   <div class="collapse navbar-collapse">
    31  - <form class="navbar-form navbar-left" role="search">
    32  - <div class="form-group">
    33  - <label class="sr-only" for="InputSelect">select</label>
    34  - <select class="form-control" id="InputSelect">
    35  - <option>Username</option>
    36  - <option>Hostname</option>
    37  - <option>IPAddress</option>
    38  - </select>
    39  - <input class="form-control" type="text" value="administrator" id="query-input" size="10">
    40  - <div id="itemForm"></div>
     34 + <form class="navbar-nav" role="search">
     35 + <div class="form-group mt-3" id="itemForm">
     36 + <div class="form-inline">
     37 + <label class="sr-only" for="InputSelect">select</label>
     38 + <select class="custom-select" id="InputSelect">
     39 + <option>Username</option>
     40 + <option>Hostname</option>
     41 + <option>IPAddress</option>
     42 + </select>
     43 + <input class="form-control my-2 my-lg-0 ml-1" type="text" value="administrator" id="query-input">
     44 + </div>
    41 45   </div>
    42  - <input type="button" class="btn btn-default" value="+" onclick="ItemField.add();" />
    43  - <input type="button" class="btn btn-default" value="-" onclick="ItemField.del();" />
    44  - <input type="button" class="btn btn-default" data-toggle="modal" value="Filter" data-target="#Filters">
    45  - <button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" data-original-title="Username/IPAddress/Hostname search" onclick="createQuery()">search</button>
    46  - <button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" data-original-title="Search for how exploit the administrator account from the account. (only one Username)" onclick="searchPath()">search path</button>
    47  - <div class="btn-group">
    48  - <a href="#" class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">
    49  - Export <span class="caret"></span>
    50  - </a>
    51  - <ul class="dropdown-menu" role="menu">
    52  - <li role="presentation"><a onclick="exportCSV()">CSV</a></li>
    53  - <li role="presentation"><a download="image.json" id="export-json" onclick="exportJSON()">JSON</a></li>
    54  - <li role="presentation"><a download="image.png" id="export-png" onclick="exportPNG()">PNG</a></li>
    55  - <li role="presentation"><a download="image.jpeg" id="export-jpeg" onclick="exportJPEG()">JPEG</a></li>
    56  - </ul>
     46 + <input type="button" class="btn btn-primary ml-1 mt-3 h-25" value="+" onclick="ItemField.add();" />
     47 + <input type="button" class="btn btn-primary ml-1 mt-3 h-25" value="-" onclick="ItemField.del();" />
     48 + <input type="button" class="btn btn-secondary ml-1 mt-3 h-25" data-toggle="modal" value="Filter" data-target="#Filters">
     49 + <button type="button" class="btn btn-outline-primary ml-1 mt-3 h-25" data-toggle="tooltip" data-placement="bottom" data-original-title="Username/IPAddress/Hostname search" onclick="createQuery()">search</button>
     50 + <button type="button" class="btn btn-outline-primary ml-1 mt-3 h-25" data-toggle="tooltip" data-placement="bottom" data-original-title="Search for how exploit the administrator account from the account. (only one Username)" onclick="searchPath()">search path</button>
     51 + <div class="btn-group ml-1 mt-3 h-25">
     52 + <button class="btn btn-outline-secondary" type="button">Export</button>
     53 + <button class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" type="button" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
     54 + <span class="sr-only"></span>
     55 + </button>
     56 + <div class="dropdown-menu" aria-labelledby="navbarDropdown">
     57 + <a class="dropdown-item" onclick="exportCSV()" href="#">CSV</a>
     58 + <a class="dropdown-item" download="image.json" id="export-json" onclick="exportJSON()" href="#">JSON</a>
     59 + <a class="dropdown-item" download="image.png" id="export-png" onclick="exportPNG()" href="#">PNG</a>
     60 + <a class="dropdown-item" download="image.jpeg" id="export-jpeg" onclick="exportJPEG()" href="#">JPEG</a>
     61 + </div>
     62 + </div>
     63 + <div class="custom-control custom-switch ml-4 mt-4">
     64 + <input type="checkbox" class="custom-control-input" id="darkSwitch">
     65 + <label class="custom-control-label" for="darkSwitch">Dark Mode</label>
    57 66   </div>
     67 + 
     68 + <script src="static/js/dark-mode-switch.min.js"></script>
    58 69   </form>
    59 70   </div>
    60  - </div>
    61 71   </nav>
    62 72   
    63 73   <div class="container-fluid">
    64 74   <div class="row">
    65 75   <div class="col-sm-2 col-md-2 sidebar">
    66  - <div class="list-group">
    67  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing all users and hosts." onclick="createAllQuery()">All Users</button>
    68  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing users with system privileges." onclick="createSystemQuery()">SYSTEM Privileges</button>
    69  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing remote logon users and hosts using NTLM authentication. If not using NTLM authentication, it may be pass-the-hash." onclick="createNTLMQuery()">NTLM Remote Logon</button>
    70  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing RDP logon users and hosts (Logon type: 10)." onclick="createRDPQuery()">RDP Logon</button>
    71  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing logon users and hosts from remote network (Logon type: 3)." onclick="createNetQuery()">Network Logon</button>
    72  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing batch server logon (Logon type: 4)." onclick="createBatchQuery()">Batch Logon</button>
    73  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing Services Control Manager logon (Logon type: 5)." onclick="createServiceQuery()">Service Logon</button>
    74  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing the error log that the ms14-068 exploit failed." onclick="create14068Query()">MS14-068 Exploit Failure</button>
    75  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing failed logon." onclick="createFailQuery()">Logon Failure</button>
    76  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing DCSync and DCShadow log." onclick="dcsQuery()">Detect DCSync/DCShadow</button>
    77  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing deleted or added users." onclick="adddelUsersQuery()">Add/Delete Users</button>
    78  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing all domain names. If an attacker is intrude into a network, there may be a malicious domain name." onclick="createDomainQuery()">Domain Check</button>
    79  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing changed audit policy." onclick="policyQuery()">Audit Policy Change</button>
    80  - <button type="button" class="list-group-item" data-toggle="modal" data-target="#Diff">Diff Graph</button>
    81  - <button type="button" class="list-group-item" data-toggle="tooltip" data-placement="bottom" data-original-title="Displays hourly event log counts in time series." onclick="window.open('timeline')">Create Timeline</button>
     76 + <div class="list-group mt-3">
     77 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing all users and hosts." onclick="createAllQuery()">All Users</button>
     78 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing users with system privileges." onclick="createSystemQuery()">SYSTEM Privileges</button>
     79 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing remote logon users and hosts using NTLM authentication. If not using NTLM authentication, it may be pass-the-hash." onclick="createNTLMQuery()">NTLM Remote Logon</button>
     80 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing RDP logon users and hosts (Logon type: 10)." onclick="createRDPQuery()">RDP Logon</button>
     81 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing logon users and hosts from remote network (Logon type: 3)." onclick="createNetQuery()">Network Logon</button>
     82 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing batch server logon (Logon type: 4)." onclick="createBatchQuery()">Batch Logon</button>
     83 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing Services Control Manager logon (Logon type: 5)." onclick="createServiceQuery()">Service Logon</button>
     84 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing the error log that the ms14-068 exploit failed." onclick="create14068Query()">MS14-068 Exploit Failure</button>
     85 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing failed logon." onclick="createFailQuery()">Logon Failure</button>
     86 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing DCSync and DCShadow log." onclick="dcsQuery()">Detect DCSync/DCShadow</button>
     87 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing deleted or added users." onclick="adddelUsersQuery()">Add/Delete Users</button>
     88 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing all domain names. If an attacker is intrude into a network, there may be a malicious domain name." onclick="createDomainQuery()">Domain Check</button>
     89 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Visualizing changed audit policy." onclick="policyQuery()">Audit Policy Change</button>
     90 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="modal" data-target="#Diff">Diff Graph</button>
     91 + <button type="button" class="list-group-item list-group-item-action list-group-item-light" data-toggle="tooltip" data-placement="bottom" data-original-title="Displays hourly event log counts in time series." onclick="window.open('timeline')">Create Timeline</button>
    82 92   </div>
    83 93   <hr>
    84 94   <a data-toggle="tooltip" data-placement="bottom" data-original-title="Add value to edges of visualization graph.">Add event value</a><br>
    85  - <div class="btn-group" data-toggle="buttons">
    86  - <label class="btn btn-default">
     95 + <div class="btn-group btn-group-toggle" data-toggle="buttons">
     96 + <label class="btn btn-outline-secondary">
    87 97   <input type="checkbox" name="options" id="label-count" autocomplete="off">Count</label>
    88  - <label class="btn btn-default">
     98 + <label class="btn btn-outline-secondary">
    89 99   <input type="checkbox" name="options" id="label-type" autocomplete="off">Type</label>
    90  - <label class="btn btn-default">
     100 + <label class="btn btn-outline-secondary">
    91 101   <input type="checkbox" name="options" id="label-authname" autocomplete="off">Auth</label>
    92 102   </div>
    93 103   <hr>
    94 104   <a data-toggle="tooltip" data-placement="bottom" data-original-title="Select visualization graph mode.">Graph mode</a><br>
    95  - <div class="btn-group" data-toggle="buttons">
    96  - <label class="btn btn-default active">
     105 + <div class="btn-group btn-group-toggle" data-toggle="buttons">
     106 + <label class="btn btn-outline-secondary active">
    97 107   <input type="radio" id="modeGrid" name="graphmode" checked="checked">grid</label>
    98  - <label class="btn btn-default">
     108 + <label class="btn btn-outline-secondary">
    99 109   <input type="radio" id="modeCose" name="graphmode">cose</label>
    100  - <label class="btn btn-default">
     110 + <label class="btn btn-outline-secondary">
    101 111   <input type="radio" id="modeCircle" name="graphmode">circle</label>
    102  - <label class="btn btn-default">
     112 + <label class="btn btn-outline-secondary">
    103 113   <input type="radio" id="modeTree" name="graphmode">tree</label>
    104 114   </div>
    105 115   <hr>
    106 116   <a data-toggle="tooltip" data-placement="bottom" data-original-title="Enable visualization of malicious account ranking.">Rank visualize mode</a><br>
    107  - <input type="checkbox" data-toggle="toggle" data-on="Enabled" data-height="35" data-off="Disabled" id="rankMode">
     117 + <input type="checkbox" data-toggle="toggle" data-on="Enabled" data-onstyle="secondary" data-height="35" data-off="Disabled" data-offstyle="outline-secondary" id="rankMode">
    108 118   <hr>
    109 119   <a data-toggle="tooltip" data-placement="bottom" data-original-title="Import event logs in EVTX or XML format.">Upload</a><br>
    110  - <button class="btn btn-default" data-toggle="modal" data-target="#UploadEVTX">Upload Event Log</button>
     120 + <button class="btn btn-secondary" data-toggle="modal" data-target="#UploadEVTX">Upload Event Log</button>
    111 121   </div>
    112 122   <div class="col-sm-8 col-md-8 main">
    113 123   <div id="error"></div>
    skipped 2 lines
    116 126   <span class="fa fa-refresh fa-spin"></span>
    117 127   </div>
    118 128   </div>
    119  - <div class="col-sm-2 col-md-2">
     129 + <div class="col-sm-2 col-md-2 mt-3">
    120 130   <div class="container" id="rankUser"></div>
    121  - <ul class="pager">
    122  - <li><a onclick="pruserBack()">Back</a></li>
    123  - <li><a onclick="pruserNext()">Next</a></li>
     131 + <ul class="pagination justify-content-center">
     132 + <li><a class="btn page-link rounded-pill" onclick="pruserBack()">Back</a></li>
     133 + <li><a class="btn page-link rounded-pill ml-2" onclick="pruserNext()">Next</a></li>
    124 134   </ul>
    125  - <hr>
    126 135   <div class="container" id="rankHost"></div>
    127  - <ul class="pager">
    128  - <li><a onclick="prhostBack()">Back</a></li>
    129  - <li><a onclick="prhostNext()">Next</a></li>
     136 + <ul class="pagination justify-content-center">
     137 + <li><a class="btn page-link rounded-pill" onclick="prhostBack()">Back</a></li>
     138 + <li><a class="btn page-link rounded-pill ml-2" onclick="prhostNext()">Next</a></li>
    130 139   </ul>
    131 140   </div>
    132 141   </div>
    133 142   </div>
    134 143   <!-- Upload -->
    135 144   <div class="modal fade" id="UploadEVTX" tabindex="-1">
    136  - <div class="modal-dialog modal-lg">
     145 + <div class="modal-dialog modal-xl">
    137 146   <div class="modal-content">
    138 147   <div class="modal-header">
    139  - <button type="button" class="close" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span></button>
    140 148   <h4 class="modal-title">Upload Event Log File</h4>
    141  - <p>Import the event log. Supported file format is EVTX or XML (exported Event Viewer or PowerShell).</p>
     149 + <button type="button" class="close" data-dismiss="modal"><i class="fas fa-times"></i></button>
    142 150   </div>
    143 151   <div class="modal-body">
    144  - <div id="zoneTime"></div>
    145  - <div class="col-xs-2">
    146  - <select class="form-control" id="logType">
     152 + <p>Import the event log. Supported file format is EVTX or XML (exported Event Viewer or PowerShell).</p>
     153 + <div class="form-inline">
     154 + <div class="w-auto" id="zoneTime"></div>
     155 + <div class="w-auto ml-2">
     156 + <select class="custom-select" id="logType">
    147 157   <option>EVTX</option>
    148 158   <option>XML</option>
    149 159   </select>
    150 160   </div>
    151  - <div class="input-group">
     161 + <div class="input-group w-75 ml-2">
    152 162   <input multiple id="lefile" type="file" style="display:none">
    153 163   <input type="text" id="evtx_name" class="form-control" placeholder="select file (multi files) ...">
    154 164   <span class="input-group-btn"><button type="button" class="btn btn-info" onclick="$('input[id=lefile]').click();">Browse</button></span>
    155 165   </div>
     166 + </div>
     167 + <div class="custom-control custom-checkbox mt-3">
     168 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="If you want to add more logs, please enable the checkbox.">
     169 + <input type="checkbox" class="custom-control-input" id="add_log">
     170 + <label class="custom-control-label" for="add_log">Add additional EVTX or XML files</label>
     171 + </label>
     172 + </div>
    156 173   <div id="uploadBar"></div>
    157 174   <div id="status"></div>
    158 175   </div>
    159 176   <div class="modal-footer">
    160 177   <button type="submit" class="btn btn-primary" onclick="file_upload()">Upload</button>
    161  - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    162  - <a href="log" target="_blank"><button type="button" class="btn btn-default">Log</button></a>
     178 + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
     179 + <a href="log" target="_blank"><button type="button" class="btn btn-secondary">Log</button></a>
    163 180   </div>
    164 181   </div>
    165 182   </div>
    166 183   </div>
    167 184   <!-- Filter -->
    168 185   <div class="modal fade" id="Filters" tabindex="-1">
    169  - <div class="modal-dialog">
     186 + <div class="modal-dialog modal-lg">
    170 187   <div class="modal-content">
    171 188   <div class="modal-header">
    172  - <button type="button" class="close" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span></button>
    173 189   <h4 class="modal-title">Event Log Filter</h4>
    174  - <p>Filter event log by date, count and id.</p>
     190 + <button type="button" class="close" data-dismiss="modal"><i class="fas fa-times"></i></button>
    175 191   </div>
    176 192   <div class="modal-body">
     193 + <p>Filter event log by date, count and event id.</p>
    177 194   <div class="container-fluid">
    178 195   <div class="row">
    179  - <h4 class="col-md-2">Date<h4>
    180  - <div class="col-md-10 ml-auto">
    181  - <div class="form-group">
    182  - <div class="input-group fromdate">
    183  - <input type="text" placeholder="From" id="from-date" class="form-control" />
    184  - <span class="input-group-addon">
    185  - <span class="glyphicon glyphicon-calendar"></span>
    186  - </span>
     196 + <h4 class="col-md-3">Date<h4>
     197 + <div class="form-group">
     198 + <div class="input-group fromdate" id="datetimepicker1" data-target-input="nearest">
     199 + <input type="text" placeholder="From" id="from-date" class="form-control datetimepicker-input" data-target="#datetimepicker1"/>
     200 + <div class="input-group-append" data-target="#datetimepicker1" data-toggle="datetimepicker">
     201 + <div class="input-group-text"><i class="far fa-calendar-alt"></i></div>
    187 202   </div>
    188 203   </div>
    189  - <div class="form-group">
    190  - <div class="input-group todate">
    191  - <input type="text" placeholder="To" id="to-date" class="form-control" />
    192  - <span class="input-group-addon">
    193  - <span class="glyphicon glyphicon-calendar"></span>
    194  - </span>
     204 + </div>
     205 + <div class="form-group">
     206 + <div class="input-group todate" id="datetimepicker2" data-target-input="nearest">
     207 + <input type="text" placeholder="To" id="to-date" class="form-control datetimepicker-input" data-target="#datetimepicker2"/>
     208 + <div class="input-group-append" data-target="#datetimepicker2" data-toggle="datetimepicker">
     209 + <div class="input-group-text"><i class="far fa-calendar-alt"></i></div>
    195 210   </div>
    196 211   </div>
    197 212   </div>
    skipped 1 lines
    199 214   <hr>
    200 215   <div class="row">
    201 216   <h4 class="col-md-3">Event ID</h4>
    202  - <div class="col-md-9 ml-auto">
    203  - <div class="checkbox">
    204  - <label data-toggle="tooltip" data-placement="bottom" data-original-title="Successful logon">
    205  - <input type="checkbox" id="id4624" checked="checked"> 4624
    206  - </label>
    207  - <label data-toggle="tooltip" data-placement="bottom" data-original-title="Logon failure">
    208  - <input type="checkbox" id="id4625" checked="checked"> 4625
    209  - </label>
    210  - <label data-toggle="tooltip" data-placement="bottom" data-original-title="Kerberos Authentication (TGT Request)">
    211  - <input type="checkbox" id="id4768" checked="checked"> 4768
    212  - </label>
    213  - <label data-toggle="tooltip" data-placement="bottom" data-original-title="Kerberos Service Ticket (ST Request)">
    214  - <input type="checkbox" id="id4769" checked="checked"> 4769
    215  - </label>
    216  - <label data-toggle="tooltip" data-placement="bottom" data-original-title="NTLM Authentication">
    217  - <input type="checkbox" id="id4776" checked="checked"> 4776
    218  - </label>
    219  - </div>
     217 + <div class="custom-control custom-checkbox custom-control-inline">
     218 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="Successful logon">
     219 + <input type="checkbox" id="id4624" class="custom-control-input" checked="checked">
     220 + <label class="custom-control-label" for="id4624">4624</label>
     221 + </label>
     222 + </div>
     223 + <div class="custom-control custom-checkbox custom-control-inline">
     224 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="Logon failure">
     225 + <input type="checkbox" id="id4625" class="custom-control-input" checked="checked">
     226 + <label class="custom-control-label" for="id4625">4625</label>
     227 + </label>
     228 + </div>
     229 + <div class="custom-control custom-checkbox custom-control-inline">
     230 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="Kerberos Authentication (TGT Request)">
     231 + <input type="checkbox" id="id4768" class="custom-control-input" checked="checked">
     232 + <label class="custom-control-label" for="id4768">4768</label>
     233 + </label>
     234 + </div>
     235 + <div class="custom-control custom-checkbox custom-control-inline">
     236 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="Kerberos Service Ticket (ST Request)">
     237 + <input type="checkbox" id="id4769" class="custom-control-input" checked="checked">
     238 + <label class="custom-control-label" for="id4769">4769</label>
     239 + </label>
     240 + </div>
     241 + <div class="custom-control custom-checkbox custom-control-inline">
     242 + <label data-toggle="tooltip" data-placement="bottom" data-original-title="NTLM Authentication">
     243 + <input type="checkbox" id="id4776" class="custom-control-input" checked="checked">
     244 + <label class="custom-control-label" for="id4776">4776</label>
     245 + </label>
    220 246   </div>
    221 247   </div>
    222 248   <hr>
    223 249   <div class="row">
    224  - <h4 class="col-md-2">Count<h4>
    225  - <div class="col-md-5 ml-auto">
    226  - <div class="form-group">
    227  - <input class="form-control" type="text" value=0 id="count-input" data-toggle="tooltip" data-placement="bottom" data-original-title="Set the lower limit of Event ID to visualize.">
    228  - </div>
     250 + <h4 class="col-md-3">Count<h4>
     251 + <div class="form-group">
     252 + <input class="form-control" type="text" value=0 id="count-input" data-toggle="tooltip" data-placement="bottom" data-original-title="Set the lower limit of Event ID to visualize.">
    229 253   </div>
    230 254   </div>
    231 255   </div>
    232 256   </div>
    233 257   <div class="modal-footer">
    234  - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
     258 + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    235 259   </div>
    236 260   </div>
    237 261   </div>
    skipped 4 lines
    242 266   <div class="modal-dialog">
    243 267   <div class="modal-content">
    244 268   <div class="modal-header">
    245  - <button type="button" class="close" data-dismiss="modal"><span class="glyphicon glyphicon-remove"></span></button>
    246 269   <h4 class="modal-title">Diff Graph</h4>
    247  - <p>Compare two days and view unique events.</p>
     270 + <button type="button" class="close" data-dismiss="modal"><i class="fas fa-times"></i></button>
    248 271   </div>
    249 272   <div class="modal-body">
     273 + <p>Compare two days and view unique events.</p>
    250 274   <div class="container-fluid">
    251 275   <div class="row">
    252 276   <div class="form-group">
    253  - <div class="input-group fromday">
    254  - <input type="text" placeholder="From" id="from-day" class="form-control" />
    255  - <span class="input-group-addon">
    256  - <span class="glyphicon glyphicon-calendar"></span>
    257  - </span>
     277 + <div class="input-group fromday" id="datetimepicker3" data-target-input="nearest">
     278 + <input type="text" placeholder="From" id="from-day" class="form-control datetimepicker-input" data-target="#datetimepicker3"/>
     279 + <div class="input-group-append" data-target="#datetimepicker3" data-toggle="datetimepicker">
     280 + <div class="input-group-text"><i class="far fa-calendar-alt"></i></div>
     281 + </div>
    258 282   </div>
    259 283   </div>
    260 284   <div class="form-group">
    261  - <div class="input-group today">
    262  - <input type="text" placeholder="To" id="to-day" class="form-control" />
    263  - <span class="input-group-addon">
    264  - <span class="glyphicon glyphicon-calendar"></span>
    265  - </span>
     285 + <div class="input-group today" id="datetimepicker4" data-target-input="nearest">
     286 + <input type="text" placeholder="To" id="to-day" class="form-control datetimepicker-input" data-target="#datetimepicker4"/>
     287 + <div class="input-group-append" data-target="#datetimepicker4" data-toggle="datetimepicker">
     288 + <div class="input-group-text"><i class="far fa-calendar-alt"></i></div>
     289 + </div>
    266 290   </div>
    267 291   </div>
    268 292   </div>
    skipped 1 lines
    270 294   </div>
    271 295   <div class="modal-footer">
    272 296   <button type="submit" class="btn btn-primary" data-dismiss="modal" onclick="diffQuery()">Compare</button>
    273  - <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
     297 + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    274 298   </div>
    275 299   </div>
    276 300   </div>
    skipped 9 lines
    286 310   <p>Web page loading slow due to large graph. Do you want to continue searching?</p>
    287 311   </div>
    288 312   <div class="modal-footer">
    289  - <button type="button" class="btn btn-default" onclick="contQuery()" data-dismiss="modal">Yes</button>
     313 + <button type="button" class="btn btn-secondary" onclick="contQuery()" data-dismiss="modal">Yes</button>
    290 314   <button type="button" class="btn btn-primary" data-dismiss="modal">No</button>
    291 315   </div>
    292 316   </div>
    skipped 21 lines
    314 338   var currentNumber = 0;
    315 339   var ItemField = {
    316 340   currentNumber: 0,
    317  - itemTemplate: '<label class="sr-only" for="InputSelect">select</label>\
    318  - <select class="form-control" id="InputSelect_count_">\
     341 + itemTemplate: '<div class="form-inline my-5 my-lg-0"><label class="sr-only" for="InputSelect">select</label>\
     342 + <select class="custom-select" id="InputSelect_count_">\
    319 343   <option>Username</option><option>Hostname</option><option>IPAddress</option></select>\
    320  - <input class="form-control" type="text" id="query-input_count_" size="10">\
     344 + <input class="form-control my-2 my-lg-0 ml-1" type="text" id="query-input_count_">\
    321 345   <label class="sr-only" for="InputSelect">select</label>\
    322  - <select class="form-control" id="InputRule_count_">\
    323  - <option>OR</option><option>AND</option></select>',
     346 + <select class="custom-select ml-1" id="InputRule_count_">\
     347 + <option>OR</option><option>AND</option></select></div>',
    324 348   add: function() {
    325 349   currentNumber++;
    326 350   if (currentNumber <= 10) {
    skipped 15 lines
    342 366   }
    343 367   }
    344 368   
    345  - var downMenu = '<div class="col-xs-2"><select class="form-control" id="utcTime"><option>Time Zone</option>';
     369 + var downMenu = '<div class="col-xs-2"><select class="custom-select" id="utcTime"><option>Time Zone</option>';
    346 370   for (i = +14; i >= -12; i--) {
    347 371   downMenu += '<option>' + i + '</option>';
    348 372   }
    skipped 14 lines
    363 387   $(function () {
    364 388   $('[data-toggle="tooltip"]').tooltip();
    365 389   })
     390 + 
     391 + $(function(){
     392 + deSVG('.my_svg', true);
     393 + });
    366 394   </script>
    367 395  </body>
    368 396   
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    templates/timeline.html
    skipped 3 lines
    4 4  <head>
    5 5   <meta charset="utf-8">
    6 6   <title>LogonTracer</title>
    7  - <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    8  - <link rel="stylesheet" href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" integrity="sha384-yBEPaZw444dClEfen526Q6x4nwuzGO6PreKpbRVSLFCci3oYGE5DnD1pNsubCxYW" crossorigin="anonymous">
     7 + <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
     8 + <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/css/bootstrap4-toggle.min.css" integrity="sha384-yakM86Cz9KJ6CeFVbopALOEQGGvyBFdmA4oHMiYuHcd9L59pLkCEFSlr6M9m434E" crossorigin="anonymous">
    9 9   <link rel="stylesheet" href="static/css/style.css">
     10 + <link rel="stylesheet" href="static/css/dark-mode.css">
    10 11   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
    11 12   <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js" integrity="sha384-0saKbDOWtYAw5aP4czPUm6ByY5JojfQ9Co6wDgkuM7Zn+anp+4Rj92oGK8cbV91S" crossorigin="anonymous"></script>
    12 13   <script src="https://cdnjs.cloudflare.com/ajax/libs/floatthead/2.1.2/jquery.floatThead.min.js" integrity="sha384-ASdxdxzGplF9B/P3mStsNmNS1x+OFhChbFeLziK29WOvaWkGDMspp2xw5+Vha6Ck" crossorigin="anonymous"></script>
    13  - <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js" integrity="sha384-cd07Jx5KAMCf7qM+DveFKIzHXeCSYUrai+VWCPIXbYL7JraHMFL/IXaCKbLtsxyB" crossorigin="anonymous"></script>
    14  - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <!-- Neo4j JavaScript Driver -->
    15  - <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/browser/neo4j-web.min.js" integrity="sha384-XVrDQNh79isRQKoUzX8pCHmnP2HmtLQJTDMfzI5/4gxbjqz7mHlGjTKyQxVGKR7k" crossorigin="anonymous"></script>
     14 + <script src="https://cdn.jsdelivr.net/gh/gitbrent/[email protected]/js/bootstrap4-toggle.min.js" integrity="sha384-Q9RsZ4GMzjlu4FFkJw4No9Hvvm958HqHmXI9nqo5Np2dA/uOVBvKVxAvlBQrDhk4" crossorigin="anonymous"></script>
     15 + <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.15.0/umd/popper.min.js" integrity="sha384-L2pyEeut/H3mtgCBaUNw7KWzp5n9+4pDQiExs933/5QfaTh8YStYFFkOzSoXjlTb" crossorigin="anonymous"></script>
     16 + <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
     17 + <script src="https://cdn.jsdelivr.net/npm/[email protected]/desvg.min.js" integrity="sha384-J1rV4940pYhBtFhx6SqDEMJP35rgSVSVx+44+TPf67jyXL8dsBtYMZeBCNLf/2zk" crossorigin="anonymous"></script>
     18 + <!-- Neo4j JavaScript Driver -->
     19 + <script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/browser/neo4j-web.min.js" integrity="sha384-VaW5fiy/7vrN4S7dr0pOBxTer8CLIPL86Br0V7QmvA0AhwjWAL+emVM8Hp1WUFP4" crossorigin="anonymous"></script>
    16 20   <script src="static/js/script.js"></script>
    17 21  </head>
    18 22   
    19 23  <body>
    20  - <nav class="navbar navbar-default">
    21  - <div class="container-fluid">
    22  - <a class="navbar-brand" href="#"><img src="static/images/logo_timeline.svg" alt="top" width="144" style="margin-top: -5px"></a>
    23  - <div class="collapse navbar-collapse">
    24  - <form class="navbar-form navbar-left" role="search">
    25  - <div class="form-group">
     24 + <nav class="navbar navbar-expand-lg navbar-light bg-light p-1 shadow">
     25 + <a class="navbar-brand" href="#"><img class="my_svg" src="static/images/logo_timeline.svg" alt="top" width="144"></a>
     26 + <div class="collapse navbar-collapse">
     27 + <form class="navbar-nav mr-auto" role="search">
     28 + <div class="form-group mt-3" id="itemForm">
     29 + <div class="form-inline">
    26 30   <label class="sr-only" for="InputSelect">select</label>
    27  - <select class="form-control" id="InputSelect">
     31 + <select class="custom-select" id="InputSelect">
    28 32   <option>Username</option>
    29 33   </select>
    30  - <input class="form-control" type="text" value="administrator" id="query-input" size="10">
    31  - <div id="itemForm"></div>
     34 + <input class="form-control my-2 my-lg-0 ml-1" type="text" value="administrator" id="query-input">
    32 35   </div>
    33  - <input type="button" class="btn btn-default" value="+" onclick="ItemField.add();" />
    34  - <input type="button" class="btn btn-default" value="-" onclick="ItemField.del();" />
    35  - <input checked data-toggle="toggle" data-on="Table" data-off="Graph" data-onstyle="primary" data-offstyle="info" data-height="35" type="checkbox" id="timelineTypes">
    36  - <button type="button" class="btn btn-default" onclick="searchTimeline()">search</button>
    37  - <button type="button" class="btn btn-default" onclick="createAlltimeline()">all</button>
    38  - <div class="btn-group">
    39  - <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">
    40  - Download <span class="caret"></span>
    41  - </button>
    42  - <ul class="dropdown-menu" role="menu">
    43  - <li role="presentation"><a onclick="downloadSummary()">Summary</a></li>
    44  - <li role="presentation"><a onclick="downloadDetail()">Details</a></li>
    45  - </ul>
     36 + </div>
     37 + <input type="button" class="btn btn-primary ml-1 mt-3 h-25" value="+" onclick="ItemField.add();" />
     38 + <input type="button" class="btn btn-primary ml-1 mt-3 h-25 mr-1" value="-" onclick="ItemField.del();" />
     39 + <span class="mt-3">
     40 + <input type="checkbox" data-toggle="toggle" data-on="Table" data-onstyle="outline-info" data-height="38" data-off="Graph" data-offstyle="outline-primary" id="timelineTypes">
     41 + </span>
     42 + <button type="button" class="btn btn-outline-primary ml-1 mt-3 h-25" onclick="searchTimeline()">search</button>
     43 + <button type="button" class="btn btn-outline-primary ml-1 mt-3 h-25" onclick="createAlltimeline()">all</button>
     44 + <div class="btn-group ml-1 mt-3 h-25">
     45 + <button class="btn btn-outline-secondary" type="button">Download</button>
     46 + <button class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" type="button" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
     47 + <span class="sr-only"></span>
     48 + </button>
     49 + <div class="dropdown-menu" aria-labelledby="navbarDropdown">
     50 + <a class="dropdown-item" onclick="downloadSummary()" href="#">Summary</a>
     51 + <a class="dropdown-item" onclick="downloadDetail()" href="#">Details</a>
    46 52   </div>
    47  - </form>
    48  - </div>
     53 + </div>
     54 + <div class="custom-control custom-switch ml-4 mt-4">
     55 + <input type="checkbox" class="custom-control-input" id="darkSwitch">
     56 + <label class="custom-control-label" for="darkSwitch">Dark Mode</label>
     57 + </div>
     58 + 
     59 + <script src="static/js/dark-mode-switch.min.js"></script>
     60 + </form>
    49 61   </div>
    50 62   </nav>
    51 63   
    52 64   <div class="container-fluid">
    53 65   <div class="row">
    54  - <div class="col-sm-12 col-md-12 main">
     66 + <div class="col-sm-12 col-md-12 main mt-3">
    55 67   <div id="error"></div>
    56 68   <div id="cy"></div>
    57 69   <div id="addcanvas"></div>
    skipped 10 lines
    68 80   var currentNumber = 0;
    69 81   var ItemField = {
    70 82   currentNumber: 0,
    71  - itemTemplate: '<label class="sr-only" for="InputSelect">select</label>\
    72  - <select class="form-control" id="InputSelect_count_">\
     83 + itemTemplate: '<div class="form-inline my-5 my-lg-0"><label class="sr-only" for="InputSelect">select</label>\
     84 + <select class="custom-select" id="InputSelect_count_">\
    73 85   <option>Username</option></select>\
    74  - <input class="form-control" type="text" id="query-input_count_" size="10">',
     86 + <input class="form-control my-2 my-lg-0 ml-1"" type="text" id="query-input_count_"></div>',
    75 87   add: function() {
    76 88   currentNumber++;
    77 89   if (currentNumber <= 10) {
    skipped 14 lines
    92 104   currentNumber--;
    93 105   }
    94 106   }
     107 + 
     108 + $(function(){
     109 + deSVG('.my_svg', true);
     110 + });
    95 111   </script>
    96 112  </body>
    97 113   
    skipped 2 lines
Please wait...
Page is in error, reload to recover