Hi. My name is Sham Peers. And in the subject matter expert for introduction to malware analysis.
Today we're gonna be covering the basics of stack analysis Part four,
where we will actually be reverse engineering a piece of malware. And we're gonna be looking at some of the tricks commonly imposed by malware,
sometimes in an effort to burke assemblers, sometimes in an effort to just be confusing or make analysis more difficult whether it be automated or
just to try to trick a person.
illusion bought before we looked at it. Last time,
I'm gonna just extract it here,
which is something you should be a bit careful with.
I care for you. Click.
So I'm just gonna hit f two and renamed these files so they don't accidentally get executed.
I'm gonna pull up. I'd approve
the bought binary dot dxc
because that is the execute a ble that actually does the infection.
So some pretty fast analysis.
So here we see something immediately down here and read
says sp analysis failed.
That's the stack pointer analysis. So last time we were talking about
the stack a lot, and we're talking about how the compiler will generate instructions toe clean out the stack or make functions that will save registers. And then
you pushed them in the beginning and pop them off at the end or will
do things so that it can clean up the stack before, after different functions called a paying off on if it's standard call or see tackle. And here we can see this very basic trick where a lot of very basic assemblers will just break is where the stack
doesn't match up from beginning to end.
So we see we see here, push EVP move
A B p e s p standard introduction to a,
um, the standard prologue to ah subroutine.
And then there's no minus E S P. So it's not making room on the stack
except for it is it's doing this push, push, push.
Usually this is done in an effort to save these registers, but you'll notice there's no popping here at the end.
So it does this load effective address
and does this subroutine
or the location to the subroutine. I have figured out this was excusable code
puts it into this address
and it pushes this address
and does this return.
Now think about that for just a minute.
The return instruction.
return instruction it thinks it's supposed to go to, because there's thinks some
function Cole called it. So it has to return to that address.
So the return instruction,
once it executes it, will actually execute this function.
Now, if we had space,
we can see that there might have been something else down here.
I like to hit c and find out.
but it seems like it failed.
I'm gonna switch over to the *** view, which, uh, is basically hex editor.
I like to look at this data here.
These data in between these two functions,
these two bits of code and
I like to usually look to see if their strings or unusual data or if this random junk
it looks to be random junk because there's no references to it. So it looks just from the side of it. It looks like there's no part of the program trying to access it,
but it could do that dynamically. because, like we said, there's no way to know what the code is gonna do until it actually does it
until we actually executed.
So here I to recognize that there is a reference to this, and it was likely some code.
So this is the function here. So I'm gonna hit end and call this riel main,
and we can see that it's also called right here,
So I don't know how this Coke it's executed at all.
I won't hit ex to see if there's any references to it, and there's
not not at least ah kind Ida has found.
So that might be interesting, but it's not important to us right now, so we'll look into it later.
I'm interested in what this function does.
What this separate e does was more proper,
so it looks like it calls three functions.
It uses some strings like Win 98.
So perhaps it's testing to see what version of the operating system it's using.
Now we see this constant here, so that would be something I would google for.
Perhaps someone else has done some analysis that we can leverage.
I keep looking down and I see this
registry coal or see this path.
but notice that there's no names to any of these functions.
That's not uncommon, especially if something statically linked.
But what is interesting is here it's calling a D word. Usually you call addresses,
but there's d words here everywhere, so that means it's data.
So at some point, this is manipulated. So I like to see
was there. We look at it and we see it's just a reference to some memory address that hasn't been filled in.
So I want to see what
references are to this memory address.
Someone hit X and see that it's reference and three places.
here we can see on the right hand side, uh, the instructions associated with it and one instruction. This move instruction
is the only one that rights to it.
So that's curious. The only places modified and the whole program is right here,
so I don't click on it and go to it.
So this is very interesting,
These were all function calls,
and there's this skit Prock address
and if we scroll up, we can see there's the's, this load library address
deals. So it's getting the functions it needs
rather than have all these deals. Are all these function names populated in the import address table?
So under imports, we see that's actually just using
a few of these function calls. You only need to load library and get Prock address to resolve all the other function calls.
So the library is used to get a handle to a library
and then get Prock addresses used
to get the address to that
function. Call, as you might guess,
so we can flip back over here
and we can start looking at this pattern
little library is called.
It needs a parameter.
It's doing the same kind of move
is doing the same kind of push
So it looks like E. A axe was being stored in the bar. Eight.
We can see that the library was called up here as well,
push on to the stack.
This move doesn't really affect that and load library was called
So load library was called and a handle was returned. A handle was put into E. X.
Because remember, E X is what
It's the E X holds the value off whatever the function returned.
there's a Kit Prock address
it's moving that in the S. I
because low libraries not using it anymore,
that's going to push
and move E X and two of our four.
So e x was last modified when I called Load Library.
So we now know that far for
is the one I knit Deal l
So I'm gonna just say
get Prock Address will return
a value in the e x register.
And if you ah, look at that, it will be
and that's a pretty standard return AP Windows A p I return.
are the D words to say
send or whatever else?
So if we run, get proxy address here and store the result in yaks,
make a little cleaner and say
still, check that. So get Prock address
I think it returns well. The good thing about this is we can always google in check.
So retrieves the address of an exported function or variable from the specified dynamic link library or Diello.
It takes in two parameters H module,
which is a handle to the library. And
ah, long pointer to the product Name as a long point or C string
the return value if it succeeds to return values the address of the exported function.
And if it's no, then it failed. But there doesn't seem to be any error checking,
so we can kind of see this pattern.
All right, get Prock. Address was called
so we know that Yea axe
was moves last calls law library.
So when was this receive? Used
Pushed the each module
called Get Prock address. Okay, so
was a parameter to the next one.
was actually the perimeter to this Get Prock address.
So this was actually
So what tipped me off to this was a little when I net
use this string which is seven receiver pretty common functions used by network Aware software. And they're pretty common in malware as well.
So we can continue the same type of process
the X was then inserted here. Send was next one.
good to be consistent.
And we could do all of this
down the line. If you're really good, you can use I, D. C
to write a small script to do this for you.
But what are we really after again?
we might like to know, um, you Tex that's created
so we can see it's pushed.
It will be the parameters to this.
as a result of Prague address So we know this
was creating you text A
It's like, Do you want to make it bigger? So I'm gonna say ax. What else, uh, uses this?
Only two functions use this.
So if we see here called create you text function, eh?
There's three prowlers that were pushed
this one being the first I'm willing to bet
the right most parameter
will be the name of the mu Tex I'm willing to, but this is probably zero.
or ex or yes, I yes, I So it zeroes out. Yes. I
compares it to something but reuses the value. Don't hear. So it's calling, creating you text a,
00 and then this value.
a If you see these kinds of functions, like message box message box a mess box w creating you text Kareem, you tax a create new text w a at the end stance for ask e w at the end stance for Unicode.
Ah, I was right. The last prouder the right most parameter is a long pointer c string
and it's pointing to the name of the Mu Tex. So this is another indicator of compromise. If this mu tex appears on your computer,
then you might be compromised with this piece of malware.
And this is a pretty good knowledge
when you're fighting malware because
So if your organization had the capability to search across the entire enterprise for all running you. Tex is
with some software, like titanium or
whatever. Agents were listening on your devices.
You could immediately pass set over to ah, Hunt team or something like that, or the soft team or whoever does that. And you can say, Hey, I'm not done with my analysis. But look for this man attacks,
and then you can keep going.
So I'm kind of interested to know what
what part of the program is checking them. You, Tex?
To see if there's another infection going on.
We can see that it was called by Real Main.
If I'm not mistaken. Real main also called creating you, Tex Here.
So is this the same string
we had escaped and we could just go back
forward, Back, forward, back,
back. It looks like the same strength. So it's checking in two different places in its code to make sure another instance of infection isn't running.
I'd like to know this code is
depending on, uh, what
the create new text a function returns. It's going to do something else
eso. It makes another function call and then compares the output of that to this value.
I'm gonna go find out what this is,
so it's only written to once.
Yea, x e x was modified by this call instruction. Forget Prague addressing the options to that get product.
The parameters of that get Prock address was get last error,
so that's pretty useful. It's probably called and
more than one place.
So following that path of logic again,
last error was pushed
as a parameter to Cole
and which affected e x e a e a e X, which was inserted into here.
And then it compares that to be
So let's do some more Googling,
Let's just say I hope they have hex
error already exists, so we know that it's comparing that to error already exists. And if it already exists,
exit process or terminate or do something else.
So another cool trick we could do with Ida
is we can say, Hey, I know this is that Ah,
error already exists. You knew, you know,
So we can actually specify that here.
Use standards and book constant or the M shortcut.
It's gonna bring us a list of all the error or all of the
in new Marais shins that it knows off.
it knows that air already exists.
Matches this value and they can click. Okay,
so it makes it a little easier to read.
Get last. Error already exists
means we'll figure out what this is.
It's written to here.
It's written to hear. That's very interesting. Let's check this one out.
Hope that's the location. We already are at
creating you text A. It stores a Valium here
and the result of creating you text a
that the function succeeds, the return value is a handle to the newly created
function fails. The value is no.
It's a new tax handle,
so it's a local variable.
I want to find out what this is. Apparently, it's called a lot.
We should really label that function,
figure out with the suits
the X was modified by get Prock address
which had the parameters off close handle
or I guess I should be consistent and say function close handle. But it's okay.
So I'm gonna name this because I see it quite frequently.
table builder. It's not really a table, um,
real name. That's right.
Calls it right there as the first thing that calls.
So we can pick apart this program
bit by bit and really get into exactly what it's doing. And we can totally
all of its capabilities.
before diving in, you should really ask yourself, What am I after? A. My after indicators compromise. Um, I am after a network traffic.
Because it's easy to get lost in the details because you have a very detailed view
of everything, and you can easily just go down a rabbit holes. You can go off into the weeds. You can,
you know, take whatever analogy you want. But early on I said, this is very detail oriented,
every once in a while you need to pop your head up and say, OK, what am I after again?
because this power was found on the machines. Okay, what's its capabilities? Okay, I can go for that.
A good way to determine s capabilities. Uh,
after you've already gotten a look at what it's doing to defend itself
would be to look at the function calls it makes
host name. We could do some,
we can say, OK, it's doing something with the network.
I can delete files that can read files, create files,
It can modify the registry.
And we already kind of knew this from our dynamic analysis. We saw that mollify the registry opened a hole in the firewall for itself. We saw that
It could take certain commands from the IRC server
so we can see virtual free virtual Alec. This is important because it could create memory, which he could,
and then use the virtual protect
function to then execute that code
in such directories.
It's using some Z W functions. Zw are usually reserved for lower level libraries. That should almost
yeah, they should never be cold by
Unless you really know what you're doing. And even then you probably shouldn't do it.
using this function,
and I would be curious to see how he's using that, because it's probably an anti debugging
because you can call this function
and you will get back information about
your process or your threat or any other process of threat you want.
And you can determine from the colonel's response
if that threat process or whatever is being debugged.
uh, I'd be willing to look into that if I wanted to debug it,
say in an open address
it can also messed with service is. So If I didn't know any better, I would be like, Okay, it's probably installing be a service. And if I wanted to go
down that rabbit hole and determine its the service name it's using,
uh, I could do that with these functions
very quickly. I could just
seo Where is this thing being used?
It's only being used in one function.
I can look for any strings around there.
I go for another one.
follow that rabbit hole, I could
Now here's some Maur. Interesting strings
is interesting because there's a slash slash and escape slash In there
this is interesting.
colon slash slash On what looks to be a file name extension
and this looks interesting. These look like encrypted shrinks basic off use cation.
So it looks like it's pushing these
into the word excess modified by this. So this is delete registry
So it was the last of
after is received the parameters earthy the parameters of,
pointers to these strings.
And it's called multiple times. And each time there's a
off you skated string
and a different location.
So I'm willing to bet this string is input.
Dysfunction is decryption or D a few vacation and this is output.
So let's take a quick look into that.
takes into arguments to pointers is what it looks like.
Source on the E s. I and then stores
assistant to a l, which is the lower
eight bits of the 32 bit
So this is useful for she just want character.
means it tests to see if this is zero
ale says is the string blank
active was ah one bit in there, it will skip to the end.
if there was any characters in that string.
If they're if that string had a character in it,
then I would begin executing this loop.
It calls us function
and then moves. Yes, I
increments idea Eddie, I
off the stack into E c X
and test it to see if it zero.
not zero, the jump is taken. So this is taken.
That means conversely, if it is zero,
this falls through so we can hit space and say
if this is not taken
okay, if it the value is zero
then just falls through
to the next instruction
has something to do with these lists decryption.
So we can peek at it
there's an alphabet there and there's an alphabet there.
I'm just going to guess just by looking at it.
It's not really encryption off your vacation. It's really more of an encoding.
It does. A simple swap
Does the Basic Function prologue make space for its local variables as a push? Push, push?
This is interesting,
and it would take a few minutes to figure it out. It wouldn't be too hard.
We could even write our own version,
and we could decrypt the strings ourselves.
However, in the next video, I'm going to show you the easy way of doing that.