Wednesday, January 21, 2015

MC-SQLR Amplification: MS SQL Server Resolution Service enables reflected DDoS with 440x amplification

Summary

The MS SQL Server Resolution Service allows a client to interrogate a server hosting a SQL Server installation and to receive back detailed information about the SQL Server instances available on the server.  The client sends a one-byte request to the server, and the server responds with a variable-length message containing instance names, versions, and other connection details. 

This service can be exploited to conduct reflected DDoS attacks.  Because the client request is very small and the server response is potentially large, an attacker can gain significant amplification.  A large number of MS SQL Servers are internet-facing, providing ample reflection surfaces for attackers.

This technique was observed in the wild in December 2014, when it was employed as part of a DDoS attack against the website of the City of Columbia, Missouri.  In this incident, the technique resulted in an average incoming response of approximately 440 bytes.  Assuming a one-byte request size per response, the attack yielded an amplification factor of 440x.

Details

Beginning at about 11:00 PM on Christmas Eve 2014, the website of the City of Columbia, Missouri was hit by a DDoS attack.  Over the course of the next 24 hours, the attacker, going by the handle Bitcoin Baron, used a number of the attack techniques we've all grown accustomed to seeing: NTP amplification, SSDP amplification, and a good old fashioned SYN Flood.  One of the attack techniques hurled at the city, though, was a little out of the ordinary.

Three weeks after the attack, Danny Paul, IT Manager for the City, was kind enough to host an after-action meeting for local information security pros where he described the attack and the City's response to it.  Mr. Paul provided a wealth of information about the attack, including excerpts of packet captures his team collected during their response.  This was an excellent opportunity to learn from this incident and to share thoughts on how to prepare for attacks like this.

During the debriefing, Mr. Paul described one phase of the attack that I found particularly interesting.  At one point in the night, the incoming packets were on port 1434/UDP and the content of the packets contained text that seemed to describe SQL Server instances. Mr. Paul's team captured 10,000 packets during this period of the attack.  In that sample, there were 3,388 originating IP addresses, and the average packet size was 483 bytes (average data length = 441 bytes).  Mr. Paul said that his team hadn't seen anything like it before, and that some of the outside help he brought in during the response was similarly unfamiliar with the technique.

After the debriefing, I asked Mr. Paul if he would be able to share some of the packet captures with me so I could dig into them a little.  He graciously agreed, and I started looking into the issue.

Here are a few of the packets Mr. Paul's team captured:

Note the port (1434/UDP, MSSQL Monitor) and the range of packet lengths. 

And here is a detailed view of one of the packets, with the data view expanded:

When the data in the packet is made a little easier to read, it looks about like this (dashes removed and line breaks added for readability):

ServerName;WIN3H1QPRPTOAS;InstanceName;MSSQLSERVER;IsClustered;No;Version;9.00.5000.00;tcp;1433;np;\\WIN3H1QPRPTOAS\pipe\sql\query;;

ServerName;WIN3H1QPRPTOAS;InstanceName;SQLEXPRESS;IsClustered;No;Version;10.50.4000.0;;

ServerName;WIN3H1QPRPTOAS;InstanceName;MSSQLSERVER2008;IsClustered;No;Version;10.50.1600.1;tcp;50110;np;\\WIN3H1QPRPTOAS\pipe\MSSQL$MSSQLSERVER2008\sql\query;;

ServerName;WIN3H1QPRPTOAS;InstanceName;MSSQLSERVER2012;IsClustered;No;Version;11.0.2100.60;tcp;50175;np;\\WIN3H1QPRPTOAS\pipe\MSSQL$MSSQLSERVER2012\sql\query;;


After some research, I learned that this output is typical of the SQL Server Resolution Service.  The protocol backing this service is the SQL Server Resolution Protocol, or MC-SQLR.  MC-SQLR is described in detail on the Microsoft site here.

Every version of SQL Server since SQL Server 2000 has included the Resolution Service.  Once SQL Server was able to host multiple database instances, clients needed a way to get basic information about the instances on a server before initiating a connection request.  The solution was MC-SQLR.

As described in the protocol, clients interested in connecting to a server running SQL Server send a CLNT_BCAST_EX message, which is a packet with a single byte, the value of which must be 0x02 (see here).  The server responds to all client requests with SVR_RESP, which can contain up to 1,024 bytes and which varies depending on the type of request (see here).  The SVR_RESP sent in response to CLNT_BCAST_EX follows the format shown above.

Tools like NMAP SQL scanning and SQLPing rely on MC-SQLR.  MC-SQLR is also what makes it possible for Shodan to list the server names, instance names, and version information of over 700,000 exposed SQL Servers (as of this writing).  You can also run a Python script to demonstrate this functionality (example below in Python 3.4):

     import socket
     HOST_IP = "192.168.1.1"
     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     sock.connect((HOST_IP, 1434))
     qry = bytes.fromhex('02')
     sock.send(qry)
     ans = sock.recv(5120)

     print(ans)

Armed with a botnet and a list of SQL Servers exposed to the internet, an attacker can direct his bots to start sending the servers packets with a spoofed source IP and with a single 0x02 as data, and let the servers flood the victim with hundreds of bytes of details about their resident SQL Server instances.  This appears to have been the method used by Bitcoin Baron in his attack on the City of Columbia.  Because the size of the response is variable depending on the number of SQL instances on the server, the attacker would not be able to predict the amplification factor precisely.  However, if the attack on the City of Columbia is a fair sample, then an MC-SQLR reflection attack would be expected to yield an amplification factor of around 440x on average.

Update: I received some feedback that my amplification factor calculation is misleading because it doesn't take into account the header size.  With the headers included, the amplification is more like 22x. This is a fair point, and honestly I'm not sure what the "official" method of expressing DDoS amplification factor is.  So, I'll leave the post as-is with this note. 

Conclusion

The DDoS attack aimed at the City of Columbia beginning December 24, 2014 provided an example of an attack technique that is not well described in the information security literature.  In this incident, the attacker exploited a feature of the MC-SQLR protocol to flood a target with SQL Server Resolution Service replies, achieving an amplification of approximately 440x. 

The behavior exploited in this reflection attack is a key component of the functioning of MS SQL Server 2000 and later.  Disabling this service is likely not to be an option.  It may be possible to limit the address space to which a server will respond to CLNT_BCAST_EX messages.  Most of all, though, owners of SQL Servers should question whether their servers should really be exposed to the internet in the first place. I admit it's been a while since I've managed a SQL Server, but I do struggle to come up with many scenarios in which exposing one directly to the internet would be the preferred option. 

Microsoft's MC-SQLR protocol documentation has a section titled "Security Considerations for Implementers".  The full text of that section is as follows:  "No security considerations are associated with the SQL Server Resolution Protocol".  The authors of the protocol documentation might consider a revision of that section.