mirror of
https://github.com/lgandx/Responder.git
synced 2025-07-07 05:21:22 -07:00
Added DB for RunFinger results & Report
This commit is contained in:
parent
51411e6b20
commit
f90b76fed2
2 changed files with 78 additions and 15 deletions
18
Report.py
18
Report.py
|
@ -31,6 +31,10 @@ def DbConnect():
|
||||||
cursor = sqlite3.connect("./Responder.db")
|
cursor = sqlite3.connect("./Responder.db")
|
||||||
return cursor
|
return cursor
|
||||||
|
|
||||||
|
def FingerDbConnect():
|
||||||
|
cursor = sqlite3.connect("./tools/RunFinger.db")
|
||||||
|
return cursor
|
||||||
|
|
||||||
def GetResponderData(cursor):
|
def GetResponderData(cursor):
|
||||||
res = cursor.execute("SELECT * FROM Responder")
|
res = cursor.execute("SELECT * FROM Responder")
|
||||||
for row in res.fetchall():
|
for row in res.fetchall():
|
||||||
|
@ -66,7 +70,12 @@ def GetUniqueDHCP(cursor):
|
||||||
res = cursor.execute("SELECT * FROM DHCP WHERE MAC in (SELECT DISTINCT UPPER(MAC) FROM DHCP)")
|
res = cursor.execute("SELECT * FROM DHCP WHERE MAC in (SELECT DISTINCT UPPER(MAC) FROM DHCP)")
|
||||||
for row in res.fetchall():
|
for row in res.fetchall():
|
||||||
print('MAC: {0}, IP: {1}, RequestedIP: {2}'.format(row[1], row[2], row[3]))
|
print('MAC: {0}, IP: {1}, RequestedIP: {2}'.format(row[1], row[2], row[3]))
|
||||||
|
|
||||||
|
def GetRunFinger(cursor):
|
||||||
|
res = cursor.execute("SELECT * FROM RunFinger WHERE Host in (SELECT DISTINCT Host FROM RunFinger)")
|
||||||
|
for row in res.fetchall():
|
||||||
|
print(("{},['{}', Os:'{}', Build:'{}', Domain:'{}', Bootime:'{}', Signing:'{}', Null Session: '{}', RDP:'{}']".format(row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9])))
|
||||||
|
|
||||||
def GetStatisticUniqueLookups(cursor):
|
def GetStatisticUniqueLookups(cursor):
|
||||||
res = cursor.execute("SELECT COUNT(*) FROM Poisoned WHERE ForName in (SELECT DISTINCT UPPER(ForName) FROM Poisoned)")
|
res = cursor.execute("SELECT COUNT(*) FROM Poisoned WHERE ForName in (SELECT DISTINCT UPPER(ForName) FROM Poisoned)")
|
||||||
for row in res.fetchall():
|
for row in res.fetchall():
|
||||||
|
@ -98,5 +107,8 @@ GetResponderUsernames(cursor)
|
||||||
print(color("\n[+] Username details:", code = 2, modifier = 1))
|
print(color("\n[+] Username details:", code = 2, modifier = 1))
|
||||||
GetResponderUsernamesWithDetails(cursor)
|
GetResponderUsernamesWithDetails(cursor)
|
||||||
GetResponderUsernamesStatistic(cursor)
|
GetResponderUsernamesStatistic(cursor)
|
||||||
#print color("\n[+] Captured hashes:", code = 2, modifier = 1)
|
print color("\n[+] RunFinger Scanned Hosts:", code = 2, modifier = 1)
|
||||||
#GetResponderCompleteHash(cursor)
|
cursor.close()
|
||||||
|
cursor = FingerDbConnect()
|
||||||
|
GetRunFinger(cursor)
|
||||||
|
print('\n')
|
||||||
|
|
|
@ -17,11 +17,15 @@
|
||||||
import re,sys,struct
|
import re,sys,struct
|
||||||
import datetime
|
import datetime
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
from socket import *
|
import os
|
||||||
from odict import OrderedDict
|
|
||||||
import errno
|
import errno
|
||||||
import optparse
|
import optparse
|
||||||
|
import sqlite3
|
||||||
from RunFingerPackets import *
|
from RunFingerPackets import *
|
||||||
|
from odict import OrderedDict
|
||||||
|
from socket import *
|
||||||
|
from odict import OrderedDict
|
||||||
|
|
||||||
__version__ = "1.7"
|
__version__ = "1.7"
|
||||||
|
|
||||||
parser = optparse.OptionParser(usage='python %prog -i 10.10.10.224\nor:\npython %prog -i 10.10.10.0/24', version=__version__, prog=sys.argv[0])
|
parser = optparse.OptionParser(usage='python %prog -i 10.10.10.224\nor:\npython %prog -i 10.10.10.0/24', version=__version__, prog=sys.argv[0])
|
||||||
|
@ -42,6 +46,7 @@ Host = options.TARGET
|
||||||
Filename = options.Filename
|
Filename = options.Filename
|
||||||
SMB1 = "Enabled"
|
SMB1 = "Enabled"
|
||||||
SMB2signing = "False"
|
SMB2signing = "False"
|
||||||
|
DB = os.path.abspath(os.path.join(os.path.dirname(__file__)))+"/RunFinger.db"
|
||||||
|
|
||||||
class Packet():
|
class Packet():
|
||||||
fields = OrderedDict([
|
fields = OrderedDict([
|
||||||
|
@ -62,6 +67,13 @@ if (sys.version_info > (3, 0)):
|
||||||
else:
|
else:
|
||||||
PY2OR3 = "PY2"
|
PY2OR3 = "PY2"
|
||||||
|
|
||||||
|
|
||||||
|
if not os.path.exists(DB):
|
||||||
|
cursor = sqlite3.connect(DB)
|
||||||
|
cursor.execute('CREATE TABLE RunFinger (timestamp TEXT, Protocol TEXT, Host TEXT, WindowsVersion TEXT, OsVer TEXT, DomainJoined TEXT, Bootime TEXT, Signing TEXT, NullSess TEXT, IsRDPOn TEXT)')
|
||||||
|
cursor.commit()
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
def StructWithLenPython2or3(endian,data):
|
def StructWithLenPython2or3(endian,data):
|
||||||
#Python2...
|
#Python2...
|
||||||
if PY2OR3 == "PY2":
|
if PY2OR3 == "PY2":
|
||||||
|
@ -117,7 +129,23 @@ def WorkstationFingerPrint(data):
|
||||||
def GetOsBuildNumber(data):
|
def GetOsBuildNumber(data):
|
||||||
ProductBuild = struct.unpack("<h",data)[0]
|
ProductBuild = struct.unpack("<h",data)[0]
|
||||||
return ProductBuild
|
return ProductBuild
|
||||||
|
|
||||||
|
def SaveRunFingerToDb(result):
|
||||||
|
for k in [ 'Protocol', 'Host', 'WindowsVersion', 'OsVer', 'DomainJoined', 'Bootime', 'Signing','NullSess', 'IsRPDOn']:
|
||||||
|
if not k in result:
|
||||||
|
result[k] = ''
|
||||||
|
|
||||||
|
cursor = sqlite3.connect(DB)
|
||||||
|
cursor.text_factory = sqlite3.Binary
|
||||||
|
res = cursor.execute("SELECT COUNT(*) AS count FROM RunFinger WHERE Protocol=? AND Host=? AND WindowsVersion=? AND OsVer=? AND DomainJoined=? AND Bootime=? AND Signing=? AND NullSess=? AND IsRDPOn=?", (result['Protocol'], result['Host'], result['WindowsVersion'], result['OsVer'], result['DomainJoined'], result['Bootime'], result['Signing'], result['NullSess'], result['IsRDPOn']))
|
||||||
|
(count,) = res.fetchone()
|
||||||
|
|
||||||
|
if not count:
|
||||||
|
cursor.execute("INSERT INTO RunFinger VALUES(datetime('now'), ?, ?, ?, ?, ?, ?, ?, ?, ?)", (result['Protocol'], result['Host'], result['WindowsVersion'], result['OsVer'], result['DomainJoined'], result['Bootime'], result['Signing'], result['NullSess'], result['IsRDPOn']))
|
||||||
|
cursor.commit()
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
def ParseSMBNTLM2Exchange(data, host, bootime, signing): #Parse SMB NTLMSSP Response
|
def ParseSMBNTLM2Exchange(data, host, bootime, signing): #Parse SMB NTLMSSP Response
|
||||||
data = data.encode('latin-1')
|
data = data.encode('latin-1')
|
||||||
SSPIStart = data.find(b'NTLMSSP')
|
SSPIStart = data.find(b'NTLMSSP')
|
||||||
|
@ -132,7 +160,19 @@ def ParseSMBNTLM2Exchange(data, host, bootime, signing): #Parse SMB NTLMSSP Res
|
||||||
WindowsVers = WorkstationFingerPrint(data[SSPIStart+48:SSPIStart+50])
|
WindowsVers = WorkstationFingerPrint(data[SSPIStart+48:SSPIStart+50])
|
||||||
WindowsBuildVers = GetOsBuildNumber(data[SSPIStart+50:SSPIStart+52])
|
WindowsBuildVers = GetOsBuildNumber(data[SSPIStart+50:SSPIStart+52])
|
||||||
DomainGrab((host, 445))
|
DomainGrab((host, 445))
|
||||||
print(("[SMB2]:['{}', Os:'{}', Build:'{}', Domain:'{}', Bootime: '{}', Signing:'{}', RDP:'{}', SMB1:'{}']".format(host, WindowsVers, str(WindowsBuildVers), Domain, Bootime, signing, IsRDPOn((host,3389)),SMB1)))
|
RDP = IsRDPOn((host,3389))
|
||||||
|
print(("[SMB2]:['{}', Os:'{}', Build:'{}', Domain:'{}', Bootime: '{}', Signing:'{}', RDP:'{}', SMB1:'{}']".format(host, WindowsVers, str(WindowsBuildVers), Domain, Bootime, signing, RDP,SMB1)))
|
||||||
|
SaveRunFingerToDb({
|
||||||
|
'Protocol': '[SMB2]',
|
||||||
|
'Host': host,
|
||||||
|
'WindowsVersion': WindowsVers,
|
||||||
|
'OsVer': str(WindowsBuildVers),
|
||||||
|
'DomainJoined': Domain,
|
||||||
|
'Bootime': Bootime,
|
||||||
|
'Signing': signing,
|
||||||
|
'NullSess': 'N/A',
|
||||||
|
'IsRDPOn':RDP,
|
||||||
|
})
|
||||||
|
|
||||||
def GetBootTime(data):
|
def GetBootTime(data):
|
||||||
data = data.encode('latin-1')
|
data = data.encode('latin-1')
|
||||||
|
@ -159,9 +199,9 @@ def IsDCVuln(t, host):
|
||||||
|
|
||||||
def IsSigningEnabled(data):
|
def IsSigningEnabled(data):
|
||||||
if data[39] == "\x0f":
|
if data[39] == "\x0f":
|
||||||
return True
|
return 'True'
|
||||||
else:
|
else:
|
||||||
return False
|
return 'False'
|
||||||
|
|
||||||
def atod(a):
|
def atod(a):
|
||||||
return struct.unpack("!L",inet_aton(a))[0]
|
return struct.unpack("!L",inet_aton(a))[0]
|
||||||
|
@ -285,9 +325,9 @@ def check_smb_null_session(host):
|
||||||
s.send(NetworkSendBufferPython2or3(buffer0))
|
s.send(NetworkSendBufferPython2or3(buffer0))
|
||||||
data = s.recv(2048)
|
data = s.recv(2048)
|
||||||
if data[8:10] == b'\x75\x00':
|
if data[8:10] == b'\x75\x00':
|
||||||
return True
|
return 'True'
|
||||||
else:
|
else:
|
||||||
return False
|
return 'False'
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -346,14 +386,25 @@ def handle(data, host):
|
||||||
ParseSMBNTLM2Exchange(data, host[0], Bootime, SMB2signing)
|
ParseSMBNTLM2Exchange(data, host[0], Bootime, SMB2signing)
|
||||||
|
|
||||||
##################
|
##################
|
||||||
#run it
|
|
||||||
def ShowSmallResults(Host):
|
def ShowSmallResults(Host):
|
||||||
if ConnectAndChoseSMB((Host,445)) == False:
|
if ConnectAndChoseSMB((Host,445)) == False:
|
||||||
try:
|
try:
|
||||||
Hostname, DomainJoined = DomainGrab((Host, 445))
|
Hostname, DomainJoined = DomainGrab((Host, 445))
|
||||||
Signing, OsVer, LanManClient = SmbFinger((Host, 445))
|
Signing, OsVer, LanManClient = SmbFinger((Host, 445))
|
||||||
NullSess = check_smb_null_session((Host, 445))
|
NullSess = check_smb_null_session((Host, 445))
|
||||||
print(("[SMB1]:['{}', Os:'{}', Domain:'{}', Signing:'{}', Null Session: '{}', RDP:'{}']".format(Host, OsVer, DomainJoined, Signing, NullSess,IsRDPOn((Host,3389)))))
|
RDP = IsRDPOn((Host,3389))
|
||||||
|
print(("[SMB1]:['{}', Os:'{}', Domain:'{}', Signing:'{}', Null Session: '{}', RDP:'{}']".format(Host, OsVer, DomainJoined, Signing, NullSess,RDP)))
|
||||||
|
SaveRunFingerToDb({
|
||||||
|
'Protocol': '[SMB1]',
|
||||||
|
'Host': Host,
|
||||||
|
'WindowsVersion':OsVer,
|
||||||
|
'OsVer': OsVer,
|
||||||
|
'DomainJoined':DomainJoined,
|
||||||
|
'Bootime': 'N/A',
|
||||||
|
'Signing': Signing,
|
||||||
|
'NullSess': NullSess,
|
||||||
|
'IsRDPOn':RDP,
|
||||||
|
})
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -364,12 +415,12 @@ def IsRDPOn(Host):
|
||||||
try:
|
try:
|
||||||
s.connect(Host)
|
s.connect(Host)
|
||||||
if s:
|
if s:
|
||||||
return True
|
return 'True'
|
||||||
else:
|
else:
|
||||||
return False
|
return 'False'
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
return False
|
return 'False'
|
||||||
|
|
||||||
def RunFinger(Host):
|
def RunFinger(Host):
|
||||||
if Filename != None:
|
if Filename != None:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue