Dik1s / volatility

Automatically exported from code.google.com/p/volatility
GNU General Public License v2.0
0 stars 0 forks source link

rawreg.value_data() backtrace #426

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
root@bt:/volatility# python vol.py -f jonsmith.mem --profile=Win7SP0x86 
printkey -K "ControlSet001\Control\TimeZoneInformation"
Volatile Systems Volatility Framework 2.3_beta revision 3432
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \REGISTRY\MACHINE\SYSTEM
Key name: TimeZoneInformation (S)
Last updated: 2013-04-04 01:57:34 UTC+0000

Subkeys:

Values:
REG_DWORD     Bias            : (S) 300
REG_DWORD     DaylightBias    : (S) 4294967236
REG_SZ        DaylightName    : (S) @tzres.dll,-111
REG_BINARY    DaylightStart   : (S)
0x00000000  00 00 03 00 02 00 02 00 00 00 00 00 00 00 00 00   ................
REG_DWORD     StandardBias    : (S) 0
REG_SZ        StandardName    : (S) @tzres.dll,-112
REG_BINARY    StandardStart   : (S)
0x00000000  00 00 0b 00 01 00 02 00 00 00 00 00 00 00 00 00   ................
Traceback (most recent call last):
  File "vol.py", line 186, in <module>
    main()
  File "vol.py", line 177, in main
    command.execute()
  File "/volatility/volatility/commands.py", line 111, in execute
    func(outfd, data)
  File "/volatility/volatility/plugins/registry/printkey.py", line 110, in render_text
    tp, dat = rawreg.value_data(v)
  File "/volatility/volatility/win32/rawreg.py", line 186, in value_data
    valdata = valdata.decode('utf-16-le', "ignore")
AttributeError: 'NoneType' object has no attribute 'decode'

patch to fix:

Index: volatility/win32/rawreg.py
===================================================================
--- volatility/win32/rawreg.py     (revision 3432)
+++ volatility/win32/rawreg.py     (working copy)
@@ -149,7 +149,7 @@
     if inline:
         if val.DataLength == 0x80000000:
             return ("REG_DWORD", val.Type.v())
-        valdata = val.obj_vm.read(val.Data.obj_offset, val.DataLength & 
0x7FFFFFFF)
+        valdata = val.obj_vm.zread(val.Data.obj_offset, val.DataLength & 
0x7FFFFFFF)
     elif val.DataLength > 0x4000:
         # Value is a BIG_DATA block, stored in chunked format
         datalen = val.DataLength
@@ -175,7 +175,7 @@
             valdata += chunk_data
             datalen -= amount_to_read
     else:
-        valdata = val.obj_vm.read(val.Data, val.DataLength)
+        valdata = val.obj_vm.zread(val.Data, val.DataLength)

     valtype = VALUE_TYPES.get(val.Type.v(), "REG_UNKNOWN")
     if valtype in ["REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_QWORD"]:

as you can see, it seems we assume that if the "val" structure is valid, then 
val.Data is also valid, however val.Data is a pointer and can easily not be 
valid even when val is valid. 

this is what he gets now:

root@bt:/volatility# python vol.py -f /madsec/jonsmith.mem --profile=Win7SP1x86 
printkey -K "ControlSet001\Control\TimeZoneInformation"
Volatile Systems Volatility Framework 2.3_beta
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \REGISTRY\MACHINE\SYSTEM
Key name: TimeZoneInformation (S)
Last updated: 2013-04-04 01:57:34 UTC+0000

Subkeys:

Values:
REG_DWORD     Bias            : (S) 300
REG_DWORD     DaylightBias    : (S) 4294967236
REG_SZ        DaylightName    : (S) @tzres.dll,-111
REG_BINARY    DaylightStart   : (S)
0x00000000  00 00 03 00 02 00 02 00 00 00 00 00 00 00 00 00   ................
REG_DWORD     StandardBias    : (S) 0
REG_SZ        StandardName    : (S) @tzres.dll,-112
REG_BINARY    StandardStart   : (S)
0x00000000  00 00 0b 00 01 00 02 00 00 00 00 00 00 00 00 00   ................
REG_SZ        TimeZoneKeyName : (S)
REG_DWORD     DynamicDaylightTimeDisabled : (S) 0

so the difference is this one shows two extra values that the previous one (w/o 
patch) didn't show: TimeZoneKeyName and DynamicDaylightTimeDisabled. of the 
two, TimeZoneKeyName is the one whose data isn't present (its a REG_SZ but 
shows up blank/no string). 

questions:

1) why did we assume the val.Data pointer is valid just because the val struct 
is valid
2) what effects does changing read to zread do for all the registry plugins

assigning gleeda as the owner because she volunteered to run some comparison 
tests before/after the patch to help figure out #2. 

Original issue reported on code.google.com by michael.hale@gmail.com on 8 Jun 2013 at 3:52

GoogleCodeExporter commented 8 years ago
So one note: the extra two values are probably after the value with the invalid 
".Data" member and would therefore be accessible if we just did proper error 
handling for possibly invalid members without doing a zread().  I'm working on 
running tests against samples now to see what possible problems could arise 
from this patch as it is, so it will take a bit longer...

Original comment by jamie.l...@gmail.com on 12 Jun 2013 at 5:30

GoogleCodeExporter commented 8 years ago
oh sorry, it's actually TimeZoneKeyName that seems to have the issue and 
anyways there is no data returned.... so maybe  this would be a good patch:

Index: volatility/win32/rawreg.py
===================================================================
--- volatility/win32/rawreg.py  (revision 3436)
+++ volatility/win32/rawreg.py  (working copy)
@@ -178,6 +178,8 @@
         valdata = val.obj_vm.read(val.Data, val.DataLength)

     valtype = VALUE_TYPES.get(val.Type.v(), "REG_UNKNOWN")
+    if valdata == None:
+        return (valtype, obj.NoneObject("Value data is unreadable"))
     if valtype in ["REG_DWORD", "REG_DWORD_BIG_ENDIAN", "REG_QWORD"]:
         if len(valdata) != struct.calcsize(value_formats[valtype]):
             return (valtype, obj.NoneObject("Value data did not match the expected data size for a {0}".format(valtype)))

Original comment by jamie.l...@gmail.com on 12 Jun 2013 at 5:48

GoogleCodeExporter commented 8 years ago
So that looks like it works just fine on the TimezoneInformation key. Let me 
know if you need me to run any further tests or anything. 

Here are the results so you can confirm its working as you expected.
root@bt:/volatility# python vol.py -f jonsmith.mem --profile=Win7SP0x86 
printkey -K "ControlSet001\Control\TimeZoneInformation"
Volatile Systems Volatility Framework 2.3_beta
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \REGISTRY\MACHINE\SYSTEM
Key name: TimeZoneInformation (S)
Last updated: 2013-04-04 01:57:34 UTC+0000

Subkeys:

Values:
REG_DWORD     Bias            : (S) 300
REG_DWORD     DaylightBias    : (S) 4294967236
REG_SZ        DaylightName    : (S) @tzres.dll,-111
REG_BINARY    DaylightStart   : (S) 
0x00000000  00 00 03 00 02 00 02 00 00 00 00 00 00 00 00 00   ................
REG_DWORD     StandardBias    : (S) 0
REG_SZ        StandardName    : (S) @tzres.dll,-112
REG_BINARY    StandardStart   : (S) 
0x00000000  00 00 0b 00 01 00 02 00 00 00 00 00 00 00 00 00   ................
REG_SZ        TimeZoneKeyName : (S) -
REG_DWORD     DynamicDaylightTimeDisabled : (S) 0

Original comment by wyattroe...@gmail.com on 12 Jun 2013 at 7:25

GoogleCodeExporter commented 8 years ago
Awesome!  Thanks for your help, Wyatt!  I'll commit changes soon :-)

Original comment by jamie.l...@gmail.com on 12 Jun 2013 at 7:26

GoogleCodeExporter commented 8 years ago
This issue was closed by revision r3438.

Original comment by jamie.l...@gmail.com on 12 Jun 2013 at 7:31