 Hello, DDS Stevens here, Senior Handler at the Internet Storm Center. This video is for my latest diary entry, the crypting cobalt strike traffic with keys extracted from process memory. So I did obtain a beacon from a malicious cobalt strike server. Let's analyze it with my tool 1768. So here it is. Here's the beacon and that is a configuration. So it's HTTP communication on port 80. The public key is not a public key for which I have found a private key and there is no indication of a private key being found. It will just use the usual get them post, get to get commands and post to post the results. And what is new now in this version of my tool 1768 is that for these fields, the manageable C2 instructions, HTTP get header and HTTP post header, I now do an analysis of parsing of the instructions. So what I did previously was just extract the strings and show the strings. But now I parse the instructions because that is something I have a need for now to decrypt traffic. Now in this case here, there is nothing special being done with the input and output. If you look at the input, the instruction for the input is just a print. So that means that the encrypted data will be decrypted as it is received. It will not be transformed before decryption and the same with the output. After it has been encrypted, it will just be printed. So that means that it will just be passed along to the couple strike team server that malicious server without any transformations. So that beacon here that I just analyzed, as you can see, it's version 4.2. I did execute that beacon. I run it into in a sandbox with internet access and I let it communicate with the C2. And I also took a process memory dump of the running beacon. So with Procmon and I'm just doing a process dump of writable process memory because that's the only thing that I need here. With that process memory dump, I can search for the AES and HMAC encryption keys that are being used for the encryption of the communication. So the tool to use is CS extract key and then give it the memory dump. Now the tool here finds nothing. That is to be expected because the tool will find the keys inside the metadata if it is a version 3 beacon. Version 3 beacons keep their metadata longer in memory and it's more likely to be found while for version 4 it disappears very quickly for memory. So we don't have it here. What we need to do then is to find encrypted data in the capture file with Wireshark. I also captured the traffic. We need to find the encrypted data in the Wireshark traffic and then pass an example of such encrypted data to the tool and then the tool will do a kind of dictionary attack searching for keys inside the memory dump. Because for version 4, like I said, AES and HMAC key are inside the writable process memory, but there is nothing that identifies them. It's just a sequence of 16 random bytes. It's not like with the metadata that you have a header that indicates this is metadata for the key that is not the case. So the solution is to do this kind of dictionary attack. So I start the tool, see a sparse HTTP traffic. I tell it that I don't know the key for the moment, key unknown. And when I do this, it will present me the encrypted data. It will not attempt to decrypt the data. And I then give it the capture file. And then you can see here that there is an HTTP response for a GET request and that there is a POST request, both with encrypted data. So this is a command that was received and this is the result of the command that was posted back. This is the encrypted data, the task to be executed. And this is the encrypted data for the result, which is called a callback. It's encrypted with the same keys, but there is a slight difference. Here this is completely encrypted. You see everything looks random. While if you look here, you can see three bytes preceding this that are zero. And it's the following. The first four bytes of a callback, that is the size of the encrypted data. So here this is 40 exodysmal. So this data here, the length of that data is 40 exodysmal. And so 64, and as you can see that corresponds 64 plus 4 for this length here, that's 68. Now we can use either this data or this data to attempt to do a decryption. So I'm going to start with a task, my copied encrypted task data. And then I do an extract key, but I give it option task with that encrypted data like this. And here we have already found the keys. What the tool does, it looks for SHA256 with a null byte string inside the memory dump, because I've observed that the keys are found somewhere behind after that string. So to speed up the search, I do that search. And so from that position on, the tool will select 16 bytes, 16 consecutive bytes and try if it can decrypt and validate the signature of that data. If it is not the case, it just move on to the next sequence. So it's shift, it moves one byte up in the memory dump, takes again 16 bytes and so on until it finds AES key that does a decryption and an HMAC key that does the validation. Because that data is not only encrypted, it is also assigned the last 16 bytes here. That's an HMAC signature. And once those keys are found, they also combine together as the SHA256 of the row key. So the row key of the cobble strike beacon, a row key is just 16 bytes, 16 random bytes that are generated each time that the beacon is executed. And then the SHA256 of those 16 bytes that row key is calculated and the first half of that SHA256 that is the HMAC key and the second half that is the AES key. And once my tool has found that, it also tries to find the row key in memory, but here it did not find it. So now we can use this, I'm going to copy this key and I go back to my parse HTTP traffic tool and I give it the key instead of saying unknown, I give it the key. And then here you have the decrypted traffic. So the first packet that is decrypted is the response to an HTTP get request. Here you can see one element in the data is a timestamp when this packet was transmitted. So that is inside the packet itself, inside the encrypted data. The command is run command, it will execute the command interpreter, so CMD here on my sandbox and give it the who am I command. And then here you have the post request. So that is the result that is being sent back here. And here you can see the information that is being sent back. Now I did show you how to find the keys with a task. You can also do it with a callback. So let me copy a callback, then again run the extract key tool. Let's take this one here. And now instead of a task, I'm giving it a callback as input and it finds the same keys. So remember there is a difference in the, not actually in the encryption, but in the format of a task and a callback and that's why you have two different options. Now I'm going to interrupt this. Now when I run the tool here, it did find the keys. It is also possible that my tool will not find the keys. And that is the case when a sleep mask option has been set. And that means that the beacon will encode by default with the 13 byte long key doing XOR encoding, it will encode its data while it is sleeping. And since a beacon is sleeping most of the time, most of the time that process memory is then encoded and it will not be able to find it. But I have the tool to do that decoding and then you can run CS extract key and that is something that I will explain in an upcoming diary and video.