forked from sans-blue-team/DeepBlueCLI
-
Notifications
You must be signed in to change notification settings - Fork 0
/
DeepBlue.py
132 lines (121 loc) · 4.71 KB
/
DeepBlue.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python
# DeepBlue.py Alpha 0.12 (post-DerbyCon release)
# Eric Conrad
# Twitter: @eric_conrad
# http://ericconrad.com
# deepblue at backshore dot net
# Currently alpha level functionality, supports CLI parsing only
# More features to come
# Requires libevtx: https://github.com/libyal/libevtx
import sys
import re
import csv
import base64
import os.path
import string
from subprocess import Popen, PIPE
def filter(str):
# Used to convert base64 decoded data (unicode) to ASCII
return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])
def CheckRegex(regexes,command):
string=""
for regex in regexes:
if (regex[0] == "0"):
if re.search(regex[1],command,re.IGNORECASE):
string+=" - "+regex[2]+"\n"
return(string)
def CheckObfu(cli,minpercent,minlength):
string=""
noalphastring=re.sub("[A-Za-z0-9]","",cli)
length1=float(len(cli))
if (length1 > minlength):
length2=float(len(noalphastring))
if ((length1/150) < minpercent):
minpercent=length1/150 # Shorter strings get lower minpercent, based on the string length
percent =((length1-length2)/length1)
if (percent < minpercent):
percent=(round(percent,2))*100
string += " - Potential command obfuscation: "+str(int(percent))+"% alpha characters"
return(string)
def CheckCommand(time, log, eventid, cli):
minpercent=.65
minlength=25 # Minimum CLI length to check for obfuscation
string=""
decoded=""
noalphastring=""
string=CheckRegex(regexes,cli)
if re.search("\-enc.*[A-Za-z0-9/+=]{100}",cli,re.IGNORECASE):
b64=re.sub("^.* \-Enc(odedCommand)? ","",cli,re.IGNORECASE)
decoded=base64.b64decode(b64)
decoded=str(filter(decoded)) # Convert base64 to ASCII
string+=CheckRegex(regexes,decoded)
string += CheckObfu(cli,minpercent,minlength)
if(string):
print "Date: %s\nLog: %s\nEventID: %s" % (time,log,eventid)
print "Results:\n%s\n" % (string.rstrip())
print "Command: %s\n" % (cli)
if(decoded):
print "Decoded: %s" % (decoded)
if(string):
print "\n"
filename=""
regexfile="regexes.txt"
regexes=[]
if len(sys.argv)==2:
if os.path.isfile(sys.argv[1]):
filename=sys.argv[1]
if os.path.isfile(regexfile):
with open(regexfile) as csvfile:
reader = csv.reader(csvfile, delimiter=',')
for row in reader:
if not row[0].startswith('#'):
regexes.append(row)
else:
print "Error: cannot open "+regexfile+"\n"
else:
print "Error: no such file: %s\n" % (sys.argv)
else:
print "Error: filename required as an argument\n"
if (filename and regexes):
process=""
try:
process = Popen(['evtxexport', filename], stdout=PIPE, stderr=PIPE)
except:
print 'Can\'t find libevtx. Check the path and verify it is installed. See: https://github.com/libyal/libevtx'
if (process):
time=""
log=""
eventid=""
cli=""
path=""
for line in iter(process.stdout.readline,''):
if re.search("^Written time",line):
#Written time : Aug 30, 2017 19:16:26.133985000 UTC
time = re.sub("^.*: ","",line)
time = time[:21]
elif re.search("^Source name",line):
log = re.sub("^.*: ","",line).rstrip()
elif re.search("^Event identifier",line):
# Looks like this, grab the number between the parentheses:
#Event identifier : 0x00001008 (4104)
#Event identifier : 0x00000001 (1)
eventid = re.sub("^.*\(","",line.rstrip())
eventid = re.sub("\).*$","",eventid)
elif re.search("^String: 3",line):
#Source name : Microsoft-Windows-PowerShell
if log=="Microsoft-Windows-PowerShell":
cli = line[14:].rstrip()
elif re.search("^String: 5",line):
if log=="Microsoft-Windows-PowerShell":
path = line[14:].rstrip()
elif log=="Microsoft-Windows-Sysmon":
cli = line[14:].rstrip()
elif re.search("^String: 9",line):
if log=="Microsoft-Windows-Security-Auditing":
cli = line[14:].rstrip()
elif re.search("^$",line):
# 4688: CLI via System log
# 4104: PowerShell CLI if path is blank (non-blank path == PowerShell script)
# 1: Sysmon CLI
if ((eventid=="4688")or(eventid=="1")or((eventid=="4104")and(path==""))):
CheckCommand(time,log,eventid,cli)