Michael,
I think a few things are going wrong here. See below.
On Thu, Jun 14, 2012 at 4:51 AM, Michael Felber <MichaelFelber(a)gmx.net> wrote:
Hi all,
still playing with fire (or a single “Flame” ;-)) I have tried to dump the
possibly infected services.exe from a decompressed hiberil.sys but run into
an error message:
C:\Micha\Forensics\Volatility-2.1a>python vol.py pslist -f
D:\X-Ways-Images\flame.mem | egrep -i "(PID|services)"
Volatile Systems Volatility Framework 2.1_alpha
Offset(V) Name PID PPID Thds Hnds Sess Wow64
Start Exit
0x84cae5a8 services.exe 912 868 37 966 0 0
2012-06-03 07:47:48
C:\Micha\Forensics\Volatility-2.1a>python vol.py procexedump -p 868 -f
D:\X-Ways-Images\flame.mem -D C:\temp\VolDumpFlame
Volatile Systems Volatility Framework 2.1_alpha
************************************************************************
Dumping winlogon.exe, pid: 868 output: executable.868.exe
C:\Micha\Forensics\Volatility-2.1a>python vol.py procexedump -p 912 -f
D:\X-Ways-Images\flame.mem -D C:\temp\VolDumpFlame
Volatile Systems Volatility Framework 2.1_alpha
************************************************************************
Error: ImageBaseAddress not memory resident for process [912]
C:\Micha\Forensics\Volatility-2.1a>python vol.py procexedump -o 0x84cae5a8
-f D:\X-Ways-Images\flame.mem -D C:\temp\VolDumpFlame
Volatile Systems Volatility Framework 2.1_alpha
************************************************************************
Error: PEB not memory resident for process [-]
Why the PEB header seems to be paged out? Isn’t it a strange behavior for
such an important process like services.exe?
The PEB for this process isn't paged. What's happening is you tried to
supply a virtual offset as the -o parameter, when that parameter
should be a physical offset. For example:
$ python vol.py -f flame_hiberfil.sys procexedump -h
Volatile Systems Volatility Framework 2.1_alpha
Usage: Volatility - A memory forensics analysis platform.
...
-o OFFSET, --offset=OFFSET
EPROCESS offset (in hex) in the physical address space
...
So by supplying a virtual offset instead, the plugin is definitely not
going to work properly. However, even if you supplied a physical
offset to -o, you'll see the same thing as if you supplied -p 912,
which is the "ImageBaseAddress not memory resident for process"
message. This happens because the services.exe image base is in fact
paged. The image base contains the PE header which is the "map" that
procexedump uses to rebuild the PE.
>> cc(pid = 912)
Current context: process
services.exe, pid=912, ppid=868 DTB=0x13edc000
>> hex(self.eproc.Peb.ImageBaseAddress)
'0x1000000L'
>> dd(0x1000000L)
Memory unreadable at
01000000
So that proves the PEB is not paged, else we wouldn't be able to
determine the ImageBaseAddress. Take a look at the memory map for this
process:
$ python vol.py -f hiberfil.sys -p 912 memmap
Volatile Systems Volatility Framework 2.1_alpha
services.exe pid: 912
Virtual Physical Size
---------- ---------- ----------
....
0x00fbf000 0x18ce0000 0x1000
0x00ffc000 0x00736000 0x1000
0x00ffd000 0x0f87f000 0x1000
0x00ffe000 0x19b7a000 0x1000
0x00fff000 0x18f34000 0x1000 <---- last page before image base
0x01001000 0x13f47000 0x1000 <---- first page after image base
0x01002000 0x0caca000 0x1000
0x01003000 0x0cacb000 0x1000
0x01004000 0x0cac4000 0x1000
0x01005000 0x0cac5000 0x1000
0x0100e000 0x0cace000 0x1000
0x01014000 0x0cae1000 0x1000
0x0101b000 0x14003000 0x1000
0x01020000 0x18ca6000 0x1000
....
As you can see, 0x01000000 (ImageBaseAddress) is not memory resident,
but 0x01001000 is available. After the Windows loader uses the PE
header, its rarely referenced again, so the PE header being paged is
not out of the ordinary, even for an important process like
services.exe. So what can you do? Just use vaddump to obtain the
memory region where services.exe resides. It'll pad the missing page
with 0's to retain original size.
$python vol.py -f hiberfil.sys -p 912 vaddump -D out2
Volatile Systems Volatility Framework 2.1_alpha
Pid: 912
************************************************************************
$ ls -al out2
...
-rw-r--r-- 1 Michael staff 118784 Jun 23 10:25
services.exe.48ae5a8.01000000-0101cfff.dmp
Now if you wanted to analyze it in IDA, use a hex editor and steal the
first 0x1000 bytes from services.exe on disk and paste it at the front
of services.exe.48ae5a8.01000000-0101cfff.dmp. Make sure you overwrite
and don't just prepend or the file size will change. Also, you may
need to use a PE editor and fix up some sections since volatility's
procexedump could not do that for you due to the missing PE header.
There is really no header:
In your commands below, 0x84cae5a8 is the virtual address of the
_EPROCESS kernel structure for services.exe. You would not find an MZ
header at this address nor any code to disassemble.
C:\Micha\Forensics\Volatility-2.1a>python vol.py
volshell -f
D:\X-Ways-Images\flame.mem
Volatile Systems Volatility Framework 2.1_alpha
Current context: process System, pid=4, ppid=0 DTB=0x39000
Welcome to volshell! Current memory image is:
file:///D:/X-Ways-Images/flame.mem
>> cc (offset=0x84cae5a8)
Current context: process services.exe, pid=912, ppid=868 DTB=0x13edc000
>> db(0x84cae5a8)
0x84cae5a8 03 00
1b 00 00 00 00 00 b0 7c b6 84 b0 7c b6 84
.........|...|..
0x84cae5b8 b8 e5 ca 84 b8 e5 ca 84 00 c0 ed 13 00 50 ee 13
.............P..
0x84cae5c8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
................
0x84cae5d8 ac 20 00 00 00 00 00 00 39 0a 00 00 4f 0c 00 00
........9...O...
0x84cae5e8 e8 e5 ca 84 e8 e5 ca 84 00 00 00 00 00 00 00 00
................
0x84cae5f8 58 9f b8 84 d0 51 60 84 00 00 00 00 01 00 00 00
X....Q`.........
0x84cae608 14 00 09 06 00 00 00 00 00 00 00 00 00 00 00 00
................
0x84cae618 00 f3 e8 2b 5d 41 cd 01 00 00 00 00 00 00 00 00
...+]A..........
>> dis(0x84cae5a8)
0x84cae5a8
0300 ADD EAX, [EAX]
0x84cae5aa 1b00 SBB EAX, [EAX]
0x84cae5ac 0000 ADD [EAX], AL
0x84cae5ae 0000 ADD [EAX], AL
0x84cae5b0 b07c MOV AL, 0x7c
0x84cae5b2 b684 MOV DH, 0x84
0x84cae5b4 b07c MOV AL, 0x7c
0x84cae5b6 b684 MOV DH, 0x84
0x84cae5b8 b8e5ca84b8 MOV EAX, 0xb884cae5
0x84cae5bd e5ca IN EAX, 0xca
0x84cae5bf 8400 TEST [EAX], AL
0x84cae5c1 c0ed13 SHR CH, 0x13
…
The goal was to find hooks within the code but it seems to be a challenge to
find the complete process itself….
Unless flame places hooks in services.exe by modifying/patching the
services.exe code itself, then extracting the services.exe binary is
not going to help you find hooks. Usually the hook is in a DLL loaded
by the process, not in the process itself. However, in the few brief
reports of Flame I read, it sounds like the one hooked API function is
in the memory of explorer.exe, not services.exe anyway. For example
according to the CrySyS paper [1] section 3.4 Hooks, Flame hooks
shell32!SHGetSpecialFolderPathW in explorer.exe.
The apihooks plugin is now committed and available in the 2.1 alpha
branch, however it still doesn't show any hooks in the explorer.exe
process. Its not an error in the plugin though, as you can check
manually that the function is not hooked in your memory dump:
$ python vol.py -f hiberfil.sys volshell
Volatile Systems Volatility Framework 2.1_alpha
Current context: process System, pid=4, ppid=0 DTB=0x39000
Welcome to volshell! Current memory image is:
file:///Users/Michael/Desktop/flame%20hiber/hiberfil.sys
To get help, type 'hh()'
>> ps()
Name PID PPID
Offset
System 4 0 0x84fca830
smss.exe 764 4 0x84cf29e8
csrss.exe 844 764 0x84eba020
winlogon.exe 868 764 0x84c16460
services.exe 912 868 0x84cae5a8
lsass.exe 924 868 0x84ba8a20
svchost.exe 1088 912 0x84bc5870
svchost.exe 1164 912 0x84bcfa28
svchost.exe 1204 912 0x84c1a768
svchost.exe 1244 912 0x84b818b0
svchost.exe 1364 912 0x84bda420
vsmon.exe 1532 912 0x84e3a3f0
explorer.exe 1604 1572 0x84bc8da0
...
>> cc(pid = 1604)
Current context: process
explorer.exe, pid=1604, ppid=1572 DTB=0x19fd1000
>> shell32 = None
>> for mod in self.eproc.get_load_modules():
... if str(mod.BaseDllName).lower() == "shell32.dll":
... shell32 = mod
... break
...
>> shell32
[_LDR_DATA_TABLE_ENTRY
_LDR_DATA_TABLE_ENTRY] @ 0x00192F00
>> func =
shell32.getprocaddress("SHGetSpecialFolderPathW")
>> func_addr = mod.DllBase + func
>> hex(func_addr)
'0x7c9eb198L'
>> dis(func_addr)
0x7c9eb198 8bff
MOV EDI, EDI
0x7c9eb19a 55 PUSH EBP
0x7c9eb19b 8bec MOV EBP, ESP
0x7c9eb19d 33c0 XOR EAX, EAX
0x7c9eb19f 394514 CMP [EBP+0x14], EAX
0x7c9eb1a2 0f85f4f90300 JNZ 0x7ca2ab9c
0x7c9eb1a8 ff750c PUSH DWORD [EBP+0xc]
0x7c9eb1ab 50 PUSH EAX
0x7c9eb1ac 50 PUSH EAX
0x7c9eb1ad ff7510 PUSH DWORD [EBP+0x10]
0x7c9eb1b0 ff7508 PUSH DWORD [EBP+0x8]
0x7c9eb1b3 e81e400000 CALL 0x7c9ef1d6
0x7c9eb1b8 f7d8 NEG EAX
0x7c9eb1ba 1bc0 SBB EAX, EAX
0x7c9eb1bc 40 INC EAX
0x7c9eb1bd 5d POP EBP
0x7c9eb1be c21000 RET 0x10
Most likely, flame is installed but not all functionality is being
exhibited, perhaps because of some anti-analysis capabilities. For
example, GFI had to create a system with hebrew language pack
installed to elicit certain behaviors [2].
[1].
http://www.crysys.hu/skywiper/skywiper.pdf
[2].
http://vimeo.com/44382073
What could I do?
Regards
Mic
_______________________________________________
Vol-users mailing list
Vol-users(a)volatilityfoundation.org
http://lists.volatilityfoundation.org/mailman/listinfo/vol-users