Contents

PwnMe2023 - Compromised

I found that the idea of using ntds.dit to find persistence was very original. First, we have to convert the ETL file provided to a PCAP format. Then, we extract the files contained in the SMB frames. Three files are relevant here: SYSTEM hive, ntds.dit, and ticket.kirbi. By decrypting the ticket file, we can identify the first persistence technique, which is a diamond ticket. Afterward, we mount ntdis.dit and parse it with AdTimeline to extract Active Directory replication metadata. With the result, we discover that Logon Script, Shadow Credentials and krbtgt delegation persistence techniques have been used.

Description

An attacker has successfully compromised your company and more specifically your Active Directory! Your role is to find all the persistence techniques that the attacker has used in order to apply countermeasures.

The flag should be submitted in the following form: PWNME{persistence1user1-persistence2user2-persistence3user3-persistence4user4} Where persistence is the name of the technique in lower case and user is the samAccountName of the user impacted in lower case. The persistence techniques need to be put in chronological order of usage in the Active Directory.

Exemple : PWNME{scheduletaskjessie_vaughan-createaccountmagdalena_gonzales-goldenticketjordan_gates-adminsdholderjaclyn_huber}

Author: rayanlecat

Resolution

From ETL to PCAP

For the challenge, a file named compromised.etl is provided. The extension ETL stands for Event Trace Log and is a file format used by the Windows to store event tracing data. ETL files are created by the Event Tracing for Windows (ETW) subsystem and can contain a wide variety of data, including system events, application-specific data, or network traffic.

By looking at the file type, we noticed that the file default name was NetTrace.etl. Therefore, it is possible that the generated file corresponds to a network capture given the name.

1
2
$ file compromised.etl
compromised.etl: Windows Event Trace Log "C:\Users\Administrateur\AppData\Local\Temp\NetTraces\NetTrace.etl"

To confirm that it is indeed a network capture, the ETL file is opened in the Windows Event Viewer. The fact that the source of the file is listed as NDIS-PacketCapture indicates that it was generated by capturing network packets at the NDIS (Network Driver Interface Specification) layer. NDIS-PacketCapture is a built-in feature of Windows that allows capturing network traffic.

/Compromised/fed37eff09980b4fbf816e1570cc3657.png

Now, it is necessary to convert this file into PCAP format to be able to read it in Wireshark. The tool to run is etl2pcapng, which transforms ETL files containing NDIS packet captures into PCAPNG format.

At the beginning, I used etl-parser a library from CERT Airbus, but it did not correctly convert the ETL file to PCAP format, which contained gaps.

1
2
3
PS> etl2pcapng.exe compromised.etl compromised.pcap
IF: medium=eth                  ID=0    IfIndex=6       VlanID=0
Converted 316276 frames

PCAP analysis

By analyzing the protocol statistics (Statistics -> Protocol Hierarchy), we see that it is mainly Kerberos et SMB packets.

/Compromised/168aa008f68ad37374b846ec78df3ea9.png

It is possible to obtain more information, especially on the IPs, by importing the ETL file into NetworkMiner. .

We can also import the PCAP format, but not PCAPNG in the free version.

It turns out that there are two significant machines: KALI and a DC. In Host Details, we noticed that KALI attempted to authenticate hundreds of accounts through Kerberos and NTLM. Furthermore, it accessed three shares of the DC: IPC$, 9VnPPWu9 and share. Given that the name 9VnPPWu9 is suspicious for a shared folder, it was probably used during the attack, but this folder is useless for this challenge, unlike share.

/Compromised/bf73126af266426a3ff145cc0a7992c6.png

Therefore, we known that several shares have been accessed by the attacker. We go in the File menu of Wireshark, then Export Objects and SMB to view the exchanged files. Five different files are found.

/Compromised/5a6da1e216a9715c5709d81f879ea721.png

The files named samr and srvsvc are named pipes that provide access to specific remote procedure call (RPC) interfaces in Windows.

  • samr (Security Accounts Manager Remote Protocol) is a protocol that allows managing user and group accounts on a Windows system remotely.
  • srvsvc (Server Service Remote Protocol) is a protocol that provides remote access to server-related information, such as the server name, domain name, and domain controller status.
  • ntds.dit is the main database file for the Active Directory Domain Services (AD DS) on a Windows Server. It contains user and group account information, security policies, and other data related to the domain.
  • ticket.kirbi is a Kerberos authentication ticket that is generated when a user logs on to a Windows domain. It contains information about the user’s identity and authentication status, and can be used to access network resources without having to re-authenticate.
  • SYSTEM is a registry hive file that contains configuration information about the hardware, drivers, and operating system settings on a Windows system.

The last three files are extracted, which are of interest in finding persistence mechanisms.

Continuing to explore the PCAP in more depth was a significant rabbit hole in the challenge. However, here are some useful resources I found during my research:

Diamond ticket

To obtain more information about the ticket, it is first transformed into a .ccache (a Kerberos ticket format under Linux) with ticketConveter and then we read it with describeTicket. Unfortunately, it is impossible to determine whether the ticket is malicious or not with the readable information here; the PAC must be decrypted.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ ticketConverter.py ticket.kirbi ticket.ccache
$ describeTicket.py ticket.ccache
[*] Number of credentials in cache: 1
[*] Parsing credential[0]:
[*] Ticket Session Key            : f4e2cbd2ee9ac0a3e83dc8e1f382c4d35b604261bde879035c82e76340bc309b
[*] User Name                     : MARSHA_MCFARLAND
[*] User Realm                    : PWNME.LOCAL
[*] Service Name                  : krbtgt/PWNME.LOCAL
[*] Service Realm                 : PWNME.LOCAL
[*] Start Time                    : 05/05/2023 15:22:15 PM
[*] End Time                      : 06/05/2023 01:22:15 AM (expired)
[*] RenewTill                     : 12/05/2023 15:22:15 PM
[*] Flags                         : (0x40e10000) forwardable, renewable, initial, pre_authent, enc_pa_rep
[*] KeyType                       : aes256_cts_hmac_sha1_96
[*] Base64(key)                   : 9OLL0u6awKPoPcjh84LE01tgQmG96HkDXILnY0C8MJs=
[*] Decoding unencrypted data in credential[0]['ticket']:
[*]   Service Name                : krbtgt/PWNME.LOCAL
[*]   Service Realm               : PWNME.LOCAL
[*]   Encryption type             : aes256_cts_hmac_sha1_96 (etype 18)
[-] Could not find the correct encryption key! Ticket is encrypted with aes256_cts_hmac_sha1_96 (etype 18), but no keys/creds were supplied

The SYSTEM hive contains a BootKey key that decrypts the secrets contained in the ntds.dit database. By retrieving the aes256_cts_hmac_sha1_96 key of the krbtgt account used to encrypt the ticket PAC, it will be possible to read its contents.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
$ secretsdump.py -system SYSTEM -ntds ntds.dit LOCAL | grep krbtgt:aes256
krbtgt:aes256-cts-hmac-sha1-96:e6b60b8a70ad9bda01419465c44b73413f29c4b02908877a2a6714baaf775d02
$ describeTicket.py ticket.ccache --aes e6b60b8a70ad9bda01419465c44b73413f29c4b02908877a2a6714baaf775d02
[...]
[*] Decoding credential[0]['ticket']['enc-part']:
[*]   LoginInfo
[*]     Logon Time                : 05/05/2023 13:17:09 PM
[*]     Logoff Time               : Infinity (absolute time)
[*]     Kickoff Time              : Infinity (absolute time)
[*]     Password Last Set         : 05/05/2023 05:36:47 AM
[*]     Password Can Change       : 06/05/2023 05:36:47 AM
[*]     Password Must Change      : 16/06/2023 05:36:47 AM
[*]     LastSuccessfulILogon      : Infinity (absolute time)
[*]     LastFailedILogon          : Infinity (absolute time)
[*]     FailedILogonCount         : 0
[*]     Account Name              : MARSHA_MCFARLAND
[*]     Full Name                 : MONTE_KIDD
[*]     Logon Script              :
[*]     Profile Path              :
[*]     Home Dir                  :
[*]     Dir Drive                 :
[*]     Logon Count               : 17
[*]     Bad Password Count        : 0
[*]     User RID                  : 5251
[*]     Group RID                 : 513
[*]     Group Count               : 1
[*]     Groups                    : 512
[*]     Groups (decoded)          : (512) Domain Admins
[*]     User Flags                : (32) LOGON_EXTRA_SIDS
[*]     User Session Key          : 00000000000000000000000000000000
[*]     Logon Server              : DC
[*]     Logon Domain Name         : PWNME
[*]     Logon Domain SID          : S-1-5-21-2001501047-2154456596-4111723621
[*]     User Account Control      : (16) USER_NORMAL_ACCOUNT
[*]     Extra SID Count           : 1
[*]     Extra SIDs                : S-1-18-1 Authentication authority asserted identity (SE_GROUP_MANDATORY, SE_GROUP_ENABLED_BY_DEFAULT, SE_GROUP_ENABLED)
[*]     Resource Group Domain SID :
[*]     Resource Group Count      : 0
[*]     Resource Group Ids        :
[*]     LMKey                     : 0000000000000000
[*]     SubAuthStatus             : 0
[*]     Reserved3                 : 0
[*]   ClientName
[*]     Client Id                 : 05/05/2023 13:22:15 PM
[*]     Client Name               : MARSHA_MCFARLAND
[*]   UpnDns
[*]     Flags                     : (2) S_SidSamSupplied
[*]     UPN                       : MARSHA_MCFARLAND@pwnme.local
[*]     DNS Domain Name           : PWNME.LOCAL
[*]     SamAccountName            : MARSHA_MCFARLAND
[*]     UserSid                   : S-1-5-21-2001501047-2154456596-4111723621-5251
[*]   Attributes Info
[*]     Flags                     : (1) PAC_WAS_REQUESTED
[*]   Requestor Info
[*]     UserSid                   : S-1-5-21-2001501047-2154456596-4111723621-5251
[*]   ServerChecksum
[*]     Signature Type            : hmac_sha1_96_aes256
[*]     Signature                 : 981b5e910992ea904c4b6aa6
[*]   KDCChecksum
[*]     Signature Type            : hmac_sha1_96_aes256
[*]     Signature                 : 383145c7ab181334d1fe95e2

We observed that the FULL NAME MONTE_KIDD is different from the Account Name MARSHA_MCFARLAND, indicating that the PAC has been modified. It is a diamond ticket. Indeed, the purpose is to request a normal ticket, decrypt the PAC, modify it, recalculate the signatures and encrypt it again.

The time indicated in the ticket is in GMT+2.

Replication metadata

Replication metadata refers to information about the replication state and history of Active Directory objects. The metadata includes information such as the time of the change, the type of change, and the ID of the domain controller that made the change. The goal is to ensure consistency and accuracy of data across all domain controllers in the same domain. They are stored in the ntds.dit database, that we already have.

We need to expose the database in order to query it with LDAP. For this, Windows offers the tool dsamain. However, you need a Windows server with the Active Directory Lightweight Directory Services (AD LDS) role and the Remote Server Administration Tools (RSAT) feature.

It is possible to replace AD LDS with the Active Directory Domain Services (AD DS) role, but it is heavier and unnecessary.

We use vagrant, to get immediately an operational Windows Server VM where we just need to install the roles and features.

1
2
$ vagrant init StefanScherer/windows_2019
$ vagrant up

With the AD LDS role, it is necessary to use the Administrator account as the domain administrator, not vagrant.

We can now mount the database and interact with the LDAP directory to retrieve informations.

1
2
3
4
PS> dsamain -dbpath ntds.dit -ldapPort 3266 -allowNonAdminAccess
...
EVENTLOG (Informational): NTDS General / Service Control : 1000
Microsoft Active Directory Domain Services startup complete

To avoid manually searching for persistence techniques, we will use a tool from the ANSSI, ADTimeline, which will generate a CSV with a timeline of modifications as well as an XML of the attributes that have been modified, when and for which object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
PS> .\ADTimeline.ps1 -server "127.0.0.1:3266"
---- Running script on: 127.0.0.1:3266 ----
---- Collecting AD objects ----
---- AD objects collected ----
---- Freeing up memory ----
---- Exporting objects as XML ----
---- Export done ----
---- Generating AD timeline ----
---- 3498 Objects to process ----
---- Timeline created ----

The dates here are in GMT and not GMT+2.

By sorting the modifications in the CSV by date, we discover a persistence of type delegation to krbtgt. Indeed, the msDS-AllowedToActOnBehalfOfOtherIdentity attribute allows an attacker to obtain a service ticket for the krbtgt account on behalf of any user.

/Compromised/26ce0baabb144e4b77b9ee32d9adb22d.png

Two other persistences can be found by descending into the latest modifications. We find a modification of the nTSecurityDescriptor attribute on the AdminSDHolder object as well as the scriptPath attribute for the user DUDLEY_DEJESUS.

/Compromised/26447945bdd3923c149bf651170d2262.png

The first modification potentially corresponds to a AdminSDHolder persistence by adding an account to this object. The purpose of AdminSDHolder is to protect domain objects from permission changes by resetting them to their default value every hour. By modifying the DACL, we can add a user that we own with GenericAll rights over the entire domain.

We then find the SID S-1-5-21-2001501047-2154456596-4111723621-5099 in the DACL of AdminSDHolder, which match with with the user ROSEANN_JACOBS.

/Compromised/2be8a0e315ecfd68fd11403dc1ccb70c.png

After discovering this persistence, the creator of the challenge told me that it was his mistake to forget to remove it, and it does not count towards the flag. 🙃

The second modification corresponds to a Logon Script persistence consisting of executing a binary at the opening of a user session. In our case, it is beacon.exe, which leaves no doubt about the persistence.

/Compromised/94cf10ae089a6f10e40e39d6d49ab5f6.png

Finally, for the last persistence, we notice that only 5 accounts have a lastLogonTimestamp attribute different from 2023-05-05T07....

/Compromised/90af39695a526ceb6afce93f81c1ba9f.png

By looking at the attributes of each one, we can see that the account KELLEY_HESTER has an attribute msDS-KeyCredentialLink.

/Compromised/ec3d01b380d4b7eb80231228094c8901.png

This is a persistence via Shadow Credentials, the principle is to add a public key to an account via the msDS-KeyCredentialLink attribute, which will allow us to authenticate with the private key to obtain a TGT.

Flag

PWNME{logonscriptdudley_dejesus-shadowcredentialskelley_hester-rodcgoldenticketsmarsha_mcfarland-krbtgtdelegationkrbtgt}