Skip navigation
All Places > Metasploit > Blog > Authors William Webb


5 Posts authored by: William Webb Employee
William Webb

Metasploit Weekly Wrapup

Posted by William Webb Employee Mar 10, 2017


The last couple of weeks in the infosec world have appeared busier, and buzzier, than most others.  It seems almost futile to pry everyone away from the current drama--that being the bombshell revelation that intelligence agencies collect intelligence--long enough to have them read our dev blog.  Regardless, we've been busy ourselves.  And if you're the least bit like me, you could probably use a quick respite from the cacophony.  Keeping up with all the noise is enough to make anyone feel like Ricky:



This is Ricky.  Don't be like Ricky.


Features and Fixes


There are few things worse than getting a Meterpreter session on a host, only to find yourself unable to download large files that you might be interested in because your connection is spotty.  Unfortunately, download timeouts in such sessions have been a reality for as long as Meterpreter has been around.  Thankfully, a recent patch by Pearce Barry goes a long way to alleviate said issues by providing more fault tolerance to adverse network conditions.  I personally tested this on over 1GB of data across a network link with 20% packet loss, and while it felt like I was using CompuServe once again, it delivered the goods.


Other issues addressed include a fix by mrjefftang for an issue in BrowserExploitServer.  Instead of delivering the obfuscated Javascript from JSObfu, raw Javascript was mistakenly being sent.  Good catch.  Also, a major rewrite of the reverse_shell_jcl payload was submitted by bigendiansmalls and merged.  Functionally, it behaves the same as the previous iteration; however, the actual code is much cleaner and easier to maintain.  So if you haven't tried your hand at IBM mainframe hacking, it's now even easier to jump right in.


A Requiem for Meterpreter Scripts


We obliterated what we believe to be the last vestige of Meterpreter scripts in framework.  In their time, an exploit module may have used migrate -f to automatically migrate the session to another process on the target.  This is now handled by 'post/windows/manage/priv_migrate', and has been for some time.  The old migrate -f argument set in InitialAutoRunScript was pointed at this new module; however, there's been a few hiccups over the last few weeks.  That's been corrected, and all should now be right with Windows process migration.  Note: This doesn't mean that your personal custom scripts will stop working. Scripts are still a handy way to bust out a prototype to get stuff done quickly without needing to care about the reliability requirements of a post module.


In other assorted bugfix news, Brendan Watters resolved an issue that occurred when sorting tables from auxiliary modules when the results contained both IPv4 and IPv6 addresses.  We also updated Metasploit to use the latest Nexpose client libraries, so it's now able to validate that it's communicating with a trusted Nexpose instance via preconfigured SSL certificates.




One final item in this release was the addition of a basic Dockerfile and Docker Compose configuration.  With support for Docker, you can now isolate your Metasploit instances, and it allows you to both quickly and easily setup new testing and development environments.  Plans are in the works to publish the container to, and users will be able to deploy new installations of Metasploit Framework just as easily as they would other applications using Docker.


New Modules


Exploit modules (5 new)

Auxiliary and post modules (2 new)


Get it


As always, you can update to the latest Metasploit Framework with msfupdate and you can get more details on the changes since the last blog post from GitHub:



To install fresh, check out the open-source-only Nightly Installers, or the binary installers which also include the commercial editions.


That's all for now.  Stay tuned, as we have several interesting projects in the works that should be debuting in the coming weeks.

Merry HaXmas to you! Each year we mark the 12 Days of HaXmas with 12 blog posts on hacking-related topics and roundups from the year. This year, we’re highlighting some of the “gifts” we want to give back to the community. And while these gifts may not come wrapped with a bow, we hope you enjoy them.




Towards the end of November, the Tor community was shaken up by the revelation of an previously unknown vulnerability being actively exploited against pedo^H^H^H^H Tor Browser users. Some further drama unfolded regarding who the source for the exploit may be, and I received questions from several reporters who wanted every single detail I could give them. While I did not participate in commenting at the time, I'll say everything I will ever say about it now:


- Yes, I'm aware of a very similar exploit which targeted Firefox

- No, I didn't write it


Largely lost among all the noise are the nuances of the vulnerability and the exploit itself, which I know the author put his heart and soul into. If anonymous entrants are ever retroactively awarded Pwnies, I'd like to put his unsaid name into the hat. In this part of the 12 Days of HaXmas, I wanted to offer a high level overview to some of the more interesting parts of both the vulnerability--which in my opinion doesn't fit cleanly into any classic category--and the exploit. I'm not going to dive into all of the gory details for a couple of reasons. Firstly, timing. Had this been leaked earlier in the year, I might have been able to do the analysis part some justice. Second, while verbose technical expositions certainly have their place, a blog is not the right spot. The content might take take another 12 days to cover, and for those seeking to learn from it, I feel your own analysis of the exploit coupled with lots of dirty work in a debugger would be your best option. In that case, hopefully this can offer you some direction along the way.


The Discovery


It would be remiss of me if I didn't begin by pointing out that no fuzzer was used in the discovery of this vulnerability. The only tools employed were the Woboq Code Browser (Woboq Code Browser - Explore C++ code on the web), WinDBG, a sharp mind, and exhaustive effort. The era of low-hanging fruit is largely over in my opinion. Don't be the gorilla, be the lemur, climb that tree.


The Vulnerability


In the following snippet from nsSMILTimeContainer.cpp, the pointer p is initialized to the beginning of the mMilestoneEntries array.


  // Called when the container time is changed with respect to the document
  // time. When this happens time dependencies in other time containers need to
  // re-resolve their times because begin and end times are stored in container
  // time.
  // To get the list of timed elements with dependencies we simply re-use the
  // milestone elements. This is because any timed element with dependents and
  // with significant transitions yet to fire should have their next milestone
  // registered. Other timed elements don't matter.
  const MilestoneEntry* p = mMilestoneEntries.Elements();
  uint32_t queueLength = mMilestoneEntries.Length();
  while (p < mMilestoneEntries.Elements() + mMilestoneEntries.Length()) {
    mozilla::dom::SVGAnimationElement* elem = p->mTimebase.get();
    MOZ_ASSERT(queueLength == mMilestoneEntries.Length(),
               "Call to HandleContainerTimeChange resulted in a change to the "
               "queue of milestones");


Now, consider the following two examples:


Exhibit One

  Exhibit One
    <svg id='foo'>
        <animate id='A' begin='1s' end='10s' />
        <animate begin='A.end + 5s' dur='15s' />


Exhibit Two

  Exhibit Two
    <svg id='foo'>
        <animate id='A' begin='1s' end='10s' />
    <svg id='bar'>
        <animate begin='A.end + 5s' dur='15s' /> 


In these examples, for each <svg> element that uses <animate>, an nsSMILTimeContainer object is assigned to it in order to perform time book keeping for the animations (<animateTransform> or <animateMotion> will also have the same behavior).  The epoch of each container is the time since the creation of the <svg> element it is assigned to relative to the creation of the page.  The nsSMILTimeContainer organizes each singular event in an animation with an entry for each in the mMilestoneEntries member array. See: nsSMILTimeContainer.h - DXR


In Exhibit One, the mMilestoneEntries array will contain four entries: one for both the beginning and ending of 'A', in addition to another two, one being relative to A's completion (A.end + 5s), and the other demarcating the end of the animation, in this case 30 seconds (A.end + 5s + 15s).


In Exhibit Two we see two independent <svg> elements.  In this example, two separate nsSMILTimeContainer objects will be created, each of course having it's own mMilestoneEntries array.


The exploit makes a single call to the function pauseAnimation(), which in turn triggers entry into the NotifyTimeChange() method.  nsSMILTimeContainer::NotifyTimeChange() proceeds to iterate through all entries in the mMilestoneEntries array, retrieving each individual entries nsSMILTimedElement object, after which it calls the object's HandleContainerTimeChange() method.  After some time, this method will end up making a call to the NotifyChangedInterval() method of of the nsSMILTimedElement object.  In NotifyChangedInterval(), HandleChangedInterval() will be entered if the animation being processed has a milestone relative to another animation.  In Exhibit Two, bar's beginning is relative to the element A belonging to foo, so HandleChangedInterval() will be called.


Within HandleChangedInterval(), a call to nsSMILTimeValueSpec::HandleChangedInstanceTime() will inevitably be made.  This method determines if the current animation element and the one it has a dependency on are contained within the same nsSMILTimeContainer object.  If so, as is the case with Exibit One, the pauseAnimations() function basically lives up to it's name and pauses them.  In Exhibit Two, the animations do not share the same nsSMILTimeContainer object, so additional bookkeeping is required in order to maintain synchronization.  This occurs, with subsequent calls to nsSMILTimedElement::UpdateInstanceTime() and nsSMILTimedElement::UpdateCurrentInterval() being made, and nothing too interesting is to be seen, though we will be revisiting it very shortly.


Deeper down the rabbit hole ...


What about the case of three or more animation elements with relative dependencies? Looking at the exploit, we see four animations split unequally among two containers.  We can modify Exhibit Two using details gleaned from the exploit to arrive at the following example.


Exhibit Three

  Exhibit Three
     var foo = document.getElementById('foo');
    <svg id='foo'>
        <animate id='A' begin='1s' end='5s' />
        <animate id='B' begin='10s' end='C.end' dur='5s' />
    <svg id='bar'>
        <animate id='C' begin='0s' end='A.end/> 


In this example, C's ending is relative to A's end, so we end up in nsSMILTimedElement::UpdateCurrentInterval() again, except that a different branch is followed based on the example's milestones:


if (mElementState == STATE_ACTIVE) {
  // The interval is active so we can't just delete it, instead trim it so
  // that begin==end.
  if (!mCurrentInterval->End()->SameTimeAndBase(*mCurrentInterval->Begin()))
    NotifyChangedInterval(mCurrentInterval, false, true);
  // The transition to the postactive state will take place on the next
  // sample (along with firing end events, clearing intervals etc.)


NotifyChangedInterval() is called to resolve any milestones relative to other animations for C.  Within foo, B has milestones relative to C in bar.  This results in a recursive branch along the same code path which ultimately hits UpdateCurrentInterval(), which in turn sets the state of the nsSMILTimedElement.  mElementState can be one of four possible values:




all of which perfectly describes their own respective meanings.  In Exhibit Three, B's beginning is set to occur after it's ending is set (C.end == A.end == 5s).  Since it will never start, the code marks it as STATUS_POSTACTIVE.  This results in the following code within the UpdateCurrentInterval() method creating a new interval and setting it as current.


if (GetNextInterval(GetPreviousInterval(), mCurrentInterval,
                    beginTime, updatedInterval)) {

  if (mElementState == STATE_POSTACTIVE) {

               "In postactive state but the interval has been set");
    mCurrentInterval = new nsSMILInterval(updatedInterval);
    mElementState = STATE_WAITING;


With this occurring, UpdateCurrentInterval() now makes a call to the RegisterMilestone() method.  This was not the case in Exhibit Two.  With a new interval having been created, the method will add a new entry in the mMilestoneEntries array of containerA's nsSMILTimeContainer object, resulting in the array being freed and reallocated elsewhere, leaving the pointer p from nsSMILTimeContainer::NotifyTimeChange() referencing invalid memory.


Exploitation Overview


Just because the pointer p in NotifyTimeChange() can be forced to point to free memory doesn't mean it's all over.  Firefox overwrites freed memory with 0x5a5a5a5a, which effectively mitigates a lot of classic UaF scenarios.  Secondly, there is no way to allocate memory in the freed region after the milestone array is relocated.  Given these conditions, it's becoming clear that the vulnerability cannot be exploited like a classic use-after-free bug.  If you forced me to categorize it and come up with a new buzz word as people are so apt to in this industry, I might call it a dangling index, or an iterator run-off.  Regardless of silly names, the exploit utilizes some artful trickery to overcome the hurdles inherent in the vulnerability.  As I mentioned at the offset, for the sake of brevity, I'm going to be glossing over a lot of the details with regards to heap determinism (the terms "heap grooming" and "heap massaging" irritate me more than the word "moist").


In the first step, the exploit defragments the heap by spraying 0x80 byte blocks of ArrayBuffers, and another 0x80 of milestone arrays.  Each of the milestone arrays is filled to capacity, and then one additional element is added to each.  This causes the arrays to be reallocated elsewhere, leaving 0x80 holes.  After filling these holes with vulnerable milestone arrays, assuming the <b>last element</b> of the array is the one that triggers the vulnerability, there is now a high probability that the next iteration of the NotifyTimeChange() loop will point within one of the 0x80 ArrayBuffer's that were allocated first.  It is important that the last element be the one to trigger the bug, as otherwise, the memory would be freed and overwritten before an attacker could take advantage of it.


The next obstacle in the process is bypassing the object reference count which, under normal circumstances, would cause the loop to exit.  Even if this were a full technical exposition, I'd leave this part as an exercise to the reader because of reasons.  I invite you to figure it out on your own, because it's both quite clever and critical to the success of the exploit.  Those pesky reasons though.  Seasoned exploitation engineers will see it quickly, and astute students will have truly learned when they unravel the knot.


I'd like to think that this is a good hint, but the only certainty is that it comes up on my 3 AM debugging session playlist a lot


In any case, after the exploit does it's thing, the exit condition of the loop


while (p < mMilestoneEntries.Elements() + mMilestoneEntries.Length()) 


will never be reached, and instead the loop will continue to iterate infinitely.  While this is great news, it also means that an attacker is unable to continue executing code.  The solution to this is one of the more brilliant aspects of this exploit, that being the use of a Javascript worker thread.


  var worker = new Worker('cssbanner.js');


With the worker thread, Javascript can continue being executed while the infinite loop within the main thread keeps spinning.  In fact, it's used to keep tabs on a lot of magical heap manipulation happening in the background, and to selectively exit the loop when need be.  From here, the exploit leverages a series of heap corruptions into a r/w primitive, and bypasses ASLR by obtaining the base address of xul.dll from said corruptions by parsing the files DOS header in memory.  This, along with resolving imports, is the main purpose of the PE(b,a) function in the leaked exploit.


With ASLR defeated, all that lies ahead is defeating Data Execution Prevention, as the Tor browser doesn't feature any sort of sandbox technology.  The exploit handles this beautifully by implementing an automatic ROP chain generation function, which can locate the addresses of required gadgets amongst multiple versions of Firefox/Tor browser.  After constructing the chain, the following shellcode is appended (I've converted all addresses to base 16 for readability and added comments):


ropChain[i++] = 0xc4819090;   // add esp, 800h
ropChain[i++] = 0x0800;
ropChain[i++] = 0x5050c031;   // xor eax, eax ; push eax ; push eax
ropChain[i++] = 0x5b21eb50;   // push eax ; jmp eip+0x23 ; pop ebx
ropChain[i++] = 0xb8505053;   // push ebx ; push eax ; push eax
ropChain[i++] = CreateThread; // mov eax, kernel32!CreateThread
ropChain[i++] = 0xb890d0ff;   // call eax
ropChain[i++] = arrBase + 0x2040;   // mov eax, arrBase+0x2040
ropChain[i++] = 0x5f58208b;   // mov esp, dword ptr [eax] ; pop eax ; pop edi
ropChain[i++] = 0xbe905d58;   // pop eax ; pop ebp
ropChain[i++] = 0xffffff00;   // mov esi, 0xffffff00
ropChain[i++] = 0x000cc2c9;   // ret 0x0c
ropChain[i++] = 0xffffdae8;   // call eip+0x21
ropChain[i++] = 0x909090ff;   // placeholder for payload address


The shellcode basically allocates stack space and makes a call to CreateThread with the address of the final payload, which is obtained via the jmp eip+x023 ; pop ebx line, as it's argument.  It next performs stack cleanup and exits the current infinite NotifyTimeChange() loop to ensure clean process continuation.  At least, it's supposed to.  Initial findings I've read from other researchers seem to indicate that it does not continue cleanly when used against Tor browser.  I need to investigate this myself at the first lull in the holiday festivities.


"I hope I managed to prove that exploiting buffer overflows should be an art"

                                                                                         - Solar Designer


That wraps this up for now. Check back for updates in the future as I continue analysis on it. If you have questions about anything, feel free to ask either here or find me on Twitter @iamwilliamwebb. Happy holidays!




Original leaked exploit: [tor-talk] Javascript exploit

William Webb

Metasploit Weekly Wrapup

Posted by William Webb Employee Aug 12, 2016

Las Vegas 2016 is in The Books


This week's wrap-up actually covers two weeks thanks in large part to the yearly pilgrimage to Las Vegas.  I myself elected not to attend, but I'm told everyone had a great time.  Many on the team are still recuperating, but I'd wager that they all enjoyed seeing you there as well.  Here's to everyone's speedy recovery.




Centreon Web UserAlias Command Execution


Our first new module this go-around exploits a remote command execution vulnerability in Centreon Web via a pre-auth SQL injection.  The bug, originally discovered by Nicolas Chatelain, is detailed in a nice writeup here:  The short version is that they don't escape "\", they call 'echo' via exec(), and very bad things happen.  Luckily the bug was promptly fixed in late 2014 and doesn't affect current versions, but, if for some reason you haven't updated by now, you should probably look into it.


Polycom Command Shell Authorization Bypass


Next, we have a module that managed to slip through the cracks for about 4 years now.  Sorry.  It targets an authorization bypass vulnerability in older firmware releases for the Polycom HDX line of video conferencing endpoints.  The original vulnerability discovery was made by Paul Haas in 2012 and publicly disclosed in January of 2013.  You can check out his original advisory here  Paul released a module at the time, but for some reason it wasn't incorporated into Metasploit Framework.  That's all changed thanks to h00die, who has ported the module to work with newer versions of the framework.  While bugs this old are often not that exciting, it's reasonable to assume that firmware for video equipment may be one of the last things on the mind of many IT administrators when considering a maintenance strategy for their organization, making this one a bit more interesting.


Drupal RESTWS Moule Remote PHP Code Execution


In other SQL injection news, we recently landed a module by Mehmet Ince targeting a remote code execution vulnerability in the Drupal 7.x RESTWS Module.  RESTWS versions below 2.6 in the 2.x series and 1.7 in the 1.x series are affected by the issue.  Despite resulting in arbitrary code execution on any host running the affect module, the bug is fairly simple, and exploitation couldn't be easier thanks to Mehmet's module:




Internet Explorer 11 VBScript Memory Corruption


Last week, some jerk wrote a module for CVE-2016-0189, which exploits a memory corruption vulnerability within Internet EXplorer 11's VBScript engine.  The module was based off the original PoC publicized by Theori, who provided an excellent writeup on their efforts reversing this interesting bug from patches here  In a nutshell, the exploit leverages some logical errors into a write primitive and uses this to enable execution of arbitrary VBScript.  While Internet Explorer 11 on Windows 10 isn't that popular, and VBScript is akin to a Lovecraftian horror that would drive one to insanity should they even contemplate it, vulnerabilities such as these are quite interesting to work with, especially given that mitigations against common browser exploit vectors such as Use-after-Free's continue to improve.



Utility Module Goodness


Our last two modules this week aren't exactly exploits, but they do provide some awesome auxiliary capabilities.  For one, we landed an incredibly useful SMB Delivery module by Andrew Smith and Russel Van Tuyl.  Hosting payloads via an SMB share is sometimes the best option available for delivery depending on the situation.  In the past, authors have had to roll their own SMB functionality into their Metasploit modules.  This module greatly simplifies that process. Finally, Robert Kugler submitted a module that lets one recover the installation password for recent versions of Avira Antivirus.

Back in February, Exodus Intelligence released their blog entry titled "Execute My Packet", which detailed their discovery and exploitation of CVE-2016-1287.  Since then, I've fielded numerous requests for modules and witnessed much discussion generated from it.  From this discussion, I've gathered that many researchers seem to consider the Cisco ASA as an unruly beast, difficult to approach, even harder to tame.  I feel that this is far from the truth, and this article is a response to such notions.


We attempted a module and stopped.  Before explaining why, some disclosures may be in order: while I wasn't on this project with David or Jordan, I actually worked at Exodus Intelligence during the discovery of this vulnerability and the initial exploitation attempts.  Jordan's original exploit, which the public has seen, is impressive in itself, though not portable across ASA's due to loss of heap determinism given variances in device configurations.  I'm positive that given more time, he would have found an information leak necessary to circumvent that.  Unfortunately, both he and I left Exodus before the disclosure of the bug, so I can't comment on the decision to release it in such a state.


Since the initial disclosure, I’ve worked both with him and independently to find a fruitful memory disclosure, but to no avail.  Given enough time, I'm sure it would come about, but the bug is patched.  Releasing a module now that could be used to compromise one's own personal device running an outdated software release feels like a wasted effort at best.  Rather, with the aforementioned questions and discussions in mind, I felt that more value would be had in using this as a teaching opportunity.  Much of this article will be old hat to many of you, but on that note, you aren't the intended audience.


While some people appear to almost fear the ASA, and embedded reverse-engineering in general, I'd argue that this is simply because it is an unknown.  I believe this is actually an extremely good way to get one's feet wet in the field.  The ASA runs on a common architecture, can be had with a valid license relatively cheap, and requires no electronics knowledge to begin picking apart.  Any bugs you may eventually find could prove rather valuable.  How much better could it be?


First Steps

The first step in all of this obviously involves setting up a research environment.  Though other, cheaper options do exist, by far the easiest approach to this is purchasing an ASA.  The other options include possibly using the ASA virtual appliance (which I have not investigated at all), or virtualization of the system software via other means.  I did attempt getting it running inside of QEMU, but the amount of work required to succeed when all you want to do is debug is quite daunting, so I went with a physical device.  In a town where tech startups crash and burn everyday, obtaining a used ASA on Craigslist is infinitely easier and cheaper when considering how much your time is worth.  For those of you so inclined, many Cisco certification seekers have formed a community centered around the effort to emulate the software within QEMU and GNS3.  Patches, scripts aimed at both packing and unpacking images, and hacked binaries exist for several older versions; however, there was none available at the time of writing for the vulnerable release.  Google is your friend!


On the hardware end, if you do end up getting an actual ASA, be sure to upgrade the RAM if it's operating with anything less than 256MB.  Debugging via the serial console is slow, and you'll likely be rebooting the device a lot.  You definitely want to eliminate any bottlenecks that you can before you begin.  Cisco sold branded memory for the device at quite a premium which is guaranteed to work.  I myself decided to risk $12 on a 1GB PC-3200 184 pin DIMM from Fry's that looked as if a small animal had been using the packaging as a chew toy.  So far it has worked flawlessly.  YMMV.  As for the serial connection, I use and recommend Parallax's USB to RS-232 adapter []


Platform Overview




My bookshelf is lined with tomes such as Compilers (the classic "dragon book"), Windows NT Device Driver Development, Inside OLE, and many other equally thick books.  I am all for rigorous academic discourses on various topics when the situation calls for it.  This is not such a situation.  I feel that reverse engineering is often more about knowing what you need to ignore than trying to know everything one possibly can.  That said, I'm going to gloss over a lot of details which are well defined elsewhere.  For our purposes, I believe the salient points that require focus are as follows:


  • The Cisco ASA 5505 is a tiny computer
  • It's x86
  • It has a lot of network interfaces
  • It has a removable CF card which contains the firmware image
  • It runs Linux
  • The system boot sequence involves traversing through the BIOS, ROMMON (ROM Monitor, Cisco's bootstrap program available on this and other devices), GRUB, and off into Linux land which ends by loading the lina binary, which we will speak more of later.  The boot sequence is important because in order to do what we want, we have to hijack it.


Armed with this knowledge and a Cisco ASA 5505 in either it's physical or virtual manefestation, we're ready to get started.


Un-nesting the Matryoshka Dolls


The next step in our progression is to get setup for debugging.  Thankfully, Cisco was kind enough to include gdbserver on the firmware image, but for some unknown reason, they didn't make access to it very straightforward.  "Jailbreaks" from the CLI in earlier releases have been accomplished by unpacking the firmware, editing some script or another to start /bin/sh, repacking the firmware, and hoping that you didn't screw up somewhere along the line.  You can find details regarding techniques such as these in the excellent presentation "Breaking Bricks and Plumbing Tips" by Alec Stuart-Muirk.  (Alec's presentation is actually really, really good.  You should definitely check it out after reading this)


As I mentioned earlier, shell scripts and techniques for unpacking and repacking the firmware exist online, albeit not publicly for version 9.2.4.  While I won't link them, they are worth investigating for educational purposes, as the same general approach can be used for reversing firmware for other devices.  'xxd', 'dd', a keen mind, and a little experience are all that are truly required.  I recommend you also check out devttys0's excellent tool binwalk, as it can simplify much of the process for you.


I had originally intended to extract and repack the firmware myself, but after bouncing around ideas with David Barksdale, he provided me with alternative, that being a zen-like, that's-so-stupid-why-didn't-i-think-of-that, offset.  Assuming you have a copy of the vulnerable ASA firmware (asa924-k8.bin), open the file in your favorite hex editor.  From there, proceed to offset 0x1d1a03c.  You should see something like




This certainly looks relevant to our interests, almost like it might be Linux kernel boot parameters or something.  I wonder what would happen if we used a clever 1994 era trick and overwrite some of these options with something like:





Save the file as something like asa924-k8-hax.bin


Once we have our modified image, we can transfer it to our device using one of a few methods, such as via TFTP from the ROMMON interface, or writing it to the CF card.  I had one laying around, so I went the card writer route.  With the CF card mounted in the OS of your choice, you can simply copy the file to the top level directory.  The TFTP process is fairly simple and well documented in the product manuals, so there's no need to run out and buy one if you're lacking such.


iomega-floppy-plus-7-in-1-card-reader-usb-powered-drive-cre-01a_401076393934.jpg    This project helped justify Brent's obsession with hoarding archaic historical relics



When you see “Use BREAK or ESC to interrupt boot”, do exactly as it says, and you should end up with something quite similar:




From the ROMMON prompt, we can force the device to load our firmware by using


boot disk0:/asa924-k8-hax.bin


Hit enter and be patient.  The boot time is excruciatingly slow in this age of NVMe SSD's.  Before too long, you should see something like this:




Score.  We're in.  Before getting too excited, realize that having a standard shell on an ASA is not too terribly useful, but it is a crucial step towards our end goal.  Typically, the first step one takes in auditing a product for bugs is to identify and enumerate the attack surface, ie all of the inputs of the system.  In other words, where will it let you shove a bunch of A's into it.  Cisco has simplified this process for us by cramming nearly all functionality that makes an ASA more useful than a decked out Raspberry Pi into one place: the lina process.  At least in my experience, and apart from the WebVPN interface which I have not investigated, nearly all packet filtering, QoS, and protocol capabilities, among others, are handled by this process.  There may be some other binaries I've overlooked, but lina is sufficiently large and complex enough to keep one busy for a long time.


With the boot sequence hijacked, we need to find a way to cleanly start lina under gdbserver.  Fortunately, a little 'sed' goes a long way towards that end:


sed -i 's/#\(.*-g -d.*\)/\1/' /asa/scripts/rcS
sed -i 's|-g -d|-g -s /dev/ttyS0 -d|' /asa/scripts/rcS
exec /sbin/init


Without explaining in minute detail, these two sed commands basically edit the flags for lina in /asa/scripts/rcS, setting it to execute in debug mode on the serial console.  After executing the real init process with the last line, if everything went according to plan, you should soon see a screen such as this:




Finally!  You might think we're done at this point, and you wouldn't be foolish to assume so despite the fact that you'd be wrong.  From here it follows that one should be able to debug the lina process by connecting gdb over the serial line.  This is true save for one final hurdle.  The application includes a watch dog mechanism that will reboot the system should the process fail to respond to polling within a given time limit.  This is great news for those who want redundancy in their SOHO networking hardware, and bad news for those who want to take their sweet time investigating the machine state from the confines of gdb.  I considered this as a stopping point for this article, but I'm feeling generous.  Consider the following:




And consider the first few lines of my .gdbinit


set disassembly-flavor intel
target remote /dev/ttyUSB1
set *0x0A53F168=0
file ~/lina


This should get you going.  The proof of why it works is left as an exercise to the reader.


Where Do We Go From Here?


Bug hunting on this platform is our ultimate goal, but I feel the actual process of such is tangential to the aims of this article.  Still, I feel the need to offer a few pointers.  Before anything else, as soon as you are able to pull the lina binary from the file system, go ahead and begin processing it in your favorite disassembler whether you plan to statically audit code right away or not.  Remember how I said that Cisco packed nearly, if not all, functionality of the ASA into one binary?  Yea, it's huge.  I believe it took about 2 hours in IDA Pro on my Macbook, and a little less on my PC.  In any case, it was enough time to go have a cup of coffee or four.


With regards to the Cisco heap allocator and heap exploitation in general, I never thought I'd live to hear the question "What is Doug Lea's malloc?" - and this coming from people who I feel have a decent handle on more modern implementations such as the Windows Low Fragmentation Heap.  It seems a bit like learning Riemann Sums before mastering elementary algebra.  Still, I suppose it's entirely possible and becoming more commonplace as time marches on.  If you're already familiar with a more modern allocator, that's great, dlmalloc should be easy for you to pick up.  And if you're going to be doing vulnerability research on embedded devices, you definitely should pick it up.  While modern desktop operating systems have long since abandoned dlmalloc in favor of more robust solutions, variations of it pop up frequently in embedded systems given that it's simple and relatively efficient.  The most concise overview I can think to recommend would be the excellent "Once upon a free()... " written by the all-knowing anonymous and published in Phrack 57, article 0x09.  Exodus Intelligence's original report features an excellent write up on the proprietary changes Cisco built on top of dlmalloc, so I defer all vendor specific heap questions to their blog post.


Finally, for any of you asking "ok, how do I find bugs?", I'll leave you with this: you probably already know how.  If you're reading this and truly don't know where to start, I'd recommend reading the "Binary Auditing" chapter of "The Shellcoder's Handbook" or any of the innumerable references on fuzzing.  While it's true that spotting vulnerabilities takes some intuition, I believe that intuition can be learned.  There are no silver bullets.  The biggest hurdle is taking the time to do it.  That said, I certainly feel a future blog post specifically on this subject may be in order.  Happy hunting!


Special thanks to:

    Jordan Gruskovnjak of Crowdstrike [w0 (@jgrusko) | Twitter] - my empathetic sounding board who understands the agony of crashing and rebooting an ASA 12+ hours a day.

    David Barksdale - who admirably has less of an online presence than I do

    Brent Cook and everyone on the Metasploit team: proofreading and moral support



Execute My Packet:

Breaking Bricks and Plumbing Tips: pdf

Once Upon a free() ...:

    .:: Phrack Magazine ::.

The Shellcoder's Handbook: Discovering and Exploiting Security Holes:

    The Shellcoder's Handbook: Discovering and Exploiting Security Holes: 9780470080238: Computer Science Books @


     Binwalk | Firmware Analysis Tool

New Modules



First up this week, we have a new module from rastating which exploits an unauthenticated file upload vulnerability in the popular WordPress plugin, Ninja Forms.  Versions affected include those within the range of v2.9.36 to 2.9.42, and the vulnerability can be leveraged into a shell running within the security context of the web server process in a fairly silent manner.  With over 2.5 million downloads and 500k active installs, according to the developer and the Wordpress plugin repos, this silent attack could prove deadly ... sort of like a ninja ... get it?


New from @wvu is a module exploiting a recently discovered pre-auth file upload vulnerability in Ubiquiti Network's airOS, which runs on their airMAX line of devices.   Given the ease with which the module turns a file upload exploit into a privileged BusyBox shell, we recommend that affected users check with the vendor for software updates.


Also new from @wvu (he's been busy) is an exploit module targeting Oracle Application Testing Suite version  The software allows users to perform load and regression testing--among other useful features--on their web applications. Unfortunately, this version also opens a wide security hole that an attacker can easily turn into a connect-back jsp shell.  While Oracle's applications are sometimes derided as being both complex and demanding to install, the Metasploit module couldn't be easier to use.  Simply point it at the vulnerable target, allow it a moment to attempt cleaning off any exploit artifacts, and wait for your shell.  It's just that easy!


Totally wrecking the whole pre-auth file upload theme we had going ...


h00die <mike [at]> recently contributed a module for local privilege escalation vulnerability in Allwinner's (the maker of some really cool embedded devices) 3.4 legacy kernel.  Kernel-land vulnerabilities and exploits are often thought of as being quite complex, esoteric, and daunting to approach by many researchers.  Allwinner has heard these sentiments echo and made accommodations for all those in agreeance.  To exploit, type:


echo "rootmydevice" > /proc/sunxi_debug/sunxi_debug

and you're done!.  Or, simply fire up the module by h00die and forgo the rigorous echo command.  Granted, there is a good chance that this was implemented as crutch for development and testing with perfectly altruistic intentions, but it's certainly not something you'd want to leave running on any multiuser system where you'd hope to maintain productivity.  New Armbian images were released on May 1st to address this issue, and we recommend that users look into upgrading as soon as possible.


Bug Fixes


A nasty bug existed when attempting to upgrade the python/shell_reverse_tcp_ssl payload in which send() was not sending all necessary protocol data over the connection, causing an EOF error to occur frequently.  The fix was contributed by geckom and remedies the issue by using sendall()


jhart squashed a couple of bugs and performed some maintenance within the ssh_identify_pubkeys auxiliary module.  For one, both KEY_DIR and KEY_PATH would not expand if they contained symbolic values (such as ~/bobbobthebobbob/.ssh/bobskeys.txt).  Secondly, if the key included a white list of commands that the user could run, it wouldn't be processed as all.  Finally, several unused options and some dead code snippets were removed from the module, which has now been tested and confirmed to work properly.


Our own Brent Cook (@busterbcook) tidied up and merged changes, which where originally contributed by RageLtMan, to the reverse_tcp_rc4 and bind_tcp_rc4 payloads.  This removes the static shellcode originally contained within the payload modules and implements them as assembly which is then compiled by Metasm.  Brent also squashed bugs found by @_sinn3r while auditing module ms08_067_netapi, which later proved to affect many more modules.  This fixes issues where the 'check' command would erroneously report that a host was vulnerable when in fact it wasn't, and also allows for correctly checking a range of ip addresses (as in 'check').  Not content to stop there, Brent also corrected an issue in the BrowserAutoPwn2 server where the CookieExpiration variable was not being set correctly.  Finally, in other bugfix news not involving Brent, darkbushido worked in changes to msfvenom, which fixes an issues where it would still generate a payload even if it's larger than the size option. It also no longer fails silently when invalid payload options (such as an ELF file for OS X) are specified.

Filter Blog

By date: By tag: