Hi George,
thanks for your answer, it definitely shows that you're deeply in the
field and that I still have a lot to learn about:)
Here are my comments:
On Mon, Jan 7, 2013 at 4:10 PM, George M. Garner Jr.
<ggarner_online(a)gmgsystemsinc.com> wrote:
Luka,
Good to hear from you and thanks again for drawing attention to the
importance of reliability issues in volatile evidence acquisition. The
robustness and reliability of memory acquisition tools has received scant
attention up until now, Yet, the acquisition phase is the most important
step. You can run an analysis tool and, if it fails, you can still run a
different analysis tool or patch the first analysis tool and run it again.
If an acquisition tool fails silently you are typically out of luck! Note
that the reliability issues addressed in your presentation are not unique to
memory acquisition but also apply to the live acquisition of other storage
media as well. Darren Bilby's 2006 Blackhat presentation (DDefy) addressed
both "live" memory and other storage acquisition. While your current
presentation focuses on physical memory acquisition, your techniques could
easily be applied to the "live" acquisition of fixed storage media as well.
And perhaps they should be so applied.
I agree completely - this was just an extension of DDefy to memory
forensics (although it did posess some mem-related hiding abilities)
and addition of new features.
My apologies if my previous post seemed dismissive. The appropriate
response to a critical work is to view it critically, however. Darren
unfortunately abandoned his work on DDefy. My intention is not that you
abandon Dementia but that you improve it! I wouldn't worry too much about
giving the "bad guys" ideas, as they already are implementing plenty of
ideas, including some that haven't been mentioned yet.
Thanks:)
1. Acquisition tools should utilize drivers correctly, (i.e. they should
acquire memory into a kernel mode buffer and write that buffer to a file
from kernel mode)!
It is true that a tool such as win32dd will not be susceptible to user mode
DeviceIoControl/NtDeviceIoControlFile or WriteFile/NtWriteFile hooks.
However, win32dd will be/is vulnerable to your kernel mode NtWriteFile hook
and to a file system filter driver (assuming that you are implementing those
methods correctly). Also, if you are able to install an inline hook in the
kernel mode NtWriteFile function, you ought equally to be able to install
inline hooks in NtMapViewOfSection, MmMapIoSpace and MmMapMemoryDumpMdl. Or
the same could be accomplished using IAT hooks, like the driver verifier
does it. Indeed, hooking those three functions would cover all of the
memory acquisition tools which you tested and render output compression or
encryption irrelevant. So how is the KM/KM paradigm (e.g. win32dd) superior
to other methods? Your PoC itself subverts both UM and KM acqusition,
assuming that you have implemented your NtWriteFile hook correctly. If not
then shame on you! Note that I am not saying this to disparage win32dd. I
am just saying that the approach taken by this tool is not inherently more
reliable than other methods.
Dementia has two drivers - one is using NtWriteFile hook, the other
one is a FS minifilter. They are not used in parallel of course:)
Using any of these two drivers, Dementia is able to hide mentioned
artifacts from all acquisition tools I tested (Win32dd included),
except Winen and OSForensics.
Winen is creating EWF and it's tricky to modify the file as it's being
written (but not impossible). However, it transfers the memory pages
to user-mode in *clean* format, so I could use the user mode injection
(DeviceIoControl hook). Injection to Winen process is not implemented
at the moment, but it's trivial to extend Dementia in order to support
it.
OSForensics is doing something strange with the buffers being written
to the file. I had no time (and no motivation either) to check why
can't I access the buffer being written to the file (AV fault), but
it's again susceptible to UM injection.
KM/KM paradigm used ONLY by win32dd is better in many ways:
1. Buffer never leaves the kernel space - attacker cannot attack it
from the user-mode
2. Buffer never leaves the kernel space - no performance overhead of
communicating with the driver, copying the memory back to user-space
(or not, depending on the method used, but then you have additional
probes of UM buffer etc.)
3. Logging and/or encryption methods done in KM-only are again much
safer than doing it in user-mode (you mention it later in your answer)
It does not solve the problem, as I have demonstrated, but I think it
is simply unnecessary and worse approach to transfer the buffer back
to user-mode and then write it to dump.
I'm not completely sure how would you do sound acquisition using
crypto/logging mechanisms if someone hooks deeply in the kernel? By
the time you get your buffer, it has already been tampered with. Some
kind of cross-viewing could be applied, but I'm not quite sure about
that...
As a side note - win32dd is the fastest tool I tested, and it's my
definitive favorite:)
2. Use hardware acquisition tools.
You're absolutely right regarding the 4 GB
limit. But from
an attacker's perspective, this method cannot be used for hiding
arbitrary object, and it might be difficult to "relocate" the
driver, allocations and all resources above the specified limit. <
Actually it is quite easy to load a driver or arbitrary object (e.g.
encryption key or key schedules) into a reserved physical address space
above 4 GiB. We are currently shipping some software to our customers that
is able to do precisely that. It wasn't written with the intention of
"cheating" firewire memory dumps; however, it should serve that purpose
equally well.
Maybe I'm missing something here, but how would you move *an
arbitrary* object above 4 GB.
By arbitrary, I mean really arbitrary object, for example an
allocation in user-mode, network connection (i.e. socket), file
object, VAD, anything...
Wow, I completely forgot about Rustock, this is my fault:(
Does anyone have a short analysis of this part of the Rustock.C?
I was able to find the sample itself, but I really don't have the time
to reverse engineer the rootkit in search for this tiny functionality
I'm interested in:(
I'm really interested in how Rustock does it.
Very nice find, and fail for me not reading the Matthieu's and other's
presentations:/
Once again, the superiority of crashdumps over other
acquisition methods
appears to be largely due to a design decision on your part not to attack
crashdumps as vigorously as you might.
You may be right.
However, as Matthieu mentioned in his post, win32dd is not utilizing
normal Windows crash-dump path - but Dementia modifies the crash-dump
produced by the win32dd in the same way it modifies raw dump produced
by any other tool:(
And yes, I did thought that, from a forensics perspective, crash-dumps
are more sound than raw dumps, because they use different I/O path:(
Will probably investigate this part further.
Once we are satisfied that a tool implements a sound forensic method we
would then like to see if the evidence adulteration is reflected in the
output of the tool in the form of log entries and/or modified cryptographic
checksum. In other words, I would like to see you acquire memory evidence
the way that a professional computer forensic "expert" would acquire
evidence and then see whether the PoC is able to subvert the acquisition
process without any indication in the form of log entries or altered
cryptographic checksums.
I'm not a computer forensic "expert" and unfortunately I don't have
the ability to test expensive memory acquisition tools.
I had the opportunity to work with EnCase for a brief period of time,
but it seems that memory analysis capabilities of EnCase are
relatively weak (various EnScripts, I didn't test them throughly) and
acquisition is completely based on Winen.
None of the tools I tested had such cryptographic and advanced logging
capabilities.
I had no chance to work with KnTTools, so I cannot say anything about KnTTools.
How is using Dimentia to wipe certain
artifacts from memory different from using CCleaner to destroy disk
evidence, if I can find artifacts which show that Dimentia was used? Inline
hooks in a user mode process leave some definite artifacts even after they
have been removed. Kernel mode inline hooks (e.g. in NtWriteFile) also are
highly visible, and they don't work on 64-bit Windows as you acknowledge.
Even the lower disk filters used by most bootkits are visible now that
everyone knows to look for them.
I could see some analogies between CCleaner and Dementia, but I
wouldn't say that they are equal (in the "cleaning-stuff" analogy) .
Dementia is operating in a different realm than the data being
collected. Although that sounds a bit pretentious, it's actually a
simple premise - it's not modifying the live machine, it is modifying
the data inside the "dead dump", and it can do anything it wants
inside the dump.
Although inline hooks are highly visible, they are not visible inside
the dump if I deliberately remove them:) And it's completely trivial
to restore the original opcodes if you're the one that did the
hooking.
Minifilters are noisy and visible as well, but again, Dementia could
remove that as well.
That being said, Dementia DOES NOT currently hide hooks or
minifilters, but could do so in the future.
That's why one of my conclusions was to perform "live" anti-rootkit
analysis, or cross-viewing.
I don't think that's a valuable or "sound" conclusion, because, as you
mentioned, AV's have been fighting with this for a long time.
One approach may be to place the rootkit in a
memory location that the forensic tool does not acquire. For example, some
tools aren't able to acquire non-cached or write-combined memory on Windows
systems prior to Windows 7 (e.g. MDD). You might be able to "hide" a
rootkit from one of these tools simply by placing the rootkit in non-cached
or write-combined memory without any hooks whatsoever. (Well, actually,
only the appropriate entry in the PFN database needs to say that the memory
is non-cached or write-combined, and not the PTE entry itself.)
Very cool, I didn't know that:)
To be fair you should not ignore suitable and
obvious methods of subverting KM acquisition methods. (Why is it that you
chose not to attack NtMapViewOfSection, MmMapIoSpace and MmMapMemoryDumpMdl
directly?)
I got that question after the talk:)
Here are some of the reasons (you'll probably find them foul in one
way or another, but anyway...):
1. File-write-interception is a generic method that covers all tools -
they have to write the dump in the end (unless they send it over the
network, which is when Dementia is currently screwed:))
2. File-writes gives me context - I can detect (easily? with adequate
accurracy?) that memory acquisition app is being used and it's going
to write the dump. Although MmMapMemoryDumpMdl is called rarely,
Nt(Mm)MapViewOfSection is called A LOT and it might be difficult to
detect whether dump is being written or not.
3. One hook is better than multiple hooks:)
4. No hooking in x64.
And I can hook deep, I have another PoC that does MmMapMemoryDumpMdl
hooking, but it's not generic enough. And it's not usable on x64.
Dementia "evolution" would probably go in the direction of deep
hooking on x86, while keeping the minifilter on x64.
A very interesting extension of your work would be to
modify
open source router firmware to strip malicious artifacts from the data
stream as it is being transmitted over the wire. Then see how many tools
notice that the evidence was modified. :-)
Cool, but I certainly don't have enough knowledge for that:)
Encryption may also be useful
to protect evidence written to removable storage media from tampering after
it has been written to disk. You didn't really look at that possibility.
That was not in scope of my research.
Encryption post-festum does not provide any protection against tools
such as Dementia.
So here are my conclusions after reading your presentation:
1. Computer forensic investigators should acquire volatile evidence in a
forensically sound manner.
Agree, but what does "forensically sound manner" actually mean in this context?
Forgive me for perhaps not knowing the basics...
2. Memory acquisition tools should employ robust error logging and
cryptographic checksums to ensure the integrity of volatile evidence as it
is being transmitted and archived for future uses
3. Cryptographic checksums should be generated for
volatile evidence as
early as possible in the acquisition process, preferrably in kernel mode.
4. Encryption should be employed during the transmission and archival of
digital evidence to preserve the confidentiality of sensitive data and to
reduce the attack surface.
Agree, but again, your view of memory could be polluted before you
even have the chance to calculate the checksum.
Yes, "could", but Dementia does prove it in a simplistic way
(DeviceIoControl hook).
I'm not sure where I'm actually heading with Dementia:) It was a cool
research for me, I learned quite a bit about Windows internals and
maybe raised awareness and pointed out some weak points with memory
acquisition process (that you were all probably already aware of, but
maybe since there was no tool to directly exploit them, it wasn't
perceived as "dangerous" enough).
I don't know my further steps. I'm wondering how deep and "under the
radar" can I go, but as Matthieu says - "That's the cat and mouse game
we all know very well."
Thank you for your thoughts and comments.
And sorry for using another account:)
Cheers,
Luka