Introducing RubySMB: The Protocol Library Nobody Else Wanted To Write

Blog Post created by thelightcosine Employee on Apr 3, 2017

The Server Message Block (SMB) protocol family is arguably one of the most important network protocols to be conversant in as a security professional. It carries the capability for File and Print Sharing, remote process execution, and an entire system of Named Pipes that serve as access points to any number of services running on a machine, such as Microsoft SQL Server. For users of Metasploit, they will know SMB as the protocol used for PSExec, a remote code execution module that can turn any Administrator credentials into a session on the box. It is also the protocol that has played host to several of the most high-profile vulnerabilities, such MS08-067 (the vulnerability used by the Conficker Worm), and MS03-039 (the vulnerability used by the Blaster Worm).


Additionally, the File and Print Sharing services mean that SMB is the default means of sharing files in a Windows environment. Whenever you create a “network share” in Windows, it is being served up over SMB. I can tell you, from personal experience, that network shares are a gold mine during a penetration test.


Now, armed with some understanding of why this protocol is so important, we must dive into how Metasploit handles SMB. Metasploit’s current “implementation” of SMB has been an ad hoc reverse-engineered effort that started small and was added to with each major SMB vulnerability we wrote modules to target, which turned out to be rather a lot. The implementation is extremely rough, and only supports SMB1. There are some very good reasons for why this is the case.


SMB is complex

SMB, by its very nature is complex. It is a binary protocol, opposed to a text protocol such as HTTP, and is only readable by computers that have been trained to do so. It also has a wide array of capabilities, some of which are interdependent upon each other.


Earlier I called SMB a protocol family, and that’s because it is not really just one protocol, nor is it a group of protocols operating at various layers as is the case with something like RDP. It is a Frankenstein’s Monster of efforts by different groups including IBM, Intel, 3COM, and Microsoft. The formative years of SMB were not governed by a single driving design, and it can be seen in the protocol. What’s worse, is that for a long time there was no available developer documentation for the protocol specification. Anecdotally I have heard the story that Microsoft themselves had lost any documentations on the spec, and had to reverse engineer the protocol to provide said documentation.


This left Metasploit developers and contributors in the position of only being able to look at packet captures to reproduce what they see going on.


The rise of SMB2 and SMB3 and the decline of Metasploit’s SMB

After years of dealing with SMB/CIFS Microsoft finally designed a new protocol, SMB2. They rolled this out for the first time in Windows Vista, and it has since become standard in every Windows OS. SMB2 is a more elegant and more streamlined version of the SMB protocol. Unfortunately, none of Metasploit’s existing code supported the new protocol. For a while this was fine as SMB1 was still enabled by default in the Windows OSes. Over the past few years it has become an increasingly common practice however, to disable SMB1 and only allow SMB2.


This change meant that Metasploit could no longer talk to those boxes. Modules from information gathering, to brute forcing, to exploits all suddenly became ineffective against these boxes. On top of this, Metasploit’s ad hoc implementation of SMB1/CIFS had become very recognizable due to its particular idiosyncrasies. IDS/IPS vendors began to differentiate between Metasploit’s SMB traffic and that of a legitimate SMB client. All of this culminated in our SMB support becoming less and less useful as time went on.


RubySMB to the rescue

We on the Metasploit team knew something had to be done about our aging SMB code. We weighed several options including trying to clean up the existing code. In the end, we decided to create a new library from scratch. This new library would support both SMB1/CIFS as well as SMB2, and be designed with an eye to coming back and adding the even newer SMB3.


We are pleased to announce that, not only have we been working on this new RubySMB gem, but that we have hit the first milestone in its development. The RubySMB Gem can do full client authentication to a remote server. It can communicate over SMB1 or SMB2, and does multi-protocol negotiation so that it can find the correct dialect to speak invisibly to the user.  It handles Extended Security mode for the old SMB1, and can handle security signing for both versions of the protocol.


The gem has also been integrated into Metasploit Framework for the first time. We recently added a new version of the SMB Bruteforce, auxiliary/scanner/smb/smb2_login. This version of the SMB LoginScanner module behaves essentially like the original, except that it seamlessly handles both versions of the protocol, and security signing all without any user configuration. It currently does not support the admin privilege check, which is why it has not replaced the original smb_login module.


This represents Metasploit’s first steps into future proofing our support for the SMB Protocol family.


The Future of RubySMB

We still have a lot of work to do on the RubySMB project, and a lot of important milestones to hit. In the short term, we are shooting for the following goals:


  • In the Gem:
    • Support for Listing, Reading, and Writing Files
    • Support for named pipes
    • Simple SMB File Share Server
  • In Framework:
    • Converting smb_version information gathering module to use the new gem
    • Converting PSExec to use the new gem
    • Building in support for the simple file server that will allow modules to define resources on the server and set callbacks for when something requests those resources, much like how the Rex HTTPServer works today.
    • Look at adding SMB Named Pipe transports for Meterpreter payloads


In the longer term we have several other goals we hope to accomplish with this project:

  • Adding Support for SMB3
  • Adding SMB3 protocol level encryption (potential IDS/IPS evasion capabilities)
  • Begin work on a similar project for DCERPC to integrate with this gem


Creating protocol libraries at this level is not a simple or easy task, but the results will be rewarding for all members of the Metasploit Community. We will be able to not only update compatibility for our existing SMB-based features, but begin expanding those capabilities. If you are interested in joining in on this effort, please check out our starting wiki page for the project.


- David “thelightcosine” Maloney