86 lines
3.4 KiB
Python
86 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
import socket
|
|
import sys
|
|
|
|
class NXCModule:
|
|
'''
|
|
Module by CyberCelt: @Cyb3rC3lt
|
|
|
|
Initial module:
|
|
https://github.com/Cyb3rC3lt/CrackMapExec-Modules
|
|
'''
|
|
|
|
name = 'find-computer'
|
|
description = 'Finds computers in the domain via the provided text'
|
|
supported_protocols = ['ldap']
|
|
opsec_safe = True
|
|
multiple_hosts = False
|
|
|
|
def options(self, context, module_options):
|
|
'''
|
|
find-computer: Specify find-computer to call the module
|
|
TEXT: Specify the TEXT option to enter your text to search for
|
|
Usage: nxc ldap $DC-IP -u Username -p Password -M find-computer -o TEXT="server"
|
|
nxc ldap $DC-IP -u Username -p Password -M find-computer -o TEXT="SQL"
|
|
'''
|
|
|
|
self.TEXT = ''
|
|
|
|
if 'TEXT' in module_options:
|
|
self.TEXT = module_options['TEXT']
|
|
else:
|
|
context.log.error('TEXT option is required!')
|
|
exit(1)
|
|
|
|
def on_login(self, context, connection):
|
|
|
|
# Building the search filter
|
|
searchFilter = "(&(objectCategory=computer)(&(|(operatingSystem=*"+self.TEXT+"*)(name=*"+self.TEXT+"*))))"
|
|
|
|
try:
|
|
context.log.debug('Search Filter=%s' % searchFilter)
|
|
resp = connection.ldapConnection.search(searchFilter=searchFilter,
|
|
attributes=['dNSHostName','operatingSystem'],
|
|
sizeLimit=0)
|
|
except ldap_impacket.LDAPSearchError as e:
|
|
if e.getErrorString().find('sizeLimitExceeded') >= 0:
|
|
context.log.debug('sizeLimitExceeded exception caught, giving up and processing the data received')
|
|
resp = e.getAnswers()
|
|
pass
|
|
else:
|
|
logging.debug(e)
|
|
return False
|
|
|
|
answers = []
|
|
context.log.debug('Total no. of records returned %d' % len(resp))
|
|
for item in resp:
|
|
if isinstance(item, ldapasn1_impacket.SearchResultEntry) is not True:
|
|
continue
|
|
dNSHostName = ''
|
|
operatingSystem = ''
|
|
try:
|
|
for attribute in item['attributes']:
|
|
if str(attribute['type']) == 'dNSHostName':
|
|
dNSHostName = str(attribute['vals'][0])
|
|
elif str(attribute['type']) == 'operatingSystem':
|
|
operatingSystem = attribute['vals'][0]
|
|
if dNSHostName != '' and operatingSystem != '':
|
|
answers.append([dNSHostName,operatingSystem])
|
|
except Exception as e:
|
|
context.log.debug("Exception:", exc_info=True)
|
|
context.log.debug('Skipping item, cannot process due to error %s' % str(e))
|
|
pass
|
|
if len(answers) > 0:
|
|
context.log.success('Found the following computers: ')
|
|
for answer in answers:
|
|
try:
|
|
IP = socket.gethostbyname(answer[0])
|
|
context.log.highlight(u'{} ({}) ({})'.format(answer[0],answer[1],IP))
|
|
context.log.debug('IP found')
|
|
except socket.gaierror as e:
|
|
context.log.debug('Missing IP')
|
|
context.log.highlight(u'{} ({}) ({})'.format(answer[0],answer[1],"No IP Found"))
|
|
else:
|
|
context.log.success('Unable to find any computers with the text "' + self.TEXT + '"')
|