Merge pull request #8 from robert-todora/dev

added LDAP login functionality and ability to get list of computers from Active Directory...
This commit is contained in:
Robert Todora
2023-07-03 16:27:22 -04:00
committed by GitHub
2 changed files with 106 additions and 3 deletions
+105 -1
View File
@@ -1,5 +1,9 @@
import sys
from ldap3 import *
import socket
import urllib.parse
import dns.resolver
from ldap3 import ALL_ATTRIBUTES, Server, Connection, ALL, SUBTREE
from time import sleep
from .smb import *
@@ -9,7 +13,27 @@ def begin_snaffle(options):
print("Beginning the snaffle...")
sleep(0.2)
domain_names = []
# TODO: Talk to AD via LDAP to get list of computers with file shares
if options.no_discovery or options.disable_computer_discovery:
log.debug("Computer discovery is turned off. Snaffling will only occur on the host(s) specified.")
pass
else:
login = access_ldap_server(options.targets[0], options.username, options.password)
domain_names = list_computers(login, options.domain)
# list_computers() returns list so need to individually add entry
for target in domain_names:
log.info(f"Found{target}, attempting to resolve to IP and add to targets to snaffle...")
sleep(0.5)
try:
# TODO: Try to fix this?
ip = resolve(options.domain, target)
options.targets.append(ip)
except Exception as e:
log.debug(f"Exception: {e}")
log.warning(f"Unable to resolve{target} to IP address")
continue
print(f"Targets that will be snaffled: {options.targets}")
# Login via SMB
for target in options.targets:
@@ -31,3 +55,83 @@ def begin_snaffle(options):
except Exception as e:
print("Exception: ", e)
def access_ldap_server(ip, username, password):
server = Server(ip, get_info=ALL)
try:
conn = Connection(server, username, password)
if not conn.bind():
log.critical(f"Unable to bind to {server} as {username}, ")
return conn
except Exception as e:
log.critical(f'Error logging in to {ip}, {e}')
log.info("Trying guest session... ")
try:
conn = Connection(server, username='Guest', password = '')
if not conn.bind():
log.critical(f"Unable to bind to {server} as {username}, ")
return conn
except Exception as e:
log.critical(f'Error logging in to {ip}, as {username}; {e}')
log.info("Trying null session... ")
conn = Connection(server, username='', password = '')
if not conn.bind():
log.critical(f"Unable to bind to {server} as {username}")
return None
return conn
def list_computers(connection:Connection, domain):
dn = get_domain_dn(domain)
filter = "(objectCategory=computer)"
if connection is None:
log.critical("Connection is not established")
try:
connection.search(search_base=dn,search_filter=filter,search_scope=SUBTREE,attributes=['dNSHostName'])
#log.debug(connection.entries)
#connection.search(search_base=dn,search_filter=filter,search_scope=SUBTREE,attributes=ALL_ATTRIBUTES)
domain_names = []
log.debug(connection.entries)
for entry in connection.entries:
sep = str(entry).strip().split(':')
domain_names.append(sep[6])
return domain_names
except Exception as e:
log.critical(f"Unable to list computers: {e}")
return None
def get_domain_dn(domain):
base_dn = ''
domain_parts = domain.split('.')
for i in domain_parts:
base_dn += 'DC=%s,' % i
base_dn = base_dn[:-1]
return base_dn
def resolve(nameserver, host_fqdn):
resolver = dns.resolver.Resolver()
resolver.nameservers = [nameserver]
answer = resolver.query(host_fqdn, "A")
return answer
def get_ip(target):
try:
print(socket.gethostbyname(target))
except socket.gaierror:
parsed_url = urllib.parse.urlparse(target)
hostname = parsed_url.hostname
try:
answers = dns.resolver.query(hostname, 'A')
for rdata in answers:
print(rdata.address)
except dns.resolver.NXDOMAIN:
print('ip not found')
-1
View File
@@ -63,7 +63,6 @@ class SMBClient:
if self.conn is None or refresh:
try:
self.conn = SMBConnection(self.server, self.server, sess_port=445, timeout=20)
#print("Here: ", self.conn)
except Exception as e:
print("Exception: ", impacket_error(e))
return None