
Hi everyone, my name is Tim. I work at Bishop Fox and I'm one of the developers working on Sliver. This is a very improvised talk so please bear with me. The slides were only made yesterday, but let's talk a bit about Sliver. So, Sliver is one of the well-known C2 platforms used by red teams. Specifically, it's the type of tool that you'd use in a security assessment that requires stealth, where you need to evade detections, try to stay under the radar, and slowly move your way across your target's environment.
Let's talk a bit about an assessment I had a while ago. As we typically do in these, we started with looking at their external parameter, searching for vulnerabilities and anything that could allow us to gain an entry point into our target's network. And lucky for us, after a while, we found an RCE. And it wasn't just an RCE. It was an RCE as the root user on some random web server. After a bit of enumeration on that host, we quickly noticed there was actually no EDR running on there. And even better, looking at the network interfaces, it seemed to have some way to pivot to the on-premise environment. At this point, this is really the perfect scenario for us. We have a pivot point. We can quickly deploy some implant on there and use it to start targeting our client's internal network. Basically, jackpot.
However, after a couple hours, we lost access. All our beacons died and we were no longer able to reach into the environment at all. So, as we typically do in these scenarios, we started doing some investigation trying to find out what actually happened. We talked with our clients and as far as we could tell, the domain was good. Our implants weren't causing any alerts in their logs or anything like that. We just couldn't figure out what had happened. It turned out later on the client had actually caught it through the network traffic for a very simple reason: they had been compromised with Sliver before. So they wrote some customized detections and got us caught. Pretty dumb scenario.
So at that point in time I started taking a look at how Sliver actually handled its HTTP traffic to see if I could maybe improve on that. To give you a quick description, this is the situation in Sliver 1.5. When you generate your implants, you have a single C2 configuration where you define extensions for the different operations that your implant is going to do and a bunch of URLs, a bunch of paths, and your implant will just generate your traffic on the fly. You end up with URLs that look essentially like this. The extensions always have to stay the same, and the rest is just procedurally generated based on the configuration that you provided. The configuration is going to be the same across all implants for that Sliver host, which means that over time you're going to see a lot of requests going to .js. Why? Because that is the one used for poll requests. Essentially, every time the implant is looking whether there's a new activity to run, it's going to call a .js URL, which ends up generating a lot of very predictable network traffic.
And so, the other thing that you have is by default you have this little URL parameter. This is actually an encoder ID. So it's used to determine what method the implant used to hide the data it's exchanging with its backend server. In this particular case for example, it's using an English language encoder, which is essentially data encoded in the lengths of the different words that you're seeing around the screen. It can also do PNGs and a few other things. But the problem is you always have the single ID. So if you start adding all of this up together, you start getting to a situation where it's actually possible to write some detections for this particular network traffic.
And so I spent the last 6 months essentially trying to address these problems, allowing more flexibility in the implant by removing the need for specific extensions, making sure that the content type actually matches the request. If you look at this here, we're calling it a JS file, but this is actually random English, or it could be a picture or anything else. And finally, also removing the need for that encoder ID, allowing to hide it in other places like for example in cookies or inside the URL instead of a random parameter.
So what you're seeing here is the latest release as of Thursday, where I've implemented a lot of these fixes. Essentially what you'll see here is, first of all, we actually allow having multiple C2 profiles now. So you're no longer tied to one specific type of traffic, but rather you have the ability to switch between as many as you want. You can have — here we go — you can have as many extensions as you want, and the implant will just randomly pivot between all of these. For each extension, you will have specific types of encoder that are specified, which allow you to tie the right content type to the right network traffic request and kind of avoid that small discrepancy there.
And so essentially when you generate your implant, you now just specify whichever C2 profile you wanted to use. Once it starts running, we'll have a look at the logs here. You can see that it now no longer has that URL parameter because in this particular case, it's hiding it inside of the URL. It's randomly switching extensions as it goes on, which makes it a lot more difficult to fingerprint using the methods that the client had used in that assessment I mentioned earlier.
So this is it for my talk. Sorry it's pretty short. We have a website with our documentation and this is an open source project. So if you want to contribute or learn more about the tool, here you go.
Hello. Thanks for your talk. It was short but great. Question for you. Do you have the ability, or have you considered, to do malleable C2 profiles and using CDNs to kind of blend in with traffic with Azure domains and other legitimate domains, for example like Cobalt Strike would do?
So we actually do use these domains, but this isn't something that we've included in the tool itself. It's more automation that we build on top of this. As far as malleable C2 profiles, this is another ongoing project that we're working on, but it is not currently included in Sliver itself.