Showing posts with label debugging. Show all posts
Showing posts with label debugging. Show all posts

Unofficial security patch for Ubiquiti Networks mFi Controller 2.1.11

On September 3, 2015 SecuriTeam disclosed a vulnerability in the Ubiquiti Networks mFi Controller, a software to configure and control automation devices such as power outlets, light/motion/temperature sensors, etc. To understand the capabilities of the machine-to-machine platform, please have a look at the vendor page.
The security flaw allows an attacker to retrieve the current admin password due to a bypass in the authentication mechanism used by the mFi Controller Server.
Just few hours after the public release of the SSD Advisory – Ubiquiti Networks mFi Controller Server Authentication Bypass, the page was removed to accommodate the vendor's request since a patch was not available for download. According to the advisory and Noam Rathaus's tweet, the vendor was aware of this critical vulnerability since the beginning of July 2015.

Digital Self-Defense

Considering that the advisory published on 09/03/2015 contained a technical description of the vulnerability, including a reliable exploit, it is reasonable to assume that the security flaw can be easily abused by unsophisticated attackers. While the information was removed from the SecuriTeam website and /r/netsec, a quick search on Google is sufficient to find the exploit for this bug.
Despite the public exposure, Ubiquiti has yet to publish a patch.
After waiting patiently for a few weeks, I created my own patch. Using mFiPatchMe, you will be able to easily patch your controller and leave it running without worries.
You can download the Unofficial Security Patch for Ubiquiti Networks mFi Controller 2.1.11 from here: https://github.com/ikkisoft/mFiPatchMe
Disclaimer: This is NOT an official patch provided by Ubiquiti Networks

Anti-debugging techniques and Burp Suite

Incipit

No matter how good a Java obfuscator is, the bytecode can still be analyzed and partially decompiled. Also, using a debugger, it is possible to dynamically observe the application behavior at runtime making reverse engineering much easier. For this reason, developers often use routines to programmatically detect the execution under a debugger in order to prevent easy access to application's internals. Unfortunately, these techniques can be also extremely annoying for people with good intents.

 

Burp Suite

Over the course of the years, starting from the very first release, I have been an enthusiastic supporter of Burp Suite. Not only @PortSwigger was able to create an amazing tool, but he also built a strong community that welcome each release as a big event. He has also been friendly and open to receive feedback from us, ready to implement suggested features. Hopefully, he won't change his attitude now.

Since a few releases, both Burp Suite Free and Pro cannot be executed under a debugger. Unfortunately, this is a severe limitation - especially considering the latest Extensibility API.  The new extensibility framework is a game-changer: it is now possible to fully integrate custom extensions in our favorite tool. But, how to properly debug extensions in an IDE? Troubleshooting fairly complex extensions (e.g. Blazer) requires lot of debugging. Setting breakpoints, stepping in and out of methods, ... are must-have operations.

Inspired by necessity, I spent a few hours to review the anti-debugging mechanism used in Burp Suite Free. According to Burp's EULA (Free Edition), reversing does not seem to be illegal as long as it is "essential for the purpose of achieving inter-operability". Not to facilitate any illegal activity, this post will discuss details related to the Free edition only.  
Disclaimer: Don't be a fool, be cool. If you use Burp Pro, you must have a valid license.

 

Automatic detection of a debugger

In Java, it is possible to enable remote debugging with the following options:

-Xdebug -agentlib:jdwp=transport=dt_socket,server=y,address=8000,suspend=n 

and attach a debugger with:

 jdb --attach [host]:8000

A common technique to programmatically understand if a program is running under a debugger involves checking the input arguments passed to the Java Virtual Machine. The following is the pseudo-code of a very common technique:
 for(ManagementFactory.getRuntimeMXBean().getInputArguments() ...){
                if(Argument.contains("-Xdebug") || Argument.contains("-agentlib") ...){
                   // Do something annoying for the user
            }
In practice, ManagementFactory returns the managed bean for the runtime system of the current Java Virtual Machine that can be used to retrieve the execution arguments (see RuntimeMXBean API for further details). In case of Burp Free, the application gets shutdown via a System.exit(0);

 

Bypass techniques, an incomplete list

First of all, it is always possible to attach the debugger once the Java process is already up and running. Any check performed during the application startup won't block the execution:   

jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=[Process ID]

Unfortunately, this is a read-only mechanism and cannot be used within traditional IDEs. A few better solutions require tweaking the application in order to modify the program execution. This can be achieved via static changes in the .class files or using static/dynamic bytecode instrumentation. The code above is pretty simple and can be bypassed in several ways:
  • Using ClassEditor, reJ or any other tool that allow .class manipulation, it is just necessary to identify all strings in the constant pool used during the string comparison within the if-statement. For instance, you could replace all strings with a bunch of "a" so that the program won't even enter in the if-statement body
Manually changing the Constant Pool of a .class file


  •  An even more portable solution, especially when strings obfuscation is used, consist of editing the bytecode using JavaAssist or similar libraries. This allows to write a piece of code that search a class and patch it:
    • For instance, we could force the getInputArguments() to return an empty List;
    • Or, we could insert an arbitrary unconditional jump jsr to skip the program shutdown;
    • Or again, it is possible to override the System.exit() method with a local method using an empty body. First, we need to create a fake static exit(int) method. Then, we replace System.exit() with the custom method within our class.
Using JavaAssist to replace an existent method within a Class

Patching Burp Free for debugging your custom extensions

With the honest intent to simplify the life of coders writing custom Burp's extensions, I have developed a small utility (BurpPatchMe) to patch your own copy of Burp Free - which will allow you to debug your code in NetBeans, Eclipse, etc.
BurpPatchMe
    A few important details:
    • BurpPatchMe works for Burp Suite Free only. I have included a specific check for it as well as I have used a technique compatible with that release only. Again, you won't be able to remove debugging in Burp Suite Pro using this tool. Go and buy your own copy of this amazing tool!
    • BurpPatchMe is compiled without debugging info and it has been obfuscated too. A quick skiddie prevention mechanism to avoid abuses
    • BurpPatchMe does not contain any Burp's code, library or resource. It is your own responsability to accept the EULA agreement and its conditions, before downloading Burp Free. Also, this tool is provided as it is - please do not send emails/comments asking for "features"
    • Java JDK is required in order to use this tool. All other dependencies are included within the jar
You can download BurpPatchMe here and launch it with:
$ java -jar BurpPatchMe.jar -file burpsuite_free_v1.5.jar   
 Long life Burp Suite and happy extensions!