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.