Packers Part 4

Video Activity

Welcome to Packers Part 4. In this module, we'll demonstrate an example to unpack a malware code. We'll use UPX Packed Regshot and take a look at the strings, before and after the packing. We'll also explain how to manually unpack UPX, dump the process, and reconstruct the Import Address Table (IAT).

Join over 3 million cybersecurity professionals advancing their career
Sign up with
Required fields are marked with an *
or

Already have an account? Sign In »

Time
9 hours 10 minutes
Difficulty
Advanced
CEU/CPE
9
Video Description

Welcome to Packers Part 4. In this module, we'll demonstrate an example to unpack a malware code. We'll use UPX Packed Regshot and take a look at the strings, before and after the packing. We'll also explain how to manually unpack UPX, dump the process, and reconstruct the Import Address Table (IAT).

Video Transcription
00:03
>> Now we're going to do
00:03
a unpacking demonstration where
00:03
I will use UPX to pack Regshot,
00:03
a tool that we demoed earlier because it's
00:03
a simple executable that we're going to look at
00:03
the strings as we have before and after packing,
00:03
and show how we can unpack with the UPX tool itself.
00:03
That's quite unique. With most packers,
00:03
they don't offer an unpacking tool built-in.
00:03
Some reverse engineers may make
00:03
their own UnPacker, or unpacking scripts to help.
00:03
Every once in a while,
00:03
someone in academia, or someone
00:03
in the industry will say
00:03
>> they have a universal UnPacker,
00:03
>> but it's usually not what they say it is,
00:03
or they're being very misleading,
00:03
or they're just being very general.
00:03
Because, there are some more advanced packers
00:03
out there that is really not possible.
00:03
I will talk about that in a little bit.
00:03
But for now, I will show you
00:03
>> how to manually unpack UPX,
00:03
>> and this technique will work with many other packers.
00:03
>> Then, we can just dump the process,
00:03
and then reconstruct
00:03
an important data structure called the IAT,
00:03
the import address table.
00:03
That is very useful because we can actually see
00:03
what the dependencies are for the executable.
00:03
Here I've reverted the VM back
00:03
to its ready to be infected state.
00:03
I will just drag over a few tools we're going to use.
00:03
The first is OllyDbg 1.1.
00:03
Because if we open an executable,
00:03
it's packed with UPX with Olly 2.0.
00:03
It will automatically unpack it for us.
00:03
That defeats the point of doing it
00:03
manually so we can figure out exactly what's going on.
00:03
Another one is Import REConstructor,
00:03
which I will demonstrate here in
00:03
a bit to help us rebuild the IAT.
00:03
UPX 391.
00:03
This one I demonstrated earlier, and PEiD.
00:03
I'm just going to drag these over here.
00:03
As I mentioned before, we're going to
00:03
take Regshot copied over to
00:03
the desktop and execute just to make sure it works.
00:03
It does. Now, we're going
00:03
to run PEiD on it to see if we get any detections.
00:03
Nothing found. Sometimes, we have to do
00:03
more deep scan to see if it finds
00:03
anything, and it hasn't.
00:03
Now we can go ahead and pack Regshot here,
00:03
I'm going to copy this over to the desktop,
00:03
type in CMD,
00:03
that only works with Windows 7.
00:03
To control our CMD and CD to the desktop.
00:03
Then do upx.exe and do
00:03
Regshot file, because you didn't actually do it.
00:03
Regshot X86.
00:03
It's trying to go after the shortcut.
00:03
We compressed it by 60 percent.
00:03
That's quite impressive. We can
00:03
run it again just to show that it does work.
00:03
If we look at the strings from the
00:03
original and the strings
00:03
after it's been packed,
00:03
we can see there's a lot of stuff
00:03
beforehand, and next to nothing after.
00:03
There's strings in both, but there's more in
00:03
the unpacked version, and the non unpacked version.
00:03
We can drag Regshot again over to PEiD, and it
00:03
immediately detects that it is UPX.
00:03
There are other indicators,
00:03
such as the section names are all renamed,
00:03
UPX0, UPX1, etc.
00:03
[LAUGHTER] PEiD can actually
00:03
allow for a lot more customization
00:03
in its signature detection.
00:03
Like user db.txt can be
00:03
modified, and you can put in a name of
00:03
packer and give it
00:03
a signature of a series of bytes it should look for.
00:03
That is useful. If you just Google around online,
00:03
people have made huge databases
00:03
of signatures for packers,
00:03
and I suggest that you grab one of those.
00:03
I've seen sands put out one,
00:03
I took 30 seconds to download it,
00:03
and found that they messed
00:03
up some encoding and it didn't really work.
00:03
I'm sure I could figure out.
00:03
But I saw that other people
00:03
have released other large databases as well.
00:03
I haven't ever had a problem with PEiD,
00:03
but I'm sure more signatures can't hurt.
00:03
There's a lot of false positives out there
00:03
sometimes, I found,
00:03
but it always helps
00:03
to just give a 30-second scan for something.
00:03
If we knew something was packed with UPX,
00:03
we can simply run
00:03
upx_d, and give it the name of the executable.
00:03
It will do its best to unpackage itself.
00:03
We can see that this executable works again,
00:03
and UPX is just unpacked.
00:03
That works pretty well a lot of the times because
00:03
the Burgo is just one of the packet to obviously get
00:03
the strings, or just change the hash, or whatever else.
00:03
Sometimes it does work,
00:03
but [LAUGHTER] I think there was a vulnerability in
00:03
the unpacking portion of UPX.
00:03
If people run upx_d on the
00:03
>> specially crafted executable,
00:03
>> it would actually turn remotely execute code.
00:03
If someone wasn't running this in
00:03
a VM, there would be infected.
00:03
Be careful, and I like to keep all the tools
00:03
inside the VM as best as possible.
00:03
Sometimes, a minor change would make
00:03
it so that UPX could not just automatically unpack it,
00:03
like the section names.
00:03
>> Let's see if we have a PE Explorer, not really.
00:03
I usually have one installed
00:03
but if we look at the section names,
00:03
let's see if we have a binary template.
00:03
We do not, but I can look
00:03
pretty easily here,
00:03
>> and see the section names.text.rdata.
00:03
>> If we do UPX, just repack it.
00:03
I'm surprised it didn't complain that
00:03
the vowels are altered.
00:03
Here, it's packed, and the section names have been
00:03
changed to UPX0 UPX1.resource.
00:03
If we were to change the section name,
00:03
it doesn't actually matter,
00:03
or just UPXX and save it and try to unpack it.
00:03
[NOISE].
00:03
It would do its best,
00:03
and sometimes it would work.
00:03
>> But if we change it again and save it,
00:03
>> then not packed by UPX, I think we corrupted it.
00:03
[LAUGHTER].
00:03
Let's delete it and start again.
00:03
Regshot, press it over here, 64 bit,
00:03
this is 60X86,
00:03
we pack it, we look at the section names.
00:03
We'll change one of the section names, save it.
00:03
This still runs just fine.
00:03
Let's see if UPX still recognizes
00:03
it when we try to unpack it, no.
00:03
Just by simply editing a small bit of the file,
00:03
UPX can no longer just unpack it by itself because it
00:03
uses some of those indicators
00:03
to unpack it properly because it
00:03
knows it's the packer that built the executable.
00:03
Unpacking automatically won't always work.
00:03
We can see here that we still got that signature.
00:03
We can do a deep scan,
00:03
hardcore scan, and it's showing
00:03
the wrong version for that packer.
00:03
It was showing the wrong version for UPX,
00:03
and we were actually using a different version.
00:03
Maybe if we downloaded
00:03
a new database file it would catch that but maybe not.
00:03
Someone even might have taken
00:03
the source code that doesn't help.
00:03
The PID is no longer developed.
00:03
You can get off the Internet,
00:03
but it's no longer maintained so if there's a bug,
00:03
there's a bug and you can't fix it.
00:03
But, if someone has
00:03
a bad signature out there or whatever,
00:03
or someone took the
00:03
>> UPX source code, and modified it more
00:03
>> then we have to unpack it manually, if we want to
00:03
get at the decryptor strings
00:03
and other resources in the file.
00:03
Here I've taken an original old OllyDbg 1.1.
00:03
It's saying a newer version of
00:03
the DLL corresponding to the system directory,
00:03
delete the old library.
00:03
Yes, I want to use the newest library.
00:03
I'm going to add a plugin to help us.
00:03
It looks like the plugins are just dropped in
00:03
here and the plugin is OllyDump.
00:03
I'll tell you about why
00:03
>> this is going to be useful later.
00:03
>> Going to restart Olly.
00:03
Drag Regshot into it.
00:03
It says hey,
00:03
look it has a high amount of entropy,
00:03
is probably packed are you sure you want to continue?
00:03
Because it knows that there
00:03
might be some funkiness going on.
00:03
We can even execute it
00:03
>> and it'll still work but there is
00:03
>> a process being executed by OllyDbg.
00:03
The first thing that is really
00:03
important is this PUSHAD instruction.
00:03
Let me see if I can make the appearance a bit more
00:03
friendly, terminal 6.
00:03
[NOISE]
00:03
PUSHAD is an instruction
00:03
that pushes all the registers onto
00:03
the stack and that's unusual
00:03
because compilers don't usually admit this instruction.
00:03
It's a bit slow, but it's frequently used by
00:03
packers because it easily saves the environment.
00:03
They can do a pop AD at the end of whatever they're
00:03
doing whatever witchcraft and they
00:03
can ensure that the same options
00:03
are there for their regular program
00:03
as they were there for
00:03
the packer or
00:03
the unpacking stub that's
00:03
at the beginning of the program.
00:03
We know that the original program is going
00:03
to use whatever is pushed
00:03
onto the stack so we're going to do a step over.
00:03
We're going to let all these values get pushed
00:03
onto the stack right down here,
00:03
and we're just going to
00:03
let it unpack the whole executable.
00:03
ESP is the extended stack pointer
00:03
and is pointing at the top of the stack,
00:03
so that's where all these values
00:03
just got pushed onto the stack.
00:03
I'm going to say follow and dump, expand this.
00:03
We can see over here these are
00:03
the values that are over here that have been
00:03
pushed onto the dump or push onto the stack,
00:03
and I'm going to just put a hardware breakpoint
00:03
right on access Dword,
00:03
so that's 32 bits,
00:03
aka, four bytes, and I'm just going to hit "Run" and
00:03
let the whole unpacker unpack the original code.
00:03
We can see that it accesses the values it pushed on.
00:03
Right here it does a pop AD
00:03
and put everything back in its registers.
00:03
I can see here that it's going to do a jump,
00:03
and that's probably going to be the jump
00:03
into the original code.
00:03
I'm going to say let's start walking through this.
00:03
But there's this little loop
00:03
here and the only way to get out of
00:03
it is for this condition
00:03
to allow this jump not to happen.
00:03
I know this is going to happen eventually.
00:03
I'm going to hit a breakpoint, hit
00:03
"F2" for a soft breakpoint.
00:03
Don't really care that it's hard or soft.
00:03
I'm just going hit "Play"
00:03
>> the hard breakpoint hit again,
00:03
>> but I'm just going to hit "Play" again.
00:03
It's now reached this breakpoint.
00:03
I want to remove it by pressing "F2",
00:03
and I know it's going to jump into the original code.
00:03
I'm going to say follow into
00:03
and here is the original code
00:03
that's now been unpacked. That's fantastic.
00:03
Now I can scan for strings and do all this other stuff,
00:03
but I really want it back into
00:03
a file form or I can just transfer it
00:03
to somebody or do some more stack analysis of the data.
00:03
I'm going to dump what
00:03
I have in memory right here into a file.
00:03
I can do that with that OllyDump program,
00:03
add plug-in that I mentioned earlier.
00:03
I'm going to say dump debug process.
00:03
>> There's our section AA that we edited.
00:03
I'm going to get EIP as OEP.
00:03
Now, this means that, I'm going to say,
00:03
this current area that
00:03
is about to be executed right now,
00:03
that is the original entry point, the OEP.
00:03
I'm going to copy that value too,
00:03
Control C. This is
00:03
important because the file on disk that's
00:03
packed says that the beginning entry point
00:03
is actually in the packer stuff.
00:03
The thing that does the unpacking, the decrypting.
00:03
We don't want that to be true anymore,
00:03
we want the original unpacked code
00:03
to just begin executing.
00:03
This is an old plugin,
00:03
OllyDump, and that's okay.
00:03
It tries to rebuild
00:03
the import table for us
00:03
>> and that can be a little tricky.
00:03
>> I've used method 1 and method 2,
00:03
and they've always worked for me unless it wasn't
00:03
a really simple program.
00:03
In general, I turn this off and
00:03
let another program help me out with that.
00:03
I'm going to dump this to disk,
00:03
and I usually say, whatever it is, underscore unpacked.
00:03
Save it. This is still executing
00:03
the memory even though the window hasn't popped
00:03
up or nothing else has been initialized,
00:03
it just unpacked the code.
00:03
I'm going to use my import reconstructor program.
00:03
Before I launch into that,
00:03
I just want to say that there are
00:03
other dumping programs that we can use.
00:03
This plugin for Olly,
00:03
there's Load PE,
00:03
a program that we have here that I introduced early on.
00:03
I can demo it real quick.
00:03
The more I can select which thing,
00:03
which process running,
00:03
I want right here.
00:03
I can say, "Dump" and create a folder, Partial Dump.
00:03
It's a dumper so it has a lot more options to it,
00:03
and it will even help you rebuild things in the PE.
00:03
But for simplicity's sake,
00:03
I'm not going to be showing that off.
00:03
There's even a newer Olly Plugin Dumper,
00:03
but the old one works just fine for
00:03
>> a lot of my purposes.
00:03
>> That one's called OllyDebg PE Dumper or PE Dumper.
00:03
[NOISE] Here, I'm moving on to
00:03
the next phase which is
00:03
rebuilding the import address table.
00:03
There's a lot of options to this.
00:03
I suggest that you take a look at them.
00:03
But for right now, I'm just going to rebuild
00:03
this executable as fast as I
00:03
can because it currently will not work.
00:03
If we double-clicked on it,
00:03
it would say, "Hey, the Windows loader says,
00:03
I can't find which dependencies this executable needs
00:03
and then tries to execute the code
00:03
and the code doesn't quite work."
00:03
But it's already been loaded up in the memory,
00:03
and it's still currently running even
00:03
though it's been halted by Debugger.
00:03
We can use Import Reconstructor to look at
00:03
our processing memory and find
00:03
the proper import address table.
00:03
Because the packer has already done this work for us,
00:03
we don't need to do it again,
00:03
we can just take a look at what it's done.
00:03
I'm going to go here to the OEP and paste that value in
00:03
that I had earlier and say,
00:03
"Okay, I want you to make
00:03
>> this the original entry point.
00:03
>> When this file is executed,
00:03
I want it to jump straight to the unpacked code,
00:03
skip the whole unpacking stub that UPX added in."
00:03
Now, I'm going to hit the "IAT AutoSearch".
00:03
I'm saying, break into
00:03
this process and look through its memory,
00:03
and find what looks to be an import address table.
00:03
It says it's found one.
00:03
It looks about right but hit,
00:03
"Get Imports" and we do,
00:03
and there are several DLLs loaded,
00:03
and we're just like, "Okay, that looks good.
00:03
That looks about what this program would probably use."
00:03
A good method to verify that is show invalid.
00:03
Say, "Go through that and look to see which ones
00:03
are not real that are messed up or something."
00:03
Then you can get an idea for where
00:03
exactly the import address table really is.
00:03
If you wanted to, you could,
00:03
with Olly, find that import address table.
00:03
All you have to do would be to find
00:03
the inner module calls which we
00:03
showed beforehand and find
00:03
a table where if we looked through the memory enough,
00:03
we would find an easy table where it would show,
00:03
this is the GetFileTime function,
00:03
and the FindClose function,
00:03
and the FindNextFileA function,
00:03
and so on and so forth.
00:03
Like I said, we could find
00:03
the import address table manually in Olly,
00:03
and there's plenty of tutorials out
00:03
there to find it efficiently.
00:03
But fortunately, the man who made this,
00:03
[inaudible] made
00:03
some clever algorithms to find it for us.
00:03
Now, we have what looks to be
00:03
the IAT and we have the DLL dependencies
00:03
that we need to make a functioning PE executable.
00:03
Here, I'm going to say, fix a dump.
00:03
The guy who made this was pretty smart
00:03
>> and he was saying,
00:03
>> "Okay, they've probably already have
00:03
a dump of the file
00:03
and here with my program, I can repair it.
00:03
I can build the IAT table
00:03
to what it looks like in memory."
00:03
We can select the unpacked non-functioning executable
00:03
that we have here, and boom,
00:03
it creates another executable,
00:03
copies everything over,
00:03
adds an underscore to the end of that file,
00:03
and inserts an IAT that looks just like this one,
00:03
that looks like the one I found in memory.
00:03
If we execute this one now,
00:03
it completely bypasses the unpacking coach
00:03
straight to the unpacked code.
00:03
That's how you manually
00:03
unpack a file if
00:03
you don't have the luxury of using UPX-T.
00:03
The same technique of using the Push AD and
00:03
Pop AD instructions as indicators for when
00:03
to follow a jump into the original entry point,
00:03
dump the code, and then use
00:03
import reconstruction program
00:03
>> like import reconstructor.
00:03
>> This will work with a lot of packers out there
00:03
such as AS Pack and a few other common ones.
00:03
There are many tutorials on there.
00:03
Tuts 4 You is a great website
00:03
for finding tutorials on reverse engineering packers.
00:03
There's a lot of automated scripts
00:03
that people have made for Olly to
00:03
help you find certain data structures
00:03
or to help you just unpack things.
00:03
In fact, when I Googled around a few minutes ago,
00:03
I found someone made a unpacker for Olly,
00:03
and it did almost exactly what we did here which was
00:03
find the push AD instruction
00:03
and find the Pop AD instruction,
00:03
place a breakpoint, dump it,
00:03
and then reconstruct it with the import address table.
00:03
But it's good to know what's going
00:03
on underneath the hood.
Up Next