WEBVTT

00:00.000 --> 00:01.440
All right, we're back.

00:01.580 --> 00:09.880
And thank you, Alvaro, for supporting the community, supporting DEF CON, for, of course, presenting here, and definitely supporting the Red Team Village as well.

00:10.820 --> 00:13.260
We're glad to have you here, and the floor is yours.

00:13.260 --> 00:14.100
Take it away.

00:14.480 --> 00:15.620
Thank you so much, Omar.

00:15.620 --> 00:19.900
I'm so happy to be here another year presenting the DEF CON Red Team Village.

00:19.980 --> 00:24.760
Welcome to Total Eagresio, Evading Intrusion Detection System for Stealthier Implants.

00:24.780 --> 00:27.260
So, first of all, I would like to introduce myself.

00:27.260 --> 00:35.560
My name is Alvaro Folgado, hashtag Rebuhacker, and I was a product security engineer where I perform a lot of software and architecture security reviews.

00:35.560 --> 00:41.820
I do a lot of offensive appsec, bug hunting, a little bit of research about this last topic.

00:41.820 --> 00:49.540
But in my free time, I have been spending more or less the last two years working on a main project that is an implant framework.

00:49.760 --> 00:51.380
It's kind of divided in two parts.

00:51.380 --> 00:55.220
The first part is the C2 operation manager, that is grown on Golang.

00:55.720 --> 01:00.660
Most of it, like, it used Terraform to deploy, like, infrastructure, proxies, and redirectors.

01:00.660 --> 01:09.080
And the other half is the modular Vegeto that is grown on Go, C++, and OGTC to perform a little bit more of, like, native action over the target device.

01:09.080 --> 01:16.020
I have the lag in the past, as I say, to present this framework on the DEF CON Red Team Village of the past year alongside Shellcon.

01:16.020 --> 01:22.760
I am here again to speak a little bit of this kind of same topic, but connected to other stuff that I'm gonna develop.

01:22.760 --> 01:38.680
So the connection here, it's, you know, in the last year when I was presenting this framework, one of the stuff that I was kind of most proud about is, like, the ability of my implant of egressing, not just using HTTPS against a custom server, but using Gmail itself.

01:39.040 --> 01:46.960
And I was saying in my talk, like, you know, give me a string to egress and I should hack the planet because, you know, you can use Gmail, but you can use any other software service.

01:47.240 --> 01:51.100
And from that talk, I got an amazing amount of cool feedback.

01:51.100 --> 02:06.660
But, you know, one of the most interesting one was from one Blue Team engineer back then that told me, you know, this looks cool, but you know that by analyzing some header of your flow, like the TLS fingerprints, we could perfectly detect that that's a Go HTTP client.

02:06.660 --> 02:13.280
And , you know, if we kind of, while this is the kind of software we have in the domain host of a corporate network, that will look sketchy.

02:13.280 --> 02:23.640
So I was like, okay, so you're telling me I am egressing through Gmail, but still not even by, you know, doing a deep packet inspection, we are able to detect I'm using some kind of malware.

02:23.740 --> 02:25.820
So, you know, this really triggered my attention.

02:25.820 --> 02:46.880
So I focused my next year research on them towards like creating kind of an skeletal network model, not just for my tool, but also as a piece of code for every, everything around the community to be able to use this for bypassing this kind of filtering of this kind of rules that the Blue Team could have deployed in a corporate network.

02:46.880 --> 03:08.020
So, you know, if we focus on this, you know, on this field and we really want to like look stealthy on the network level, I wanted to start a little bit like a high level vision of kind of the different techniques that the Blue Team could deploy in a corporate network towards detecting or running implant in a foothold just by looking at the network package.

03:08.020 --> 03:11.580
So I like to divide in kind of like two big parts, right?

03:11.580 --> 03:23.900
We have all the deep packet inspection techniques where, you know, somehow the Blue Team has deployed the infrastructure to force every domain host network package to go through a proxy, right?

03:23.900 --> 03:33.100
And this proxy normally is a TLS proxy that filter out all this flow and make the target operating system all up to accept the certificates.

03:33.100 --> 03:35.740
So I can deep look at the body of the flow.

03:35.740 --> 03:49.940
And then, you know, by looking at this body, I can get kind of common strings that match to malware and I can try to create a set of fine grained rules to detect which one are the flows that match most common like indicative of compromise and most common like problems,

03:49.940 --> 03:50.600
right?

03:50.820 --> 03:54.740
But I'm not gonna get still really deep into these techniques.

03:54.740 --> 03:58.560
I want to focus a little bit in not deep packet inspection techniques, right?

03:58.980 --> 04:06.980
That those techniques will be focused not in what the body of the payload is, but more in things like where the aggression is going, right?

04:06.980 --> 04:10.220
Which is the server or foothold is connecting to.

04:10.520 --> 04:19.800
So, you know, the Blue Team will start to look at things like a sketchy IP range, or if we are using some kind of service like Amazon or Azure, they can start to look at the domain, right?

04:19.800 --> 04:21.500
Which kind of domain we are using.

04:21.540 --> 04:28.880
And if we use something like domain fronting, they start to look at, oh, which kind of operating system or software is listening to the connection, right?

04:28.880 --> 04:33.520
Which kind of certificate is this server like serving?

04:33.520 --> 04:35.460
Is self-signed or not?

04:35.700 --> 04:41.220
And then they will also could look at the wire itself, you know, which kind of protocol we are using.

04:41.220 --> 04:48.600
If there is a huge amount of package load on a DNS aggression, you know, they could say, oh, something is going on here.

04:48.640 --> 05:01.920
So, you know, if we come back to the concept of aggressing to a software as a service, like email, then we can finish with all the problems of detection by the endpoint, almost all of them.

05:01.920 --> 05:12.060
And we can do this easily because if it's a software as a service, it has the opportunity to modify on a string, we can make our foothold to communicate through the C2 just by pulling, pushing data on it.

05:12.460 --> 05:22.100
And now it's where you come to the funny part, like we have finished with the problem with the endpoint, but still the blue team has powerful tools to analyze which kind of HTTP client we're using.

05:22.100 --> 05:25.840
And they can say, oh, this domain host is using a common browser.

05:25.840 --> 05:33.440
That looks good to me, but oh, this human resource laptop is running a Python script to go to whatever server or a Go client.

05:33.440 --> 05:35.800
That kind of look a little bit more sketchy.

05:35.800 --> 05:52.340
So at the end of the day, the blue team has a powerful tool to analyze before breaking the encryption through TLS fingerprints, which kind of software the foothold is using for this, which kind of software we are using, or redirect, or proxy, or whatever,

05:52.340 --> 05:53.800
to receive the connection.

05:53.800 --> 05:58.340
And by matching both of them, they could get a really strong indicator of compromise.

05:59.140 --> 06:08.240
This will work similarly to like antivirus or host intrusive detective system, where they will extract a hash from the binary and compare it with a public database.

06:08.240 --> 06:17.900
Instead of now doing that with the binary, they will do that with a TLS handshake, and they will extract a certain number of bytes, perform a hash, and compare it with a public database.

06:17.900 --> 06:23.720
This is around a really interesting research that was done time ago by a bunch of blue team engineers.

06:23.920 --> 06:28.600
And alongside with this research, they publish it with this GA3 tool.

06:28.600 --> 06:29.960
This is a Python script.

06:30.260 --> 06:33.120
I'm going to do a little bit of a deep dive, what's going on.

06:33.120 --> 06:40.300
So let's imagine we're writing our implant, and now we need to think about how he's going to egress or how he's going to connect to the C2, right?

06:40.300 --> 06:51.800
So if we are going to use HTTPS, and a lot of you will say, okay, don't use HTTPS, use HTTP, but for some reason we need to use HTTPS, or endpoint for some reason uses HTTPS.

06:51.800 --> 06:55.500
The first thing that our implant will perform is opening a TCP socket.

06:55.860 --> 06:59.740
And following that TCP socket, the TLS handshake will start.

07:00.140 --> 07:14.120
And that TLS handshake has a lot of information on it, because first the client is going to tell to the server which kind of TLS version we want to use, which kind of C4CZ you want to use, but particularly which kind of extension you want to use.

07:14.120 --> 07:20.920
And a lot of these bytes, they're really related to the kind of software we are using or the kind of library we are using to write our implant.

07:21.000 --> 07:23.600
In the same way, the server will do the same.

07:23.700 --> 07:39.180
So the Python script will parse this pickup of, you know, if we're using YSHA or any other software to get them, and then we'll just select this package and we'll analyze the bytes, transform them in MD5 hash and match them to a really particular software.

07:39.600 --> 07:52.480
If we're writing with our implant, sometimes we rely on those libraries, and other times we're going to use some software that is already matched, and it's already like, give us a really particular alert to the blue timers.

07:52.940 --> 07:59.500
So if you follow the source code, you can go to the GF3 tool and see exactly what he's doing when you provide to the Python script a pickup.

07:59.540 --> 08:12.180
But if we go to the YSHA, and we start to listen to the flows, and we just open a browser that is performing HTTPS connection, we can easily filter those package and we can see what's going on.

08:12.180 --> 08:17.740
We can go to the header of the SQL Socket layer and we can see all these particular bytes that we have.

08:17.800 --> 08:26.760
And while TLS version and CIFS are kind of easy to modify, there is a bunch of extension that are assisted by the RFC that can be configured.

08:26.760 --> 08:42.080
So the Python script will just go over that set of package, divide those bytes in five section, transform them in hexadecimal, and then generate this MD5 hash that particularly match a certain version of a server for the client and the server.

08:42.220 --> 08:44.360
So, okay, where are the red timers?

08:44.620 --> 08:48.840
We know this is a problem and we know that we may be detected because of this.

08:48.900 --> 08:56.460
So now it's where it becomes the idea of blending in the network and trying to like evading these techniques, right?

08:56.460 --> 08:58.300
So I had a bunch of ideas.

08:58.300 --> 09:02.480
My first idea was, okay, I'm using a programming language.

09:02.480 --> 09:07.760
This programming language gave me the option to create my own HTTP client, choose the library I want to.

09:07.840 --> 09:21.320
But the problem is like most of the HTTP clients that accept TLS configuration, while they provide you a lot of bytes for configuring your own TLS handshake, they really don't provide you like an input where you can put all the bytes you like and the order you like.

09:21.320 --> 09:26.060
So you can have the hash to decide for copying another client software.

09:26.320 --> 09:28.520
So this was kind of a tricky one.

09:28.520 --> 09:37.460
So my next idea was, okay, I will just open a TCP socket and throw there my copy client hello package and see what happened.

09:37.460 --> 09:43.540
Obviously the TLS handshake breaks and it's not interesting to us because at the end of the day, we need to use HTTPS.

09:43.780 --> 09:54.400
So my last option were like getting a little bit my hands dirty and go and modify the source code of the programming language I was using in this case was Golang.

09:54.400 --> 09:59.080
So I will say, okay, I will add a feature and this is more or less how it works.

09:59.860 --> 10:10.780
So , you know, and I'm sort of similar in other languages that relate to which kind of language you're using for writing your input, but at least in Golang, when you want to address, you need to graph your HTTP client.

10:10.820 --> 10:15.860
And when you graph the HTTP client and you want to use HTTPS, you provide the TLS configuration that is like a struct.

10:17.080 --> 10:28.240
Before requesting to the endpoint with a post get, whatever HTTP request you want to, the language will go through the flow of crafting this TLS hello.

10:28.260 --> 10:34.780
And it will take kind of your configuration and then grab up the bytes and send them to perform the handshake.

10:34.780 --> 10:40.080
The problem is, I was telling before, we don't have a feature where we can like put whatever bytes we want to.

10:40.080 --> 10:48.080
So I modify the source code of Golang and HTTP client to accept in the TLS configuration, a new string input.

10:48.080 --> 10:53.520
And this string input will be exactly what the GF3 tool provide to us.

10:53.520 --> 11:02.280
So in that case, we can use like GF3 tool for copying a Chrome Firefox Opera browser and throwing in the compilation of our implant.

11:02.560 --> 11:20.900
In that way, when you go to TLS, the TLS flow, and you need to add another part of the code where you are like marshalling or creating this client hello, I added a for loop and for each hexadecimal value, I kind of copy a reference, which is the package or the syntax that respect the RPC.

11:21.020 --> 11:27.260
So if you have a bunch of hexadecimal bytes in the right order, you can extract the fingerprint of the browser you are targeting.

11:27.700 --> 11:41.380
It's true that a lot of them, and I'm sure this extension will be like modified with the time, but I have enough right now, entropy or availability of like hexadecimal bytes already caught for like accepting most of the browser.

11:41.380 --> 11:44.520
If you feel that you need more hexadecimal bytes, I will add them.

11:44.600 --> 11:45.300
There is no problem.

11:45.300 --> 11:48.260
The source code is already published in these links on GitHub.

11:48.480 --> 11:49.100
So, okay.

11:49.100 --> 11:58.580
Now we have the HTTPS client that we need for copying rightful connection of browsers and any other like software you like, antivirus, aggression, whatever.

11:58.900 --> 12:02.440
But now it came the problem that we want to address using Gmail.

12:16.020 --> 12:21.120
That I need to change on the source code.

12:21.480 --> 12:23.160
So that's it.

12:23.160 --> 12:31.640
I want to like provide you a flow of how this implant will work on the background, once we get the execution on the foothold.

12:31.800 --> 12:36.760
So when we craft our implant, the first thing we need to have is the Gmail connected app.

12:36.760 --> 12:40.200
We configure it and we provide those credentials to the C2.

12:40.200 --> 12:48.200
And the C2 on the completion of the implant will provide both the credential to the digital alongside with the TLS fingerprint.

12:48.260 --> 12:50.460
And then the implant will start with the aggression.

12:50.460 --> 12:55.920
And for aggression, the first thing he will do is using the refresh token against the Google authentication servers.

12:55.920 --> 13:01.820
And then when he get the access token, we will start to like push, pull information through Gmail.

13:01.820 --> 13:04.380
The C2 or the operation server will do similarly.

13:04.380 --> 13:11.040
And we could create a data connection for sending or receiving commands perfectly and totally transparent to the operator.

13:11.260 --> 13:18.740
At the eyes of the blue team that is looking to this proxy, it will just look like a Chrome browser, which is good to go.

13:20.260 --> 13:26.240
So to speak a little bit about DeepPacket inspection or how we can bypass or avoid this stuff.

13:26.240 --> 13:43.740
So , you know, if we have the bad luck that the sock or the scissor is gripping common string within or like flow against Gmail, we could kind of use some kind of later cryptography and share a symmetric key with the C2 and then common grips or common errors will not pop up.

13:43.740 --> 13:51.060
If we have the bad luck that it's a threat hunter catching our flows, we can also use other techniques like stenography.

13:51.060 --> 13:56.540
It wouldn't be as difficult because also Gmail provides us the ability to attach images to the draft emails.

13:57.220 --> 14:09.400
So a little bit of how the network model with the encryption will work in Siesta time is using the similar thing, putting on the body of the draft whatever JSON payload we want to process by height.

14:09.400 --> 14:14.240
But instead of just putting playing the strings, we can use like encrypting with the symmetric key.

14:14.560 --> 14:19.340
I have still not developed this full model, but it will be added to Siesta time in the future.

14:20.360 --> 14:22.920
So let's let's go ahead with the demo.

14:22.920 --> 14:31.540
So what I have created here is trying to reproduce this environment where the blue team has deployed this kind of detection technique in a network.

14:31.720 --> 14:33.600
I have created two different implants.

14:33.600 --> 14:35.860
This is the graphical interface of Siesta time.

14:35.860 --> 14:44.160
And alongside all the inputs that I'm not going to speak about each one of them, particularly we see here we have this TLS fingerprint with an extra 4G S3 tool.

14:44.160 --> 14:48.760
In that way, we can create different implants that mimic whatever connection we want to.

14:49.260 --> 14:58.680
If we focus a little bit the network topology of the demo, what this is going to look like I am using a BIMI workstation with three machines on it.

14:58.680 --> 15:13.200
But particularly interesting is we have the Windows 10 foothold that is going to run two different implants and every connection that I get through email is going to be read by a Ubuntu server that is a TLS proxy with Polar Proxy, which is not the most interesting.

15:13.200 --> 15:17.660
The important thing is running a Suricata network interface detection system.

15:18.120 --> 15:26.040
And you have a bunch of alerts just to like detect that if the TLS fingerprint is not going to the client to show me an alert, if not, you can go ahead.

15:26.080 --> 15:28.220
So let's go to the demo.

15:31.280 --> 15:34.660
So as you can see here, this is a graphical interface of siesta time.

15:34.660 --> 15:37.260
These are all the jobs that the Hive has processed already.

15:37.380 --> 15:39.980
And now we have two implants that are created.

15:40.400 --> 15:49.160
That means we can just download the executable and somehow we will make the foothold to execute through any attack vector we want to.

15:49.420 --> 15:54.640
So this is the Ubuntu machine that is listening to all the connection or the aggression of the foothold.

15:54.640 --> 15:56.880
And we have the Suricata running on it.

15:57.760 --> 16:00.560
Suricata will match the two following rules.

16:00.960 --> 16:09.340
These two rules, they're using a GS3 plugin for Suricata, and they will get the header of the TLS connection of every aggression package.

16:09.340 --> 16:11.480
They will generate an MD5 hash.

16:11.480 --> 16:15.180
If that hash match this one, we will pop up an alert.

16:15.580 --> 16:23.220
We can check that these two hashes, they match by the public database of GS3, a Go HTTP client.

16:26.490 --> 16:30.170
So let's search for the hash, similarly to VirusTotal, but with TLS fingerprints.

16:30.170 --> 16:32.330
We see this is a Go HTTP client, right?

16:33.290 --> 16:38.750
We are going to run the first implant in the Windows 10 foothold and we're going to be detected.

16:41.970 --> 16:50.510
So the interesting thing about these two is like, obviously, this Go client is going to be using the default configuration, but we can change things.

16:50.950 --> 16:56.750
But the cool thing about this is like, it doesn't matter how many configuration is changed by using a Go HTTP client.

16:56.750 --> 17:00.870
By the end of the day, all those hashes, they will be registered with this public database.

17:00.990 --> 17:03.650
So we have two appearances on the log of Suricata.

17:03.650 --> 17:10.850
And the reason is because I was saying before, one request is for getting the access token for the Google authorization servers.

17:10.850 --> 17:15.070
And the second one is for pushing, pulling data from Hive through Gmail.

17:15.770 --> 17:17.390
So let's clean the logs.

17:17.410 --> 17:27.350
And now we are going to do exactly the same, but using the implant that has been created with siesta time and with the TLS fingerprint of a Chrome browser.

17:30.250 --> 17:37.030
So the creation of the implant is just the same process, which is going to change with the execution of it and how we detect it.

17:37.030 --> 17:38.850
And the data flow is just the same.

17:38.850 --> 17:44.750
So let's execute the implant that now is copying the fingerprint of a Chrome browser.

17:45.550 --> 17:47.470
And let's go back to the Suricata.

17:47.490 --> 17:51.870
And we see there is no any log, but let's recheck what's going on.

17:51.870 --> 17:59.650
So let's open a Wireshark and start to detect and read all the packets that are going through the TLS proxy.

18:00.590 --> 18:06.190
And the objective of this is, since we maybe don't trust what Suricata is saying to us, right?

18:06.190 --> 18:10.570
Let's make sure that this fingerprint is a Chrome browser instead of a Go HTTP client.

18:10.570 --> 18:16.170
So let's filter, let's get all the main hello, and then let's export it in a pickup.

18:16.770 --> 18:26.650
And we can use this pickup for like a GS3 to parse it and tell to us which fingerprints of bytes is detecting from this aggression.

18:28.270 --> 18:34.690
This way will be the same that we need to follow if we need to copy the TLS fingerprint from any other rightful software.

18:35.310 --> 18:38.730
So here you see there is like this five section of bytes.

18:38.730 --> 18:43.590
This one will be the input for CSTATIME frame we want to generate an implant with these fingerprints.

18:43.590 --> 18:51.170
And there is two different MD5 hashes because as this is a TLS proxy, there is a second fingerprint for polar proxy itself.

18:51.190 --> 19:12.950
But if we go and we take the fingerprint of the implant, we are going to see that this is effectively the public database GS3 is effectively pointing it to a Chrome browser instead of a Go HTTP client or a Java client, Python client, whatever we have HTTP library we have used for our implant to address.

19:14.290 --> 19:21.730
So if we go back to CSTATIME graphical interface, we can see we already have the host infected.

19:21.830 --> 19:24.210
We have killed one implant.

19:24.210 --> 19:26.470
So that's offline, but the other is still alive.

19:26.630 --> 19:32.810
So now we can do things like, you know, injecting a shell or injecting a reverse SQL shell.

19:32.810 --> 19:36.730
We have all the information from the target host that we have infected.

19:36.770 --> 19:40.250
And we also have like, you know, an asynchronous interactive shell.

19:40.250 --> 19:44.770
And all these will happen totally transparent to the operator and through email.

19:44.770 --> 19:46.570
You see the fingerprints we need.

19:48.270 --> 20:03.930
So, I want to speak last but not least, how to help defender, how to make them better because at the end of the day, you know, the routing operation is have a lot of reason, but we want to make the defenders to be better, right?

20:03.930 --> 20:05.470
And to be prepared to this kind of attack.

20:05.470 --> 20:16.050
So if I focus on the network intrusive detecting techniques and in the TLS, a fingerprint detection, if you ask me if there is gap of improvement, I will say, yes.

20:16.790 --> 20:24.130
There is for one reason that the Python script of GS3, it's, you know, going through all these extensions by it.

20:24.130 --> 20:27.790
So they will, the big entropy happens, but it's just taking the headers.

20:27.790 --> 20:34.510
You know, the Python screen, we could write a new for loop for like getting more byte inside this like an onion layer, right?

20:34.510 --> 20:37.150
And this is something that GS3 is not doing right now.

20:37.150 --> 20:43.150
That we always generate more md5 hashes and more different entropy to search.

20:43.150 --> 20:43.890
But that's it.

20:43.890 --> 20:44.890
That's cool.

20:45.070 --> 20:49.610
But this is the catch of the mouse.

20:49.610 --> 20:54.770
If they do that, I will use another for loop in my HTTPS client and then we're in the same.

20:54.830 --> 21:07.350
What I think is interesting is not just using network intrusive detecting technique, but, you know, focusing on the host intrusive detecting techniques or now called EDR and trying to match kind of the two signatures and see if something is going on.

21:07.350 --> 21:15.730
I say this because while my VGTO is regressing really efficiently, this is still doing not so like a straightforward actions in the operating system.

21:15.890 --> 21:17.750
And, you know, this could be easily detected.

21:17.770 --> 21:25.750
Like , you know, when we can see md.x as a forward cell x or for persisting use, calling the APIs of a schedule that's on Windows.

21:25.910 --> 21:30.410
This could be like a little bit more like a shiny at the hour of detection.

21:31.870 --> 21:33.250
So that's everything.

21:33.250 --> 21:34.390
Thank you so much.

21:34.770 --> 21:37.630
The source code is already published for everything.

21:37.630 --> 21:42.190
And there is a user guide for the CSTATIME framework as well.

21:44.030 --> 21:46.810
I have the Discord and I can answer questions.

21:46.890 --> 21:48.630
So just let me know.

21:53.260 --> 21:53.700
Okay.

21:53.700 --> 21:53.880
Yeah.

21:53.880 --> 21:55.920
The slides will be, I will publish the slides.

21:55.920 --> 21:56.580
Source code is there.

21:56.580 --> 21:57.460
There is user guide.

21:57.460 --> 21:57.940
Yeah.

22:02.560 --> 22:03.480
So that's everything.

22:03.480 --> 22:04.380
Thank you so much.

