[Music]
all right we're going to get started
we're going to talk about uh bypassing
EDR by dlll side loading and C so a
title filled with mystery I'm sure we're
all wondering what we're about to do
today uh I am Gary lber I work as a
senior adversarial security engineer for
Northwestern Mutual uh what that means
is I'm a red teamer I'm a penetration
tester um tech nerd
right so what are we going to talk about
today um we're going to talk about a
technique that we're using here dll side
loading we're going to look at the dll
structure we're going to look at exes
that'll load a dll for you uh we're
going to find out how to find exports or
functionality inside of those dlls we're
going to write that dll in C and then
we're going to nullify everything we
just did by showing you a couple of
tools that'll do that all for you
so I think we should get
started uh first off what do I mean by
bypassing EDR right um the way I've
looked at it is kind of like this I've
got this same source code that I've been
using for who knows how long right and
it's just standard Shell Code Runner um
like you might see like a virtual aloc
right ma create thread uh I'm using Heap
aloc Heap create and then a function
pointer but same thing I've been using
for a long time right it's been working
for a long time I've noticed lately if I
compile it as an exe EDR kind of steps
in and says Hey listen that's a globally
unique exe file there's entropy if I'm
keeping Shell Code in there you're doing
some Network calls I'm sorry pal that's
just not flying right and so that exe is
kind of burned to me but what I did
notice is if I just take the same source
code and compile it as a dll perfect
send it it's fine with it right it loves
it so what I need now is because I'm
lazy I'm not going to rewrite my my
shell code Runner right I just need a
way to execute that dll so that's what
we're going to do today we're going to
find a way to execute those
DLS the technique we're going to use DL
side loading bet you would have guessed
that uh so what is DL side loing I kind
of feel like that depends on who you ask
if you would asked me this like three
four five years ago everyone kind of
defined DL side loading is like hey
weird side by-side manifest file
explicitly defines where the dll gets
loaded from and and I think now if you
ask people what DL side loing is they
kind of just conflated all together like
it might be a manifest file might be
like a load Library call that just
whatever it's a search order hijack
right and the dll lives in the same
directory so for the most part what it
means now if you read articles about
dlll side loading now
it just means an exe that's going to
load the dll kind of adjacent to it
right so that's kind of what we're going
to do we're going to find a Microsoft
sign binary that loads or rather side
loads our dll um we're going to place
our DL in the same directory of that and
we'll get execution through that signed
binary uh like I said it's kind of
conflated with d search order hijacking
I think at the end of the day nobody
cares anymore like the deal loads
whatever right um there are some good
articles I'm going to find a place for
these slides so you guys can get to the
uh references but mandant has a really
good blog post that's basically a step
byep for what we're going to do today I
promise I submitted this talk before
they released that blog post um hijack
lbs. net is kind of the project that
inspired this so if you're looking for
more dll sideload options great place to
start they basically have several
hundred of them and different utilities
that will load those
DLS so we are going to start by finding
a vulnerable
exe so there's a couple of ways to do
this um what I like to do is start with
some signed binaries so um Microsoft's
SDK can be downloaded from you know msdn
whatever it is I like that one because
it's a boatload of Microsoft signed
binaries that aren't on dis already
that's kind of important Sometimes some
of your Security Solutions will look at
dll side loading of binaries that
already live on disk and kind of just
kill it so for example if I take
something that normally lives in system
32 I just copy it out somewhere else it
might side load DLS but when would I
ever do that right every single user on
the machine has a path entry that points
them over to system 32 so I can type ip
config and it just resolves right it
finds it in system 32 well a lot of your
Security Solutions look at that and say
okay why would ip config ever exist
anywhere else but system 32 especially
if there's a dll next to it that is who
knows what it is right so I prefer to
bring my own Microsoft signed binaries
partially because like if you look at
what we're going to look at today is O
view the only way that ends up on disk
is if you download it to some random
directory right so the the perfectly
normal use case is that it lands in a
random directory and needs the
supporting dlls in that same directory
or it's not going to
work
so what we're looking at is like in this
example you see um this is the SDK and
the SDK like that DX caps viewer. exe I
don't know this I didn't look at it but
right next to it there's a couple of DLS
like DX compiler and dx. dll probably
Sid loads those right like I don't even
have to look to kind of make that guess
but we are going to do more than just
guesswork uh the way I typically go
about this I run that I run the exe I
want to use and then watch it with the
CIS internals tool procmon process
monitor right so check for DLS check for
a result not found right or I kind of
like to just monitor a specific
directory and copy the exes into that
directory to see everything that it's
about to do right so we are going to do
that and we're going to test it with the
uh the Microsoft sign binary o view
there's a couple of reasons for this
it's a really good like example case
because it does a few things for us that
make it clearer I think but still kind
of teach us the
process so we are going to copy o view
to CM xes we're going to monitor that
directory for not found and we're going
to get a bunch of stuff back here um
we'll go through this live so don't
worry if you can't see it on the slide
um it's going to do a couple things for
us so let's just do
it
love the not responding that's
fun
all
so this directory is the SDK there's a
bunch of different versions of a bunch
of different files in here including o
view what did it
freeze okay hold on is it
uh how about duplicate better right
[Music]
on
and Explorer just
crashed I might have this thing's
riddled with popel
[Music]
disease
all right so this time this is the this
is the SDK so o leave VI here going to
right click it real quick and just show
you guys properties uh digital
signatures right so we've got a
Microsoft science certificate
we like that uh there's a couple reason
reasons we like that we'll get into them
a little
bit and all that was for nothing because
it was already in
here so all
right
procmon of course I have other
[Music]
projects
[Music]
right all
right clear
it oh my God should have brought a
faster machine thanks
NM so o views and CM exe there's no DLS
in there right now so basically what's
going to happen is it's going to search
for those DLS in that directory and not
find them so when I run
this one of the reasons we're using o
view is because of this popup box makes
it a little bit easier to see exactly
what's going on here uh even though not
everything will work work this
way first thing it calls out is could
not find I viewers. dll in this
directory
right probably start there right if you
don't most things won't give you that
like verbose of an error message right
but we're going to go verify that if I
pop over to oily view
here look at it in procmon we see a lot
of things um any of these name not
found pretty good thing we want to look
for we see a lot of DLS here here
right one of them is i viewers. d So in
theory almost any of these can be used
that's not necessarily always true
but most of the time you can find
something that works so we know I
viewers dll is not found in C temp xes
it's looking there for it we also know
that it barked at us that hey I didn't
find it
there so we're going to use that as our
starting
point well we want to do now is we want
to inspect that original dll we want to
say what's going on in that dll that
that we might need to replicate so first
thing to know is that dlls export
functionality to a program so when I
have o o view launching it's looking for
I viewers. dll because it says hey I
don't have this code natively but I can
work with it through this dll which does
give me that functionality so load the
dll call the function and we'll get that
functionality right that's the idea and
RX rxe expects that functionality which
means if it looks at a dll and it
doesn't find that functionality it's not
going to work so we can explore the dll
a thing called the export address table
to see what functions are going on
inside of that
dll there's a couple of tools to do this
cff Explorer is a really popular one um
if you're like me the first time you go
to that website you're like sorry pal I
don't know if I trust this right like it
looks like it's been running since 1998
um there are some other tools out there
like pear is a GitHub project that
basically does the same same thing it's
a little bit newer interface um same
thing though and then if you're more of
a CLI junkie object dump CLI version to
get the exact same information so if we
look at U our I viewers. dll we can open
it with cff Explorer it's going to show
us this information so it's basically
just showing us the structure of that
dll right one of the things we really
care about is the export directory
that's where it's going to list out all
of the functions that are inside of that
dll that an application can call so we
care about those because we need to
recreate those functions so that when
application a calls that dll it can go
call that exact function that it's
looking
[Music]
for so if we go back to the original dll
inside of the SDK look for I viewers.
dll here it is open it with cfff
Explorer there's this export directory
this is another reason we're using view
as an example there's only four
functions in here right some dlls can
export hundreds of functions makes for a
harder harder time to manually write a
PC if you have to manually write several
hundred functions four of them we can
handle right so these four functions are
what we care about dll can unload now
dll get class object register server and
unregister that's what we want to
rebuild and
recreate so writing that dll you're
going to see a lot of examples
for PS that are written in C or
C++ I like C that's all this comes down
to I just like C so that produces a
little bit of a problem um when you
compile C or C++ you're taking the the
compiled Lang the language that you
write is getting compiled all the way
down to the CPU level right it's it's
getting compiled down to managed code uh
machine code unmanaged code or like
native code these are all kind of
synonymous terms and all it means is
that we're taking our language and
bringing it all the way down to the CPU
level so it's it's running it through
the cpu's instruction set right it knows
what to process uh that's not how C
works there's other language C Java they
they don't compile all the way down to
native code they compile like halfway
down right they compile down to what's
called bite code managed code
Intermediate Language so those are all
synonymous terms to say I'm G to take
your code compile it down halfway and
then underneath that is going to be a
runtime and that runtime is what handles
the rest of the comp compilation down to
the machine code layer
so that's kind of what that's kind of an
issue for us uh because the way those
two things load and their structures is
essentially different right uh so the
result is that methods or functions that
we create in C aren't going to exist in
an export address table they don't need
to that's not how it works I still call
those C dlls from other assemblies and
call those functions they don't need to
be advertised
right so applications like o view they
won't they won't see anything they'll
look they'll look for the export address
table they're not going to see an entry
there and they're going to say sorry pal
I I was expecting this function you
don't have it so I can't
run and actually we're we're going to
keep going into this one and just build
it out right away so we're going to
write it in C we're going to write those
same functions and we're not going to
export anything because that's just how
it works
right the source code is going to look a
little bit like this there's going to be
the standard Shell Code Runner I was
talking about before inside of a method
called conference and then all of those
other functions I'm just going to create
them as methods that if they get called
will in turn call conference and that'll
bump up our Shell Code
Runner then we're going to go look at it
we'll compile it look at it see that
there's no exports in
[Music]
there I don't suppose any of that is
like even remotely visible from out
there but it's what it looks like
embedded Shell Code base 64 encoded
there's a multi-te xor in here that's
encrypting it so kind of standard ausc
techniques right and then the end of the
day Heap create Heap aloc and a delegate
function pointer to actually point the
CPU to that memory address and start
executing your shell code
so if we take this no
exports build
[Music]
it
[Music]
here's our dll no exports we'll take a
look at that right click open the cff
Explorer and we see net directory right
it identifies that this dll isnet
instead of just an unmanaged code binary
but what we don't see is an export
directory so there's nothing there for
for o view to to reference
right so if I bring it over there anyway
and I run o view we do get a different
error message another great reason to
use this as an example right basically
it it's not the error message that says
I view isn't there right it found it but
what it didn't find could not find dll
register server function right it looked
it can't find it it's not going to do it
so we did load our dll we're just not
getting any Shell Code execution at this
point all right so let's manually export
those methods there's a really cool
thing we can do with uh Intermediate
Language when we compile our C down to
the I we can disassemble that I which
means we're going to kind of see what
the runtime would see and how it would
execute that iel so what we're going to
see is that the methods that we Define
are kind of right in that I and then the
next thing you see is the call stack to
that conference method right so in
theory you call this method it calls the
other
method so since we can see those methods
inside we can add our own export
descriptor what that means is inside of
the method when we add that export
descriptor and then reassemble it
copy it over as a dlll it adds it to an
export address table right so now we
have this function being advertised in
the way a traditional like unmanaged C
or C++ dlll would would export
it so you'll see something like this
right the exact same same thing we saw
manually exported will now have the
export directory and then the dll
register server
function but we're going to going to do
it so we
have our dll here no exports we're going
to copy that over drop it into a
different directory that has
my
disassembler paste it into
here copy and paste the commands because
otherwise I will screw it
up
[Music]
so IL disassembler put it out to manual
exports doil file and go point it to the
dll we just
compiled notepad that manual no
exports and we can see this is the ilil
right this is this is what the runtime
is going to be processing so if we just
scroll scroll through this some of it is
maybe over our heads we don't really
care some of it's pretty readable it's
pretty reversible from the IL standpoint
and we can actually see you know this is
a method I defined this method can
unload now it has a call stack call
stack calls the conference method right
so we can this is familiar enough we
know what we're looking at if I go down
to let's say d register server and I
come inside of this
method
export and save this that's all I have
to
do and now I can recompile it or rather
reassemble
it so IL assembler point it to that IL
file we just modified say we want a dll
out and then manual exports. dll will be
the
name now we've got manual exports.
dll look at that at cff
Explorer now we have an export directory
and we have a DL register server so in
theory if we did this on all of the
methods cool we have all of them
exported we should be good to
go yes but no I'm lazier than that um
what you need to do is get the dll
export Nate package that's how we do it
under the hood get the Nate package and
when you run this it goes and does all
that hard work for you so what that
means is now in your source code all
have to do in C is type D export and it
knows that it should take that function
and Export it to the address table so
you don't have to do any of that work
that's just how it works under the hood
right so if we look at that I have this
prepped and ready to go already it looks
like this it's the exact same code but
now every one of these methods has the D
export decorator at the top of the
method right so when I compile this all
of the those functions will be exported
for
[Music]
me exports. dll check that out in cff
Explorer we've got our export directory
and we've got four different exports in
it so C now has the exports that we need
in theory if we copy this over we should
have everything we need for a dll that
does what we want it to
do exports. DL copy
that I viewers. dll that's the one that
we know side loads double click o View
and there's our msf Venom message box um
wish it was is cooler than that message
box doesn't feel cool enough but it is
what it
is so P just double click o leave view
there's our message
box um there's a question you should be
asking at this point is why is this even
working because at the end of the day um
we just created an export and that's it
right why would the unmanaged code o
view have any knowledge of what's going
on inside of bite code uh and to be more
explicit that's machine code right it's
compiled all the way down and we just
handed it something that's compiled
halfway down and needs a runtime right
so in in in my head I'm like well this
shouldn't work it shouldn't know what to
do with that and if we look at o view in
CIS internals process Explorer what
you're going to notice is that the DL
the dlls that are loaded in O view do
not include cl.dll there is no common
language runtime by default inside of o
leave you so does does anybody here
speak fluent
Spanish okay so small number of people
right willing to bet everybody knows
what that says right kind of magic
behind the scenes but that's what's
happening the OS recognizes bite code
and it kind of says hold on I know how
to process that so I'm just going to
load the CLR for you and plug it in to
this process and now I can run the rest
of that for you this is kind of a good
tip off from the C trade C tradecraft
perspective if you can get the insight
into like where your normal CLR loads
are and you can kind of Baseline what's
not normal it might be something to look
at right it basically indicative of C
where it shouldn't
be you might be saying cool I don't
write code right like that's fine you
don't really have to um under the hood
this is how it works but there's a lot
of toolkits that do this for you
um I like the one by Optive it's a
project called
Freeze General premise is you're going
to give it um the name of a dll that you
care about like I viewers. dll you're
going to tell it what export to use like
whatever and you can feed it shell code
and what it's going to do is AES AES
encrypt that Shell Code uh compile a dll
for you and it'll have exports out there
there's also a current poll request that
allows you to feed at multiple exports
and I've used that before it works great
so um you can feed it at dll directly so
if you have the original I viewers. dll
or whatever DL you're side side loading
pointed to that it'll strip out all the
exports add them to the new one with the
Shell Code inside of it and produce a
dll that surprisingly effective to be
honest I I something didn't work on one
of my last engagements and I went and
quickly crafted up one with freeze and
it worked great against unnamed
edrs
so this just broke o view right when I
double clicked it it didn't launch
anymore it gave us our message box um to
be honest that's all I really care about
right I just want the beacon and I don't
want anything else to be on the screen
so it worked like I wanted it to but
there are also ways to maintain
application functionality and what
you're thinking of there is a dll proxy
the reason I bring it up is because 100%
what we just went through still
perfectly adapts to that uh the concept
being we created a DL that exports all
of those functions and now when the
application calls our dll with all those
functions RDL can dll proxy it to the
original dll because it's a proxy that
middle process will execute our Shell
Code give us a beIN and then hand it off
to the original so that the application
is none the wiser it gets all the
functionality that it's
expecting I use a project called sharp D
proxy for this um what I like about this
is it doesn't give you a dll it gives
you source code for a dll which I think
too many tools just directly give you
dll and that's cool for the like three
or four months that it works and then
after that the tool is kind of burned
and you have to customize it anyway just
give me the source code and I will get
the skeleton that I need and then I can
modify that as needed and for that
reason I've been using this tool for
years because I can just go in there and
say like yeah tweak this and then it'll
continue to work but I get the structure
of the the dll efficiently
right
blue team I'm not going to pretend to
know what I'm talking about here but uh
I can at least give you a little bit of
insight into uh what I think are
opportunities um first off like I said
there's a lot of security projects that
security tools that if they identify
that tool already exists in system 32
there's no reason that it should be side
loading something outside of that
directory uh especially if there's that
adjacent dll so that's something to look
into to if if your security tool doesn't
do that um I think like check out hijack
li.nu and just pop it out there and see
if you get blocked or not um so I that's
why I don't use them anything from in
there I can just bring my own right grab
the SDK and bring my
own uh Microsoft signed exes really good
chance that the DLS are also signed so
if you're getting a dll that's unsigned
through you know this bring your own dll
exe that is
signed maybe an indicator maybe
something to pull
on uh C specifically right we talked
about those CLR loads if you can
identify what's normal there that's kind
of important uh it's good indicator that
c is running maybe where it shouldn't
be um I asked my blue teamers for this
information so I'm going to tell you it
and then have like deer and headlights
looks uh if you can Baseline where your
executables are running from their their
exe and their their original file name
and then identify non-standard
directories where you see those running
from in your environment that might be a
good way for you to kind of grasp like
hey this is where it would normally run
from even if it's non-standard so when
we see it somewhere else yeah okay maybe
we should pay more attention to it in
theory you can do the same thing with
DLS right based on your image load
events um sounds like it's
harder I did kind of fly through that I
think it's okay because we all want to
get the keynote anyway um there's a
couple of things I'm going to plug real
quick uh one there's a adversary
emulation Village downstairs does
anybody check that out I don't blame you
uh the sign is mislabeled it says
advisory Village so nobody's interested
in
that uh the whole premise of that
Village is they give you like three
different edrs that you can test against
and they give you a Dev box and so the
the concept is like go write your own
malware and if you can get past these 3D
edrs we'll give you a prize immediately
after this talk I'm going down there I
am going to run o view with I viewers
against it and get a beacon out of it
and I already know it'll work against
all three edrs so I'm gonna walk away
with the cash uh second thing I want to
plug uh I am also doing a talk later
today with my boss Matt and it's called
attacking unicorns uh we are basically
taking um mini malware samples that we
write and coined a term called threat
injections what we do is we if you're
familiar with like Atomic red team or
miter Calera project we do that we built
our own custom system we execute all
these attacks on our on our systems
hundreds of them per day in the effort
of of automatically checking that our
detections are working like they're
supposed to so routine controls
validation fully automated pretty fun
stuff um other than that that's what I
got
questions
yeah
no I haven't but that's a good idea so
the question is if I've thought about
contributing the dll export Nate package
into Roslin and make it part of the the
whole thing so no that's that's a fun
project I think the other uh maybe mic
drop moment we could do here is uh for
what it's worth I didn't prep this on a
on the right machine so this is a
production machine with uh crowd strike
actively running on it so we did just
load against crowd strike I'm gonna go
do it against sofos Microsoft ATP I use
it against Sentinel one I mean if you
get it across one of them you're going
to get it across all of them right so
would you be willing
to my blue team is probably already
going to kill me for doing this on my
production
machine they're back there
like yeah I don't
know not good
enough
yeah yeah I'll get the slides up on uh
you know my LinkedIn my Twitter and all
that
yeah um I don't know as far as I know it
compiles down to what needs the
CLR but I think there's options in C or
C++ I'm not a c guy so I just know that
that one
slide uh we'll go all the way back to it
if I
[Music]
can
all the way
back yeah so this slide almost indicates
that C++ could be compiled down to CLR I
don't know that maybe somebody knows
more about that and that might be maybe
what you're thinking of too because I
was unaware that maybe it could be
compiled to a CLR or all the way down to
native code or it could just be you know
a crappy
screenshot
awesome no other questions let's get out
get out to that keynote
thanks