Finding and Decoding Malicious Powershell Scripts – SANS DFIR Summit 2018


(dramatic music) (audience applauds) – So my name is Mari DeGrazia. I’m with Kroll Cyber Security and at Kroll we
come across a lot of malicious PowerShell scripts
in our investigations. So today I’m gonna walk through how you find these
malicious PowerShell scripts and then how you
can decode them. But first, one of the
things you may have noticed here at this conference
is DFIR Superheros. You’re here to learn how
to channel these powers. And so today, I have
some prizes to help you channel that inner
DFIR Superhero. Some of you that know
me know that I’m a maker and I enjoy making things. So right here I have an
Iron Man arc reactor. It’s gonna go through and do
a couple different things. I made it with an
Arduino 3D printed case and I have some Easter eggs
hidden in my presentation. So if you see one
of these Easter eggs either raise your hand or stand
up, it’s a pretty big room. I have my colleagues
Ron and Kirtan in here. They’ll come around and find
you and give you a ticket. Come and see me afterwards and
I will give you one of these. The next thing I have is
the Lasso of Truth here from Wonder Woman. Nice strong powerful woman, so we gotta get this going. Rob Lee, if I could
have you come up here to help me test
this Lasso of Truth, I would greatly appreciate that. So go ahead, hold one end
and I’ll wrap it around you. Yes, here we go. So Rob, I know you can’t
see this, but it lights up. Can you tell me the last
time you were in Vegas at the Cosmopolitan, how
much did you really lose on the Blackjack tables? (audience laughs) Wait a minute, you gotta
demonstrate that this works. (Rob groans)
A lot, okay. (Rob groans)
We won’t disclose it here. We’re all professionals. – On account of the drinkin’. (both laugh) More than I usually lose. – Close enough, close
enough. (laughs) Thank you. All right, so keep your eyes
open for these Easter eggs. See if you can find ’em and if you want one, make sure that you stand
up or raise your hand so that you can be seen. So why PowerShell? We’ve had a couple
presentations already that have demonstrated how
powerful PowerShell is. Yesterday Devon Ackerman
talked about Office 365 and he leveraged PowerShell
to access Office 365. We had another
presentation today where they were
demonstrating techniques of stealing tokens
with PowerShell. So this is a very
powerful language, just like the name would
suggest, PowerShell. This let’s attackers
live off the land. They don’t have to
bring a binary with them and drop it on a system, they can leverage the tools
that are in Windows systems to actually get
what they need done. All right, so this helps
them also be fileless. Like is said, they’re not
dropping a binary on the system, they’re getting to use the
tools that are there natively which ultimately helps
them evade anti-virus. They’re in there, they’re
getting things done, the last thing they wanna do
is starting tripping that AV to let them know that
they’re in there. They also want
their tools to run. If AV trips and starts
catching those tools, of course they’re
not gonna get done what they need to get done. It gives them full access to
WMI and the .NET Framework. These are both powerful tools. You think about these tools, these are things
that administrators
use to do their job. So whatever can be used for
good can also be used for evil. And also, there is a
huge lack of logging when it comes to
Windows PowerShell. So when we talk about
logs that we look at as forensic examiners,
before Windows 10, there isn’t a lot of
logging for PowerShell. Now you can go on, take
some additional steps on some older systems,
update some libraries, get that PowerShell
logging installed, but even after you get
the PowerShell logging there’s additional steps you
have to take to enable it. So in a lotta the cases
that we work at Kroll, we don’t see this. We get into an environment
and very rarely do we get the logging
associated with PowerShell. All right, so what
kind of bad stuff can you do with PowerShell? Well you might not have
your attacker taking off with a whole stadium
like Magneto did, but they definitely, you saw
with those demonstrations earlier with PowerShell,
you can do a ton. You’ve got the data
exfiltration, you’ve
got the recon, you’ve got the remote
command execution. Pretty much anything your
attacker wants to do, they can leverage
PowerShell to do this. And a lot of it like I
said is done in memory. So here is an example, something that I have seen a
lot within our investigations. One way that they use
to push out PowerShell within the environment is
the service control manager. And I kinda like to call
this spray and play, because if you find
this on one system, there’s a good chance
you’re gonna find it across your entire environment
on a lot of systems. The service control
manager is a native tool built into Windows. It allows you to install
services and to manage them, stop them, and start them. So it’s pretty simple. You just use the command S-E. Another good way to think of it is like a poor man’s PsExec. The service control
manager you can execute on remote machines. So you think about using
a tool like PsExec, well the attacker is
already leaving a footprint. That’s not a native tool to
Windows, that’s a PsExec tool. So they have to bring
in a tool, PsExec, to push things out remotely. But with a service
control manager, that is a native tool built
into Windows that they can use. If you’re familiar with
some of the artifacts left behind by PsExec, if you use it, it makes an
entry in the registry key when you accept the EULA. Well not with the
service control manager. So here they have a tool
that let’s them access any Windows system in
the environment remotely. Okay, so they’re gonna use this and they’re gonna call
the create command and then supply a service name. Now here I’ve used the
FakeDriver service name, but typically what we
see on our investigations is a random service name, anywhere from maybe
12 to 16 digits long with capital and
lower case letters. They do this because the
service control manager wants a unique name. So if they’re pushing it
out to multiple systems, multiple times across
the environment, they wanna make sure that
there’s not a collision in the service control name, so they’ll use a
random name here. The next thing they supply is
what’s called the the bin-path the binary path. So normally if you’re
installing a legitimate service in Windows, this would
be where you would supply the path to the executable
that you’re going to run. But here, what they do
instead of pointing it to a legitimate service,
is they’re pointing it to command.exe and then they’re
gonna leverage commande.exe to run whatever PowerShell
command is that they wanna do. And don’t forget, they can do
this remotely on any system. And here we have some other
variables that they’ll use. They’ll use a -c, -q, something so when that
command prompt in PowerShell pop up it’s quite, right? Because if they’re on a system, the last thing they wanna do is alert you that they’re there. And right here we can see,
they’re basically setting up a backshell to meterpreter. Meterpreter is very
strong, very powerful. So ultimately their goal
is to have a reverse shell setup into meterpreter. And like a say,
you’re gonna see this across multiple systems
within the environment. Okay, so here’s what the
attacker actually sees on their end. They set up a listener and
they’re gonna listen for that. So once they execute that
command, it’s gonna establish a reverse shell
up to their system and boom, now they
have access to that from their system that
they’re working off of. So if all of this is done
from the command line, fileless so to say, they’re not downloading a
backdoor that’s an executable, how do we as examiners
find evidence of this. Well the service control
manager is actually logged in the system event log. So right here is
your magic number that you’re gonna
wanna look for, 7045. This is the event
log id associated with new services
installed on a system. So when they run
that S-E command, that will leave an entry
in the system event log. Okay, what does it look like? I ran through an example
that was in plain ASCII, but normally the attackers
are going to use obfuscation. Now it’s my understanding
through some
exercises yesterday, you saw some Base64 and you’re gonna see
the same thing here. So here we have
an event ID, 7045. And right here you
can see this is what the random service name
is going to look like. And then right here is
where you see the COMSPEC, which is that
command.exe on the system and they’re calling PowerShell. And like I said, this
is Base64 encoding that you’re going to see, when you start looking
at these entries. Now when it comes to
Base64, as a programmer, Base64 can actually look
a couple of different ways and I have two different
ways right here. Can anybody tell
me the difference between the Base64 on the top and I think I saw
a hand over here. Jake was that you? I think this was
the first one I saw. So where do you
see the Easter egg. Princess Diana, right down here. Okay, so Jake’s go
the first prize, they’ll come over and
give you the ticket. So the Base64 on top
is Unicode encoding. You can see there’s
a lot of a’s in here and it just looks
different than the Unicode, or the Base64 down here. You can also see
there’s some slashes and some different varieties. So when you’re looking at Base64 you kinda start to
recognize these patterns, Unicode and regular. So programmically I like to
deal with things in Python. I know a couple people, this
is about PowerShell right, but if you go to my
GitHub and you look at the things that I’ve worked on, I like to do things in Python. I’m stubborn, I should
probably learn PowerShell, but I’m gonna brute port this because I wanna learn
how to do this Python. A lotta my current
scripts are in Python, my processes are Python, so I just kinda wanna roll
in this decoding into Python. So Python, if you’ve never
used it before, is simple, easy to use. Just type Python, it’s
gonna drop you down into an interactive shell
to run some commands. We’re gonna just run
the import base64 so that we can
decode this Base64. Supply a variable, our code, that we’re just gonna
drop that Base64 into and then finally just do
base64.b64decode our code and we get the code. So what does this look
like on that event log that I supplied earlier? Same thing. Now the event log that I had
earlier was actually Unicode. So this is where we
have to specify UTF16. So that’s actually gonna
decode our Unicode Base64 and this is what it looks like. Now if you’re looking at
this goin’ like, holy crap, I have no idea what
that says, you know, I know Python, I
don’t know PowerShell, I don’t know JavaScript, but you can look for
things within the code to kinda tip you off
to what it might be even if you don’t fully know
the programming language. So right here we see something
that says Net.Sockets. So I start to get an idea, they’re probably opening
up something here, some kind of connection,
it’s a socket. And then right here, this
is what I’m looking for. This is the golden egg for me. This is the IP address that
those attackers are using to establish that reverse shell. Now sometimes it’s gonna
be an external IP address. Sometimes it will be
an internal IP address. We just worked a case,
and it’s pretty common in this PFI investigations where they’re stealing
credit card data, like my colleagues Ron and
Brandon talked about yesterday, they’ll find one system
or maybe two systems within the environment
that have connectivity to the outside world. So they’ll attack the
point-of-sale systems, the back of house, and
then they’ll set up one of these reverse shells
to an internal system and then go out from there. So when you’re looking
for these IOCs, you’re gonna see both internal
and external IP addresses embedded within this code. Okay, I wish it were
that easy, right, because then my presentation
would be wrapped up, we’d all be going to
lunch, but there’s more. Very rarely are you going to
just get one layer of Base64. It becomes like a
Russian stacking doll. They’re gonna use multiple
and multiple layers of obfuscation to hide
what they’re doing and to make our jobs
as investigators more challenging and difficult. Okay, here’s another
example, 7045 with COMSPEC. Now you guys should start
to notice a theme here with the COMSPEC, right? They’re calling powershell.exe. But this one, this one is using compression,
all right, Gzip compression. So the first time I saw this, I was trying to figure
out, okay I see the Base64, I see there’s some
kind of compression, I need to figure out
how to decode this. So what the attackers had
done in this situation is there’s a payload and then
that payload is compressed and then Base64. So in order to decode that,
we’ve gotta reverse the process. We have to decode that Base64. We have to decompress it and then finally
we get our payload. So I already talked about
how to decode the Base64, but this time instead of
writing it out to the screen, we’re gonna drop it into a file. Now programmically if
you’re familiar with Python, I don’t nescessarily have
to drop it out to a file, but the first time I did this I wanted to see if
these steps worked, so I kinda wanted to break
it down to the basics. So once I went ahead and
dropped that out to a zip file. I think I saw right here. What do you see? Stark right here. All right so, Iron Man’s
real name, right Stark. So the first time I did this, I went ahead and I
decoded that Base64 and put it out to a Gzip file and then I just used
7-Zip to unzip it and I about fell outta my
chair when it actually worked, because it was like, it
couldn’t be that easy right? And so this is
what I got though. I looked at this as I was
like, where’s my IP address? Where’s the code? I know that I took
the right steps because I didn’t get an error
when I tried to decompress it. If it wasn’t a zip file, Python would have thrown
out an error to me or it just wouldn’t have
looked like anything. So this is actually shellcode. So within the Base64,
within the compression, there’s now shellcode. I am not a malware
reverse engineer. My home is the
host-based forensics, but there are things
that I can do kind of to get the low hanging fruit, to see if I can find
those IP addresses so that I can pass them
off to my clients quickly so that they can start
blocking IP addresses. And like I said, there can
be internal IP addresses so I wanna look for those
so I know what other systems I can start looking at. So there’s this great
utility I like to use by PDFStreamDumper called scdbg and this is just a
nice, simple program that you can run
over the file quickly to see if it can pull out
any interesting information from the shellcode. So it’s pretty
simple to run, scdbg, you just point it to the file and it’ll run over
that shellcode. And boom, right here I can see some libraries are being
called, a WSASocket. And then boom, I
get my IP address. Now I don’t have
all the other code that goes along with this, but I know based
on this event ID, I know based on this methodology and just what we’re
seeing out there, that this is more than likely
that reverse meterpreter shell that I’m looking for. Okay, but wait, there’s more. So we had the Base64,
we had the compression, we had the payload, but the
attackers are still doing more to obfuscate this data. All right, so here we’ve
got our random service name, we’ve got the COMSPEC,
now can anybody tell me what level of Base64? Is this the Unicode or is
this the regular Base64? This is the Unicode right? This is what it looks. You can tell it’s a
lot more voluminous. It has the a’s in it. You don’t see any of
the slashes in it, so this has been Unicoded. So we know about the
Unicode and here you can see there’s an encodedcommand. And one thing about
PowerShell is sometimes you won’t actually see
the encodedcommand, they’ll use the shorthand
for it which I think is -e. Here they have a -nop,
which means no profile. They’re gonna run the
PowerShell with no profile, but sometimes you’ll see the
-nop written out as noprofile. So like in the
presentation previously where they were talking about
all the different variables and how you can switch it up. With these PowerShell
signatures, if you start thinking
about those signatures, same type a thing. It might be spelled out
encodedcommand, it might be -e, it might be spelled out
noprofile, or nop, or -whidden, or whatever the
shortcut is for that. So those are things that
if you’re running your keyword searches, you’re gonna
have to be careful about, that you don’t get
trapped into just thinking one type of command
is always used. So right here we decoded
that first layer of Base64 and guess what we get again? We get another layer of Base64. So they Base64
encoded it Unicode, now we have regular
Base64 again. And then on top of it,
we get compression. But this time if you
scan this string, you’re gonna see it’s
not Gzip compressed. It just says IO.Compression. And like I said, I am
not a PowerShell person. I’m a Pythonista, I love Python, so I wanted to figure out, okay what kind of
compression is this? It’s not Gzip. I tried running it, put
it out to a Gzip file. So silly me, I think
okay, this is Windows, right, this has just gotta
be regular compression. So I just put it into
a regular zip file. I try and open that up. It doesn’t work. I try several different Python
libraries to decompress this. I tried seeing if it was
.tar file, a .rar file, couldn’t figure it out. Then finally I figured out, I call it just like
the .NET compression. I know the people in
here that know PowerShell are probably like yeah,
that’s what it is, right? But I work with Python and if
you’re familiar with Python, Python is cross-platform
compatible. It runs on Windows, in runs
on Linux, it runs on Mac, so when you talk about .NET, Python isn’t gonna
restrict itself to just running on Windows. But me being stubborn, I’m
like there has to be a way to do this in Python. I wanna figure out how
to do this in Python. And I found something
called Iron Python. Iron Python brings
in .NET libraries so that you can utilize Python to do some of the
things on Windows. So by leveraging Iron Python
and some of the libraries, I was able to import those
libraries into Python so that I could access, what
I just kind of nicknamed IO.Compression or
.NET compression, because it seems specifically
related to PowerShell, not the typical compression
that you run across. So here I’ve just
imported the libraries. I wrote a function
where basically it’s gonna take
that decoded Base64 and then it’s gonna decompress
it and give me the .txt file. And here’s an example
of how you run it. You run it just
like regular Python, except you call ipy.exe
and the name of the script. All right, and so
here is an example of what an embedded
script looks like, once again setting up
a meterpreter shell. We have an IP
address with a port. Now in all of these
examples I’ve shown you, the PowerShell code embedded
within that Base64 can vary. You’re not always gonna
see the same script embedded inside that Base64. The other thing
that’s frustrating is within the case
what you’re gonna see, or what we have seen,
is variations, right? So everything that
I just ran through, that’s not what
you’re gonna get. These pieces are gonna be put
together in different ways. Sometimes it will
be Base64 encoded. Sometimes it will
be Base64 Unicode. And then you’re gonna
have your compression, IO.Compression and your Gzip and then maybe your shellcode. But you never quite know what
order that’s gonna go into and what you’re gonna do. And within each case,
it’s going to vary. So maybe on May fifth,
when the attacker’s in, they use one methodology. So great, you come
up with your script, you’ve got everything running,
you got everything working, and the you find a whole
new set of log entries from another day, and it’s
gonna be completely different. A lotta times
they’re using tools that automate this on the
backend to push it out. So I talked about that example
before where they’re using S-E to push it out
within the environment. So you’re thinking okay, they’re using a service control
manager, that’s persistence. No, they are actually just using
the service control manager to push it out. If you look in the event logs,
you’ll actually see an error, because it’s not a
legitimate service, they’re just leveraging
it to push it out. So they still haven’t gotten
their persistent mechanism yet. So ultimately, an attacker,
they wanna survive that reboot. They want that
persistent mechanism
within the environment. So there’s something
that we’ve come across called WMI persistence. And basically they’re using
the subscription service within the Windows
Management Instrumentation, to basically, I’d
like to think of it like a scheduled task that
is triggered by an action. So part of this
subscription is a filter. So in the filter they
can set certain triggers that will trigger this
backdoor to happen. And then once that
filter is triggered, it’ll point to a consumer. The consumer is the executable
or the script that will run. And I’ll show an example
of this in a minute. And then the third part
of this subscription is what’s called a Filter
to Consumer binding. It’s just the part
within the WMI that’s gonna tell, hey, once
this specific action happens, this is the file that
I want you to execute. And this is all stored in
a file called OBJECTS.DATA. It’s
C:WINDOWSsystem32wbemReposi. Fireeye actually has a
great blog post on this that details everything. And there’s a great Python
script, of course Python right, that you can run over this file that’s gonna help you
find these things, PyWMIPersitenceFinder. So I went ahead and
ran this script. You can get this on
GitHub by David Pany. I ran this script
over one of these and let’s take a
closer look at this. So here’s a filter
called UPDATER. All right, I saw a hand. I couldn’t quite see, Ron
or Kirtan do you know? Over here, okay. You wanna tell us what you see. Jarvas, right here. So here we have a
filter called UPDATER and it says AND
Targetinstance.EventCode
=’4625′ and Targetinstance.Message
Like ‘%admin%’. So what do we think? What’s the event code 4625? Whoops. 4625 is associated with
failed login and then admin. So this means that if
we have a failed login for admin account, go
ahead and run the consumer, which is going to be
our PowerShell script. So basically, all the
attacker has to do to get their backshell
to trigger is, go in through RDP and try
and login like an admin and as long as that
password fails, so if they’ve changed
that admin password in the environment, it
doesn’t even matter, the attacker can just go
in and try any password and as long as it fails,
it’s gonna trigger that persistent mechanism. And once again, that
persistent mechanism is Base64. Here’s the name of it,
it’s called UPDATER. And here’s our tie in right
here, that ties the filter to the consumer name and then of course
our Base64 encoding. Now like I said,
this can be encoded in all those different layers and all those different levels, so you’ll have to go
through and decode that. All right now when we talk
about persistent mechanisms the registry, right? The registry has
lotsa good places for persistent mechanisms. We’ve got the autorun keys,
we have installed services, so using the tool Registry
Explorer by Eric Zimmerman you can go in and start
looking for these things. So here is an example
of an autorun key. And typically what I’ve seen, is I kinda call it,
following the breadcrumbs. If we take a look
at this autorun key, we can see the COMSPEC. We know that COMSPEC
is command.exe and typically you’re not gonna
see that referenced like this in the registry. And then we can also
see, from Base64. But if you look here,
there’s no Base64 here. Where’s the Base64? We can see there’s
something bad going on, but there’s no Base64 here. And what this code
actually does, is it references another key. So right here it’s
saying, go get this key and then run whatever
is in this key. So then you have
to go find that key to actually find
the Base64 code. And you can see right here
is a pretty big chunk a code. Now if you see something
like this, of course, it should be a huge red flag, because really, most programmers are not gonna do
something like this and put it in the registry. PowerShell logs. If you are lucky enough
to get PowerShell logs in your investigation, it can be a great
wealth of information and I believe Matt Bromley
and I worked a case where we saw
something like this. So if you go in and you look
at these PowerShell codes, or the PowerShell log, you’re gonna find what’s
called a scriptblock. So the attackers will use a
command called Downloadstring, and that Downloadstring
will download something off the internet into memory. And then when it’s in
memory they can launch it. So something we’ll see a lot of is something called
Invoke-Shellcode. And a lotta times, they
don’t even stage this on their own system
or an IP address that you can pivot off of
or see a connection to, it’s on GitHub. They literally go and they
just download the code directly from GitHub. And once they do
that, they execute it. And in this particular instance they inject it into a process. And this time it was notepad. Okay, now sometimes I mention, we can kind of use
programs like scdbg to go through and get
that low hanging fruit out of the shellcode, but sometimes, you
just might not be able to decode the shellcode. But here we have a process that we know that the shellcode is associated
with, with notepad. So if you are lucky enough
to get a memory sample along with it, you can go into that memory
sample and pull out those IOCs rather than kinda
jumping through the hoops of trying to decode
that shellcode. Were there any hands that
went up on the last slide? Anybody see that? Did I see a hand? I’m not sure who was first. I think over here
in the red shirt. Did you? The, what’s that? Yes, that’s Wonder
Woman’s invisible plane. It’s really hard to like
draw an invisible plane, so that was the best
I could do, okay, ’cause she’s invisible, but we
can see her body right there a little bit. Yeah, I was
wondering about that. What good is it to
have an invisible plane if you can see the person in it? Okay, so anyways if
we get memory sample we can run volatility
over this memory sample to dump what is in
that notepad process to pull out those IOCs. So we used a command
called imageinfo. The memory sample
to get the profile. Then moving forward
we used that profile. Then we’re gonna run pslist to get the running process list. We find out which
instance is notepad and then we go ahead
and run the malfind, which is gonna find
injected processes and it’s gonna dump
it out to a folder. And once we have that
dumped out, like I said, I just do the real simple stuff, grab the low hanging fruit. I’m just gonna run
strings over that and see what I can find. And right here, I’ve used
the inject shellcode, it’s injected notepad. I’m able to dump that process and then get the IP address out. There’s not, but did you
find something? (laughs) Is that? What is that? Tell me. Is that an Iron Man
or a Wonder Woman? Oh, Aquaman, okay. So we’re going to whole another, isn’t he in another
universe than these guys? I don’t even know. I loved him though,
he’s pretty awesome. So wrapping up in summary, what are the IOCs that we can
look for as investigators? I just kinda wanted
to present a slide, kind of with all of our IOCs. So system event log 7045. So if you’ve got a
splunk girl like we do, I work with Scott, he’s
able to go through, and pull out all these
event logs in one shot and give us all
the basics before, and we can go through
and decode it. So this is a great magic
number I like to call, that immediately as you
start an investigation, you can start looking
for this event ID and see if you’ve
got this activity going on in the environment. There’s also the event code that is in close
proximity to it, the 7009. This is the failed event. So what happens is, that
service control manager tries to start up. It actually fails, because
it’s not a legitimate service, so you might also see the
7009 in close proximity. The other thing is, if you get
these Windows PowerShell logs you can look for these things, the Downloadstring,
executing a remote command, and you can also just
sort by the warnings in that event log. And Windows does a good
job of identifying those as malicious within
the event log itself. Search for that COMSPEC. Now you’re probably not
gonna wanna run that as keyword search over
the entire computer, but we know that we
see it in the registry, we know that we see
it in the event logs, so that’s a place that
you can be looking for it. And RegRipper is a
tool that I love to use because it’s a
command line tool. I can roll it in
with my processes. You can use two
plugins in RegRipper to help you find
this, the AutoRuns, which is gonna show
you that first key, and then the Sizes. And the Sizes plugin
will look for any values within the binary and the
RegSize within the registry that are over a
certain threshold. And because we know
that PowerShell takes up a big chunk in there, it’s gonna pull this stuff
out for you immediately and it does a good job. I shared my findings with
Harlan and he updated his plugin to help support that. – [Host] All right, big
round of applause for Mari. (host cheers) (suspenseful music)

4 thoughts on “Finding and Decoding Malicious Powershell Scripts – SANS DFIR Summit 2018

  1. you are using windows and looking at a piece of code compressed with powershell so you go and try as hard as you can to decode it with…. python??

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2019 Explore Mellieha. All rights reserved.