Okay.
In this video, I'm going to demonstrate the use of the artifact kit.
All of these payloads that we've generated up until now
are the, the default ones that come out of the,
come out of the tool.
And in Cobalt Strike client,
I've not got another aggressive script loaded for the artifact
kit, so these are the default ones.
If we go to Visual Studio Code
and open folder,
We can go to Tools, Cobalt Strike, Arsenal Kit,
Kits, and Artifacts.
And this is the basic layout of the kit.
So we have the build scripts.
We have these files in srcmain, so these are the entry points,
of each of the different formats.
So we have dllmain, which is for the DLL.
And we can see that this kicks kicks off on DLL process
attach and it also has has some exported functions
for use with things like runDLL.
Main.
C is for the executable and service main
is for the service binary.
Now,
in all cases, what they really do is call this start function.
These are actually implemented within the various bypass techniques.
So if we have a look at bypass template,
this doesn't do anything, but you can see how it implements,
start.
So all it does is it allocates a new bit of memory and copies
the payload into it, and then it passes that buffer to a spawn function.
Now this spawn function is implemented in Patch.
C.
So we have a couple of, variants.
We have this one up here,
and this is if migrate is defined.
So this is used by the service binary.
And then we have another one down here, which is used by
the, the regular binary.
And if you're familiar with process injection,
you can kinda see how this is working.
So,
based on
a allocation technique
such as virtual alloc, we're going to allocate some memory.
The payload buffer that's passed into the artifacts are
zored, so we then unzor the payload.
We do a bit of magic here.
We change the memory protection to RX
and then we create a thread to run the shellcode.
Now the whole point of the bypass templates
is to pass the shellcode buffer to this spawn function,
in a way that can't be emulated by antivirus.
So So if we have a look at, bypass pipe, for example,
we can see that in the start function here, it creates,
we create a pipe name and then we kick off two threads.
So the first is a server thread
and server thread appear calls
server, which is
further up here.
So we can see that it's creating a new name pipe,
and then it will write that shellcode
into the name pipe.
And then this,
other thread that gets kicked off is the client thread,
and it will read the shellcode over that named pipe.
It will then
pass that shellcode to the spawn function,
which is we just saw in patch dot c.
So that's how that sort of AV sandbox is
is bypassed there.
Now you can create your own bypass technique.
So all you have to do is create a new,
a new file here and then,
hook that into the build script.
Or, of course, we could just use some of these that are already here.
So we're gonna use the bypass pipe
in this instance.
So if we come out of here
and we want to build the kit, we're specifying the,
pipe bypass here.
And then the allocation technique we want,
I'm just putting virtual alloc so you can,
see where those are coming from
in patch dot c.
So that option is passed through as one of these
compilation directives,
and then depending on which technique that you choose
depends on which bit of code gets compiled in.
All of these, you can leave as they are,
and we're specifying an output directory here.
So for me, that's tools cobalt strike artifacts.
So if we go to tools, cobalt strike, we have no
artifacts directory at the moment.
So if I go ahead and build that,
we can see that the, folder's been created.
And you can build multiple
flavors of bypass,
and they will each get dropped into their own directory.
So because we just have pipe, we just have a pipe folder here.
And then as the payloads get built,
we'll see these artifacts get dropped in.
Okay.
Now that they're all built, we can see them all here.
Now the naming convention is, meaningful,
so that's sort by size this way.
So
all of these ones that have big in them are the stages one.
So you can see how these are much bigger in size.
All these ones are the,
stages.
Thirty two and sixty four is the architecture,
so thirty two bit and sixty four bit.
And these SVC ones are the service binaries.
It's worthwhile understanding that even though these ones are quite big,
they don't actually contain any beacon shellcode right now, but the,
the buffer space has already been allocated inside the
binaries themselves.
And then what happens is if we go to Payloads and then
Generate All Payloads
And after loading the aggressor,
so actually let's do that quick.
Let's go to,
c tools,
cobalt strike, artifacts, pipe, and then load the CNA.
So now if we go to generate all payloads,
what the client does
is it gets beacon shellcode and then it,
pulls these artifacts from disk and then patches
the beacon shellcode into these at the relevant, positions.
And then we'll output them to our,
payloads directory.
But some of these,
even though they don't have any shellcode in them,
they will be detected by Defender.
So we can go ahead and,
see that.
Threat check
and give it, let's say,
the regular stageless executable.
So let's, copy that path.
We can see this, yeah, defenders
not liking it, and threat check will work through
all the various chunks to see if it can find the specific
part or a specific part, I should say,
that it doesn't like.
So threatcheck will only tell you,
like, one thing at a time.
So if there are multiple parts of this binary that it doesn't
like, that defender doesn't like, retcheck will only find,
like, the the first one.
And then once we fix this one, we have to run it again.
And if there are more, then we have to, you know,
work through each one as we go.
So this bit of code here, I mean yeah.
I mean, I you you don't know what that is
looking at it.
So this is where, Ghidra comes into play.
So if we open
Ghidra
and create a new project
it doesn't matter where you do it.
Let's just throw it on my desktop.
And then we go to
import file.
And we're going to grab the payload template.
So that's in tools, couple strike,
artifacts pipe, and it was the
artifacts big artifacts sixty four big.
I see. That's the one.
And we just wait for that to import.
Okay.
And then if we double click on it,
this will open up in the code browser,
and we would like to say, yes, we want it analyzed.
And the default section here is fine.
And we just need to wait for this progress bar down here to complete.
Okay.
Now that that's done,
we want to find this portion of code in
Ghidra.
So what we can do is we can just copy some of these bytes.
Probably, these ones at the end are usually the best ones to go to.
So let's just take this bottom one here.
And then we can go to search memory,
and then just pop this in
and then search all.
And we have one just one result.
So if we click on this, it takes you to,
this portion of code.
If I make this a bit bigger.
So this part is the the raw assembly, and then this is
the the decompiles version that,
Girdre gives us.
So if you if you're like me and have no idea,
can't read assembly, this is really more useful.
So we can see some interesting things.
So we can see a call to virtualalloc here,
and then we drop into a for loop.
And then after that for loop,
we have virtual protect and create thread.
So this is I mean, we know where this is because we've seen it.
So if we go back to the kit here in patch.
C,
it's right here.
So we have the call to virtualalloc,
we have the for loop and then we have,
the call to virtual protect and then create thread.
So that
is exactly what we see here.
We have this function that it doesn't know the name of,
because we don't have debug symbols,
but that that function is this set key points as function here.
So it's this piece of code that it doesn't like.
Let's just make this a bit bigger.
So to bypass this particular
detection, what we need to do is just
rework this function a little bit so that it compiles to a
different, byte sequence.
Let's say char a
is this.
Child b
is this.
And then we can stick in some
random code here.
So we could say, get to
count.
I mean, it doesn't matter.
And then we can, dereference a
and set the value to
whatever is at b
and zored like that.
Okay. So this is just one example.
You can do anything you like as long as it's functional,
as long as it, as long as you get the same result at the end.
It doesn't really matter what you do.
So with that saved,
we have to go back to the kit
and rebuild it.
Okay. So now it's done again.
We can go back to fret check, which is here,
and we can scan it again.
Okay.
We can see that it's, still being detected as malicious, but we have
a different, signature now.
So let's find this one.
And, ideally, you would want to reload the new binary into Ghidra.
Delete and import it again.
K.
So let's search,
And here we go.
So this time, we're at that
printf statement for the pipe name.
So this is an example of where Defender has written a
signature specifically for the bypass pipe technique in the artifact kit.
So we want to change this
as well, and that's easy.
That's in bypass pipe.
These numbers here
are character representations of
backpack.
Backpipe,
which is these.
And then you can see we have netsvc,
which is a hard coded string.
But we also have this call to get tick counts
to generate a random digit here as well.
That is an effort to try and generate some randomness.
But I think in this case,
it's also working against us a little bit.
So we can delete this entirely.
I mean, again, you can do anything here as long as you,
make it sufficiently different.
But we'll get rid of this,
random digit here.
We can change the pipe name.
So let's just call it I like to do something like raster.
Let's just say raster m.
Why not?
Save the changes.
And then once again,
rebuild the kit.
Right.
Now that that's done, let's
scan the artifacts template one more time.
And now we have no threat found.
So that's what you wanna see.
So now let's go to payloads and generate our payloads.
Okay.
So what I should now be able to do
is go into the payloads directory here.
We could take the HTTP one,
copy it to the desktop
to see that it doesn't get snagged by Defender,
Run it,
and we have the beacon.
So that's the example of using the artifact kit.
Now each of these different payloads will have different
signatures that you have to work through.
So one of the things that I mentioned
was the spawn function for the service binary,
which is also up here.
And you can see that it has similar loops here,
for decoding both the
process names.
So this is the spawn two and the payload.
So if you're using the service binary,
you'd want to maybe change these as well.
The DLL also has its own set of signatures.
So you have to work through the kit and use this methodology
with ThreatTREC and Ghidra
to work all of the static signatures out of your payloads.