Detecting MS12-20 Vulnerability with Nmap

Update 6 PM 4-7-12: PCAPS of Windows Clients

For @dakami:

Windows 2000 Professional Terminal Services Client connecting to a vulnerable Windows 7 RDP Server:

win2k-client-target.pcap Captured on the Win 7 RDP server

win2k-client-attacker.pcap Captured on the Win 2k Terminal Services client


Windows 7 Professional Terminal Services Client connecting to a vulnerable Windows 7 RDP Server:

win7-rdp-client-target.pcap Captured on the Win 7 RDP server

win7-rdp-client-attacker.pcap Captured on the Win 7 Terminal Services client


Windows 2000 Professional Terminal Services Client connecting to a patched Windows 7 RDP Server:

win2k-client-targetp.pcap Captured on the Win 7 RDP server

win2k-client-attackerp.pcap Captured on the Win 2k Terminal Services client


Windows 7 Professional Terminal Services Client connecting to a patched Windows 7 RDP Server:

win7-rdp-client-targetp.pcap Captured on the Win 7 RDP server

win7-rdp-client-attackerp.pcap Captured on the Win 7 Terminal Services client


Update: 4-6-12 Reliable Success!

@dakami asked me to get some packet captures of the scan failing and working, and I finally figured out the problem.

If you run it with a SYN scan, "-sC 3389", it FAILS:

The scan failed to detect the vulnerability, as shown:

The packet captures show the nmap port scan SYN packet receiving a SYN/ACK, as it should, but the SYN packets sent by the ms12-020-rev.nse script are all rejected with RST packets:

Here are the raw packet captures:

case2fail-target.pcap

case2fail-attacker.pcap

But if you run it with a CONNECT scan "-sT 3389", it works, finding the vulnerability reliably:

Here are the raw packet captures:

case2win-target.pcap

case2win-attacker.pcap

Case 3: Patched Machine

I added all the security updates to my target machine, and scanned it again. Now the vulnerability is not detected:

Here are the raw packet captures:

case3-target.pcap

case3-attacker.pcap

Case 4: Removing the Patch

I removed the patch from the target:

And now the scan correctly reports that the target is vulnerable again:

Here are the raw packet captures:

case4-target.pcap

case4-attacker.pcap

Update: 3-28-12 11:14 am: WARNING

A few tweets from @dakami and @ea_foundation on the risks of using this script:

RT @dakami: @sambowne @ea_foundation Does this script safely detect the vuln w/o crashing the box, on multiple OSs?

RT @ea_foundation: @dakami @sambowne no one reported that it crashed the machine, but i would recommend torrough testing, before running it on production sys

RT @dakami: @sambowne @ea_foundation Sigh. That script is not actually safe. It's a "best effort prevent a BSoD".

RT @dakami: @ea_foundation @sambowne You basically create the vulnerable state and then hopefully close it.

RT @dakami: @ea_foundation @sambowne Is *anything* else before that request correlated with post-patch? That second message from RDP is a doozy...

Update: 3-28-12 10:42 am: Success (sort of)

I got a DM on Twitter from @ea_foundation with a revised script, and it works!

Here is the script correctly detecting a vulnerable Windows 7 target from Backtrack 5 R1:

@ea_foundation has given permission to post the script here!

I downloaded the script from this link:

http://pastie.org/private/kmp5xvhwmpvjkqkahtwq

In case that link is down, you can download my copy from this link:

ms12-020-rev.nse

However, when I tried it again, it failed the same way (broken pipe). I tried from Windows with the new script and it also failed.

So this is very unreliable, at least with VMware Fusion virtual machines. The problem may well be VMware network adapters--they have caused many problems for me in the past.

Here is a common sort of failure: the Windows target rejects all SYN packets after the first one, replying with RST packets, which thwarts the ms12-010 test.

Strangely, it always accepts nmap's port scan SYN, but often rejects the SYNs from the script. There must be some difference between them.

Only Failures Below This Point

I tried this using Nmap on Mac OS X, Windows 7, and Linux. It failed the same way every time.

Update: 5:14 PM Tuesday: Without VMware

I used an OS X scanner, and a Windows 8 Developer Preview target with RDP on.

I got this result on a patched target machine--the script correctly doesn't report the existence of the vulnerability.

I went into Control Panel and removed the MS12-020 patch.

But I still get the same result:

Update 1:54 PM Tuesday

I tested three different Windows VMs as targets, two Win 7 Pro and one Win XP SP3 Pro with the same result: the nmap script fails to report the vulnerability.

@DustySTS recommended capturing the packets, which is a good idea, so here's what I found:

Real RDP Connection

This capture is a Windows XP SP3 client connecting to my Win 7 Pro RDP server, and getting to the logon screen successfully. An "X.224 Connection Request" packet gets a reply of ACK, and then "X.224 Connection Confirm":

Here is the "X.224 Connection Request" packet that opens the RDP session in detail:

Here is the "X.224 Connection Request" packet nmap sends, which provokes a RST from the Windows RDP server, which I think is the reason it fails:

It looks to me like the nmap script is not properly constructing that "X.224 Connection Request" packet.

The difference is at layer 4. The "X.224 Connection Request" packet from nmap contains 12 bytes of TCP Options:

In the real RDP connection request from Windows, those options are absent.

I think this is a bug in nmap. The script specifies the layer 7 payload, but does not appear to deliberately add TCP options to the request packet.

Update: 1:05 PM Tuesday

I got this tip:
RT @DustySTS: @sambowne try explicitly specifying the port. E.g: nmap -p 3389 --script=rdp-ms12-020.nse. It's the only way I got it to work.

But it still doesn't work.

Here's what I see:

root@bt:/usr/local/share/nmap/scripts# nmap -p 3389 -sC --script=rdp-ms12-020.nse -vv --script-trace 192.168.198.129

Starting Nmap 5.61TEST4 ( http://nmap.org ) at 2012-03-27 13:03 PDT
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating ARP Ping Scan at 13:03
Scanning 192.168.198.129 [1 port]
Completed ARP Ping Scan at 13:03, 0.01s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 13:03
Completed Parallel DNS resolution of 1 host. at 13:03, 0.09s elapsed
Initiating SYN Stealth Scan at 13:03
Scanning 192.168.198.129 [1 port]
Discovered open port 3389/tcp on 192.168.198.129
Completed SYN Stealth Scan at 13:03, 0.00s elapsed (1 total ports)
NSE: Script scanning 192.168.198.129.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 13:03
NSOCK (0.1790s) TCP connection requested to 192.168.198.129:3389 (IOD #1) EID 8
NSOCK (0.1790s) Callback: CONNECT ERROR [Connection refused (111)] for EID 8 [192.168.198.129:3389]
NSE: TCP 192.168.198.136:51678 > 192.168.198.129:3389 | CONNECT
NSE: TCP 192.168.198.136:51678 > 192.168.198.129:3389 | 00000000: 03 00 00 13 0e e0 00 00 00 00 00 01 00 08 00 00                 
00000010: 00 00 00                                           

NSOCK (0.1790s) Write request for 19 bytes to IOD #1 EID 19 [192.168.198.129:3389]: ...................
NSOCK (0.1800s) Callback: WRITE ERROR [Broken pipe (32)] for EID 19 [192.168.198.129:3389]
NSE: TCP 192.168.198.136:51678 > 192.168.198.129:3389 | SEND
NSOCK (0.1800s) Read request for 0 bytes from IOD #1 [192.168.198.129:3389] EID 26
NSOCK (0.1800s) Callback: READ EOF for EID 26 [192.168.198.129:3389]
NSE: TCP 192.168.198.136:51678 > 192.168.198.129:3389 | CLOSE
Completed NSE at 13:03, 0.00s elapsed
Nmap scan report for 192.168.198.129
Host is up (0.00040s latency).
Scanned at 2012-03-27 13:03:43 PDT for 0s
PORT     STATE SERVICE
3389/tcp open  ms-term-serv
MAC Address: 00:0C:29:8A:55:E8 (VMware)

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Read data files from: /usr/local/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.20 seconds
           Raw packets sent: 2 (72B) | Rcvd: 2 (72B)
root@bt:/usr/local/share/nmap/scripts# 

In each case, I needed to update to the latest version of nmap first.

Then I downloaded this file to the nmap scripts folder:

http://seclists.org/nmap-dev/2012/q1/att-662/rdp-ms12-020.nse

Then I executed this command to update the database:

nmap --script-updatedb

I executed this command to scan my vulnerable target:

nmap -sC --script rdp-ms12-020.nse -vv 192.168.198.129

The script runs, but no output appears, as shown below:

But it really is vulnerable. Here is the BSoD test:

If anyone can see what I am doing wrong, please tell me on Twitter @sambowne.

Thanks!

Sam Bowne 6:25 pm 4-7-12