Update laps core function
parent
ef1e5d3fb1
commit
fcddee656e
|
@ -90,8 +90,8 @@ class connection(object):
|
|||
|
||||
def proto_flow(self):
|
||||
if self.create_conn_obj():
|
||||
self.enum_host_info()
|
||||
self.proto_logger()
|
||||
self.enum_host_info()
|
||||
self.print_host_info()
|
||||
# because of null session
|
||||
if self.login() or (self.username == '' and self.password == ''):
|
||||
|
|
|
@ -34,23 +34,7 @@ class KerberosAttacks:
|
|||
self.nthash = self.hash
|
||||
|
||||
if self.password is None:
|
||||
self.password = ''
|
||||
|
||||
def login_for_smb(username, password, domain):
|
||||
|
||||
# Create the baseDN
|
||||
baseDN = ''
|
||||
domainParts = domain.split('.')
|
||||
for i in domainParts:
|
||||
baseDN += 'dc=%s,' % i
|
||||
# Remove last ','
|
||||
baseDN = baseDN[:-1]
|
||||
print(domain, baseDN, domain)
|
||||
ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % domain, baseDN, domain)
|
||||
print(username, password, domain)
|
||||
ldapConnection.login(username, password, domain, '', '')
|
||||
return ldapConnection
|
||||
|
||||
self.password = ''
|
||||
|
||||
def outputTGS(self, tgs, oldSessionKey, sessionKey, username, spn, fd=None):
|
||||
decodedTGS = decoder.decode(tgs, asn1Spec=TGS_REP())[0]
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
import logging
|
||||
import random
|
||||
from pyasn1.codec.der import decoder, encoder
|
||||
from pyasn1.type.univ import noValue
|
||||
from impacket.ntlm import compute_lmhash, compute_nthash
|
||||
from impacket.ldap import ldap as ldap_impacket
|
||||
from cme.logger import CMEAdapter
|
||||
|
||||
class LDAPConnect:
|
||||
|
||||
def __init__(self, host, port, hostname):
|
||||
self.proto_logger(host, port, hostname)
|
||||
|
||||
def proto_logger(self, host, port, hostname):
|
||||
self.logger = CMEAdapter(extra={
|
||||
'protocol': 'LDAP',
|
||||
'host': host,
|
||||
'port': port,
|
||||
'hostname': hostname
|
||||
})
|
||||
|
||||
def plaintext_login(self, domain, username, password, ntlm_hash):
|
||||
|
||||
lmhash = ''
|
||||
nthash = ''
|
||||
|
||||
|
||||
#This checks to see if we didn't provide the LM Hash
|
||||
if ntlm_hash and ntlm_hash.find(':') != -1:
|
||||
lmhash, nthash = ntlm_hash.split(':')
|
||||
elif ntlm_hash:
|
||||
nthash = ntlm_hash
|
||||
|
||||
# Create the baseDN
|
||||
baseDN = ''
|
||||
domainParts = domain.split('.')
|
||||
for i in domainParts:
|
||||
baseDN += 'dc=%s,' % i
|
||||
# Remove last ','
|
||||
baseDN = baseDN[:-1]
|
||||
|
||||
try:
|
||||
ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % domain, baseDN, domain)
|
||||
ldapConnection.login(username, password, domain, lmhash, nthash)
|
||||
|
||||
# Connect to LDAP
|
||||
out = u'{}{}:{}'.format('{}\\'.format(domain),
|
||||
username,
|
||||
password if password else ntlm_hash)
|
||||
self.logger.extra['protocol'] = "LDAP"
|
||||
self.logger.extra['port'] = "389"
|
||||
# self.logger.success(out)
|
||||
|
||||
return ldapConnection
|
||||
|
||||
except ldap_impacket.LDAPSessionError as e:
|
||||
if str(e).find('strongerAuthRequired') >= 0:
|
||||
# We need to try SSL
|
||||
try:
|
||||
ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % domain, baseDN, domain)
|
||||
ldapConnection.login(username, password, domain, lmhash, nthash)
|
||||
self.logger.extra['protocol'] = "LDAPS"
|
||||
self.logger.extra['port'] = "636"
|
||||
# self.logger.success(out)
|
||||
return ldapConnection
|
||||
except ldap_impacket.LDAPSessionError as e:
|
||||
errorCode = str(e).split()[-2][:-1]
|
||||
self.logger.error(u'{}\\{}:{}'.format(domain,
|
||||
username,
|
||||
password))
|
||||
else:
|
||||
errorCode = str(e).split()[-2][:-1]
|
||||
self.logger.error(u'{}\\{}:{}'.format(domain,
|
||||
username,
|
||||
password))
|
||||
return False
|
||||
|
||||
except OSError as e:
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(domain,
|
||||
username,
|
||||
password,
|
||||
"Error connecting to the domain, please add option --kdcHost with the FQDN of the domain controller"))
|
||||
return False
|
||||
|
||||
|
||||
def hash_login(self, domain, username, ntlm_hash):
|
||||
lmhash = ''
|
||||
nthash = ''
|
||||
|
||||
#This checks to see if we didn't provide the LM Hash
|
||||
if ntlm_hash.find(':') != -1:
|
||||
lmhash, nthash = ntlm_hash.split(':')
|
||||
else:
|
||||
nthash = ntlm_hash
|
||||
|
||||
self.hash = ntlm_hash
|
||||
if lmhash: self.lmhash = lmhash
|
||||
if nthash: self.nthash = nthash
|
||||
|
||||
self.username = username
|
||||
self.domain = domain
|
||||
|
||||
if self.kdcHost is not None:
|
||||
target = self.kdcHost
|
||||
else:
|
||||
target = domain
|
||||
self.kdcHost = domain
|
||||
|
||||
# Create the baseDN
|
||||
self.baseDN = ''
|
||||
domainParts = self.kdcHost.split('.')
|
||||
for i in domainParts:
|
||||
self.baseDN += 'dc=%s,' % i
|
||||
# Remove last ','
|
||||
self.baseDN = self.baseDN[:-1]
|
||||
|
||||
if self.hash == '' and self.args.asreproast:
|
||||
hash_TGT = KerberosAttacks(self).getTGT_asroast(self.username)
|
||||
if hash_TGT:
|
||||
self.logger.highlight(u'{}'.format(hash_TGT))
|
||||
with open(self.args.asreproast, 'a+') as hash_asreproast:
|
||||
hash_asreproast.write(hash_TGT + '\n')
|
||||
return False
|
||||
|
||||
# Connect to LDAP
|
||||
try:
|
||||
self.ldapConnection = ldap_impacket.LDAPConnection('ldap://%s' % target, self.baseDN, self.kdcHost)
|
||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||
self.check_if_admin()
|
||||
out = u'{}{}:{} {}'.format('{}\\'.format(domain),
|
||||
username,
|
||||
nthash,
|
||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
||||
self.logger.extra['protocol'] = "LDAP"
|
||||
self.logger.extra['port'] = "389"
|
||||
# self.logger.success(out)
|
||||
|
||||
if not self.args.continue_on_success:
|
||||
return True
|
||||
except ldap_impacket.LDAPSessionError as e:
|
||||
if str(e).find('strongerAuthRequired') >= 0:
|
||||
try:
|
||||
# We need to try SSL
|
||||
self.ldapConnection = ldap_impacket.LDAPConnection('ldaps://%s' % target, self.baseDN, self.kdcHost)
|
||||
self.ldapConnection.login(self.username, self.password, self.domain, self.lmhash, self.nthash)
|
||||
self.logger.extra['protocol'] = "LDAPS"
|
||||
self.logger.extra['port'] = "636"
|
||||
# self.logger.success(out)
|
||||
except ldap_impacket.LDAPSessionError as e:
|
||||
errorCode = str(e).split()[-2][:-1]
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
||||
self.username,
|
||||
self.password,
|
||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
||||
color='magenta' if errorCode in ldap_error_status else 'red')
|
||||
else:
|
||||
errorCode = str(e).split()[-2][:-1]
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
||||
self.username,
|
||||
self.password,
|
||||
ldap_error_status[errorCode] if errorCode in ldap_error_status else ''),
|
||||
color='magenta' if errorCode in ldap_error_status else 'red')
|
||||
return False
|
||||
except OSError as e:
|
||||
self.logger.error(u'{}\\{}:{} {}'.format(self.domain,
|
||||
self.username,
|
||||
self.nthash,
|
||||
"Error connecting to the domain, please add option --kdcHost with the FQDN of the domain controller"))
|
||||
return False
|
|
@ -3,6 +3,7 @@
|
|||
import socket
|
||||
import os
|
||||
import ntpath
|
||||
import hashlib,binascii
|
||||
from io import StringIO
|
||||
from impacket.smbconnection import SMBConnection, SessionError
|
||||
from impacket.smb import SMB_DIALECT
|
||||
|
@ -26,8 +27,7 @@ from cme.protocols.smb.mmcexec import MMCEXEC
|
|||
from cme.protocols.smb.smbspider import SMBSpider
|
||||
from cme.protocols.smb.passpol import PassPolDump
|
||||
from cme.protocols.smb.samruser import UserSamrDump
|
||||
from cme.protocols.ldap.kerberos import KerberosAttacks
|
||||
from impacket.ldap import ldapasn1 as ldapasn1_impacket
|
||||
from cme.protocols.ldap.smbldap import LDAPConnect
|
||||
from cme.helpers.logger import highlight
|
||||
from cme.helpers.misc import *
|
||||
from cme.helpers.powershell import create_ps_command
|
||||
|
@ -260,15 +260,9 @@ class smb(connection):
|
|||
if self.args.local_auth:
|
||||
self.domain = self.hostname
|
||||
|
||||
if self.args.laps:
|
||||
print("laps auth")
|
||||
print(self.args.username)
|
||||
self.laps_search(self.args.username, self.args.password, self.domain)
|
||||
|
||||
def laps_search(self, username, password, domain):
|
||||
print("ldap connection")
|
||||
connection = KerberosAttacks.login_for_smb(username[0], password[0], domain)
|
||||
print("ldap connection end", self.hostname)
|
||||
def laps_search(self, username, password, ntlm_hash, domain):
|
||||
ldapco = LDAPConnect(self.domain, "389", self.domain)
|
||||
connection = ldapco.plaintext_login(domain, username[0] if username else '', password[0] if password else '', ntlm_hash[0] if ntlm_hash else '' )
|
||||
|
||||
searchFilter = '(&(objectCategory=computer)(ms-MCS-AdmPwd=*)(name='+ self.hostname +'))'
|
||||
attributes = ['ms-MCS-AdmPwd','samAccountname']
|
||||
|
@ -286,10 +280,13 @@ class smb(connection):
|
|||
sAMAccountName = str(computer['vals'][0])
|
||||
else:
|
||||
msMCSAdmPwd = str(computer['vals'][0])
|
||||
context.log.highlight("Computer: {:<20} Password: {}".format(sAMAccountName, msMCSAdmPwd))
|
||||
logging.debug("Computer: {:<20} Password: {} {}".format(sAMAccountName, msMCSAdmPwd, self.hostname))
|
||||
self.username = "administrator"
|
||||
self.password = "October2021"
|
||||
|
||||
self.password = msMCSAdmPwd
|
||||
if ntlm_hash:
|
||||
hash_ntlm = hashlib.new('md4', msMCSAdmPwd.encode('utf-16le')).digest()
|
||||
self.args.hash = [binascii.hexlify(hash_ntlm).decode()]
|
||||
self.domain = self.hostname
|
||||
|
||||
def print_host_info(self):
|
||||
self.logger.info(u"{}{} (name:{}) (domain:{}) (signing:{}) (SMBv1:{})".format(self.server_os,
|
||||
|
@ -298,6 +295,9 @@ class smb(connection):
|
|||
self.domain,
|
||||
self.signing,
|
||||
self.smbv1))
|
||||
if self.args.laps:
|
||||
self.laps_search(self.args.username, self.args.password, self.args.hash, self.domain)
|
||||
|
||||
def kerberos_login(self, aesKey, kdcHost):
|
||||
#Re-connect since we logged off
|
||||
self.create_conn_obj()
|
||||
|
@ -394,19 +394,19 @@ class smb(connection):
|
|||
self.hash = ntlm_hash
|
||||
if lmhash: self.lmhash = lmhash
|
||||
if nthash: self.nthash = nthash
|
||||
|
||||
self.username = username
|
||||
if not self.args.laps:
|
||||
self.username = username
|
||||
self.domain = domain
|
||||
self.conn.login(username, '', domain, lmhash, nthash)
|
||||
self.conn.login(self.username, '', domain, lmhash, nthash)
|
||||
|
||||
self.check_if_admin()
|
||||
self.db.add_credential('hash', domain, username, ntlm_hash)
|
||||
self.db.add_credential('hash', domain, self.username, ntlm_hash)
|
||||
|
||||
if self.admin_privs:
|
||||
self.db.add_admin_user('hash', domain, username, ntlm_hash, self.host)
|
||||
self.db.add_admin_user('hash', domain, self.username, ntlm_hash, self.host)
|
||||
|
||||
out = u'{}\\{} {} {}'.format(domain,
|
||||
username,
|
||||
out = u'{}\\{}:{} {}'.format(domain,
|
||||
self.username,
|
||||
ntlm_hash,
|
||||
highlight('({})'.format(self.config.get('CME', 'pwn3d_label')) if self.admin_privs else ''))
|
||||
|
||||
|
@ -423,14 +423,14 @@ class smb(connection):
|
|||
except (SessionError, NetBIOSTimeout) as e:
|
||||
error, desc = e.getErrorString()
|
||||
self.logger.error(u'{}\\{}:{} {} {}'.format(domain,
|
||||
username,
|
||||
self.username,
|
||||
ntlm_hash,
|
||||
error,
|
||||
'({})'.format(desc) if self.args.verbose else ''),
|
||||
color='magenta' if error in smb_error_status else 'red')
|
||||
|
||||
if error not in smb_error_status:
|
||||
self.inc_failed_login(username)
|
||||
self.inc_failed_login(self.username)
|
||||
return False
|
||||
if not self.args.continue_on_success:
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue