DEF CON 29 - Dimitry Op Nomad Snezhkov - Use of Offensive Enclaves In Adversarial Operations

Aug 5, 2021 17:35 · 3161 words · 15 minute read

- Hello, DEFCON. Welcome to Your House is My House.

00:06 - Use of Offensive Enclaves in Adversarial Operations.

00:10 - My name is Dimitry Snezhkov, and I’m part of protiviti, Attack and Penetration Testing Team, where I have a chance to do tooling, offensive research, and automation.

00:19 - Shout out to my team at protiviti for making that happen.

00:24 - So today we’re gonna talk about SGX technology as it applies to offensive operations.

00:29 - Being part of the offensive team and tasked with testing, I sometimes find myself, and we, as a team find ourselves, on unknown boxes, and sometimes we need to leverage the technology that exists there to be able to withstand the kinda the onslaught of EDR inspections or defensive technology inspections.

00:52 - And so SGX technology here was a curious case when a developer was using SGX technology to protect the trusted credentials and so the box was instrumented with SGX enclaves, which we thought, why not use them? And how can we use them to further our goals of bringing payloads and taking care of secure communication for us.

01:22 - But first things first, SGX is a technology developed by Intel Corporation to essentially protect specific code or data from disclosure or modification to adversarial parties.

01:35 - Adversarial parties defined by Intel or SGX technology, is anybody who is running in non-ring three.

01:45 - For example, privileged system code, operating system, virtual hypervisor, managers, bios, all the things that kind of work around the hardware.

01:56 - And so SGX enclaves were born in technology that solved the issue of protecting areas, or tries to solve the issue of protected areas of execution and increased security on platforms that are considered to be compromised from all the contexts that runs around them.

02:19 - So SGX, as we’ve defined, SGX enclave is a trusted code, and it’s also linked into application.

02:26 - So the application, it kind of runs in two modes, split personality modes, one is the untrusted part of the code, and another is trusted part of the code.

02:36 - The trust that they’re safe, part of the code runs in the SGX enclave, which we construct and we interact with underlying bootstrapping, and orchestration platform to be able to execute or reach into the trusted area and execute a very specific operations from the untrusted memory, which is our application.

03:01 - That’s possible by SGX of introducing two new upcodes, of switching in and out of the trusted area over CPU, which is locked to the enclave or enclave is encrypted by CPU key.

03:17 - And so this technology is very kinda prevalent in the high security environments.

03:23 - Obviously, part of the wherever Intel Core processor, six plus generation lives on laptops, servers, and data centers, but also in cloud virtual machines.

03:37 - Namely, we found it on Azure DC level trusted computing machines.

03:42 - And so if we find ourselves as operators on those machines, we might be able to use some of that protection for our purposes.

03:51 - So the offensive goals for us here is kinda twofold.

03:55 - First is understand the technology, how to construct the application so we can actually invoke SGX and use enclaves to store our data, which is payloads or other things.

04:10 - Also use SGX technology and SDK to try and secure communications with our C2 without revealing keys that we use for our payload encryption.

04:22 - And then in the process, try to kinda have the EDR divert attention from us by splitting the kinda the deployment model between several components that are not fully assembled or introspected.

04:41 - And so in this case, we’re gonna do Windows as an example.

04:46 - we’re gonna create a system called exclave or kinda design, a method of communication between our cradle to load securely our payloads.

04:56 - Store them in the enclave on the box, but also hide the algorithm of encryption and the keys that kinda travel back and forth in clear text.

05:07 - And so the Windows is the example in this case, but the Linux side will be pretty much the same in concepts.

05:14 - Although, implementation may be a little bit different and hopefully, we’re gonna have fun going through those exercises.

05:21 - One thing to mention is that this talk is not about SGX vulnerabilities or SGX deep dives.

05:28 - We’re gonna touch on some of the relevant parts, but I refer to other great talks on that matter.

05:36 - The SGX components that will be interesting for us will be the platform software that gets installed to kinda interact with enclave.

05:47 - If we’re dropping into a box that has appropriate type of CPU, and we’re on the Windows, Microsoft Windows machine, then operating system would have already have the driver for it because that’s a standard update process for it.

06:07 - But you could obviously, have more a type of, have other type of platform software if you’re operating directly in the environment that SGX enclaves are used by developers to kinda help their applications be more secure.

06:25 - So there’s drivers there and the orchestration software such as attestation service which talks about and takes care of the kinda signing, and verifying the enclaves themselves to the owner and to the system i. e. the CPU.

06:44 - And also, the second part is the SDK, which we will use as part of the software development to create this application, which will utilize enclaves.

06:53 - There are two SDKs, we’re gonna take a look at Intel for the most part, but open enclave is also available for our purposes.

07:00 - And so the outcome of our efforts would be an application or a set of applications that will be created with trusted and untrusted parts.

07:10 - Trusted being an SDX enclave, and untrusted being all the bootstrapping code that allows us to share information with our C2 and process payloads from that.

07:21 - And then we’re gonna go into how high level mapping of the calls into C2, into trusted area happens, and how we can leverage some of the primitives in the SGX, SDK for our purposes.

07:35 - Such as configuration, signing and loading.

07:40 - Specifically the problem of payload transfer can be distilled to a few things.

07:45 - First of all, we do not want to load payloads in clear, we always want to protect.

07:51 - And commonly, we protect it with some XOR key maybe a AES key, but the problem is that the key itself maybe available in the memory because it’s shared key a lot of times.

08:03 - And so it’s inspectable, if not real-time in the sandbox, than in the forensic lab.

08:08 - And so if we’re running long-term campaign, we want to make sure we protect our keys in memory.

08:14 - And also, the other thing is the algorithm itself can be reversed and we can be pretty much our algorithm can be known.

08:24 - But not because we don’t wanna share the algorithm, but because that algorithm may point to weaknesses in our communication, which may be introspected and intercepted.

08:35 - And so, what we’re gonna do, the other goal is not only to store payloads, but also use SGX to secure communicate out to C2.

08:43 - To do that, there are a few alternatives. There’s some crypto libraries that come with PSW, the platform code in SDK, it’s SGX_TCRYTPO library, it is fairly limited in what it does because it’s purpose is to facilitate jobs of attestation and communication for session management, it’s not for general purpose crypto, but we can use some parts of it to construct what we want.

09:15 - We can also bring third-party to encryption, to work with that, for example, OpenSSL or wolfSSL library, but the problem is target availability.

09:26 - We do not know if these libraries runtime are gonna be available on the target.

09:31 - Plus, we want to stay away from loading things from disk as much as we can, and operate in the memory, and a lot of times it’s too heavy or impossible to load those libraries in memory.

09:42 - And the third possibility is obviously, with the limited kinda API that we have inside of the SGX enclave, the trusted area, we can roll our own, which is, probably discouraged in this exercise anyway.

10:01 - I’ve mentioned limited access to API and the SGX enclave, the reason being is because it is itself because of its kind of reason for existence to protect the code inside of it, is devoid of support for syscalls and it has a very limited IO in and out of enclave, mostly for state of preservation, but nothing less.

10:27 - So let’s see what we can do, what we’re gonna take the first approach is actually using TCRYPTO and see what we can do, how we can build it.

10:38 - So upon research, we kinda came up with three different things that we can do with that crypto in the SDK, we can generate an RSA key, actually a pair, a public and private key.

10:52 - We can actually sign something with our public key and well actually, encrypted with the public key and sign the private key, and we can actually use a routine that works on AES symmetric keys to be able to encrypt something of a value inside and potentially transfer that something, that piece of code or data outside of the enclave into untrusted area.

11:24 - And so the idea here would be for us to create an application where we do just that, the first step would be to generate RSA keys sat inside of the trusted PRM, inside of enclave, give the public key out to our C2, have it store there, and then go to C2, and C2 would be able to generate the symmetric key, send it to us inside of the trusted PRM, we’re gonna store the symmetric key and then we’re gonna have a shared symmetric key without leaking it so we can kinda generate the payload on the C2 side and then keep transferring it into our trusted PRM without having any inspection or being worried about the algorithm disclosure, or payload disclosure, or key disclosure.

12:17 - So it’s a three-step process. First, we’re generating public, private keys, we’re sending them to C2, C2 now has them then encrypts a symmetric key, sends it to us, we store it in a trusted component, which it decrypts the key because it was encrypted with RSA, which we already had from previous step, and now we just share the symmetric key between the two, and that’s how we achieve secure communication.

12:50 - And then, so components that we want to have in this sort of construction is we kinda thought of splitting it in three ways, the application, which will be inspectable by defense, it’s loaded from disk, it’s your kinda implant or cradle, or a loader.

13:09 - We went the route of establishing the bridge between enclave and that loader, which kinda facilitates and brokers interaction takes data from one process to another, but it’s also a kinda middleman that can be taken out of the equation upon first load so the EDR will not see all of the picture and the bridge can come in as a memory load of module, which will be able to kinda broker communication between the two, the enclave and the app at their own time.

13:40 - And so the bridge is also assumed inspectable and then enclave, which is assumed obfuscated and we’re gonna have some notes on that later on, in limitation section.

13:51 - But, yeah, so enclave is where we’re gonna store our keys and our algorithm.

13:58 - It will be loaded from disk, but it’s also a secure library, which may not be introspectable, and yeah, then we need to kinda start building that.

14:11 - And so we come up with that exclave system, which we’re gonna demo, and then we’ll come back to talk more about its construction limitations and all that other things.

14:24 - Let’s take a look at the exclave, its components and its operations.

14:29 - Here, we have a victim machine with an application, which is an agent or an implant.

14:34 - There’s a bridge DLL, which facilitates interaction with the enclave.

14:40 - It may or may not be on disk, it may or may not come directly from the network and being loaded that way in memory.

14:47 - And obviously, as we mentioned, there is a trusted piece of code that runs in PRM.

14:52 - It makes sense to kinda put the code in perspective and so far, is to explain those components.

14:58 - The application finds the bridge, the bridge function is invoked, which has explored, and found the bridge itself, maps through the EDL to the enclave calls.

15:12 - Here’s the EDL, essentially it’s a mapping or a matrix of trusted calls that we can invoke inside of enclave in untrusted calls that we are not.

15:24 - An enclave itself, is the trusted code that essentially does the processing, does the encryption and other things that we need to keep secure.

15:33 - And obviously on the other side, it’s a C2 that should be able to match the crypto parameters one-to-one, so it’s able to successfully decrypt and communicate with exclave that resides inside of the victim machine.

15:54 - And let’s take a look at how that works. So essentially we have two screens, one is the victim machine where all these components are deployed and there is a C2.

16:06 - Let’s start with the C2, it listens on the port and it’s responding to communication.

16:11 - Let’s start the application. And the first thing it does, it’s trying to create an enclave.

16:16 - It’s a standard procedure to create the memory mapping and launch things into existence.

16:23 - Once this is done, all checks happen, are we running on the machine that supports SGX? Are we able to create it, what are the parameters and permissions that had allow us or not allow us to do this? And then it’s trying to generate a RSA key pair for communication.

16:42 - Once this is done, the public key and private key, our available private key, it gets stored in enclave and publicly gets shared through the bridge, into the application, which connects to the C2 and solicits for a storage of this public key on our side.

16:59 - Once this happens, the C2 carries out the task.

17:03 - It does its processing, generates the symmetric key for communication and sends the response back to the application, which proxies it to the bridge into the enclave, which stores it, and this is what we’re doing here.

17:17 - So the shared key is now available, and now, we are ready to map one-to-one encryption of the payload, or would be payload that would come from C2 into the enclave again, through the app, through the bridge, into the secured area.

17:34 - And this is what happening here, we’re requesting that payload, the payload gets generated, in this case, it’s very contrived example, and it gets encrypted to match the mode of the capabilities of the enclave.

17:51 - All that processing happens and the payload travels back to the agent and ultimately to the enclave.

18:01 - And enclave, having the symmetric key is now able to decrypt the payload.

18:07 - After this is done, the payload gets stored in clear text in the enclave, but it’s protected from any kind of reachability from to defense, and then the attacker can actually work on that.

18:21 - And the last but not least, then once we created the enclave, we can destroy it if we don’t need it for whatever reason and the duration that we wanna use that.

18:31 - Once this is done, everything is good and we are ready to move on.

18:42 - Okay, so we’ve started presentation of how exclave works.

18:48 - There are some assumptions and limitations to this.

18:51 - First of all, it’s a bad coding practice, (chuckles) we are weakening the enclaves we’re using it, we’re misusing them.

18:58 - And so, but our idea is that while the technology it can be used as is, a lot of times EDRs did not inspect enclaves.

19:12 - In our testing, we were able to use the pre-release keys or in pre-release or debug mode where we’re able to compile that and then use the whitelisting, testing, signing keys to do that, it will, in theory, that should prevent us from debugging into it, which is true, the EDRs themselves did not actually make the leap on and inspecting enclaves anyway.

19:37 - And so the other side of the story is that in order to do it properly, you need to assign at the station key and have Intel provision one, and sign it with a true key and then you can sign your enclave, which will be undebugable.

19:52 - But in this case, you’re running into attestation, meaning attribution issue.

19:57 - And so we kinda went data route and said, Hey, what can we do with pre-release or debug versions of it? And so I did not attested the enclaves are supposed to be inspected, but in practice, they’re often not.

20:12 - And so, as we mentioned before, SGX provisioned the PSW services install or platform is installed and TCRYPTO, a library of cryptographic primitives is present so that should let us kinda live of the land once we arrive at SGX enabled machine.

20:35 - And you know, one thing to notice is that how do you help defenders kinda understand what the enclaves are and how to find the rogue ones is that you need to watch for signatures, identify non-approved SGX enclaves, the way you would do this, is you basically can have a really nice tool from Kudelski’s SGX fun, to dump your DLL and kinda see the details of that enclave, and kinda latch onto the keys that you have not provisioned.

21:06 - So I’d like to thank everybody who has gone to my talk, here’s the link to a proof of concept, the bridge library, the enclave of an application, which we’ve used in this presentation.

21:18 - Thank you very much. .