Slides - Dynamic loading & using tools

Report
Revealing Stealth Malware
UMD CMSC389M
Xeno Kovah – Jan. 2013
xkovah at gmail
Subject line starting with "UMD:"
1
All materials is licensed under a Creative
Commons “Share Alike” license.
• http://creativecommons.org/licenses/by-sa/3.0/
2
Outline
• ProcMon, WinDbg userspace vs. kernel,
Existing stuff review
• Lab: Using WinDbg, live system analysis with
GMER, Tuluka, VBA, and XueTr
3
Runtime Importing
• Other functions that are important to malware are
LoadLibrary() and GetProcAddress().
• LoadLibrary() can be called to dynamically, on demand,
load a DLL into the memory space of the process
• GetProcAddress() gives the address of a function
specified by name, or by ordinal (which we may talk about
briefly). This address can then be used as a function
pointer.
• These functions are often abused to make it so that which
functions the malware actually uses cannot be determined
simply by looking at the INT. Rather, the malware will have
the names of the imported libraries and functions
obfuscated somewhere in the data, and then will
deobfuscate them and dynamically resolve them before
calling the imported functions.
4
Runtime Importing 2
• When an attacker is using the more
sophisticated methods of DLL injection, he is
not necessarily injecting a full, well-formed PE
file DLL into another memory. He may just be
injecting small snippets of asm.
• When that's the case, he will typically inject
code which walks the PE headers to find the
exports table of kernel32.dll to find
GetProcAddress() and LoadLibrary().
5
Runtime Importing 3
• In *your* case, since you're loading a full, wellformed DLL, you can just put calls to these
functions into your DLL, and the OS loader will
happily fill in your IAT so that you can call these
easily.
• Therefore for this homework, you can use these
two functions, without having to walk headers,
like is in the previous slide deck, but which I
didn't cover in class (so I'm not deleting it from
the deck, but it isn't required for the homework
or final)
6
Process Monitoring with ProcMon
• ProcMon is another Sysinternals tool (like
Process Explorer, and Autoruns.)
7
When you start it up the first time, it should ask you what you want the filter criteria to be. This
is basically a question of what you want to monitor. To make this less noisy, you should only
monitor a specific process to start with.
Change the monitoring criteria to "Process Name" and then enter a process name then click Add
8
You should consequently see a new green checkbox appear in the rules. Hit Apply and then OK
9
To make sure that this doesn't eat a ton of RAM storing information about events that you're
filtering out, the first thing you want to do is change it so that it Drop[s] Filtered Events
10
The top bar lets you toggle what type of events you want to see, as well as clear existing events
and edit the filter.
Event Toggles
Filter
Clear Events
Registry
File
Network
Process
11
The Operation column can give you hints on what functions are being called, though it's by no
means a 1:1 mapping (but it's closer in the registry case than in the file case)
12
This gives a partial
explanation which
will make more
sense next week
13
WinDbgging Userspace
• As I've shown you can use WinDbg to debug
userspace programs as well as kernel ones.
• Some commands in the WinDbg cheat sheet
are kernel-only though. If something doesn't
work, double check it against the in-windbg
help (which is actually very helpful)
14
Run WinDbg (as Administrator if on Win 7).
Once it's running, open an executable
Find the exe you want to debug
You can give it command line
arguments at the bottom if you
want.
Or you can tell it to execute
from a given directory (incase
you want to give a relative path
to an input file for instance)
15
Once it starts, you'll get a single command window like normal. At this point you should set up
your WinDbg windows however you want them, or preferably like is specified in the first day
part 2 slides. Don't forget to go to File->Symbol Path and enter the symbol path given in the
slides. Your VM will need internet connectivity in order to download symbols from microsoft.
And always, just for good measure, use ".reload" to make sure your symbols are reloaded.
16
Once you have it set up, what then? Well then you can start setting breakpoints on the functions
you think are responsible for the activity you're interested in. The breakpoint will allow you to
examine the values of registers, memory, and the stack *exactly* the way they would look from
your inline/IAT hook's perspective when it's first called.
17
A simple first command is "lm" this lists the modules that are currently loaded.
In userspace, it will list .exe and .dll modules in a specific process' memory space.
In kernel, it will list the .sys kernel drivers which are loaded in the kernel memory space.
You can also use "lmf" to list with file names. See the help for other forms of "lm"
If I just hit "g" to go (continue execution) at this point, the debugger tells me that a couple
more modules loaded. Hmm, and one of them was my IAT hooking module. For debugging
purposes it sure would be nice if I could stop right when that gets loaded, and then set a
breakpoint on my DllMain() or something, so I can step through the code and make sure it's
right… You could set a deferred breakpoint which should technically get set when it loads, but
we really want to make sure it gets set…
We can use the "sxe" command to set an exception (debugger stop) whenever a particular
action occurs. The particular action we want here is module load. So by looking at the windbg
help, we see that we want something like "sxe ld". But even better than that, is some magic
Xeno's going to lay on you right now, which will tell you exactly which module just loaded. That
command is:
sxe -c ".lastevent" ld
So let's restart the process and do that before we hit g and let the rest of the modules load…
19
From here you should set the Symbol File Path to the path where your DLL was built, because
the .pdb (portable debug) file will be in that same directory, and windbg will need that file so it
can find your DllMain when you try to set a breakpoint on it
(like "bp StudentAppInitHookIAT!DllMain")
Then you can experiment with stepping through your own code to make sure it's doing the right
thing and/or setting breakpoints on the functions you think pertain to viewing registry keys
Example: modifying cmd.exe's
FindFirstFile/FindNextFile data structures
specifically to change a file name
• Reminder: if you look at the bottom of the documentation
you will see that actually FindFirstFile is technically
normally called FindFirstFileW or FindFirstFileA. You also
see this if you just use tab completion in windbg
• Reminder: if you look at the documentation you will see
that these functions take two inputs, the first is used only
for input, and the second is just passing the address of a
structure, so that the function can fill in the structure data,
and that will be the output
• Reminder: see the 1-7-2013 slides to see the x64 calling
convention and what parameters to a function are passed
in what variables
21
So now you've set some speculative function breakpoints because you want to see what data is
passed in/out
You let the program continue, by hitting "g" to go. Then you go do a "dir" in cmd.exe and it
breaks at one of your functions you theorized might be involved in file operations
But before we dig too deep into it, let's keep continuing to see what else is called…
So it looks like FindNextFile is getting called a bunch. And if we happen to take a peek back at
the cmd.exe window, we even see that there's a partial directory listing at this point
So by RTFM we know that the address of the data structure will be in RDX right when
FindNextFileW is called. So look at the value in RDX in a registers window…
And then stick it into a memory window
Now what you want is some way to see the data in that data structure location once
FindNextFileW is done. There are many ways you could do this. You could look at the assembly
in the disassembly window, and use the debugger's "step in" capability (as all debuggers have)
in order to step into the function and find where the function has a "ret" instruction, signaling
that it's done, and set a breakpoint on the ret.
You could just look at the memory pointed to by the stack pointer ESP to find the saved EIP that
you know must have been pushed onto the stack as a side effect of the call when whatever
parent function called FindNextFileW.
But I'm going to let you do it the easy graphical way. Just open a new calls window (which shows
a stack backtrace)
Open a disassembly window if you didn't already.
Then double click on the thing below FindNextFileW (this is its parent, and fwiw it's in cmd.exe
itself). This will force the disassembly window to jump to the cmd!FindNext + 0x3C
Now that this line immediately after the call to FindNextFileW is selected, you can just set a
breakpoint on this line, so that you will be able to inspect that EDX value immediately after the
function has returned.
So click the break icon and then the line is going to turn pink or something :P
Hit "g" to continue, and the next place you'll hit is that line
Meanwhile, back in the memory window…
Hmm, that kind of looks like it might be a wide character file name there on the end.
"adplus.doc"? So maybe the way this FindNextFile function works is, it's called, it gets one file
name at a time, it fills in this WIN32_FIND_DATA, and then cmd.exe take whatever comes back
and prints it to the cmd window.
So if that were true, I could just click in the memory window change that string like so…
Hit "g" to continue, and then see what I shall see in the cmd output window
Hmm…so I guess if I were an attacker executing code every time FindNextFileW was executed, I
could keep checking that string field of the WIN32_FIND_DATA and if it's ever "adplus.doc" I
could always change it to "adpluw.doc". OR. I could do other things
Tool interpretation
27
Import Address Table (IAT) Hooks (GMER)
This is the address in the IAT
pointing somewhere other than
where it should (based on the
Exports Address Table (EAT)
of the exporting module
This is the module
doing the importing
Telling you that
this is an IAT hook
If GMER can, it tries to infer
which module space the
function pointer is pointing into.
And if there's version
information in that module, it
pulls that out too
This is the function
being imported by
the first module and
exported by the
second
This is the module
doing the exporting
28
Inline Hooks (GMER)
PE section where
the hook resides
module within
process memory
hooked process name
process ID (PID)
function name
within module
number of bytes
that changed
specific virtual memory
address where the
change is found
if control flow redirect
(call, jmp)
module space where
it's redirected to
if it is within a module
address range
interpretation of
changed bytes
(if possible)
29
!chkimg (WinDbg)
• You can also find modifications to static
code/data areas with the !chkimg windbg
command. It checks the version in
memory against the file on disk
• E.g. to detect one of the above hooks
seen with gmer, you could attach to
taskmgr.exe, check your symbols, do your
.reload and then do
!chkimg -d kernel32
30
False Positives
McAfee HBSS HIPS
But when security software uses hooks like rootkits…you can remove its hooks just like you can
remove a rootkit's hooks in order to blind/disable it.
This is especially nice because it means you can defeat security software without resorting to
reverse engineering, because they always get touchy about you reverse engineering their stuff
(as if the attackers can't)
31
How to mount an ISO in VirtualBox
Go into your storage settings. Select the CD drive. Then click on the CD icon here
Select the below option and then navigate to the ISO that you want mounted inside your VM
32
How to install VirtualBox additions &
then set up a shared folder
Install the guest additions. It will then prompt you inside the VM to
install some windows programs & drivers. Just accept all the defaults
33
Go to your settings and then click this
34
If this isn't a valid
path on your host
OS, the "OK" will be
greyed out
Name in host OS
Name in guest OS
Windows
Linux
35

similar documents