💾 Archived View for aphrack.org › issues › phrack68 › 17.gmi captured on 2021-12-03 at 14:04:38. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
==Phrack Inc.== Volume 0x0e, Issue 0x44, Phile #0x11 of 0x13 |=-----------------------------------------------------------------------=| |=-----=[ Abusing Netlogon to steal an Active Directory's secrets ]=-----=| |=-----------------------------------------------------------------------=| |=-----------------------=[ by the p1ckp0ck3t ]=-----------------------=| |=-----------------------------------------------------------------------=| |=-------------------=[ anonymous_7406da@phrack.org ]=-------------------=| |=-----------------------------------------------------------------------=| <<<->>> + Prologue + Common tools & appropriate warnings! + Meet the Samba 4 project + Digging into the Netlogon replication mechanism + Extracting the secrets + A practical introduction to S4 (Stealth & Secure Secret Stealer) + S4 .VS. Windows 2008 Domain Controllers + Additional details + Last words + Bibliography + c0de: S4 <<<->>> ---[ 1 - Prologue If you've been hacking around Windows networks then you must be more than familiar with common LSA dumping tools such as pwdump [01] & co. You must also know that they are not only detected by (most?) AV, but furthermore that they may not work the expected way when an AV/HIPS is installed on your target. In the worst case a box may even crash! It's fucking annoying. In a Windows network, crashing a workstation is probably harmless (natural Windows behavior you could say) because administrators won't notice and its user will only complain. He may also kick the box, blame "fucking M$" and ultimately reboot it. But in the end, we all know that he will rather focus on the recovery of his Office document than look for evidence (assuming he has the required skills to begin with). The situation is entirely different when it comes to Windows servers and especially DC (Domain Controllers). For these kinds of target, one needs to be *very* cautious because an administrator would find a crash *very* suspicious. This paper presents a (hopefully) new technique to retrieve the AD (Active Directory [02])'s secrets using one of its (natural) replication mechanisms when a DC or a domain administrator's account has been compromised. Because it's solely based on the Windows API -without any hooks or (too) dirty tricks- it's a quiet efficient way to retrieve domain users' hashed passwords. ---[ 2 - Common tools & appropriate warnings! Let me first begin by a bit of bitching regarding what's already available out there. There are a lot of tools dealing with "online" password dumping, most being open source, a few of them being however commercial software (I haven't tested those). Judging from my experience (and that of many friends) I can tell you that only a few of them are *really* of interest. I won't fill a bug report -:]- but remember that a good password dumping tool should provide: 1. Stability: Using such a tool should *never* be risky for the target's safety. Interactions with LSASS are really intrusive and dangerous and should be avoided if possible. You wouldn't use a kernel sploit without having first understood how and why it's working right? Same thing here. Crashing LSASS means crashing the box! 2. Stealthiness: You should never take the risk to be caught by some AV/HIPS. It's no news that there are Windows APIs that you can't use anymore and it's obvious that binaries provided by a famous security website have a good chance to be detected. Take for example the case of fgdump & gsecdump. Both are great tools with a very good chance to succeed. But, can you seriously trust software that: - Hook well known LSASS functions (using even more known techniques)? (pwdump6 of fgdump) - Parse internal LSASS memory? (gsecdump) - Write well known (=> detected) dll & exe files on disk? (fgdump) - Start new services? Stop AV services? (fgdump) - Are closed source? (gsecdump) Especially with poorly designed AV/HIPS running on the same machine? Don't take me wrong, I'm not dissing pwdump* (or the similar) tools especially since they are necessary; but at least patch them a bit, you moron! In the case of a workstation target, there are no other public alternatives. But there's another story in the case of a DC target. What can be done in this matter? Let me tell you the story that months later would lead me to this paper. Because it's a story, some details are missing, especially in the reverse engineering work performed. The idea is to keep the paper simple, as well as to give you the opportunity to find the last pieces of the puzzle all by yourself; follow the hints, hacker :] ---[ 3 - Meet the spart^wSamba 4 project Unix people are well aware of the Samba project but only a few of them are truly aware of how incredible this project really is. This is not just about mounting CIFS volumes, but a complete reverse engineering/rewrite of several parts of Windows. Kudos to the Samba team. A few years ago, the Samba team decided to start a new branch of their project: Samba 4 [03]. The goal was to provide an even deeper integration of a Samba server inside an Active Directory. Now with Samba 4, a Unix computer can become a (RO)DC and what's even more incredible is that it's as easy (well if you're lucky) as typing: ------------------------------[ screendump ]------------------------------- # samba-tool join FOO.BAR DC -Uadministrator@foo.bar --realm=FOO.BAR --------------------------------------------------------------------------- This command (dc)promotes our Linux box in the AD (in this case the domain is foo.bar). It's easy to check that it's indeed properly registered as a legitimate DC using for example an LDAP query: ------------------------------[ screendump ]------------------------------- $ ldapsearch -x -LLL -h dc1.foo.bar -D "administrator@foo.bar" -W -b "OU=Domain Controllers,dc=foo,dc=bar" "(objectClass=Computer)" cn Enter LDAP Password: ******* dn: CN=DC1,OU=Domain Controllers,DC=foo,DC=bar cn: DC1 <-- first DC dn: CN=MEDIA,OU=Domain Controllers,DC=foo,DC=bar cn: MEDIA <-- second DC = our proud little Linux --------------------------------------------------------------------------- As all traditional DC functions are properly running, Kerberos services are running as well to authenticate domain users whenever it is required: ------------------------------[ screendump ]------------------------------- # samba-tool samdump [...] Administrator:500:BAC14D04669EE1D1AAD3B435B51404EE:\ FBBF55D0EF0E34D39593F55C5F2CA5F2:[UX]:LCT-4F1B2611 Guest:501:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:\ NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:[NDUX]:LCT-00000000 krbtgt:502:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:\ D25E142705B3C1B9122309D194E0B36F:[DU]:LCT-4F1B1EFC SUPPORT_388945a0:1001:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:\ 4CB5D040611B3FF00F17AF7DC344F97C:[DUX]:LCT-4F1B196F DC1$:1003:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:\ A59B7CDD1167816DFDD8C5F310ACCEC0:[S]:LCT-4F1B1F2F tofu:1117:E91851A7E394D006ABD3B435B31404EE:\ 15221599C25FA333EA6044C0513ADD45:[UX]:LCT-4F1B23FB HAXOR$:1120:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:\ 88369D133A118783D46D1C6344E99B08:[W]:LCT-4F1B366B cheese:1121:BC5F4D08D49A0099AAD3B43CB51404EE:\ 3E21E05DD9E4E790CB3783D9292F80F7:[UX]:LCT-4F1BE1F2 MEDIA$:1122:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:\ 72CCE806701E837DCBB33B29A9D48E97:[S]:LCT-4F1C3AB1 [...] --------------------------------------------------------------------------- When I discovered how mature the Samba 4 project had become and what it allowed me to perform, I started to imagine how I could take advantage of the situation. The first idea I came up with was to introduce a temporary Samba 4 DC in the AD infrastructure, dump the passwords and immediately dcpromote it again (=remove it from the AD). However this idea is really bad regarding the criteria that I gave earlier: - Stability: No matter how functional Samba 4 may appear, it's many years too soon to use it for serious purpose. To give you an example, I destroyed many testing environments as I was playing with Samba 4 (merely using it in fact). - Stealthiness: I doubt there is even one person able to tell us how many modifications the introduction of a new DC would bring in the AD. Do you honestly think that you could introduce a DC, make it disappear and that no administrator would ever be able to tell that it was there? I'm not taking the risk and neither should you. For these two reasons, it was wise to resign (interestingly, as I would be told later, some French guy apparently didn't [04]). At this point, I had no more ideas until I realized that network traffic was exchanged between DC1 (another DC from the domain) and MEDIA when I was typing the samdump command. More precisely, and thanks to Wireshark's dissectors (courtesy of the Samba team), I was able to observe the following events: 1. NTLM Authentication Protocol used to authenticate MEDIA 2. MEDIA binding on \\DC3.FOO.BAR\IPC$\lsarpc and calling -> lsa_OpenPolicy2() (opnum 44) -> lsa_QueryInfoPolicy2 (opnum 46) 3. MEDIA binding on \\DC3.FOO.BAR\IPC$\netlogon and calling -> NetrServerReqChallenge (opnum 4) -> NetrServerAuthenticate2 (opnum 15) 4. MEDIA binding again (*) on \\DC3.FOO.BAR\IPC$\netlogon and calling -> NetrDatabaseSync (opnum 8) -> NetrDatabaseSync (opnum 8) -> NetrDatabaseSync (opnum 8) (* Using 2 different binds in step 3 & 4 seems weird at first but it will be explained later.) I was immediately interested in the NetrDatabaseSync() function and googled a bit to see if I could find some documentation. Fortunately, Microsoft documents this function; it is a wrapper of NetrDatabaseSync2() [05]. -----------------------[ MS official documentation ]----------------------- NTSTATUS NetrDatabaseSync2( [in, string] LOGONSRV_HANDLE PrimaryName, [in, string] wchar_t* ComputerName, [in] PNETLOGON_AUTHENTICATOR Authenticator, [in, out] PNETLOGON_AUTHENTICATOR ReturnAuthenticator, [in] DWORD DatabaseID, [in] SYNC_STATE RestartState, [in, out] unsigned long* SyncContext, [out] PNETLOGON_DELTA_ENUM_ARRAY* DeltaArray, [in] DWORD PreferredMaximumLength ); [...] The NetrDatabaseSync2 method returns a set of all changes applied to the specified database since its creation. It provides an interface for a BDC to fully synchronize its databases to those of the PDC. [...] --------------------------------------------------------------------------- So, it seemed safe to assume that the network traffic observed was the consequence of a synchronization mechanism. If you're familiar with Windows networks then there is something that should immediately draw your attention: the documentation is mentioning PDC (Primary Domain Controller) & BDC (Backup Domain Controller) which are pre-Windows2000 (= NT4) concepts. Indeed, Windows 2000 introduced Active Directory which uses a different logic. Wikipedia [06] explains it perfectly: -----------------[ Wikipedia: Primary Domain Controller ]------------------ In later releases of Windows, domains have been supplemented by the use of Active Directory services. In Active Directory domains, the concept of primary and secondary domain controller relationships no longer applies. Primary domain controller emulators hold the accounts databases and administrative tools. [...] The same rules apply; only one PDC may exist on a domain, but multiple replication servers may still be used. --------------------------------------------------------------------------- Note: "later releases" means Windows 2000 or above. So I came up with the conclusion that Samba 4 was (and still is) using an old -now emulated- mechanism to synchronize the AD database between its DCs. More precisely in Active Directory, a unique DC holds the PDC FSMO role [12], the other DCs being (emulated) BDC as a result. Now pay attention to the "DatabaseID" parameter passed to NetrDatabaseSync2(): -----------------------[ MS official documentation ]----------------------- DatabaseID: The identifier for a specific database for which the changes are requested. It MUST be one of the following values. Value Meaning ----- ------- 0x00000000 Indicates the SAM database. 0x00000001 Indicates the SAM built-in database. 0x00000002 Indicates the LSA database. --------------------------------------------------------------------------- Assuming an attacker could call NetrDatabaseSync2() with DatabaseID=0 from an (emulated) BDC (= a compromised DC), then he would likely be able to retrieve the user database (SAM), which should include hashed passwords as well, right? I was very suspicious at first because the documentation wasn't mentioning anything about the LSA queries and lsa_QueryInfoPolicy2() is still currently undocumented (afaik). I was afraid that this would complicate things. I could have started to dig inside Samba 4's code (which is quite messy unfortunately) but I had instead a much better idea. What if this API was implemented in some native program available with Windows Server? Guess the answer. ---[ 4 - Digging into the Netlogon replication mechanism If you're familiar with Windows sysadmin stuff then you must be well aware of the "Remote Server Administration Tools" [07] which provides a set of useful new commands for the CLI, including the one I was looking for: nltest.exe (now native under Windows 2008 FYI). Here is how Microsoft describes the tool: -----------------------[ MS official documentation ]----------------------- You can use nltest to: Get a list of domain controllers Force a remote shutdown Query the status of trust Test trust relationships and the state of domain controller replication in a Windows domain Force a user-account database to synchronize on Windows NT version 4.0 or earlier domain controllers <-- synchronize + NT4 == JACKPOT? --------------------------------------------------------------------------- The last sentence is interesting, right? Looking at the IAT of nltest.exe (for Windows 2003), I saw that there were entries for I_NetServerReqChallenge(), I_NetServerAuthenticate() and I_NetDatabaseSync(), all of them being imported from NETAPI32.dll and (strangely) undocumented. A short look at them convinced me that they were mere wrappers for RPC calls to (respectively) NetrServerReqChallenge(), NetrServerAuthenticate() and NetrDatabaseSync() located in netlogon.dll and obviously called using a binding to the named pipe \\%COMPUTERNAME%\IPC$\netlogon. What's cool with these functions is that they _are_ documented in [08] and a tiny modification apart, their prototypes match those of their NETAPI32.dll cousins. To make things even easier, I observed that all our targeted functions were called inside one big function, arbitrarily called SyncFunction() from now on. Reversing SyncFunction() was a task which proved to be really easy thanks to Microsoft's API documentation. Assuming DC2 requests a synchronization from its PDC (DC1), this gives the approximate pseudo-code (I omitted details about the assembly for clarification purposes, but you can find them in the uuencoded C code at the end of the article): -----------------------------[ SyncFunction() ]---------------------------- # Step 1: # ClientChallenge is an 8 bytes array randomly chosen RANDOM(ClientChallenge); # Step 2: # DC2 sends its challenge and requests one (also an 8 bytes array) # from DC1 ZERO(ServerChallenge); I_NetReqChallengeFunc( (WCHAR) L"\\\\" + DC1_FQDN, (WCHAR) DC2_HOSTNAME, ClientChallenge, [OUT] ServerChallenge); # Step 3: # The client creates a Unicode object out of its machine account name # (suffix is '