Hi and Welcome to the The Cat Flap – Your Weird Guide to Building Next-Generation AWS REAL FAKE BACKDOORS. What are you worried about? Come get REAL FAKE BACKDOORS.

Call us up, and order some real fake Backdoors today. Don’t even hesitate. Don’t even worry and don’t even give it a second thought. That’s our slogan - Me and Bens, over here with the Cat Flap.

A meme from Rick and Morty, featuring a Character that sells fake doors, the name Cat Flap is put in text

Excuse me Senior Rootcat, WTF is this about? Where is the beat, the story, the absurd and really long technical stuff, the lore?

Okay, easy there my dear beloved readers, honored furries, ransomware operators, techwitches, bronies, five eyes agents and powerpuffgirls- fear not! I know my audience by now, don’t you worry the weird will begin, the long absurd shall commence and this shit will go hard I pwomise. Come along now and follow us way down in the deep.

So, recently I met Ben a fellow Cloud Hacker- leave a like, share and subscribe to his onlyfans- and this blogpost is the culmination of us talking about how to make a real sneaky AWS Backdoor, on the basis of our real world experiences.

Oh yes you read that right, this is the first two player blogpost, a combined effort.

Let’s get started with the beat recommendations as it is tradition and also, this time perfectly balanced, as all things should be.

Beat_rootcat Beat_ben

Management Summary

This will be about how you build a sneaky AWS Backdoor in general, explained via the example of the AWSControlTowerExecution role. The post will start with the why we do it like this, will contain the defender’s perspective and also show how detection for this Backdoor would currently look like.

The github will (maybe) be further updated in the future and contains more nerdy stuff.

Generally, it goes like this:

  • You gain initial access to an AWS account. Somehow.
  • You check if you have permission to access/create/change AWS roles.
  • You create or edit the AWSControlTowerExecution role, by allowing it to be accessed with an external AWS account that you control.
  • You leave the initial access behind and now have a sneaky Backdoor with admin permissions.

Make it look legit

Yes, there are some tips on persistence out there, like adding your key to a random EC2 or playing around with Lambda versions and runtimes.
Most of these ideas are good for lab exercises, where there is a flag to catch and that’s why you need a python shell in some random service, but in real world AWS environments there are better ways to persist.

So, me and Ben we got talking. Let’s start with what you want in a Backdoor. Which is:

  • Hard to detect
  • Stable
  • Easy to Use

Ideally you want a team of Blue Teamers looking straight at your Backdoor, even googling it and throwing tools against it, and then come back with - “Yeah, we think this is legit.”

The above point is the most crucial one, honestly from real life experience:
Trying to hide shit is lame, the best is to make shit, that looks like other shit and then have an organization allowlist it, because your fake shit is nearly indistinguishable from the real shit. This is the way.

It is also actually a good idea to use something that, even if it is actually shady, should also preferably look like something that is vital to the core function of the whole org. Have defenders be real scared for the functioning of their org, before even thinking of deleting your Backdoor.

Conan, what is best in life?

To place your Backdoor, see them allowlist it before you, and to hear the lamentations of their SOC Team.

We cannot role anything out

Starting from something real is the best place to start. AWS has a huge amount of legit services, at this point they are basically as confusing and numerous as Pokemon- and no one knows them all, not even AWS.

Most of these services have roles that are needed for them to work. A role in AWS, is something that you can assume and basically wear and then you have the permission the role itself has.

These roles are either created when the service is used on the org-level, or they have to be created by an admin, which is why there is a lot of documentation on how to do this manually.

A good overview about the services and their roles can be found here.

A Screenshot of the link from above showing the roles with AWS services

AWS Control Tower is such a service that comes with roles. Control Tower “enables you to enforce and manage governance rules for security, operations, and compliance at scale across all your organizations and … offers the easiest way to set up and govern a secure, compliant, multi-account AWS environment based on best practices established by working with thousands of enterprise”. (see)

So let’s set it up!

Execute Control Tower Rule 69

To set up the Cat Flap, we follow this official AWS documentation to enroll an existing account manually into Control Tower:

Screenshot from the doku of Control Tower showing the json where you put the account
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<attacker_account_id>:root"
            },
            "Action": "sts:Assumerole",
            "Condition": {}
        }
    ]
}

Rolename: AWSControlTowerExecution

This is what it looks like when it is set up:

Screenshot of the AWSControlTowerExecution in the AWS portal after its creation

What happens if the role already exists? Well easy, you just add your attacker account to it and that’s it, that still works just fine (see github for this).

So, at this point, all we did was exactly what is needed in order to set up a legitimate role for Control Tower, step by step like in the documentation. We did it manually and added our own account as the one who can access this role. That’s it, now we have a real FAKE AWS Backdoor.

And just like that we have made a Cat Flap into the account, perfectly suitable just for us.

All that is left is to use it. Assume the victims account ID begins with a 5 and our own attacking account ID with a 3. We can then just assume this role and then we are back again in the victims’ account, now as the AWSControlTowerExecution role with full admin privileges.

A Screenshot showing that the attacker account is logged in the vicitim account as the AWSControlTowerExecution role

And no, of course these accounts need not be in the same org or have any relation, any AWS account will do.

Assume Defender Role

So how does this thing look, after we set it up, from the defender’s view?

Let us assume defenders would have some reason to take a critical look at things in their AWS account. Further let’s make the - in reality honestly unreasonable assumption- that they have the time and some sort of AWS skill to do this.

Typical steps would be to:
-> look at it - look at things carefully and in full detail
-> google it - google some parts/services/rolenames
-> tool it - run a specific tool

Look at it

In order to spot this, what would need to happen? Well, first of all, imaginary super defenders would need to start looking at the roles in the accounts of the organization.

Simplified this can look like this:

A Screenshot showing typical AWS roles in an account, the AWSControlTowerExecution is among them, there are 7 other roles

This maybe contains our example Backdoor, or others legit or shady. But it’s just a few roles in a single account.

It can also look like this:

A Screenshot showing typical AWS roles in an account, the AWSControlTowerExecution is among them, there are 18 other roles

Again, this also maybe contains our example Backdoor, or only Backdoors or none at all, and it has a few more roles. These are still simplified examples; in real world engagements it is not uncommon to have organizations containing hundreds of roles, so good luck with that.

So how to find the Backdoor. Well, you would klick on each one, read through all the permissions and go through the parts on who or what can assume the role. You would then have to find the AWSControlTowerExecution and then find the ID of the principal, which would be our attacker_account_id. Then you would have to know the ID of your own management account and realize that it is not the same.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<attacker_account_id>:root"
            },
            "Action": "sts:Assumerole",
            "Condition": {}
        }
    ]
}

That’s how one could find it, by literally looking at it, going through it and understand all of it. How likely that really is, we leave for the imagination of our dear beloved readers.

Google it

Let’s be a little more realistic. What happens if someone is unsure about these roles and just starts to search for them?

With a VPN and using a fresh Incognito Window, this is what we see when we just google for AWSControlTowerExecution:

The first Google results for AWSControlTowerExecution

We might be inclined to look at the first three in detail, what do they say:

  1. https://docs.aws.amazon.com/controltower/latest/userguide/awscontroltowerexecution.html

An introduction to the role, how it gets created and what it is being used for. Totally legit.

Screenshot of the first google link
  1. https://docs.aws.amazon.com/controltower/latest/userguide/roles-how.html

An overview about all roles used by Control Tower. Also totally legit.

Screenshot of the second google link
  1. https://www.reddit.com/r/aws/comments/u8x7tx/awscontroltowerexecution_role/

A redditor is in exactly the shoes we imagine a snoopy defender on the victim’s side to be in. His J1 (JupiterOne?) complains about the role’s permissions, and he tries to find out what the role does and if he can take away some permissions. So he asks Reddit.

The first (and only) helpful person tells him that the role should be there, all is good, and don’t touch it. Perfect. We have now reached peak legitness.

Screenshot of the third google link

Tool it

Remember, because we assumed, unreasonably so in real world cases, that the defenders have AWS experience, they will not use a random ScamAI-Bot or something like this, but they will rely also on a good tool, like Prowler, which is great. So, we run that.

But as it turns out, a default install of Prowler and usage without any modifications will ignore resources belonging to Control Tower, because they are allowlisted (docu allowlist)

The Mutelist from the above link, showing that the TowerRole is muted

To have a benchmark, we add a role 1337_Backdoor with otherwise the same trust policy and attached AdministratorAccess policy:

And this is the result of the scan, filtered for the check that lists all roles that have AdministratorAccess attached to them as “fail” (check iam_role_administratoraccess_policy, see):

  1. The 1337_Backdoor role got flagged
  2. The AWSControlTowerExecution role is connected to a failed control, but muted
The output of Prowler, showing no alarm for the AWSControlTowerExecution, but that the 1337_Backdoor is flagged

So basically, this does not show up, which is wild at first glance and great for us, but actually totally reasonable. There is more to this and something that can pawtentially be done better, but this would derail us here. (There are a more details about this in the github if you like)

The important part here is: You do not see it, real FAKE Backdoors right here!

Bonus round

Okay at this point, we think we got the point across on how hard it is to spot the Cat Flap. But please keep in mind that the AWSControlTowerExecution role is just one way to do it. Sure, it is a convenient one and it has the plus of having natural AdministratorAccess to it, but this does not mean it needs to be done like this.

From the uncountable other AWS service related roles, you could do the same with another one. And then maybe you do not attach AdministratorAccess to it. Sure Prowler might scan for it and it still does not help in the above case, but you can actually go harder.

You can write your own permissions for an existing random AWS service role.

Some orgs have admin groups, which means in that case, one could just add external access from their account to a service role and just add the permission to change role membership into the existing 400+ lines permission document. Good luck finding that, and it also will not pop up on any scan as they typically check for AdministratorAccess.

To be honest you can do a lot with this. Literally endless pawsiblities.

Unfortunately not everything is endless

So our dear beloved readers, we have reached the end.

Thank you for reading all through this, and we hope you learned something from it.

We also hope you appreciate life, yourself and your loved ones. Loved ones like Barsik, who was Ben’s cat and is no longer with us.

We like to dedicate this blogpost to him, as he was also an avid Cat Flap user and one of the best to ever do it. Hug your cats, and if you can give to your local animal shelter.

A Picture of the cat Barsik, laying very chill next to a keyboard