Book info – Hands-On AWS Penetration Testing with Kali Linux
Disclaimer: Working through this book will use AWS, which costs money. Make sure you are doing things to manage your costs. If I remember, I’ll keep up with my costs to help get a general idea. But prices can change at any time, so major grain of salt.
Disclaimer #2: Jail is bad. Cybercrime is illegal. Educational purposes. IANAL. Don’t do things you shouldn’t. Etc.
I decided to keep posting by chapter since that worked well for me in the last section. GuardDuty is the AWS security monitoring service. Remember that depending on your setup, you may not have to specify
profile in the CLI commands. And make sure your user has the required permissions so you can check things out in the CLI.
Ch 16 – GuardDuty
Per the authors, pentesting basics – understanding the monitoring being done is important to inform your attack plan. If you find GuardDuty is not enabled, that doesn’t mean there is no monitoring going on because there are other options available. But GuardDuty is cheap and built-in, which makes it an attractive option when an org is getting started with AWS or is looking to control some costs.
Thus the recon step that pentesting generally starts with. Depending on the situation, you may have some of this information provided by your client. You might also be able to use OSINT to get an idea of what the target is using. Job postings and LinkedIn would be some of the first places I look for this. The book just kind of jumps into GuardDuty, so I wanted to think a bit about how you can get this information when you are dealing with more of a blackbox situation. I’m hoping this chapter will cover something you can do in AWS to determine what settings are enabled. Part of pentesting can be gradually getting nosier until you get caught to get an idea of what’s in place. Depends on the situation.
Back to the book.
GuardDuty pulls info from VPC flow logs, CloudTrail event logs, and DNS logs (if the requests go through AWS DNS resolvers). You can’t review DNS logs in AWS, which seems like something that will be addressed at some point. And GuardDuty can use VPC flow logs and CloudTrail logs even if not enabled. I find all of that very interesting for some reason. Not enabled, but still accessible. And not accessible otherwise but still available for GuardDuty. just strikes me as odd. Cross-account management is also available for GuardDuty. If you can get ahold of the GuardDuty master account, you can mess with GuardDuty for all of the associated accounts.
Basically, GuardDuty functions as an IDS. Alerts can set up get notifications suing CloudWatch events. GuardDuty uses machine learning to do user behavior analytics and alert on abnormal behaviors. There are settings to pop on basic attacks like port scanning EC2 instances, brute force attacks on RDP or SSH, and Tor being used to communicate with AWS. None of those are behaviors that should be the norm for an AWS environment. Since GuardDuty does use machine learning, test environments that are constantly having behavior that would be problematic in a prod environment may not alert as expected because dumpster fires are expected.
Alerting about/reacting to GuardDuty findings
GuardDuty shows findings in the web console – which is great, but not something you want to have open all the time. So CloudWatch events can be used to trigger notifications. The authors talk about using the rules to trigger Lambda functions. You could then use the Lambda functions to react to the data and set up some automation in responding to the alerts. The book example was parsing the data in the alert and then blocking outbound access to a known malicious domain. I suppose this functionality could be used to push GuardDuty into IPS territory. Definitely interesting – I’m going to have to do some digging to see if there are published Lambda functions to serve as rules like you have for Snort, Zeek, etc. A quick search makes it looks like there are some things available. Something to dig into if you are a heavy AWS shop.
GuardDuty can trigger on a lot of things, so there are also a variety of ways to bypass things. You could also essentially gaslight defenders by triggering alerts to send defenders in the wrong direction. The first option is basically turning off GuardDuty.
aws guardduty list-detectors --region <region> --profile <profile>
You can disable the detector found with:
aws guardduty update-detector --detector-id <detectorID> --no-enable --region <region> --profile <profile>
Alternatively it can be deleted with:
aws guardduty delete-detector --detector-id <detector-id <detectorID> --region <region> --profile <profile>
That would certainly prevent us from being caught via a GuardDuty alert. Though the whole GuardDuty not being there might be a bit of a red flag if someone was paying attention. Good option to have, but probably one to use at the end of a pentest when you are trying to make noise and get caught.
Bypassing everything with IP whitelisting
A better option is getting your IP added as a trusted IP. It’s under GuardDuty > Settings > Lists in the AWS console. You can also specify threat IPs. There is a max of one trusted IP list per region, so that could be problematic. Check for an existing trusted IP with:
aws guardduty list-ip-sets --detector-id <detectorID> --region <region> --profile <profile>
You can add IPs by creating a text file and putting it in an S3 bucket that is publicly accessible. It looks like at this time you have a fair number of options to name the text file. I’ll go with
aws s3 cp ./ip-trusted.txt s3://<bucket> --region <region> --profile <profile>
Then make it publicly readable so GuardDuty can read it:
aws s3api put-object-acl --acl public-read --buck <bucket> --key ip-trusted.txt --region <region> --profile <profile>
Just make sure the bucket it set up to allow public read. Now you can access the file via URL and use it to create trusted IP list:
aws guardduty create-ip-set --detector-id <detectorID> --format TXT --location <URL> --name Trusted --activate
Pacu can automate this:
run guardduty_whitelist_ip --path <URL>
The book goes on to explain that when you run
ListIPSets in Pacu and trusted IPs are present, Pacu will give you the option to delete the existing IP set and replace it with your own. This could cause issues, so be cautious about that option. You could alternatively update the list to include your IP. To amend the list, you have to get the IP set:
aws guardduty get-ip-set --detector-id <detectorID> --ip-set-id <ipsetID> --region <region> --profile <profile>
Then you can download the list, modify it, and upload it as we did earlier. Then update the IP set:
aws guardduty update-ip-set --detector-id <detectorID> --ip-set-id <ipsetID> --location <URL> --activate --region <region> --profile <profile>
Be sure to hang on to the original IP set URL so you can change the configuration back when done. The authors also point out that if GuardDuty is set up with cross-account access and another account is the primary account, you can’t modify the trusted IP settings.
Bypassing EC2 instance credential exfiltration alerts
It sounds like getting creds that will work for an EC2 instance but trigger an alert if used from an external IP can trigger an alert. The most common way would be with SSRF (server-side request forgery) on an IAM profile attached to an EC2 instance. The authors say this is a common one to find and easy to bypass. Since it’s triggering on external IPs, you can just use an EC2 instance in the same reason to avoid the trigger.
You can start the EC2 from the CLI:
aws ec2 run-instances --region <region> --image-id <imageID> --instanct-type <type> --key-name <ec2SSHkeyname> --count 1 --user-data file://userdata.txt
The userdata file will contain the install scripts for Python, pip3, Git, AWS CLI, and Pacu:
apt-get install python3 python3-pip git -y
pip3 install awscli
git clone https://github.com/RhinoSecurityLabs/pacu.git
Once launched, SSH in and run:
And then operate as normal. This GuardDuty alert will only work on EC2 instances for your account, so if creds are for a server hosted by another service, you won’t trigger this type of alert. This also doesn’t track Glue, which is an ETL (extract, transform, and load) service. That was an interesting aside…add Glue to the long list of AWS services to look into.
Bypassing operating system (PenTest) alerts
AWS also has a feature where it can alert on common pentest distros – Kali, Parrot, and Pentoo. Easy to bypass, but a cool feature. Basically, just change your user agent. Pacu will automatically change the user agent, but a script is also provided that would update the user agent.
Other simple bypasses
Since GuardDuty watches for low hanging fruit, there are some ways to avoid it. Like not using Tor, doing port scanning from/to EC2 instances, don’t brute-force SSH/RDP, and don’t interact with known bad. Those seem kind of obvious.
Don’t set up cyrptomining as part of a pentest (that’s good advice – for real, don’t do that). There are alerts for this, but you can avoid by staying away from connections to known cyrptocurrency related domains/IPs.
GuardDuty can also alert on unusual port activity. So sticking to HTTP and HTTPS will help avoid that. And you can avoid the alerts on large data exfil by using a trickle approach over a longer period of time.
This triggers on launching resources into the account. Avoid this by avoiding regions with GuardDuty enabled. If GuardDuty is enabled in all regions, bypass by avoiding the API call or using a different service like Lightsail, Glue, or AppStream.
GuardDuty also alerts if you make a password policy weaker. Avoid that by not messing with password requirements.
GuardDuty also alerts on coms with known bad IPs/domains. So don’t use those. It will also trigger on DNS data exfiltration, so you can avoid that if the DNS service is not using AWS.
There are other things you can do. The authors say they are more difficult, specific, etc. so are not covered.
Slower start with a rapid fire end. Interesting service that will be fun to watch mature. Remember that other things might be watching too, so don’t count on bypassing GuardDuty to be sufficient to avoid detection. But you should still avoid it so you avoid the easily checked things that are built in to AWS.