Refactors utils.py and tools/*

This commit is contained in:
jvoisin 2016-07-05 01:07:24 +02:00
parent 8e9205b102
commit 2fb6a1c228
15 changed files with 123 additions and 273 deletions

132
utils.py
View file

@ -21,7 +21,7 @@ import logging
import socket
import time
import settings
import struct
try:
import sqlite3
except:
@ -29,26 +29,20 @@ except:
sys.exit(0)
def color(txt, code = 1, modifier = 0):
if txt.startswith('[*]'):
settings.Config.PoisonersLogger.warning(txt)
elif 'Analyze' in txt:
settings.Config.AnalyzeLogger.warning(txt)
# No colors for windows...
if os.name == 'nt':
if os.name == 'nt': # No colors for windows...
return txt
return "\033[%d;3%dm%s\033[0m" % (modifier, code, txt)
def text(txt):
logging.info(txt)
if os.name == 'nt':
return txt
return '\r'+re.sub(r'\[([^]]*)\]', "\033[1;34m[\\1]\033[0m", txt)
return '\r' + re.sub(r'\[([^]]*)\]', "\033[1;34m[\\1]\033[0m", txt)
def IsOnTheSameSubnet(ip, net):
@ -64,52 +58,36 @@ def RespondToThisIP(ClientIp):
if ClientIp.startswith('127.0.0.'):
return False
if settings.Config.AutoIgnore and ClientIp in settings.Config.AutoIgnoreList:
elif settings.Config.AutoIgnore and ClientIp in settings.Config.AutoIgnoreList:
print color('[*]', 3, 1), 'Received request from auto-ignored client %s, not answering.' % ClientIp
return False
if len(settings.Config.RespondTo) and ClientIp not in settings.Config.RespondTo:
elif settings.Config.RespondTo and ClientIp not in settings.Config.RespondTo:
return False
if ClientIp in settings.Config.RespondTo or settings.Config.RespondTo == []:
elif ClientIp in settings.Config.RespondTo or settings.Config.RespondTo == []:
if ClientIp not in settings.Config.DontRespondTo:
return True
return False
def RespondToThisName(Name):
if len(settings.Config.RespondToName) and Name.upper() not in settings.Config.RespondToName:
if settings.Config.RespondToName and Name.upper() not in settings.Config.RespondToName:
return False
if Name.upper() in settings.Config.RespondToName or settings.Config.RespondToName == []:
elif Name.upper() in settings.Config.RespondToName or settings.Config.RespondToName == []:
if Name.upper() not in settings.Config.DontRespondToName:
return True
return False
def RespondToThisHost(ClientIp, Name):
return RespondToThisIP(ClientIp) and RespondToThisName(Name)
def IsOsX():
return True if settings.Config.Os_version == "darwin" else False
def OsInterfaceIsSupported():
if settings.Config.Interface != "Not set":
return False if IsOsX() else True
else:
return False
return not IsOsX()
return False
def IsOsX():
Os_version = sys.platform
if Os_version == "darwin":
return True
else:
return False
return sys.platform == "darwin"
def FindLocalIP(Iface, OURIP):
if Iface == 'ALL':
return '0.0.0.0'
@ -123,40 +101,29 @@ def FindLocalIP(Iface, OURIP):
ret = s.getsockname()[0]
s.close()
return ret
else:
return OURIP
return OURIP
except socket.error:
print color("[!] Error: %s: Interface not found" % Iface, 1)
sys.exit(-1)
# Function used to write captured hashs to a file.
def WriteData(outfile, data, user):
logging.info("[*] Captured Hash: %s" % data)
if not os.path.isfile(outfile):
with open(outfile,"w") as outf:
outf.write(data)
outf.write("\n")
outf.close()
outf.write(data + '\n')
return
with open(outfile,"r") as filestr:
if re.search(user.encode('hex'), filestr.read().encode('hex')):
return False
elif re.search(re.escape("$"), user):
return False
with open(outfile,"a") as outf2:
outf2.write(data + '\n')
else:
with open(outfile,"r") as filestr:
if re.search(user.encode('hex'), filestr.read().encode('hex')):
filestr.close()
return False
if re.search(re.escape("$"), user):
filestr.close()
return False
with open(outfile,"a") as outf2:
outf2.write(data)
outf2.write("\n")
outf2.close()
def SaveToDb(result):
# Creating the DB if it doesn't exist
if not os.path.exists(settings.Config.DatabaseFile):
cursor = sqlite3.connect(settings.Config.DatabaseFile)
@ -180,32 +147,23 @@ def SaveToDb(result):
logfile = os.path.join(settings.Config.ResponderPATH, 'logs', fname)
cursor = sqlite3.connect(settings.Config.DatabaseFile)
# We add a text factory to support different charsets
cursor.text_factory = sqlite3.Binary
cursor.text_factory = sqlite3.Binary # We add a text factory to support different charsets
res = cursor.execute("SELECT COUNT(*) AS count FROM responder WHERE module=? AND type=? AND LOWER(user)=LOWER(?)", (result['module'], result['type'], result['user']))
(count,) = res.fetchone()
if count == 0:
# If we obtained cleartext credentials, write them to file
# Otherwise, write JtR-style hash string to file
if not count:
with open(logfile,"a") as outf:
if len(result['cleartext']):
outf.write('%s:%s' % (result['user'], result['cleartext']))
else:
outf.write(result['fullhash'])
outf.write("\n")
outf.close()
if len(result['cleartext']): # If we obtained cleartext credentials, write them to file
outf.write('%s:%s\n' % (result['user'], result['cleartext']))
else: # Otherwise, write JtR-style hash string to file
outf.write(result['fullhash'] + '\n')
# Update database
cursor.execute("INSERT INTO responder VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", (timestamp, result['module'], result['type'], result['client'], result['hostname'], result['user'], result['cleartext'], result['hash'], result['fullhash']))
cursor.commit()
cursor.close()
# Print output
if count == 0 or settings.Config.Verbose:
if not count or settings.Config.Verbose: # Print output
if len(result['client']):
print text("[%s] %s Client : %s" % (result['module'], result['type'], color(result['client'], 3)))
if len(result['hostname']):
@ -224,30 +182,22 @@ def SaveToDb(result):
# Appending auto-ignore list if required
# Except if this is a machine account's hash
if settings.Config.AutoIgnore and not result['user'].endswith('$'):
settings.Config.AutoIgnoreList.append(result['client'])
print color('[*] Adding client %s to auto-ignore list' % result['client'], 4, 1)
else:
print color('[*]', 3, 1), 'Skipping previously captured hash for %s' % result['user']
def Parse_IPV6_Addr(data):
if data[len(data)-4:len(data)][1] =="\x1c":
return False
elif data[len(data)-4:len(data)] == "\x00\x01\x00\x01":
return True
elif data[len(data)-4:len(data)] == "\x00\xff\x00\x01":
return True
return False
else:
return False
def Decode_Name(nbname):
#From http://code.google.com/p/dpkt/ with author's permission.
def Decode_Name(nbname): #From http://code.google.com/p/dpkt/ with author's permission.
try:
from string import printable
@ -259,12 +209,12 @@ def Decode_Name(nbname):
l.append(chr(((ord(nbname[i]) - 0x41) << 4) | ((ord(nbname[i+1]) - 0x41) & 0xf)))
return filter(lambda x: x in printable, ''.join(l).split('\x00', 1)[0].replace(' ', ''))
except:
return "Illegal NetBIOS name"
def NBT_NS_Role(data):
Role = {
return {
"\x41\x41\x00":"Workstation/Redirector",
"\x42\x4c\x00":"Domain Master Browser",
"\x42\x4d\x00":"Domain Controller",
@ -272,12 +222,10 @@ def NBT_NS_Role(data):
"\x42\x4f\x00":"Browser Election",
"\x43\x41\x00":"File Server",
"\x41\x42\x00":"Browser",
}
}.get(data, 'Service not known')
return Role[data] if data in Role else "Service not known"
def banner():
banner = "\n".join([
' __',
' .----.-----.-----.-----.-----.-----.--| |.-----.----.',
@ -293,6 +241,7 @@ def banner():
print " To kill this script hit CRTL-C"
print ""
def StartupMessage():
enabled = color('[ON]', 2, 1)
disabled = color('[OFF]', 1, 1)
@ -342,21 +291,16 @@ def StartupMessage():
if settings.Config.Upstream_Proxy:
print ' %-27s' % "Upstream Proxy" + color('[%s]' % settings.Config.Upstream_Proxy, 5, 1)
if len(settings.Config.RespondTo):
print ' %-27s' % "Respond To" + color(str(settings.Config.RespondTo), 5, 1)
if len(settings.Config.RespondToName):
print ' %-27s' % "Respond To Names" + color(str(settings.Config.RespondToName), 5, 1)
if len(settings.Config.DontRespondTo):
print ' %-27s' % "Don't Respond To" + color(str(settings.Config.DontRespondTo), 5, 1)
if len(settings.Config.DontRespondToName):
print ' %-27s' % "Don't Respond To Names" + color(str(settings.Config.DontRespondToName), 5, 1)
print "\n\n"
print ""
print ""
# Useful for debugging
def hexdump(src, l=0x16):
@ -393,8 +337,4 @@ def hexdump(src, l=0x16):
res.append(('%08X: %-'+str(l*(2+1)+1)+'s |%s|') % (i, hexa, text))
return '\n'.join(res)
def longueur(payload):
length = struct.pack(">i", len(''.join(payload)))
return length
return '\n'.join(res)