Skip navigation
All Places > Metasploit > Blog > 2009 > October
2009

Joining the Team

Posted by rapid7-admin Oct 21, 2009

Originally Posted by egypt

 

 

When I started learning about programming I thought, "Man, wouldn't it be awesome if I could get somebody to pay me to write code all day?"  Not too long after that I started learning about security.  Then I thought, "Man, wouldn't it be awesome if I could get somebody to pay me to break things all day?"  As luck would have it, I've now found someone to pay me to write code that breaks things.

 

Today, Rapid7 announced its acquisition of Metasploit.  Along with that acquisition, my weekend hobbyist role will soon become full-time employment as Core Developer.  From the perspective of the framework, it means there will be a dedicated, fully funded development team where there used to be just a few volunteers hacking away on the weekends.  It means there will be more time to do proper quality assurance.  It means fewer bugs.  More exploits.  Faster development.  It means a bit more organization and planning; decisions based on long term goals and design, not just what's shiny to me right now.  Code won't have to languish waiting for updates or rewrites for lack of a long weekend.  New features won't have to sit patiently in comments or tickets waiting to be implemented because we're all busy at our day jobs. Now, Metasploit is our day job.

 

From a user's perspective Metasploit will still be free.  All of the important bits are going to remain open-source, a point that was very important to me, since its open nature is what drew me to Metasploit in the first place and what, I believe, attracts many of its users and contributors.  It is likely that the license will be 3-clause BSD for all (or nearly all) of the code I write.  Free code is happy code.

 

From my perspective, it's going to be awesome.

Metasploit Rising

Posted by rapid7-admin Oct 21, 2009

I created the Metasploit Project over six years ago as way to publish security information to those who needed it most, the security professionals in the field. The project has evolved from a personal web site, to a collaborative effort with a small group of friends, and finally to the robust community-driven project that we know today. This progress came at the cost of the evenings, lunch hours, early mornings, and weekends of countless contributors who donate their time for the benefit of the community. The volunteer nature of the project has lead to innovation in niche areas and has driven research across a wide range of topics.

 

During this time, Metasploit has always been a hobby; something I enjoy working on when my current job isn't monopolizing my free time. The project has always taken a back seat to the demands of day to day employment and this has created a bottleneck in terms of project growth. We now receive far more contributions, feature requests, and bug reports that the core team can keep up with in their free time. The project has come a long way, but nearly all patches, module submissions, and new features are still processed by only a few people. The time it takes for us to cut a release has increased as well; it has been almost a year since the last stable version of the Framework was released, with hundreds of new features in the development tree, but no time to test them well enough to consider them ready for a stable release.

 

All of this is changing. I am excited to announce that Metasploit has been

acquired by Rapid7

and that myself and Egypt will be working on Metasploit as our full-time jobs. I will be taking on the role of Chief Security Officer of Rapid7 as well as Chief Architect of Metasploit. Egypt will join as our first core developer. In addition, we are hiring an exploit developer, user interface designer, and mostly importantly, a QA engineer, all dedicated to making the Metasploit Framework the best penetration testing product available. Rapid7 has committed to keeping the project open source, with no plans to change the license or the community development model. What will be changing is how fast we add new exploits, integrate new features, and release new versions. By backing Metasploit, Rapid7 will benefit from the extensive security research experience of the Metasploit team and use this to enhance its existing NeXpose product line.

 

Rapid7 was the right company for Metasploit for a number of reasons. First and foremost, they understand the value of the community have seen the benefits that funding a project like Metasploit can provide since our first conversation. Second, the management team at Rapid7 is made up of some brilliant folks. They may not be exploit developers, but they understand business and how to make a marriage with Metasploit increase their own bottom line without destroying the value of project in the process. Third, Rapid7 has an amazing technical staff and a solid vulnerability management product. There are only a few companies in the world that understand how much work is involved in doing vulnerability assessments right, and this team has been doing it for over 9 years. Lastly, Rapid7 has an enormous QA lab, with the ability to perform regression testing across a massive array of operating systems and patch levels. The combination of their staff and technical resources will allow the Metasploit Framework to make a huge leap ahead in the coming months.

 

To the members of the community who have been contributing their time and mindshare, thank you! The best way to show our dedication is by demonstrating that we mean what we say. In the next six months, we will hammering out Metasploit Framework releases that benefit from the dedicated resources provided by Rapid7 and illustrate exactly what we can do now that we can fully focus on the framework. If you have any questions or comments, you can email me at hdm[at]metasploit.com or join our IRC channel (#metasploit on irc.freenode.net). The Metasploit web site has been updated to include a FAQ about the acquisition, as well as links to the announcement on the Rapid7 web site as well.

 

Sincerely,

 

HD Moore

Originally Posted by hdm

 

 

This a guest blog entry written by Piotr Bania .

 

Disclaimer
The author takes no responsibility for any actions taken using the provided information or code. This article is copyright (C) 2009 Piotr Bania, all rights reserved. Any duplication of code or text provided here in electronic or printed publications is not permitted without the author's agreement.

 

Prologue
About a month ago Laurent Gaffié released an advisory in which he described the SMB 2.0 NEGOTIATE PROTOCOL REQUEST Remote BSoD vulnerability. Fortunately for some and unfortunately for others this vulnerability is remotely exploitable. At the time of writing, there are only two exploits available for this flaw, one written by Immunity Inc., which only provides a copy to paying customers, and one written by Stephen Fewer and included in the Metasploit Framework.  Unfortunately, Stephen Fewer's exploit seems to be unreliable against physical machines (vs VMs) due to a hardcoded address from the BIOS/HAL memory region (0xFFD00D09) which must be initiated to "POP ESI; RET". In this article I am going to describe a method for exploiting this vulnerability that only requires a stable absolute memory address (filled with NULL bytes).

 

Step One. Where to?
First, lets take a look at the vulnerable code, we will assume a Windows Vista SP2 operating system and SRV2.SYS version 6.0.6002.18005:

vuln_code.png

At offset 0x000056B3 EAX is initialized with a word from [ESI+0Ch]. The [ESI+0Ch] location points to the SMB2 packet, giving the attacker complete control on the lower 16 bits of the EAX register (AX).  In the next instruction (0x000056B7) our controlled EAX is used as an array index. There is only one safety check on this value that verifies that *(DWORD*)ValidateRoutines[EAX*4] is not NULL. This is the cause of this vulnerability, since there is no check to determine if the EAX value (array index) exceeds the number of elements in the ValidateRoutines array.  Further in the code, the location pointed to by ValidateRoutines[EAX*4] is executed by the "call EAX" instruction (0x000056CA).

 

In summary, we can redirect execution to any location (as long as it is not null) from ValidateRoutines to (ValidateRoutines + (0xFFFF * 4)). This gives us about 2^16 potential memory locations to check. this is not completely accurate, since we cannot assume that any memory location outside the SRV2.SYS address space will be consistent across mul;tiple machines (device driver ImageBase addresses change on every boot). To make my life less miserable, I wrote a little program that dumps the SRV2.SYS address space from system memory, then disassembles every potential region that can be reached through ValidateRoutines[INDEX*4]. Additionally, I set some boundaries that ensure we are operating only on the SRV2.SYS address space. Here are the results I have obtained:

 

 

 

I must confess that I was confused at first, not because of the results obtained, but due to the Immunity exploit video that was released. In this video, they stated that exploitation is based on on time values. This led me to focus on any function that manipulated time values.  I noticed that the SrvBalanceCredits function (index 0x31, 0x4b7) can be used to modify the CurrentTime structure (0x0001D320), which can then be  used again later as the memory address for a "call EAX". However, since KeQuerySystemTime returns the time as a count of 100-nanosecond intervals since January 1, 1601 and the system time is typically updated approximately every ten milliseconds, it is very unlikely to use this as reliable offset. An alternative would be to use the BootTime variable and reboot the machine to reset it, however my results were still not satisfying (the BootTime and CurrentTime values are both returned as part of a normal SMB2 NEGOTIATE_RESPONSE packet, so it is possible to query these remotely).

 

I decided that the time approach was a dead end and that it was time to start over from scratch and never watch Immunity videos again :-) After leaving the time approach I decided to look into the functions that would corrupt the stack by using a accepting a different number of arguments than the original function. The following indexes showed the most promise: 0x217 (srv2!SrvSnapShotScavengerTimer), 0x237 (srv2!SrvScavengerTimer), 0x1e3 (srv2!SrvScavengeDurableHandlesTimer), and 0x1bb (srv2!SrvProcessOplockBreakTimer). Stephen Fewer's exploit uses the 0x217 (srv2!SrvSnapShotScavengerTimer) as a index value. All four of those indexes have something in common:

ret10_routines.png

Each of those functions ends with a "ret 10h", indicating the function expects four arguments, and will adjust the stack to account for those when it returns. To see how this helps us, lets take one more look at the vulnerable code:

vuln_code_end.png

As you can see, the procedure pointed to by EAX is called (0x000056CA) with one argument on the stack (see 0x000056C9 - PUSH EBX). SRV2.SYS assumes that the called function is using the stdcall convention (callee is responsible for cleanup of the stack). Since we forced EAX to point to one of the "ret 10" functions, the callee will clean the stack, but adjust it for for four parameters, not just the single parameter that was passed in (0x10=16 -> 16/4=4). How does this influence the execution flow? Take a look:my_stack.png

 

The first "d ESP" command shows the stack before the "CALL EAX" (where EAX points to on of the "ret 10" procedures). The second "d ESP" shows the stack after the "ret 10" function was executed. The important part is when the "POP ESI" (0x000056D0) instruction is executed, it will be exchanged with the pointer to our SMB packet (see "d poi(esp+4)") -- this will bring us some serious kudos later. Additionally, even if at the moment the stack pointer is invalid (because we haxored it) it will be reinitialized correctly by the instruction at 0x000056D9. As you probably know, the LEAVE instruction (also called High Level Procedure Exit), sets the ESP to EBP and pops EBP. In other words, despite the fact we have mangled the stack and forced ESI to point to our packed data, ESP will be "good" again. That is important, since otherwise it would cause an exception when executing the "ret 4".  Lets assume we used 0x237 (srv2!SrvScavengerTimer) as an index, after few instructions we land here:

landing1.png

As you can see, ESI still points to our packet. The instruction at 0x0001FAB1 (setnl cl) is also a key factor in the way I have chosen to exploit this, since the setnl result depends on the value our called "faked function", which is why a function like 0x1e3 (srv2!SrvScavengeDurableHandlesTimer) will not work), since the CL register must be 1 before the PUSH ecx is executed. This will be discussed later.

 

Step Two. Mum I want a Trampoline!
In this step we will create a trampoline that will transfer the code execution to the shellcode. Stephen's exploit code depended on a static "pop esi; ret" address that made it unreliable on many non-virtual machines. With my technique, we just need to find a stable 4-byte memory region filled with NULL bytes (or any other predictable value) and we will force the SMB code to build a trampoline for us, using just 351 packets. After some digging I found following piece of code interesting (located in the end of _SrvProcPartialCompleteCompoundedRequest@8 function):

go_tramp.png

The instruction located at 0x0002115F is used to automically increase the value pointed to by the EAX register by ECX (=1). This is actually a variation of the InterlockedExchangeAdd function.  The key point here is that the EAX register value is controlled by the SMB packet and ECX is set to 1. Lets review how the EBX register value is computed:

ebx_compute.png

In the code above, you can that EBX is equal to the [packet+0xAC] field. This means that the memory region that is be increased by the xadd instruction is equal to [packet+0xAC]+0xBC (this offset changes among the different Vista versions). This provides us with full control of the area that will be increased by each request. So what we are going to do with it? We are going to build a trampoline, dumbass :-)

 

To do that we, must consider:

 

1) We need an absolute memory address that is executable (see DEP) and is filled with constant data (NULLs in our case, however thanks to the xadd arithmetic operation any stable value works). We
need four bytes of NULLs at the address and an additional three bytes before it to handle overlapping writes to reduce the number of packets required.

 

2) We need to know what value to compute and how many requests it will take to accomplish this.

 

Answers:

 

1) Lets use the same BIOS/HAL region chosen by Stephen's exploit, since the memory here is readable, writeable, and executable. NULL bytes in this region are much easier to find than a POP ESI;RET for sure!

 

2) It seems that the opcode sequence "INC ESI; POP ESI; RET" (0x46 0x5E 0xC3) would be the easiest way to bounce to our shellcode using this as a trampoline. However, writing the value 0x4656C3 with a single increment per require would require us to send 4,609,731 packets. Fortunately, there is a solution that reduces this to just 351 packets -- a much more reasonable number. The trick  is to divide the process into three stages, where each stage is responsible for increasing only one byte. For example, we send 0x46 packets to increment address+0, 0x65 packets to increment address+1, and 0xC3 packets to increment loc+2.

 

Step Three. Code Execution
Now that the trampoline is ready we just need to jump to it, here is the code responsible for that:

exec_code.png

EAX (call desitnation address) is fully controlled by the value from the SMB packet (ESI+168h). This offset changes does change between different Vista versions. Here's the general schema of my attack:

algo.png

 

 


That is all for now, expect to see an updated Metasploit module in the near future that takes advantage of this technique.

Filter Blog

By date: By tag: