mirror of
https://github.com/cisagov/snafflepy
synced 2026-09-24 18:22:23 +00:00
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:
+105
-1
@@ -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')
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user