# tl;dr In the same vein as [[freeipa-postexploitation]], I wanted to explore Samba DC in a lab and test which Windows DC-specific techniques would work out-of-the-box. This is a sad article, since Samba DC is like MSAD, but boring and my tools break all the time. # lab setup For the lab, I've used an Alpine VM as a DC with the conveniently-provided `samba-dc` package. The full setup instructions are available [on the wiki](https://wiki.alpinelinux.org/wiki/Setting_up_a_samba-ad-dc). I've played with the configuration a lot, and a lot of techniques that are taken for granted for Windows DCs would actually heavily depend on non-standard Samba flags. In the end, I went with the following: ```ini # smb.conf [global] server role = domain controller workgroup = TISHINA realm = tishina.local netbios name = DC passdb backend = samba4 idmap_ldb:use rfc2307 = yes ntlm auth = yes client ntlmv2 auth = yes # ldap server require strong auth = no dns forwarder = 1.1.1.1 tls enabled = yes log level = 10 ad dc functional level = 2016 [netlogon] path = /var/lib/samba/sysvol/example.com/scripts read only = No [sysvol] path = /var/lib/samba/sysvol read only = No ``` > **note:** to upgrade the functional level after provisioning (if you forgot it, like I did), it is necessary to run the following after changing smb.conf: > ``` > samba-tool domain schemaupgrade --schema=2019 samba-tool domain functionalprep --function-level=2016 samba-tool domain level raise --domain-level=2016 --forest-level=2016 ```ini #krb5.conf [libdefaults] default_realm = TISHINA.LOCAL dns_lookup_realm = false dns_lookup_kdc = true default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96 rc4-hmac [realms] TISHINA.LOCAL = { default_domain = tishina.local } [domain_realm] dc = TISHINA.LOCAL ``` I've also enrolled a fresh install of Windows 10 as client into the domain to test Windows-based tooling. # authentication, Kerberos, and pain points Somewhat unsurprisingly, Windows-based Kerberos tooling generally works much better with Samba DC, since the Impacket protocol stack is extremely tailored to Microsoft AD. For example, while the configuration above may look sensible from a Windows client compatibility standpoint (and it is), with Impacket `examples/` even obtaining a TGT with RC4 would fail. It fails because the bundled Kerberos KDC does not include `starttime` in the `APReq`, and the fix is pretty simple (similar to https://github.com/fortra/impacket/issues/1510): ```python if encASRepPart['starttime'].hasValue(): credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['starttime'])) else: print("PATCH: encASRepPart['starttime'] is empty") ``` Even then, the SPN has to be supplied manually for Impacket to be able to use the ticket: ```bash ~$ proxychains4 getTGT.py -dc-ip 10.0.2.3 -debug -service krbtgt/[email protected] 'tishina/administrator' -hashes <hash> ``` In the end, all this to learn that Impacket does not recognize the checksum type and can't even obtain the ST with the TGT it just procured. Some Linux tooling (including, obviously `kinit`/`kvno`) will work correctly, but I'd advise against Impacket Kerberos. To use Impacket tooling with the MIT Kerberos setup with a similar configuration as my lab, I'd request TGTs and STs (manually) with `kinit`/`kvno` and then modify the tooling (if necessary) to use those even if the SPNs don't exactly match. Another authentication pain point is that PKINIT has to be configured manually in Samba, so it's rarely done. Schannel also has to be configured specifically with trusted CAs and authentication options to work with user-supplied certificates for authentication. # LDAP and reconaissance When it comes to LDAP authentication specifically, the saddest thing to learn is that NTLM is not supported in the standard configuration. In general, there are a lot of interesting "commit-documented" LDAP authentication configuration options, including SASL/NTLM options, but it says something that it is extremely hard to configure LDAP to use NTLM even if you really want to. In some environments, an OpenLDAP proxy is implemented to support NTLM authentication. If it is the case or if the administrators really know Samba and don't know security, then relaying may still be possible. Thus, in a standard environment, the most practical thing to do is a Windows box + Proxifier or something similar. If you need to use Linux-based tooling that works with LDAP (e.g. `dnstool.py` from https://github.com/dirkjanm/krbrelayx), the easiest way is to modify them to use `ldap3.SIMPLE` instead of `ldap3.NTLM` for authentication. Since the Samba schema is extremely close to Windows AD, most domain reconaissance tools will work exactly as intended. This includes Bloodhound collectors (better to run them from Windows, though), `godap`, etc. # select attack examples Samba DC, as opposed to FreeIPA environments, support a lot of Windows functionality that could be useful to the attacker, but most of it would proved to be hardly exploitable in the default configuration. Some examples: - ADIDNS works as expected, but there's hardly anything to relay the authentication to (on the DC at least), so record creation is much less powerful. - RBCD is supported, but there's no relaying (in the standard configuration) and the attribute may not be modifiable by the computer account anyway - Computer creation with SAMR works, but why would you want to? Since Samba "technically could" be broadly misconfigured to support Windows attacks, I'd still run the same boring "MSAD Top 10 misconfigurations" checklist, but after I would mostly look at Samba DC as a generic IAM with some more postexploitation opportunities than usual, rather then a primary vector of attack. If you can reach a Windows DC instead, do so. As a sidenote, Kerberos relaying still works with Samba/MIT KDC just as well, since the attack itself does not depend much on the KDC implementation. Because Samba DC has full ADIDNS support, it might be a valid attack vector against hosts that still recognize serialized objects in hostname strings. It could also be done with something like `mitm6` (for testing, I have shamelessly edited `/etc/hosts` on the Windows client). For SMB, `krbrelayx` works out-of-the-box with the Samba DC/Server with `server signing = disabled`. If you have the ability to relay `HTTP/<>` SPNs and want to target web services on Linux, the POSIX GSSAPI implementation would also pose no issue. To test this, I've made a simple web server, like so: ```bash # SPN setup samba-tool user create websvc-http 'Str0ngP@ssword!' samba-tool spn add HTTP/dc.tishina.local websvc-http samba-tool spn add HTTP/dc websvc-http samba-tool domain exportkeytab /tmp/krb5.keytab --principal=HTTP/dc.tishina.local ``` ```python # python server from http.server import HTTPServer, BaseHTTPRequestHandler import base64, gssapi, os os.environ.setdefault('KRB5_KTNAME', 'FILE:/etc/krb5.keytab') class KerberosHandler(BaseHTTPRequestHandler): def do_GET(self): auth = self.headers.get('Authorization', '') if not auth.startswith('Negotiate '): self.send_response(401) self.send_header('WWW-Authenticate', 'Negotiate') self.end_headers() return try: token = base64.b64decode(auth[len('Negotiate '):]) ctx = gssapi.SecurityContext(usage='accept') ctx.step(token) user = str(ctx.initiator_name) except Exception as e: self.send_response(401) self.send_header('WWW-Authenticate', 'Negotiate') self.end_headers() return self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() print(f"User {user} authenticated over Kerberos.") self.wfile.write(f"Hello, {user}\n".encode()) if __name__ == '__main__': HTTPServer(('', 80), KerberosHandler).serve_forever() ``` > *\<your web service here\>* ![[Pasted image 20251207191458.png]] >![[Pasted image 20251207191542.png]] On that note, unconstrained delegation abuse also works as expected on the surface (`samba-tool delegation for-any-service 'virthost on`): >![[Pasted image 20251207195445.png]] >![[Pasted image 20251207195458.png]] > **note:** making it work requires changing `addspn.py/dnstool.py` to work over simple binds and applying the patch to not advertize NTLM in the relay server. However, low-privileged users and computer objects cannot easily add SPNs. The normally-abused `msDS-AdditionalDnsHostName` attribute seemingly cannot be modified. An SPN pointing to a short name of the same computer account would still work (the FQDN would not), though, but abusing that would require DNS shenanigans, at which point a new SPN is probably not required anyway. # post-exploitation A lot of Samba post-exploitation boils down to KDC and LDAP LDB post-exploitation, which is partly covered in [[freeipa-postexploitation]] and partly obvious. However, since Samba DC is designed to sync and interface with MSAD, DCSync is also an opportunity. I won't rewrite a good article, so the topic of remote credential extraction is covered here: https://medium.com/@offsecdeer/how-to-dcsync-a-samba-dc-and-maybe-openldap-448c3914b17b