Passed the AWS Security Specialty exam!

Interesting contents. Studying for it allowed me to gain exposure to multiple AWS services I wouldn't have otherwise experimented with.

Here's a thread with random AWS facts I found interesting - and might be obvious to some.
CloudWatch Events (now "EventBridge") is a neat service allowing to react to various AWS events.

Send a SMS notification when a specific CloudTrail event occurs. Run a Lambda function to quarantine an EC2 instance when GuardDuty raises a finding. Possibilities are endless.
Security Hub, Config, Inspector, Trusted Advisor, Guard Duty, Detective, Macie, WAF, Shield, CloudTrail - AWS has a bunch of security services.

Before you ask - no, you have no chance figuring out what they do based on their names.
AWS WAF can be placed in front of an Application Load Balancer (ALB) or a CloudFront distribution.

Interestingly, this implies you can use AWS WAF to protect non-AWS websites, since CloudFront supports custom origins.
CloudTrail does *not* log S3 object-level operations (i.e. uploads, downloads and deletes) neither Lambda function invocations by default, because they're so noisy.

You need to enable them explicitly and can do so on a per-bucket / per-function basis.

https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html
If you send CloudTrail logs to a S3 bucket (or any kind of data for that matter), you can use Athena query it with a SQL-like language. Much better than grepping through .json.gz files!

https://docs.aws.amazon.com/athena/latest/ug/cloudtrail-logs.html
Let's get to the networking bits. Security groups are stateful, while Network ACLs are stateless.

If you allow inbound traffic on port 80 on a NACL, you also need to allow outbound traffic on ephemeral ports, otherwise it won't make its way to the initiator.
Security groups can only be used to *allow* access. Typically, you can't use a security group to block specific malicious IPs - you need to use a NACL or WAF rules.
When you create a new VPC, it comes with a default Security Group and NACL. This NACL allows all inbound and outbound traffic. But if you manually create a NACL in an existing VPC, beware, it's set to blocking all traffic! Spent more time debugging this one than I care to admit.
A "public subnet" means it has a route to the Internet via an Internet Gateway.

A "private subnet" doesn't and typically uses a NAT Gateway or a (non-managed) proxy to reach the Internet. This allows machines without a public IP to communicate with the external world.
A private subnet isn't exactly an isolated subnet. Even if you don't give it Internet access, it can exfiltrate data via DNS by default. @0xdabbad00 has a great post on that: https://summitroute.com/blog/2020/03/31/isolated_networks_on_aws/
You can use "VPC Endpoints" to bring the API of specific AWS services directly into a subnet without Internet access.

Create a VPC Endpoint for EC2, and AWS will create an ENI (NIC) in your subnets with a private IP and make sure "ec2.[region].amazonaws.com" resolves to it.
VPC Endpoints can be used for exfiltration. If you bring the S3 API into your subnet, an attacker can create their own S3 bucket and exfiltrate your data to it.

That's why you can VPC Endpoint Policies to filter which services and resources can be accessed through the endpoint.
Session Manager is the new SSH. Run the SSM agent on your instances, grant users ssm:StartSession and you can get an interactive shell on your instances. With all commands logged to CloudTrail, using your AWS identity
KMS... big topic. It's kind of like Hashicorp Vault, but less sexy. You have two kind of keys: default AWS-provided KMS keys, and Customer Managed Keys (CMKs).
As soon as you encrypt something (say a S3 bucket) with KMS using a CMK, any user accessing your bucket *also* needs explicit permission to use the key for decryption. s3:GetObject won't be enough, they also need kms:Decrypt. Similar for uploads.
You might want to restrict the context under which users can use CMKs for decryption.

For that, you can use the kms:ViaService and kms:EncryptionContext condition keys. How these are populated depends on the service.
A bunch of AWS services integrate with KMS, and they all have a unique way of interacting with KMS. The bible for this is https://docs.aws.amazon.com/kms/latest/developerguide/service-integration.html and is a really interesting read
Typically, since a CMK can only be used to encrypt <4KB of data, S3 will generate a random data key for each object, encrypt them with the data key, and store the ciphertext along with the encrypted data key (encrypted using the CMK you specified to encrypt the bucket).
Since we're talking about S3, how do we avoid public buckets?

One way is to use "S3 public access block". Turn it on per bucket or per account and it will ignore any bucket policy / object ACL making objects public.
Encrypting S3 buckets with KMS using a CMK also adds a layer of security.

If you unintentionally make your bucket public, no one can access it since they can't use the key to decrypt objects in it.

They could still access object metadata (e.g. file names) which is not encrypted
When you configure encryption of a S3 bucket, it does *not* ensure that all objects uploaded to it are encrypted.

It means "if the uploader doesn't request a specific kind of encryption, use this encryption"...
... but anyone uploading to the bucket can request to use another key, another kind of encryption (e.g. SSE-S3), or no encryption at all.

To make sure all objects in a bucket are encrypted, use explicit denies with s3:x-amz-server-side-encryption* condition keys
That's all for today folks!! Lots more of other things to talk / rant about, but that's for another day if this thread gets a bit of traction. :)

Here's a funny song to conclude:
You can follow @christophetd.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: