1 00:00:00,000 --> 00:00:04,580 My name is Spencer Geetson, and today I'm going to be talking about ransomware in the cloud. 2 00:00:06,320 --> 00:00:21,000 So, I'm a huge cloud nerd, so instead of the traditional Who Am I slide, I did an AWS STS Git Caller Identity slide, which basically says what Jaren just shared. 3 00:00:21,000 --> 00:00:22,660 My name is Spencer Geetson. 4 00:00:22,660 --> 00:00:25,520 I'm a cloud security researcher at CrowdStrike. 5 00:00:25,640 --> 00:00:34,300 I previously was a penetration tester at Rhino Security Labs, and I've got an interest in technical writing, gaming, and programming. 6 00:00:35,940 --> 00:00:38,720 So first I want to start off with an agenda. 7 00:00:39,060 --> 00:00:45,420 We'll talk about AWS basics, just kind of a TLDR of the services and resources I'm going to go over. 8 00:00:45,800 --> 00:00:55,680 Ransomware in the cloud, simple storage service for AWS S3, we're going to talk about ransomware techniques, prevention, detection, and indicators. 9 00:00:55,820 --> 00:01:01,200 And then the same thing for DynamoDB techniques, prevention, detection, and indicators. 10 00:01:02,440 --> 00:01:18,700 And then at the end, we're going to talk about other potential targets, so other AWS services, other clouds, those kind of things, cloud provider intervention, and other takeaways from the presentation, and then just some additional resources and references at the end. 11 00:01:20,040 --> 00:01:22,320 So AWS basics. 12 00:01:23,180 --> 00:01:30,000 I imagine there's a wide range of skill set in the audience, so you may know this, you may not. 13 00:01:30,340 --> 00:01:33,620 AWS S3 is just object storage in the cloud. 14 00:01:33,620 --> 00:01:34,940 It's their offering. 15 00:01:34,940 --> 00:01:40,200 There's S3 buckets, which basically hold all your buckets of objects. 16 00:01:40,200 --> 00:01:55,420 Objects are essentially files that are stored in buckets, and then there are bucket policies which determine the access permissions and conditions that apply to a bucket and the objects within it. 17 00:01:55,420 --> 00:01:58,460 And we'll get more into that later on. 18 00:01:59,100 --> 00:02:02,460 DynamoDB, this one's pretty simple for our needs. 19 00:02:02,460 --> 00:02:03,740 It has tables. 20 00:02:03,740 --> 00:02:09,680 It's a NoSQL database offered by Amazon, and it has tables that hold data. 21 00:02:09,680 --> 00:02:15,300 That's as much as you really need to know if you're not familiar with the service right now, at least. 22 00:02:15,860 --> 00:02:18,580 Then there's KMS, Key Management Service. 23 00:02:18,780 --> 00:02:28,860 It has keys, which could be asymmetric or symmetric keys, depending on your use case, and they're typically AWS managed. 24 00:02:29,320 --> 00:02:35,300 They have key policies, which define who can use keys and what they can be used for, etc. 25 00:02:35,720 --> 00:02:42,180 And that's kind of the rundown of the different resources and services that I'll be talking about today. 26 00:02:43,600 --> 00:02:45,320 Ransomware in the cloud. 27 00:02:45,380 --> 00:02:51,840 I'm going to be comparing the state of ransomware today to soon, essentially. 28 00:02:52,340 --> 00:03:03,720 Right now, there's traditional ransomware like Locky, WastedLocker, things like those that target traditional infrastructure. 29 00:03:04,260 --> 00:03:07,460 Cloud-native ransomware is on the way. 30 00:03:07,460 --> 00:03:10,480 There's none yet, or none publicly. 31 00:03:10,480 --> 00:03:15,980 We don't know what's going on behind the scenes or in breaches that haven't been made public. 32 00:03:16,020 --> 00:03:22,120 But it's better to get ahead of these things before it becomes a problem. 33 00:03:22,520 --> 00:03:25,220 It's better to be ready for them. 34 00:03:25,840 --> 00:03:35,140 So traditional ransomware typically targets servers and workstations, while cloud ransomware would be targeting cloud-native resources. 35 00:03:36,340 --> 00:03:39,340 Traditionally, they're operating system dependent. 36 00:03:39,340 --> 00:03:43,160 Primarily, windows and active directory environments are being targeted. 37 00:03:43,160 --> 00:03:46,820 Where in the cloud, it's going to be cloud provider independent. 38 00:03:46,820 --> 00:03:58,260 We're focusing on AWS for this presentation, but all the concepts can be applied to other cloud providers like Google Cloud and Microsoft Azure and others. 39 00:03:58,800 --> 00:04:05,020 And then traditionally, they exploit zero-day or known vulnerabilities to spread and infect their targets. 40 00:04:05,020 --> 00:04:07,140 Where in the cloud, it's none of that. 41 00:04:07,140 --> 00:04:08,240 It's just feature abuse. 42 00:04:08,240 --> 00:04:10,900 There's no vulnerability abuse. 43 00:04:10,980 --> 00:04:17,780 It's just using features the way they were designed, essentially, in a little bit of a malicious way. 44 00:04:18,840 --> 00:04:21,900 So with that, we'll dive into S3. 45 00:04:22,000 --> 00:04:23,600 There's three techniques I'm going to cover. 46 00:04:23,600 --> 00:04:28,140 It doesn't mean they're the only three techniques, but these are three notable ones, at least. 47 00:04:28,900 --> 00:04:31,200 Local encryption is the first technique. 48 00:04:31,200 --> 00:04:35,600 It's very slow compared to the others, but it's got a critical impact. 49 00:04:36,580 --> 00:04:40,100 The detection likelihood, I rate it as likely. 50 00:04:40,100 --> 00:04:44,940 But this is only if you have monitoring in your environment. 51 00:04:44,940 --> 00:04:49,160 If you aren't monitoring what's going on in your environment, you're not going to catch this. 52 00:04:49,160 --> 00:04:55,260 This is for kind of a security mature organization that it would be likely to detect. 53 00:04:55,440 --> 00:05:04,460 And so some of the defenses I'll go over will help certain companies reach that point to where they can feel like they are going to detect these attacks. 54 00:05:05,440 --> 00:05:08,440 Second method is cross-account KMS encryption. 55 00:05:08,440 --> 00:05:13,160 It's fast-ish, depending on the size of the bucket you're targeting. 56 00:05:13,160 --> 00:05:18,560 It's got a high impact, and then it's unlikely to be detected based on my rating. 57 00:05:19,100 --> 00:05:28,480 And the last, and probably the best method, as an attacker, from my point of view, is the KMS key policy lockout method. 58 00:05:28,520 --> 00:05:32,060 It's instant because it's a single API call. 59 00:05:32,060 --> 00:05:37,640 It's got high impact, and it's very unlikely to detect because it's a single API call. 60 00:05:37,680 --> 00:05:46,660 You might be able to detect it after it's happened, but you're not going to be able to prevent it if you don't have the correct defenses in place. 61 00:05:48,340 --> 00:05:54,560 So for the first method, local encryption, obviously we're going to locate a target bucket. 62 00:05:54,860 --> 00:06:03,920 We're going to download each file in the bucket, and we're going to locally encrypt each of those files with something like AES-256, you know, if you're going to be basic. 63 00:06:05,320 --> 00:06:08,320 Upload each of those encrypted files back to the bucket. 64 00:06:08,620 --> 00:06:24,700 Or, in theory, you could just delete all the files from the bucket and keep your local copies, depending on the size of the bucket, because by the time you have access, you could just release it rather than encrypt it or something like that as the attacker. 65 00:06:24,700 --> 00:06:37,360 So there's a lot of different routes here, but for this route, essentially we're just downloading from a bucket, as you can see here, AES-256 encrypting, and then re-uploading over the top of the original file. 66 00:06:37,540 --> 00:06:42,220 So I wrote a one -liner command here to demonstrate the concept. 67 00:06:42,220 --> 00:06:48,140 It looks a little convoluted, but highlighted some of the important parts here. 68 00:06:48,420 --> 00:06:53,980 Essentially, in red, we're exporting an environment variable bucket equal to our target bucket. 69 00:06:54,480 --> 00:06:59,320 Then we're using the AWS CLI, so list objects for that bucket. 70 00:06:59,320 --> 00:07:02,180 We're getting a list of all the objects that are stored in there. 71 00:07:02,360 --> 00:07:10,560 We're piping that list into jq, which is a JSON parser, and essentially it's just grabbing the names of all those objects. 72 00:07:10,560 --> 00:07:13,760 We don't care about the rest right now, but the rest of their properties. 73 00:07:14,280 --> 00:07:17,500 We're piping all those names into xrs. 74 00:07:17,980 --> 00:07:30,980 We're saying each name should run this... the following command should be run for each name, and then wherever there's an open-close bracket in the following command, it should be replaced with the current object name. 75 00:07:31,100 --> 00:07:37,480 So essentially, we're running sh-c, here's this open quote, and at the very end is the close quote. 76 00:07:37,480 --> 00:07:43,560 We're running this entire thing for each name of an object in the bucket. 77 00:07:44,240 --> 00:07:48,700 In the red, it's going to be awss3cp, which is copy. 78 00:07:48,700 --> 00:07:55,760 We're copying it from our target bucket at the current key, object key, into standard in. 79 00:07:56,040 --> 00:08:05,000 Now we're piping the result of that into openssl, which we're using to aes256 encrypt the data, and then base64 encoding it. 80 00:08:05,180 --> 00:08:16,480 We're piping that data into another awss3 copy command, but this time it's from standard in into s3, or at that bucket, at that object. 81 00:08:16,480 --> 00:08:21,320 So we're just overriding the original object with an encrypted version of the object. 82 00:08:21,380 --> 00:08:32,760 So now even if the target user has s3 permissions to read those objects, they're going to get access denied because they don't have access... or well, I guess they won't get access denied. 83 00:08:32,760 --> 00:08:36,620 They just won't be able to read the contents because it's encrypted with your password. 84 00:08:37,420 --> 00:08:43,140 So essentially they would have to pay the ransom, and you give them the password, and then they can decrypt all their data. 85 00:08:45,540 --> 00:08:49,200 So the next method is cross-account KMS encryption. 86 00:08:52,360 --> 00:08:56,180 Essentially you need an attacker AWS account for this one. 87 00:08:56,180 --> 00:09:00,160 You create a KMS key in that attacker AWS account. 88 00:09:00,460 --> 00:09:09,680 You modify the key policy to allow cross-account access to your target account, but only the encrypt permission and nothing else. 89 00:09:10,180 --> 00:09:13,660 So not the decrypt permission, especially. 90 00:09:13,860 --> 00:09:29,520 Next we're going to locate a target bucket, and we're going to use the s3 copy command to copy each object from itself to itself, which also s3 batch allows you to do at a greater scale without having to automate it yourself. 91 00:09:29,520 --> 00:09:35,120 And we're going to be specifying the KMS encryption key as the key we just created in step one. 92 00:09:35,620 --> 00:09:37,980 So I wrote another one-liner for this one. 93 00:09:37,980 --> 00:09:42,280 Again, it's a little convoluted, but this one's a little easier to understand. 94 00:09:43,400 --> 00:09:45,100 Pretty much everything is the same. 95 00:09:45,100 --> 00:09:52,060 We're getting the list of objects, the name of those objects, passing that into xargs in this shell command. 96 00:09:52,060 --> 00:10:00,060 But the shell command this time is AWS s3 copy from the s3 bucket of that object to the s3 bucket of that object. 97 00:10:00,060 --> 00:10:02,160 So basically just on top of itself. 98 00:10:02,560 --> 00:10:08,280 We're passing in SSE KMS key ID, and we're giving it our malicious key ID. 99 00:10:08,720 --> 00:10:15,220 So it's just encrypting each object in the bucket with our key instead of whatever it's currently encrypted or not encrypted with. 100 00:10:15,920 --> 00:10:28,280 And lucky for us, this is done on the server side, this copy, because it's s3 to s3, so we don't need to worry about our own upload and download speed like we would with the local encryption method. 101 00:10:28,280 --> 00:10:37,660 So this might be a better method for when there's larger files in the bucket that you don't want to be downloading terabytes of data to your system. 102 00:10:37,660 --> 00:10:39,420 You probably can't even. 103 00:10:42,410 --> 00:10:46,050 So the third method is KMS key policy lockout. 104 00:10:46,230 --> 00:10:50,410 This is my favorite method and probably the scariest method. 105 00:10:51,630 --> 00:10:54,470 So I'll get into why shortly. 106 00:10:55,290 --> 00:10:58,070 In this we're going to need our own attacker account again. 107 00:10:58,070 --> 00:11:08,650 This time we're going to allocate an elastic IP in there, and this is because there are a lot of restrictions on cross-account actions for KMS keys. 108 00:11:08,650 --> 00:11:16,610 So you can't update the policy of a KMS key cross-account, you can't disable a key cross-account, and you can't delete a key cross-account. 109 00:11:17,170 --> 00:11:25,350 So we have to do some trickery with conditions in the KMS key policy to actually lock the owner out. 110 00:11:25,890 --> 00:11:30,730 And again, I say the owner because we're targeting a key that our target owns. 111 00:11:30,730 --> 00:11:33,570 It's not our attacker key or anything like that. 112 00:11:35,310 --> 00:11:48,150 So we'll locate a target bucket and our target has to have a customer master key assigned to it as the default encryption method, or at least the objects in the bucket have to be encrypted with a customer master key. 113 00:11:48,370 --> 00:12:00,550 It can't be the default S3 KMS key and it can't be unencrypted because we're targeting the actual key behind the encryption which requires it to be a customer master key. 114 00:12:00,550 --> 00:12:02,750 Otherwise we can't mess with the policy. 115 00:12:03,870 --> 00:12:14,410 We're going to update the key policy of that KMS key to deny access to anything about it unless it's originating from your elastic IP address. 116 00:12:14,410 --> 00:12:24,290 So essentially no one can use the key unless they have control of the elastic IP address which you have control of the attacker. 117 00:12:25,230 --> 00:12:41,150 Then you demand ransom plus you know keys to unlock so you could have them give you keys that have put key policy on the key and you could use your elastic IP to restore their key policy or you can transfer them the IP allocated. 118 00:12:41,570 --> 00:12:59,490 It's a little risky because you would have to unallocate it in your own account then they would have to request it to be allocated in their account which if the timing doesn't match up they might miss it and another customer might randomly get it in AWS and at that point who knows what would happen. 119 00:13:01,550 --> 00:13:07,850 So another one-liner, this one doesn't look very simple because it's got a whole bunch of JSON in it but it's just a single command. 120 00:13:07,930 --> 00:13:16,110 So AWS CLI KMS put key policy pass in the target key ID for the key we want to target obviously. 121 00:13:16,430 --> 00:13:26,730 The policy name is always going to be default and then we're passing in a JSON policy which I have formatted to make it a little bit easier to read . 122 00:13:28,310 --> 00:13:36,730 For those of you who aren't aware of how policies work or the structure of them in AWS I'll kind of go over this. 123 00:13:36,730 --> 00:13:41,390 So there are two statements that are declaring something about the key. 124 00:13:41,410 --> 00:13:47,190 The first one is deny access to this principle which is everyone. 125 00:13:47,510 --> 00:13:57,970 Deny anyone from doing any KMS action on any resource under the condition that they're not coming from our Elastic IP address. 126 00:13:57,990 --> 00:14:02,450 So essentially if you aren't coming from our IP deny access to everything. 127 00:14:03,250 --> 00:14:16,990 Then the next statement is saying allow access to our target account's root user to do any KMS action on any resource under the condition that they're coming from our Elastic IP address. 128 00:14:17,090 --> 00:14:22,390 So overall this is saying if you're not coming from our Elastic IP you're blocked from everything. 129 00:14:22,390 --> 00:14:28,170 If you are and you're coming from the target account then you have access to do things. 130 00:14:28,710 --> 00:14:49,150 So what this means is because we have access or because we own the Elastic IP it's up to us to grant access to the target account where then they can update the policy and essentially gain access to their data again because this will deny them from using the decrypt permission which they need to obviously decrypt any data. 131 00:14:50,430 --> 00:14:56,230 Another reason this is kind of scary is because this could go across to multiple S3 buckets. 132 00:14:56,230 --> 00:15:02,010 In theory the same KMS key could be applied to three or four different S3 buckets. 133 00:15:02,010 --> 00:15:08,010 So if you ransom the key policy you've hit all of those buckets with it with one API call. 134 00:15:08,010 --> 00:15:13,190 So it's suddenly a very much more valuable attack for you. 135 00:15:16,070 --> 00:15:18,210 So S3 defenses. 136 00:15:18,210 --> 00:15:20,890 We're going to talk about prevention and detection. 137 00:15:20,890 --> 00:15:23,270 They're both very important. 138 00:15:23,270 --> 00:15:28,530 In terms of prevention, easy one is just follow the principle of least privilege. 139 00:15:28,530 --> 00:15:38,230 This applies to KMS key policies, S3 bucket policies, and the IAM privileges you're granting to your users and roles for those specific services. 140 00:15:38,610 --> 00:15:40,470 Off-site backups. 141 00:15:40,470 --> 00:15:43,510 So of course online backups are good. 142 00:15:43,510 --> 00:15:46,590 Maybe cross account or something like that. 143 00:15:46,690 --> 00:15:55,110 But off-site is good because even if you get ransomware and you lose access to your data, you can just restore from something completely unrelated. 144 00:15:56,650 --> 00:15:59,630 Organization service control policies are important. 145 00:15:59,850 --> 00:16:01,770 They're going to be customized to your environment. 146 00:16:01,770 --> 00:16:15,130 So I'm not going to go over any specific examples, but they can be used to enforce specific conditions and restrict certain permissions that may prevent or at least help detect a ransomware attack. 147 00:16:17,150 --> 00:16:20,430 S3 object versioning with MFA delete. 148 00:16:20,430 --> 00:16:21,810 It's very important. 149 00:16:22,150 --> 00:16:31,570 So object versioning makes it so that instead of your files getting overwritten when a new one with the same name is uploaded, it creates a new version. 150 00:16:31,570 --> 00:16:49,610 So if the attacker tried to do a local encrypt attack and uploaded their encrypted version over the top of an existing version, both versions would still exist and the defender could just delete the latest version, which is the encrypted version, and then restore the original version and still have access to all their data. 151 00:16:50,350 --> 00:16:59,070 But this is why MFA delete is important because an attacker could also just delete object versions if they had the permissions to do so. 152 00:16:59,070 --> 00:17:03,230 So they delete the old version and the only version left is the encrypted version. 153 00:17:03,230 --> 00:17:11,210 But with MFA delete, it requires you to have an active MFA device to delete objects and to disable object versioning. 154 00:17:11,250 --> 00:17:14,650 So in both cases, the attacker is going to be locked out. 155 00:17:14,650 --> 00:17:25,730 In most cases, they're not going to have access to an active MFA device, even if they've already bypassed MFA in the console or something along those lines. 156 00:17:28,010 --> 00:17:32,170 Another good defense is a bucket policy that enforces a specific KMS key. 157 00:17:32,170 --> 00:17:35,410 This will prevent the cross-account KMS encryption method. 158 00:17:35,770 --> 00:17:38,010 Here's an example bucket policy. 159 00:17:38,010 --> 00:17:47,090 We're denying anybody from using S3 put object to our bucket under the condition the encryption key is not this one here. 160 00:17:47,090 --> 00:17:57,070 So if someone tries to upload an object to our bucket and they specify an encryption key that is not this one that we've whitelisted, it's going to get access denied. 161 00:17:57,070 --> 00:18:02,750 And so this will prevent the cross-account attacker key from getting applied to any of our objects. 162 00:18:04,630 --> 00:18:11,770 In terms of detection, there's going to be S3 access logging and CloudTrail S3 data event logging. 163 00:18:11,770 --> 00:18:19,570 These are both pretty similar and give you visibility into the actual actions taking place within a bucket versus on a bucket. 164 00:18:19,750 --> 00:18:22,550 So this is like object level activity, essentially. 165 00:18:23,130 --> 00:18:32,130 They have slight differences, so it's worth looking into the comparison between the two and seeing which one you want or both, maybe. 166 00:18:32,950 --> 00:18:36,410 Another important thing is CloudTrail management event logging. 167 00:18:36,410 --> 00:18:47,070 You can hopefully trace the attack path through your environment and maybe kick them out before they start ransoming your buckets or something like that. 168 00:18:47,710 --> 00:19:07,090 CloudTrail KMS event logging is good, too, because you can see when maybe there's a high amount of decrypts going on, you can take that as an indicator that someone is reading lots of objects or something along those lines, which could be them downloading to locally encrypt and maybe you stop them before they re-upload. 169 00:19:08,330 --> 00:19:10,950 GuardDuty with S3 ingestion enabled. 170 00:19:10,950 --> 00:19:18,250 S3 ingestion was just released last week, I believe, and it is a great feature that's been added. 171 00:19:18,250 --> 00:19:34,030 It'll allow you to catch things like a Tor IP address interacting with your S3 buckets, so it'll make it easier to pull out malicious activity from your buckets compared to traditional activity or normal activity. 172 00:19:35,810 --> 00:19:43,190 In terms of indicators for S3, STS get caller identity, kind of like my Who Am I slide. 173 00:19:43,190 --> 00:20:01,410 This is Who Am I of the cloud, and you don't necessarily need to alert on this call because there are a lot of legitimate use cases, like EKS pods won't use it, I believe HashCorp Vault uses it, and then sometimes developers just need to do it themselves, 174 00:20:01,410 --> 00:20:09,250 but attackers will often use this, too, to identify who they are before expanding into the environment. 175 00:20:09,290 --> 00:20:16,610 So if you can create a baseline of what's normal and then alert on what's abnormal, this would be a good one to look into. 176 00:20:17,530 --> 00:20:20,650 Another obvious one is S3 list all my buckets. 177 00:20:20,650 --> 00:20:34,750 That's going to be used legitimately all the time, but if you could somehow identify when it's being used maliciously, it's going to be a really good one because this will probably be run before any ransomware attack unless they already have a bucket name, 178 00:20:34,850 --> 00:20:36,850 a target, or something along those lines. 179 00:20:36,930 --> 00:20:48,510 Maybe you pair it up with get caller identity, so you see get caller identity and then shortly after list all my buckets, that could be somewhat of an indicator and at least worth looking into. 180 00:20:49,930 --> 00:20:56,310 Attempts to disable object versioning on an S3 bucket and attempts to delete object versions in a bucket. 181 00:20:57,350 --> 00:21:15,310 An attacker could do this if they identified a bucket that has versioning enabled, they could disable it, and then they could go in and delete all the old versions and then make it so that the latest version is their encrypted file or encrypted object so it'd be just the same as if versioning was disabled. 182 00:21:16,810 --> 00:21:25,610 Attempts to disable S3 access logging to remove your visibility into the HTTP requests that are going on within your bucket. 183 00:21:26,350 --> 00:21:28,710 KMS key policy modifications. 184 00:21:28,990 --> 00:21:41,310 If it's the last KMS key policy lockout method, this is going to, or alerting on these modifications, it's going to be too late, but better late than never, I would say. 185 00:21:41,390 --> 00:21:46,290 You want to know when this stuff happens even if you weren't able to prevent it. 186 00:21:47,570 --> 00:21:51,690 S3 bucket policy modifications and S3 bucket ACL modifications. 187 00:21:51,690 --> 00:22:08,830 You want to know when your bucket gets granted cross-account access or public access, of course, but then if you're enforcing a specific KMS key in your policy for object uploads, an attacker could identify that and delete the bucket policy so that they can use their cross-account key. 188 00:22:09,170 --> 00:22:18,530 So this might be somewhere, again, where service control policies come into place and can prevent that kind of activity if you know you're not going to need that to be going on. 189 00:22:20,510 --> 00:22:24,590 High volume of S3 object downloads and uploads. 190 00:22:24,690 --> 00:22:28,810 If it's above your baseline, it might be worth looking into. 191 00:22:28,810 --> 00:22:35,990 Maybe someone's exfiltrating all the data in your bucket or they're downloading it for local encryption or something along those lines. 192 00:22:37,330 --> 00:22:39,450 A typical S3 batch usage. 193 00:22:39,450 --> 00:22:45,110 So like I talked about before, S3 batch could be used for the cross-account KMS key method. 194 00:22:46,070 --> 00:22:57,890 And so if you don't use S3 batch at all and then all of a sudden you see some jobs kicked off, that could be alarming and maybe you can stop those jobs before they complete and fully take control of your data. 195 00:22:58,750 --> 00:23:07,690 Guard duty alerts, again, those are great to look into and just great in general in terms of identifying compromise in your environment. 196 00:23:08,870 --> 00:23:11,850 So with that, we're going to be diving into DynamoDB. 197 00:23:13,670 --> 00:23:24,690 We'll cover three techniques again, and it doesn't mean they're the only three techniques, but maybe surprisingly or not, they're the same three methods. 198 00:23:24,690 --> 00:23:29,370 Local encryption, cross-account KMS encryption, and key policy lockout. 199 00:23:29,370 --> 00:23:31,090 They're a little bit different. 200 00:23:32,070 --> 00:23:34,490 They're done a little bit differently though. 201 00:23:34,870 --> 00:23:40,810 So for local encryption, we've got located the target table. 202 00:23:40,810 --> 00:23:49,630 We're going to export the entire table using the scan API, which is essentially just scan the table for data and download it. 203 00:23:50,190 --> 00:24:07,330 But we need to be careful hitting the read capacity of the table because we may cause a denial of service in the environment if we use up the read capacity, and that could trigger some alerts that then get us kicked out of the environment before we've actually downloaded any data or much data. 204 00:24:08,450 --> 00:24:13,250 Then we're going to locally encrypt the downloaded data with something like AES-256 again. 205 00:24:13,330 --> 00:24:16,650 We're going to overwrite the table's data with the encrypted data. 206 00:24:16,650 --> 00:24:24,790 So you can see target table, we scan it, locally encrypt it, and then use batch write item to write it back into the table. 207 00:24:25,850 --> 00:24:36,030 Alternatively, we could use get item and put item to encrypt items one at a time, but that would likely be much slower and there would be many more events for your actions than otherwise. 208 00:24:37,490 --> 00:24:39,090 Not so simple one-liner. 209 00:24:39,090 --> 00:24:46,910 I didn't write a one-liner for this one because the scan API returns a maximum of one megabyte of data per call. 210 00:24:48,170 --> 00:24:55,070 So that means you have to paginate the results, but essentially that's hard to do on the CLI. 211 00:24:55,070 --> 00:25:01,350 It's done a little bit funky and so I just didn't write one for this. 212 00:25:02,090 --> 00:25:08,330 It would be much easier to just write a quick Python script or something along those lines if you were going to try and abuse this method. 213 00:25:10,230 --> 00:25:15,310 So the next method for DynoDB is the cross-account KMS encryption method. 214 00:25:15,510 --> 00:25:20,130 We're going to create KMS key in our own attacker account like we did before for S3. 215 00:25:20,390 --> 00:25:26,730 We're going to configure that key policy to grant full access to the key cross-account to our target account. 216 00:25:27,510 --> 00:25:38,310 It's not going to let us apply the key to that table, to our target table essentially, unless you perform this step because there are a few different permissions that are required to successfully apply the key. 217 00:25:42,790 --> 00:25:46,130 So then you locate your target table. 218 00:25:46,590 --> 00:25:53,450 You modify the table and change the KMS key that's applied to it to be the key that you just created. 219 00:25:53,710 --> 00:25:57,970 It takes a minute to update, so you just wait for that for it to finish updating. 220 00:25:58,090 --> 00:26:03,770 Then you go into your own account and modify the KMS key policy to remove that cross-account access. 221 00:26:04,210 --> 00:26:17,790 So now, in theory, their DynamoDB database table has your encryption key applied to it and they don't have decrypt permission for that key. 222 00:26:17,790 --> 00:26:23,830 So if they try to view their table or the data within it, they're going to get non-authorized, as you can see here. 223 00:26:24,390 --> 00:26:38,010 Additionally, if they try and change the KMS key that's applied to the table, they're going to get access denied because it requires you to be able to decrypt the data of the table to then re-encrypt it with something else. 224 00:26:38,010 --> 00:26:43,920 So you essentially have full control of the table until you grant them access again. 225 00:26:46,830 --> 00:26:53,230 So the third method, KMS key policy lockout, is essentially the exact same method as S3. 226 00:26:53,370 --> 00:27:10,830 And it's another reason why this technique is even more risky than we talked about before, because like I said, it could be applied to multiple S3 buckets at once, but then also, in theory, it could be applied to one or more DynamoDB tables. 227 00:27:10,830 --> 00:27:18,190 So a single key policy ransom attack could hit, you know, three, four, five DynamoDB tables and a bunch of S3 buckets. 228 00:27:18,390 --> 00:27:23,970 Not that that's good practice, they should be applied to all those, but not everyone follows best practices. 229 00:27:24,490 --> 00:27:28,590 And so it's something to be aware of and hopefully prevent. 230 00:27:30,850 --> 00:27:35,850 In terms of defenses for DynamoDB, we'll do prevention and detection again. 231 00:27:36,590 --> 00:27:48,130 And again, the easy one, follow the principle of least privilege for KMS, key policies, and then IAM permissions for DynamoDB and KMS applied to your users and roles. 232 00:27:49,610 --> 00:27:51,110 AWS backups. 233 00:27:51,110 --> 00:28:02,150 So you want to use the backup feature of DynamoDB to create snapshots of your data, essentially, on some time period that you've set up. 234 00:28:03,130 --> 00:28:14,290 Offsite backups, those are important too, because an attacker, in theory, could just delete all your backups that are in AWS and then delete the database itself, and then there's no data anymore. 235 00:28:14,290 --> 00:28:17,750 Offsite backups could help prevent that, because you can just restore. 236 00:28:18,730 --> 00:28:21,490 And again, organization service control policies. 237 00:28:21,490 --> 00:28:22,710 I love these. 238 00:28:22,710 --> 00:28:24,470 There's lots you can do with them. 239 00:28:24,470 --> 00:28:31,210 And if you're not familiar, I really highly suggest looking into them and applying them to your organization. 240 00:28:31,210 --> 00:28:33,730 But again, they're going to be very customized. 241 00:28:34,810 --> 00:28:36,870 Use VPC endpoints for access. 242 00:28:36,870 --> 00:28:43,810 So essentially require your users to be within your VPC to access your DynamoDB tables. 243 00:28:43,810 --> 00:28:56,030 So that means an attacker would need to compromise your network prior to ransoming a DynamoDB table, which if they can do that, you're going to have far greater problems anyways. 244 00:28:56,570 --> 00:29:00,710 So it's a good practice to do this. 245 00:29:00,710 --> 00:29:05,430 And don't just let the entire internet access your table if they're aware of it. 246 00:29:07,110 --> 00:29:08,510 Point-in-time recovery. 247 00:29:08,510 --> 00:29:14,710 This is one I did have on here as a prevention, but as I did further testing, I found out it didn't actually work. 248 00:29:14,710 --> 00:29:19,370 So point-in-time recovery keeps snapshots over time in your database. 249 00:29:19,490 --> 00:29:25,030 And essentially, it allows you to go back to a specific time in the past. 250 00:29:25,030 --> 00:29:42,790 But what I found is if you enable it, and then you wait a little while, maybe mess with the data, then you apply a ransom KMS key to it, then you use point-in-time recovery to recover before that key was applied, it still doesn't work. 251 00:29:43,290 --> 00:29:52,490 It seems to be successful, and it starts creating the restored database, but then it just disappears from the console, and there's no trace of it. 252 00:29:52,490 --> 00:30:01,010 So my guess is that it just can't get to the data because it encrypted it all with the new key instead of the key that was present at the time. 253 00:30:02,330 --> 00:30:07,250 For detection, Cloud Trail Management event logging, again, very useful. 254 00:30:07,250 --> 00:30:09,610 KMS event logging, very useful. 255 00:30:09,630 --> 00:30:11,790 Guard duty, always very useful. 256 00:30:12,430 --> 00:30:24,210 CloudWatch alarms, you can use these to monitor the read and write capacity of your tables, so you know if there's a huge amount of reads or a huge amount of writes to your tables and could alert off of that. 257 00:30:24,550 --> 00:30:34,490 DynamoDB streams, scan, get item, and put item, and I think some others are not, or they're considered data events, so they're not logged by Cloud Trail. 258 00:30:35,290 --> 00:30:47,230 So you can use DynamoDB streams to stream those data events to a Lambda function and respond to them however you want, so that can be a way to monitor that data level activity. 259 00:30:48,190 --> 00:30:55,310 And maybe you can use AWS config to track changes to your tables, but usually this will be too late by the time it alerts you of anything. 260 00:30:57,190 --> 00:31:14,630 Indicators to look out for, again, STS get caller identity, KMS key policy modifications, high volume of table reads and writes, attempts to delete backups, guard duty alerts, attempts to increase the table's read capacity. 261 00:31:14,630 --> 00:31:27,190 If they find a large table that has a low read capacity, they might increase the read capacity so that they can run parallel queries and download the entire database quickly without causing a service in the environment. 262 00:31:28,910 --> 00:31:31,130 And that's kind of it for DynamoDB. 263 00:31:31,130 --> 00:31:34,390 I'm running out of time, so I'm trying to speed through a couple of these. 264 00:31:34,570 --> 00:31:53,530 Other potential targets, so there could be Elastic Walkstore and AWS, you can encrypt volumes or snapshots, relational database service, or RDS database and snapshots, Lambda function code and environment variables, secrets manager secrets, SNS topics, 265 00:31:53,530 --> 00:32:04,010 SQS queues, ECR repositories and images, which just got released last week, I believe, EFS file systems, and more. 266 00:32:04,010 --> 00:32:12,150 And then you can even do it for other cloud providers, but like I said earlier, we didn't dive into that, but something like Google Storage could be done the same way as S3. 267 00:32:13,310 --> 00:32:16,470 So cloud provider intervention and other takeaways. 268 00:32:16,470 --> 00:32:22,570 We don't know what a cloud provider could do to help you if you got targeted, so you can't rely on them for that. 269 00:32:22,570 --> 00:32:26,590 So you need to act as if they would not be able to help you under any condition. 270 00:32:26,730 --> 00:32:31,350 They can't help you with the local encryption anyways, because they're not going to know the password to your encrypted data. 271 00:32:32,010 --> 00:32:34,610 This means you need to evaluate your own defenses. 272 00:32:34,670 --> 00:32:38,810 You need to take care of your environment, monitor it, respond to things. 273 00:32:38,970 --> 00:32:42,470 You can't rely on the unknown, essentially. 274 00:32:42,630 --> 00:32:44,610 Can you keep attackers out of your environment? 275 00:32:44,610 --> 00:32:48,710 Can you prevent attackers from doing things once they're in your environment? 276 00:32:48,950 --> 00:32:53,230 Can you detect when they're doing things once they're in your environment? 277 00:32:53,290 --> 00:32:56,170 Can you match those detections to patterns? 278 00:32:56,610 --> 00:33:03,150 Can you tell that maybe a ransomware attack's coming because of these few API calls made in a row or something along those lines? 279 00:33:04,170 --> 00:33:08,650 And additionally, you need to ask, can I get back online after an attack? 280 00:33:08,670 --> 00:33:09,430 Am I ready? 281 00:33:09,430 --> 00:33:12,230 Do I know what to do if I got hit with a ransomware attack? 282 00:33:12,230 --> 00:33:14,650 If the answer is no, then you've got some work to do. 283 00:33:15,610 --> 00:33:16,770 And then how fast? 284 00:33:16,770 --> 00:33:20,330 Is it going to be fast enough before there's a major business impact? 285 00:33:20,510 --> 00:33:22,430 How much money are you going to lose in the meantime? 286 00:33:22,430 --> 00:33:24,550 It's a big, big question. 287 00:33:25,070 --> 00:33:30,290 And finally, the last big takeaway is, what if the attacker never decrypts your data? 288 00:33:30,950 --> 00:33:33,430 For some reason, what if you just can't get access? 289 00:33:33,430 --> 00:33:34,690 I mean, they are criminals. 290 00:33:34,690 --> 00:33:36,270 You can't necessarily trust them. 291 00:33:36,270 --> 00:33:39,850 Just because you pay them doesn't mean they're going to decrypt your data. 292 00:33:40,570 --> 00:33:42,730 So could you handle that? 293 00:33:42,730 --> 00:33:43,890 Are you going to go out of business? 294 00:33:44,870 --> 00:33:45,950 What's going to happen? 295 00:33:45,950 --> 00:33:48,150 That's something you need to think about. 296 00:33:49,050 --> 00:33:50,730 That kind of wraps things up. 297 00:33:50,730 --> 00:33:54,490 I have a slide here just of some additional resources and references. 298 00:33:55,790 --> 00:33:58,850 First one I always want to talk about is AWS documentation. 299 00:33:58,930 --> 00:34:00,610 I read that like it's the Bible. 300 00:34:01,750 --> 00:34:09,530 There are so many great things in there, and it's an easy way to learn in-depth about features of AWS that you might not know otherwise. 301 00:34:09,530 --> 00:34:11,770 So I'm constantly reading that. 302 00:34:11,830 --> 00:34:17,570 And then I wrote two blog posts on S3 ransomware in particular, while I ran a security labs. 303 00:34:17,570 --> 00:34:19,150 You can check those out. 304 00:34:20,010 --> 00:34:29,710 I want to give a special thanks to my team at CrowdStrike, just for helping with the presentation and the research, and giving me some feedback on that. 305 00:34:29,710 --> 00:34:37,730 Houston Hopkins from Capital One for some help with the one-liner commands and some cool tricks with the AWS CLI. 306 00:34:38,190 --> 00:34:44,430 And Rhino Security Labs for that previous research into ransomware and just AWS security in general. 307 00:34:45,370 --> 00:34:55,930 In the bottom right, you can see my Twitter handle there for if there's not sure how much time left we have for questions, but if there are any that don't get answered, feel free to reach out to me on there. 308 00:34:56,070 --> 00:35:02,110 But for that, I'll go ahead and just kind of open up and answer any questions that might be in the chat. 309 00:35:02,130 --> 00:35:09,690 Is object versioning and MFA delete good enough, or were you saying that you need to implement and do all five of those things? 310 00:35:10,710 --> 00:35:29,250 I think that object versioning and MFA delete are good for a couple of methods, but if you think of it like a local encryption method, if you downloaded the objects from the bucket, their threat could be we're going to release all this data. 311 00:35:29,650 --> 00:35:33,770 And so then versioning and MFA delete wouldn't do it. 312 00:35:34,150 --> 00:35:39,630 I like to always just follow defense in depth and implement as much as you can. 313 00:35:39,990 --> 00:35:47,610 Then it's hard to take into account the cost though, and then the work and changes that applies to your environment. 314 00:35:47,610 --> 00:35:53,970 But there's some of the best defenses, but it definitely won't protect you from everything essentially. 315 00:35:54,570 --> 00:35:55,610 Got it. 316 00:35:55,730 --> 00:36:02,170 And the second question from Skybound, I think you touched on this a little bit towards the end. 317 00:36:02,170 --> 00:36:11,290 For recovery in cases where decryption keys are within AWS, would AWS be able to help with their recovery and deal with the attacker? 318 00:36:11,290 --> 00:36:21,250 For example, with the KMS policy, basically expecting AWS to adjust the KMS policy so that the customer can get access back. 319 00:36:21,890 --> 00:36:24,290 So that's kind of where I was touching on. 320 00:36:24,290 --> 00:36:26,310 We don't know for sure. 321 00:36:27,550 --> 00:36:36,450 And then it brings up the question of how fast, you know, maybe it takes a support case and then a day or two goes by or something like that. 322 00:36:36,450 --> 00:36:38,970 And it's already, there's already a huge impact. 323 00:36:39,710 --> 00:36:56,310 I would say until there's an official statement or something along those lines, not that there needs to be one necessarily, but implementing your own defenses and detections is the way to go instead of relying on them to take care of you in the event that something goes wrong.