SharpNado - Teaching an old dog evil tricks using .NET Remoting or WCF to host smarter and dynamic payloads
TL;DR:
SharpNado is proof of concept tool that demonstrates how one could use .Net Remoting or Windows Communication Foundation (WCF) to host smarter and dynamic .NET payloads. SharpNado is not meant to be a full functioning, robust, payload delivery system nor is it anything groundbreaking. It's merely something to get the creative juices flowing on how one could use these technologies or others to create dynamic and hopefully smarter payloads. I have provided a few simple examples of how this could be used to either dynamically execute base64 assemblies in memory or dynamically compile source code and execute it in memory. This, however, could be expanded upon to include different kinds of stagers, payloads, protocols, etc.
So, what is WCF and .NET Remoting?
While going over these is beyond the scope of this blog, Microsoft describes Windows Communication Foundation as a framework for building service-oriented applications and .NET Remoting as a framework that allows objects living in different AppDomains, processes, and machines to communicate with each other. For the sake of simplicity, let's just say one of its use cases is it allows two applications living on different systems to share information back and forth with each other. You can read more about them here:
WCF
.NET Remoting
A few examples of how this could be useful:
1. Smarter payloads without the bulk
What do I mean by this? Since WCF and .NET Remoting are designed for communication between applications, it allows us to build in logic server side to make smarter decisions depending on what information the client (stager) sends back to the server. This means our stager can still stay small and flexible but we can also build in complex rules server side that allow us to change what the stager executes depending on environmental situations. A very simple example of payload logic would be the classic, if domain user equals X fire and if not don't. While this doesn't seem very climatic, you could easily build in more complex rules. For example, if the domain user equals X, the internal domain is correct and user X has administrative rights, run payload Y or if user X is a standard user, and the internal domain is correct, run payload Z. Adding to this, we could say if user X is correct, but the internal domain is a mismatch, send back the correct internal domain and let me choose if I want to fire the payload or not. These back-end rules can be as simple or complex as you like. I have provided a simple sandbox evasion example with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.
2. Payloads can be dynamic and quickly changed on the fly:
Before diving into this, let's talk about some traditional ways of payload delivery first and then get into how using a technology like WCF or .NET Remoting could be helpful. In the past and even still today, many people hard-code their malicious code into the payload sent, often using some form of encryption that only decrypts and executes upon meeting some environmental variable or often they use a staged approach where the non-malicious stager reaches out to the web, retrieves our malicious code and executes it as long as environmental variables align. The above examples are fine and still work well even today and I am in no way tearing these down at all or saying better ways don't exist. I am just using them as a starting point to show how I believe the below could be used as a helpful technique and up the game a bit, so just roll with it.
So what are a few of the pain points of the traditional payload delivery methods? Well with the hard-coded payload, we usually want to keep our payloads small so the complexity of our malicious code we execute is minimal, hence the reason many use a stager as the first step of our payload. Secondly, if we sent out 10 payloads and the first one gets caught by end point protection, then even if the other 9 also get executed by their target, they too will fail. So, we would have to create a new payload, pick 10 new targets and again hope for the best.
Using WCF or .NET Remoting we can easily create a light stager that allows us to quickly switch between what the stager will execute. We can do this either by back-end server logic as discussed above or by quickly setting different payloads within the SharpNado console. So, let's say our first payload gets blocked by endpoint protection. Since we already know our stager did try to execute our first payload due to the way the stager/server communicate we can use our deductive reason skills to conclude that our stager is good but the malicious code it tried to execute got caught. We can quickly, in the console, switch our payload to our super stealthy payload and the next time any of the stagers execute, the super stealthy payload will fire instead of the original payload which got caught. This saves us the hassle of sending a new payload to new targets. I have provided simple examples of how to do this with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.
3. Less complex to setup:
You might be thinking to yourself that I could do all this with mod rewrite rules and while that is absolutely true, mod rewrite rules can be a little more complex and time consuming to setup. This is not meant to replace mod rewrite or anything. Long live mod rewrite! I am just pointing out that writing your back-end rules in a language like C# can allow easier to follow rules, modularization, and data parsing/presentation.
4. Payloads aren't directly exposed:
What do I mean by this? You can't just point a web browser at your server IP and see payloads hanging out in some open web directory to be analyzed/downloaded. In order to capture payloads, you would have to have some form of MiTM between the stager and the server. This is because when using WCF or .NET Remoting, the malicious code (payload) you want your stager to execute along with any complex logic we want to run sits behind our remote server interface. That remote interface exposes only the remote server side methods which can then be called by your stager. Now, if at this point you are thinking WTF, I encourage you to review the above links and dive deeper into how WCF or .NET Remoting works. As there are many people who explain it and understand it better than I ever will.
Keep in mind, that you would still want to encrypt all of your payloads before they are sent over the wire to better protect your payloads. You would also want to use other evasion techniques, for example, amount of times the stager has been called or how much time has passed since the stager was sent, etc.
Examples:
Simple dynamic + encrypted payload example:
In the first example we will use SharpNado to host a base64 version of SharpSploitConsole and execute Mimikatz logonpasswords function. First, we will setup our XML payload template that the server will be able to use when our stager executes. Payload template examples can be found on GitHub in the Payloads folder. Keep in mind that the ultimate goal would be to have many payload templates already setup that you could quickly switch between. The below screenshots give an example of what the template would look like.
Template example:
This is what it would look like after pasting in base64 code and setting arguments:
Once we have our template payload setup, we can go ahead and run SharpNado_x64.exe (with Administrator rights) and setup our listening service that our stager will call out to. In this example we will use WCF over HTTP on port 8080. So, our stager should be setup to connect to http://192.168.55.250:8080/Evil. I would like to note two things here. First is that with a little bit of work upfront server side, this could be modified to support HTTPS and secondly, SharpNado does not depend on the templates being setup prior to running. You can add/delete/modify templates any time while the server is running using whatever text editor you would like.
Now let's see what payloads we currently have available. Keep in mind you may use any naming scheme you would like for your payloads. I suggest naming payloads and stagers what makes most sense to you. I only named them this way to make it easier to follow along.
In this example I will be using the b64SharpSploitConsole payload and have decided that I want the payload to be encrypted server side and decrypted client side using the super secure password P@55w0rd. I would like to note here (outlined in red) that it is important for you to set your payload directory correctly. This directory is what SharpNado uses to pull payloads. A good way to test this is to run the command "show payloads" and if your payloads show up, you know you set it correctly.
Lastly, we will setup our stager. Since I am deciding to encrypt our payload, I will be using the example SharpNado_HTTP_WCF_Base64_Encrypted.cs stager example found in the Stagers folder on GitHub. I will simply be compiling this and running the stager exe but this could be delivered via .NetToJScript or by some other means if you like.
Now that we have compiled our stager, we will start the SharpNado service by issuing the "run" command. This shows us what interface is up and what the service is listening on, so it is good to check this to make sure again, that everything is setup correctly.
Now when our stager gets executed, we should see the below.
And on our server side we can see that the encrypted server method was indeed called by our stager. Keep in mind, we can build in as much server logic as we like. This is just an example.
Now for demo purposes, I will quickly change the payload to b64NoPowershell_ipconfig_1 and when we run the same exact stager again, we instead will show our ipconfig information. Again, this is only for simple demonstration of how you can quickly change out payloads.
Simple sandbox evade example:
In this second example I will go over an extremely watered-down version of how you could use SharpNado to build smarter payloads. The example provided with SharpNado is intended to be a building block and could be made as complex or simple as you like. Since our SharpNado service is already running from or previous example, all we need to do is set our payloads to use in the SharpNado console. For this example, I again will be using the same payloads from above. I will run the b64SharpSploitConsole payload if we hit our correct target and the b64NoPowershell_ipconfig_1 payload if we don't hit our correct target.
Looking at our simple stager example below we can see that if the user anthem is who executed our stager, the stager will send a 1 back to the SharpNado service or a 0 will be sent if the user isn't anthem. Please keep in mind you could however send back any information you like, including username, domain, etc.
Below is a partial screenshot of the example logic I provided with SharpNado. Another thing I want to point out is that I provided an example of how you could count how many times the service method has been called and depending on threshold kill the service. This would be an example of building in counter measures if we think we are being analyzed and/or sand-boxed.
Moving forward when we run our stager with our anthem user, we can see that we get a message server side and that the correct payload fired.
Now if I change the user to anthem2 and go through the process again. We can see that our non-malicious payload fires. Keep in mind, the stagers could be setup in a way that values aren't hard coded in. You could have a list of users on your server and have your stager loop through that list and if anything matches, execute and if not do something else. Again, it's really up to your imagination.
Compile source code on the fly example:
Let's do one more quick example but using C# source code. This stager method will use System.CodeDom.Compiler which does shortly drop stuff to disk right before executing in memory but one could create a stager that takes advantage of the open source C# and VB compiler Roslyn to do the same thing. This doesn't touch disk as pointed out by @cobbr_io in his SharpShell blog post.
The below payload template example runs a No PowerShell payload that executes ipconfig but I also provided an example that would execute a PowerShell Empire or PowerShell Cobalt Strike Beacon on GitHub:
Then we will setup our stager. In this example I will use the provided GitHub stager SharpNado_HTTP_WCF_SourceCompile.cs.
We will then take our already running SharpNado service and quickly add our payload.
Now when we run our stager, we should see our ipconfig output.
Conclusion:
Hopefully this has been a good intro to how one could use WCF or .NET Remoting offensively or at least sparked a few ideas for you to research on your own. I am positive that there are much better ways to accomplish this, but it was something that I came across while doing other research and I thought it would be neat to whip up a small POC. Till next time and happy hacking!
Link to tools:
SharpNado - https://github.com/anthemtotheego/SharpNado
SharpNado Compiled Binaries - https://github.com/anthemtotheego/SharpNado/tree/master/CompiledBinaries
SharpSploitConsole - https://github.com/anthemtotheego/SharpSploitConsole
SharpSploit - https://github.com/cobbr/SharpSploit
SharpNado is proof of concept tool that demonstrates how one could use .Net Remoting or Windows Communication Foundation (WCF) to host smarter and dynamic .NET payloads. SharpNado is not meant to be a full functioning, robust, payload delivery system nor is it anything groundbreaking. It's merely something to get the creative juices flowing on how one could use these technologies or others to create dynamic and hopefully smarter payloads. I have provided a few simple examples of how this could be used to either dynamically execute base64 assemblies in memory or dynamically compile source code and execute it in memory. This, however, could be expanded upon to include different kinds of stagers, payloads, protocols, etc.
So, what is WCF and .NET Remoting?
While going over these is beyond the scope of this blog, Microsoft describes Windows Communication Foundation as a framework for building service-oriented applications and .NET Remoting as a framework that allows objects living in different AppDomains, processes, and machines to communicate with each other. For the sake of simplicity, let's just say one of its use cases is it allows two applications living on different systems to share information back and forth with each other. You can read more about them here:
WCF
.NET Remoting
A few examples of how this could be useful:
1. Smarter payloads without the bulk
What do I mean by this? Since WCF and .NET Remoting are designed for communication between applications, it allows us to build in logic server side to make smarter decisions depending on what information the client (stager) sends back to the server. This means our stager can still stay small and flexible but we can also build in complex rules server side that allow us to change what the stager executes depending on environmental situations. A very simple example of payload logic would be the classic, if domain user equals X fire and if not don't. While this doesn't seem very climatic, you could easily build in more complex rules. For example, if the domain user equals X, the internal domain is correct and user X has administrative rights, run payload Y or if user X is a standard user, and the internal domain is correct, run payload Z. Adding to this, we could say if user X is correct, but the internal domain is a mismatch, send back the correct internal domain and let me choose if I want to fire the payload or not. These back-end rules can be as simple or complex as you like. I have provided a simple sandbox evasion example with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.
2. Payloads can be dynamic and quickly changed on the fly:
Before diving into this, let's talk about some traditional ways of payload delivery first and then get into how using a technology like WCF or .NET Remoting could be helpful. In the past and even still today, many people hard-code their malicious code into the payload sent, often using some form of encryption that only decrypts and executes upon meeting some environmental variable or often they use a staged approach where the non-malicious stager reaches out to the web, retrieves our malicious code and executes it as long as environmental variables align. The above examples are fine and still work well even today and I am in no way tearing these down at all or saying better ways don't exist. I am just using them as a starting point to show how I believe the below could be used as a helpful technique and up the game a bit, so just roll with it.
So what are a few of the pain points of the traditional payload delivery methods? Well with the hard-coded payload, we usually want to keep our payloads small so the complexity of our malicious code we execute is minimal, hence the reason many use a stager as the first step of our payload. Secondly, if we sent out 10 payloads and the first one gets caught by end point protection, then even if the other 9 also get executed by their target, they too will fail. So, we would have to create a new payload, pick 10 new targets and again hope for the best.
Using WCF or .NET Remoting we can easily create a light stager that allows us to quickly switch between what the stager will execute. We can do this either by back-end server logic as discussed above or by quickly setting different payloads within the SharpNado console. So, let's say our first payload gets blocked by endpoint protection. Since we already know our stager did try to execute our first payload due to the way the stager/server communicate we can use our deductive reason skills to conclude that our stager is good but the malicious code it tried to execute got caught. We can quickly, in the console, switch our payload to our super stealthy payload and the next time any of the stagers execute, the super stealthy payload will fire instead of the original payload which got caught. This saves us the hassle of sending a new payload to new targets. I have provided simple examples of how to do this with SharpNado that could be expanded upon and a quick walk through of it in the examples section below.
3. Less complex to setup:
You might be thinking to yourself that I could do all this with mod rewrite rules and while that is absolutely true, mod rewrite rules can be a little more complex and time consuming to setup. This is not meant to replace mod rewrite or anything. Long live mod rewrite! I am just pointing out that writing your back-end rules in a language like C# can allow easier to follow rules, modularization, and data parsing/presentation.
4. Payloads aren't directly exposed:
What do I mean by this? You can't just point a web browser at your server IP and see payloads hanging out in some open web directory to be analyzed/downloaded. In order to capture payloads, you would have to have some form of MiTM between the stager and the server. This is because when using WCF or .NET Remoting, the malicious code (payload) you want your stager to execute along with any complex logic we want to run sits behind our remote server interface. That remote interface exposes only the remote server side methods which can then be called by your stager. Now, if at this point you are thinking WTF, I encourage you to review the above links and dive deeper into how WCF or .NET Remoting works. As there are many people who explain it and understand it better than I ever will.
Keep in mind, that you would still want to encrypt all of your payloads before they are sent over the wire to better protect your payloads. You would also want to use other evasion techniques, for example, amount of times the stager has been called or how much time has passed since the stager was sent, etc.
5. Been around awhile:
.NET Remoting and WCF have been around a long time. There are tons of examples out there from developers on lots of ways to use this technology legitimately and it is probably a pretty safe bet that there are still a lot of organizations using this technology in legit applications. Like you, I like exposing ways one might do evil with things people use for legit purposes and hopefully bring them to light. Lastly, the above concepts could be used with other technologies as well, this just highlights one of many ways to accomplish the same goal.
.NET Remoting and WCF have been around a long time. There are tons of examples out there from developers on lots of ways to use this technology legitimately and it is probably a pretty safe bet that there are still a lot of organizations using this technology in legit applications. Like you, I like exposing ways one might do evil with things people use for legit purposes and hopefully bring them to light. Lastly, the above concepts could be used with other technologies as well, this just highlights one of many ways to accomplish the same goal.
Examples:
Simple dynamic + encrypted payload example:
In the first example we will use SharpNado to host a base64 version of SharpSploitConsole and execute Mimikatz logonpasswords function. First, we will setup our XML payload template that the server will be able to use when our stager executes. Payload template examples can be found on GitHub in the Payloads folder. Keep in mind that the ultimate goal would be to have many payload templates already setup that you could quickly switch between. The below screenshots give an example of what the template would look like.
Template example:
This is what it would look like after pasting in base64 code and setting arguments:
Once we have our template payload setup, we can go ahead and run SharpNado_x64.exe (with Administrator rights) and setup our listening service that our stager will call out to. In this example we will use WCF over HTTP on port 8080. So, our stager should be setup to connect to http://192.168.55.250:8080/Evil. I would like to note two things here. First is that with a little bit of work upfront server side, this could be modified to support HTTPS and secondly, SharpNado does not depend on the templates being setup prior to running. You can add/delete/modify templates any time while the server is running using whatever text editor you would like.
Now let's see what payloads we currently have available. Keep in mind you may use any naming scheme you would like for your payloads. I suggest naming payloads and stagers what makes most sense to you. I only named them this way to make it easier to follow along.
In this example I will be using the b64SharpSploitConsole payload and have decided that I want the payload to be encrypted server side and decrypted client side using the super secure password P@55w0rd. I would like to note here (outlined in red) that it is important for you to set your payload directory correctly. This directory is what SharpNado uses to pull payloads. A good way to test this is to run the command "show payloads" and if your payloads show up, you know you set it correctly.
Lastly, we will setup our stager. Since I am deciding to encrypt our payload, I will be using the example SharpNado_HTTP_WCF_Base64_Encrypted.cs stager example found in the Stagers folder on GitHub. I will simply be compiling this and running the stager exe but this could be delivered via .NetToJScript or by some other means if you like.
Now that we have compiled our stager, we will start the SharpNado service by issuing the "run" command. This shows us what interface is up and what the service is listening on, so it is good to check this to make sure again, that everything is setup correctly.
Now when our stager gets executed, we should see the below.
And on our server side we can see that the encrypted server method was indeed called by our stager. Keep in mind, we can build in as much server logic as we like. This is just an example.
Now for demo purposes, I will quickly change the payload to b64NoPowershell_ipconfig_1 and when we run the same exact stager again, we instead will show our ipconfig information. Again, this is only for simple demonstration of how you can quickly change out payloads.
Simple sandbox evade example:
In this second example I will go over an extremely watered-down version of how you could use SharpNado to build smarter payloads. The example provided with SharpNado is intended to be a building block and could be made as complex or simple as you like. Since our SharpNado service is already running from or previous example, all we need to do is set our payloads to use in the SharpNado console. For this example, I again will be using the same payloads from above. I will run the b64SharpSploitConsole payload if we hit our correct target and the b64NoPowershell_ipconfig_1 payload if we don't hit our correct target.
Looking at our simple stager example below we can see that if the user anthem is who executed our stager, the stager will send a 1 back to the SharpNado service or a 0 will be sent if the user isn't anthem. Please keep in mind you could however send back any information you like, including username, domain, etc.
Below is a partial screenshot of the example logic I provided with SharpNado. Another thing I want to point out is that I provided an example of how you could count how many times the service method has been called and depending on threshold kill the service. This would be an example of building in counter measures if we think we are being analyzed and/or sand-boxed.
Moving forward when we run our stager with our anthem user, we can see that we get a message server side and that the correct payload fired.
Now if I change the user to anthem2 and go through the process again. We can see that our non-malicious payload fires. Keep in mind, the stagers could be setup in a way that values aren't hard coded in. You could have a list of users on your server and have your stager loop through that list and if anything matches, execute and if not do something else. Again, it's really up to your imagination.
Compile source code on the fly example:
Let's do one more quick example but using C# source code. This stager method will use System.CodeDom.Compiler which does shortly drop stuff to disk right before executing in memory but one could create a stager that takes advantage of the open source C# and VB compiler Roslyn to do the same thing. This doesn't touch disk as pointed out by @cobbr_io in his SharpShell blog post.
The below payload template example runs a No PowerShell payload that executes ipconfig but I also provided an example that would execute a PowerShell Empire or PowerShell Cobalt Strike Beacon on GitHub:
Then we will setup our stager. In this example I will use the provided GitHub stager SharpNado_HTTP_WCF_SourceCompile.cs.
We will then take our already running SharpNado service and quickly add our payload.
Now when we run our stager, we should see our ipconfig output.
Conclusion:
Hopefully this has been a good intro to how one could use WCF or .NET Remoting offensively or at least sparked a few ideas for you to research on your own. I am positive that there are much better ways to accomplish this, but it was something that I came across while doing other research and I thought it would be neat to whip up a small POC. Till next time and happy hacking!
Link to tools:
SharpNado - https://github.com/anthemtotheego/SharpNado
SharpNado Compiled Binaries - https://github.com/anthemtotheego/SharpNado/tree/master/CompiledBinaries
SharpSploitConsole - https://github.com/anthemtotheego/SharpSploitConsole
SharpSploit - https://github.com/cobbr/SharpSploit
Comments
Post a Comment