Thursday, May 5, 2011

EnCase EnScript to search for keyword in ROT13 or XOR

Most everyone in the forensic community knows there is loads of valuable information in the Registry. One of those locations is the UserAssist key. This forensic artifact has been explained and written about in just about every forensic blog online. This registry key stores data that is ROT13 encrypted and there are a number of free tools out there to decrypt these values from the registry. 

But it is also very common for other programs, including malware, to use ROT13 to 'hide' some of its settings and configuration. This is a very effective method of avoiding simple keyword searches, etc. XOR is another very common bitwise operation that is used by malware to hide itself of specific strings (i.e. domains named or URLs). In fact, many of the large antivirus companies use XOR to 'hide' the contents of a file that has been detected as a threat and placed into quarantine. 

This EnScript was written to assist in searching for known text that may appear in either a XOR string or ROT13 string somewhere on the disk. A simple use would be to search for something like "Program Files" in ROT13 in unallocated space and you are likely to find all sorts of orphaned UserAssist entries that were either temporarily written to UC or have since been deleted from the active registry. 

Another simple use would be to search for known text, such as "This program cannot" in XOR, which is text that appears in Windows executable files. This would find any executables that may have been XOR'd and do not appear like a normal executable and may have been hidden by malware or AV program or some other process.

When I first started experimenting with this technique, I began searching unallocated for many different common terms, including the logon names of the users. I was very surprised at the number of hits I would find in ROT13 AND XOR in various places across the drive, especially unallocated.

When you run this EnScript, you have a choice of which method you want to search for:


Choose either ROT13 or XOR and then enter a keyword and click OK. This EnScript searches ONLY the selected (blue checked) files in a case. This way you can isolate unallocated or any other specific objects you want to search.

Once finished, the EnScript will create either a "XOR hits" or "ROT13 Hits" folder, depending on the type of search you chose. Inside that folder will be the search hits, as well as the ROT13 text in plain text (comment field) or the XOR key (comment field) used to the find the hit, if you searching in XOR.

In the example, below I searched for the keyword of 'lance' and it found that keyword in numerous places in unallocated space. The comment field shows the plain text keyword, while the preview pane show the 'encrypted' value, as it is on the disk. By a quick glance, you can see these are full paths similar to those found in the UserAssist registry key, bit these were found in unallocated space.



In the next example, I searched for the keyword 'program' and the comment field shows the XOR key used to find that keyword, while the preview column shows the XOR'd data as it was found on disk. It is important to note that the XOR search will only be effective if the original data was XOR'd with a single 8-bit XOR key. If the data was hidden using a muli-byte XOR key, then this technique will not work since each byte of your keyword is XOR'd with every possibility between the decimal value of 1 and 254. In the example below, there are several hits for the word 'program' in unallocated space that are XOR'd.


Once XOR'd data is found by your keyword search, you can use this EnScript to sweep before and after your keyword hit to see the surrounding XOR'd text and possibly find additional artifacts.

This EnScript was inspired by a stand-alone program named 'xorsearch' by Didier Stevens.

Wednesday, May 4, 2011

General Forensics (using EnCase Enterprise) Flow chart

I had a need to put together a basic guide for using EnCase Enterprise for some new users. This guide was meant to provide some basic direction and ideas on how to use EnCase (Enterprise) and the basic flow of forensics. It is not meant to be inclusive or encompass all aspects. More of a primer of using EnCas enterprise and help to teach a mindset or routine.

The formatting will not look correct in this post, but I have posted a screenshot of the beginning of the document. You can download the PDF version below.


Download here

Thursday, April 28, 2011

What is the best computer forensic imaging tool and analysis tool available?

I get a lot of emails and general questions from students and blog readers about what tools I feel are the best to do imaging and analysis. It is no secret that I worked for Guidance Software in the past and have a personal preference for EnCase, but I also use many other tools during my various assignments depending on the type of case I am working and the client's needs.

Here is my simple opinion on the best tool for imaging and/or analysis tool.

The best tool is:
1. The one you have with you (AND)
2. Is mainstream/validated (AND)
3. You have experience using it

Tuesday, March 29, 2011

Basic Computer Forensic Analysis Techniques in EnCase

I was recently asked to provide a list of forensic analysis techniques. After looking through some of my documents, I realized I didn't really have an up-to-date worksheet that listed most of the common analysis techniques, even though we all have them memorized.


My goal is to create a flow chart to guide a new examiner to perform the commonly used techniques that we typically use in *every* case, and then also provide *case* specific techniques depending on the type of analysis or investigation. The following list is not meant to be all inclusive of every technique that we use, but instead it is designed to be a starting point and as a reminder of things to think about depending on the type of your case. Currently, I am focusing on the analysis of Windows based machines in EnCase. Please feel free to comment and add your own ideas in the comment section for others to benefit:



General Forensic techniques

  • Load Image into EnCase, verify Image
  • Check physical size of drive and compare to physical label
  • Identify & compare logical partition size(s) to physical drive size to identify any deleted partitions or unused disk space.
  • Recover folders
  •  Conduct hash analysis, indentify “known” and/or “notable” files. "Known" files can be excluded from remaining analysis techniques to reduce time and increase efficiency.
  •  Conduct file signature analysis, review renamed files.
  • Retrieve time zone settings for each disk and apply correct time zone, if applicable.

 Case specific techniques

  • Mount compound files
  • Conduct keyword search
  •  Recover client based email
  • Recover web based email
  • Recover Internet history (logical and unallocated)
  • Determine OS version, service pack, hotfixes & OS install date
  • Retrieve user account information (names, SIDs, logon dates)
  • Retrieve user specific registry artifacts (recent docs, userassist, etc.)
  • Retrieve attached USB history
  • Process LNK files to identify removable devices
  • Review installed applications
  • Review Office related files (doc, docx, xls, xlsx, ppt, mdf) & PDF files
  • Review multimedia & graphic image files
  • Identify encrypted files (entropy)
  • Data carve in unallocated (docs, multimedia, images, zips, base64)
  • Review Recycle Bin & recover deleted INFO2 records in unallocated
  • Review System Volume Information/old registry hives
  • Review Windows event logs
  • Mount image virtually and perform virus scan
  • Recover Windows logon password(s) (rainbow tables)
  • Recover username/passwords in protected storage areas


Windows Vista/7 specific

  • Review Volume Shadow Service

Thursday, March 24, 2011

Been procrastinating on upgrading EnCase?

So for those of you who have been putting off upgrading from EnCase v5 to V6, here is some incentive for you.

Take a look at this evidence file in V5, then use V6 or FTK Imager or other tool. Pay particular attention to Sector 280 and 676400.

For those of you using v6, don't think you live in a perfect world either, you may want to look at this too and see if it all looks "normal" to you.

I'm just saying...

Download Here

Sunday, March 13, 2011

EnScript to parse classic (.evt) event log entries in unallocated

This EnScript was inspired by a blog reader who emailed me to ask for a solution to parse some windows event log entries that were found in unallocated.


There are a couple ways I could think of to solve this issue. The easiest was to just build a parser to read a single event log record that was found in unallocated and display the data in the single record. The problem with that solution is it does not scale well and it will become very tedious when there are numerous records found in unallocated and requires a person to parse each one individually.


The final solution was an EnScript to perform a search for the magic value of "LfLe" which appears in every valid event log record. Once a hit is found, then the record is parsed and exported out into a separate .EVT file.  Every hit is exported out into the same .evt file and in the end, you will have a single "eventlog.evt" that contains all the valid windows event log entries that were found in unallocated. You can then use your favorite 3rd party event log viewer (Event log explorer, etc..) or the native Windows event viewer (eventvwr.exe) to read all the records that were found in unallocated. 


Each event log entry maintains a event record number. When searching in unallocated, it is possible that you could find two records with the same record number, therefore this EnScript renumbers all the records found in unallocated, but leaves the remaining data intact and as exactly as found in unallocated. Each record is assigned a new record number and then exported into the new .Evt file. A new header and footer is built based on the exported data so it can then be read with all the common event log viewing tools.


The exported records viewed in the EVENTVWR app in Windows 7:






The exported records viewed in the Event Log Explorer app in Windows 7:





Prerequisites:
None - This EnScript performs a search automatically. There is no need to search, select (blue check) or preprocess anything. The EnScript will search every unallocated object found, so if you have multiple drives loaded into the case, each one will be searched automatically. The EnScript automatically bookmarks all the "LfLe" search hits (valid and invalid). Some basic error checking is done to validate the record to attempt to ensure it is a complete and valid record before it is exported into the new .EVT file. The new "eventlog.evt" file is created in the default export folder for the active case.


Limitations:
This *only* searches and rebuilds classic Windows NT/2000/XP event (.evt) records. It does not yet support the newer .EVTX (xml) records that are used in Vista, 2008 & 7.


Download here

Answers to Forensic Puzzle #6

On February 24th, I posted a quick puzzle for people that were interested in working through a forensic puzzle. You can read the original post here.

Many comments and emails were sent asking about the puzzle, so I figured it was time to post the basic information that you were supposed to get. Going back to the scenario, a file was given to you for examination and you were asked to examine it and determine its purpose or any other information. You were also asked to provide the MD5 hash value of any final files you were able to examine.

Let start with the file:


Looking at the file and/or doing a file signature analysis using EnCase would reveal its a OLE compound file. The header is the same as a Microsoft Office document.  An OLE compound file has its own internal file system. The technical structure of this file can be found here. You can manually decode this file using the information provided on the MSDN library.

An easier solution is to use the built-in capabilities of EnCase. Since EnCase can parse OLE compound files, we can let EnCase do the tedious work for us.


Once we do this, the single file becomes two:


Now, looking at the contents of the single "suspicious file", you have two internal files named Details & File_0. Now, this next part is difficult to know without having looked at many files like this. This file is XOR encrypted. How do I know? I don't know. I's just something that after looking at many files like this, data patterns jump out and kind of reveal themselves. No, I am not Neo, but just like date fields and other structure become apparent after seeing them enough times, you can begin to recognize when data is XOR'd.

In this case, I theorized that the file named "file_0" was probably an EXEcutable. If you look at an Executable with a hex editor, you will see the MZ header followed by a bunch of zeros that make up the COFF header. So, looking at the image above, all the values with 6A, are actually 00. This makes un-xor'ing (technically xor'ing it again) the file easy since you can theorize that if this was originally an EXE, the value was 00, the resulting value is now 6A. Xor'ing the value of 00 with the XOR key of 6A, results in a value of 6A (imagine that). Therefore, we have just discovered our XOR key. 

If we XOR this file with the value of 6A, we end up with the following data:


We can clearly see this is a EXEcutable file and it has a standard COFF/PE header.  The MD5 of this file is 8dc601710e3e68b8d78b5cd73fb28616

A quick look at the contents of this file reveal a string resource that says:
"PopCap Games, Inc.,Zuma,1.0.0.1,Zuma,Copyright © 2003 - 2004 PopCap Games, Inc.,Zuma.exe,Zuma Deluxe,1.0.0.1,Presented by GameHouse".

If you save this file, there is a Icon associated with this EXE that is consistant with the game "ZUMA".  A strings of this file also reveals numerous text fragments that are consistant with a game.

If we look at the second file named "details":


We could try the same XOR key, which would work in this case. It would result in the file:


The MD5 hash value of this file is: f93a7bb8e02a8a23f87dad22b9ecd578

When I cannot determine the original type of file (like the first one above, I theorized it was an EXE by the patterns of data) or what XOR key that was used, then I use an EnScript I wrote to quickly XOR the data with all 256 possible values. It results in 256 files being written, each using a different XOR key, but then I can quickly look through those files and see any data I might recognize. 

Thanks to those who participated..... To date, *nobody* has posted any comments or answers to puzzle #1

Thursday, February 24, 2011

Forensic Puzzle #6

A System Administrator contacts you (because you're the forensic geek/god) and asks for your assistance in looking at something. He then hands you a flash device with a single zip files that he explains was "handed off" to him by another admin. The file is named "Suspicious_File" and was reported by the user as being unrecognized and not sure where it came from. Eventually the user contacted desktop support staff, who eventually forwarded it to an administrator, who has now contacted you. Unfortunately, the user changed the original name and zipped it to send to the helpdesk, so the original name or path is unknown.

Analyze the file and if possible, determine its origin, purpose, function and any other information that might be useful to the administrator. To avoid posting the correct results and spoiling it for anyone else who may be trying to work through this problem, post the final hash value of any file you analyze in the comments and I will provide feedback from there.

You get three hints. It's not any of these:
511516F439BC569D57C2853F49A192BA
DA983DD82AA924EB5BFE407F249AC9B6
63017bb2a213fa440191b204929ab0f7

Monday, February 21, 2011

EnCase EnScript to export MFT slack

During a recent EnScript training class, a student asked about how to programmatically export MFT slack, that is, the data that may exist between the end of a logical MFT record and the end of the physical MFT record. A typical MFT record can be anywhere between 400 to 700 bytes in length, but the MFT allocates 1024 bytes for each record. This can cause data to be left from previous records, the same way data remains in file slack at the end of a cluster.

I wrote this EnScript during the class to demonstrate some of the fundamental programming principles and decided I would post it in case someone has a need for it.

This EnScript will process every MFT found in the case. The EnScript only exports data in the MFT record slack area with an ASCII value between 0x20 (space)  and  0x7E (tilde). A folder is created in the case default export folder named "MFT Slack" and a file with a record number is created for every MFT record that contains slack. The reason this method was used, was so if you review the exported data and find something of interest, you can quickly map it back to the exact MFT record where it came from. If a MFT record has no data in slack, then no export file is created for that record.

Download here

Wednesday, February 9, 2011

*UPDATED* Custom FILETIME DateClass EnScript library to display millisecond granularity

This is an update to a post a few days ago, Brian has emailed me an updated library with some bug fixes, new options, updated documentation and some other modifications.

This is current as of February 10, 2011.

Download the new DateClass library here.

Sunday, February 6, 2011

Custom FILETIME DateClass to display millisecond granularity

A few months ago, I had the pleasure to go and teach two classes in Australia. During that visit, I met a very talented examiner named Brian Jones who had been learning the EnScript programming language for awhile, but had already excelled and created some great EnScripts and came up with some great ideas on using the power of EnScript.

Brian recently emailed me to comment on the recent post I made about the Windows FILETIME and the ability to see when a file's time stamp may have been manipulated. Brian shared a library that he wrote that displays an entries timestamp in millisecond granularity as well as displays the time stamps that's in the filename attribute, which are not shown by default by most forensic tools. Looking at the timestamps in the filename attribute and comparing them with what is recorded in the standard information attribute can provide lots of clues as to what has happened to that particular object (file or folder).

Brian has agreed to share his library with anyone else who is interested and I have to say he has done an excellent job. His documentation is superb! If you play around with EnScript, I highly suggest you load this library up and test it out. Even if you dont know how to program, there are simple examples in the documentation that you could try with very little effort.

The link to download the library is here.

Great Thanks to Brian Jones. If you have questions, comments or just want to say thanks, please email him at jone2bri (at) gmail (dot) com.

Here is his documentation and explanation of what the library does.



SEEBDateClass





SEEBDateClass encapsulates a date-time value. This class
represents time to a precision of seconds.

The time zone bias is set to the system's time zone bias. The GetString() method adjusts time with the bias before returning the string.


SEEBDateClass Enumeration OffsetOptions  [Top]

Name

Value

Description

NOBIAS

0

Controls the offset
values of the GetString() method(s)



NOBIAS – No Bias (UTC 0.00)

DSTADJ - Adjust time for DST.
LOCAL –
Time Zone set to examiner machine.

DSTADJ

1






LOCAL


2







SEEBDateClass Enumeration ShowOptions  [Top]

Name

Value

Description

LONGDATE

0

Controls the
output of the GetString() method(s)



LONGDATE -  02/09/2009 16:44:21

TEXTDATE -  Wednesday, 2
September 2009, 16:44:21.
SORTDATE –
02/09/09 16:44:21.

TEXTDATE

1






SHORTDATE


2





SEEBDateClass Enumeration EntryDateOptions  [Top]

Name

Value

Description

CREATED

80

Controls the
output of the EntryDate(entry, date_offset)
method. Returns the date of entry created etc. FNA = “File Name Attribute”
Time/date stamps – not shown in windows / EnCase.

CREATED –
entry created date.
WRITTEN –
entry last written.








WRITTEN

88






MFTMODIFIED


96






ACCESSED

114

MFTMODIFIED
– entries mft entry modified.
ACCESSED –
entry last accessed

FNACREATED,
FNAWRITTEN, FNAMFTMODIFIED, FNAACCESSED –
File Name
Attribute time/ date value – possible indicators of when file actually
created written on specific partition / system.






FNACREATED

184













FNAWRITTEN


192

FNAMFTMODIFIEDCREATED

200

FNAACCESSED

208







SEEBDateClass Enumeration AccuracyOptions  [Top]

Name

Value

Description

MINUTE

0

Controls the
accuracy of the Compare Functions(s)






SECOND

1






MILLISECOND


2





SEEBDateClass Methods  [Top]


Name

Return Type

Declaration

Description



SEEBDateClass


SEEBDateClass ()

Construct
default SEEBDate value. Year = 1601, month = 1, day
= 1, hour = 0,  minute = 0, second
= 0,
Millisecond = 0.



SEEBDateClass


SEEBDateClass (ulong value)

Construct SEEBDate value from 64 bit time / date stamp.



SEEBDateClass


SEEBDateClass (SEEBDateClass date)

Copy
Constructor.



SEEBDateClass


SEEBDateClass (uint day , uint month, uint yr, uint hr, uint min, uint sec, uint ms = 0)

Construct SEEBDate value from individual values. i.e. day, month,
year etc



SEEBDateClass


SEEBDateClass (DateClass date)

Construct SEEBDate value from EnCase Date
Class.



GetString


Const GetString(EntryClass entry
= null, uint offset_options
= SEEBDateClass::DSTADJbool display_bias
= true, uint show_options
= SEEBDateClass::LONGDATE, bool
hour24 = true , bool display_ms
= false)

Converts the
date to the string format.
Arguments:
Entry – EntryClass object or null.
Offset_optionsOffsetOptions
Enum value.
Display_bias – display the bias i.e.
UTC(+10.00).
Show_optionsShowOptions
Enum value.
Hour24 –
24 hour time or not (12 hr)
Display_ms – display milliseconds or not.

Time zone settings obtained  from the volume the entry is on
– otherwise UTC( 0.00)
Get String() = all default values.



GetString


const GetString (int bias_value, bool display_bias = true, uint show_options
= SEEBDateClass::LONGDATE, bool
hour24 = true, bool display_ms
= false)

Converts the
date to the string format using specified bias.
Arguments:
Bias_value – bias entered manually. i.e -10
Display_bias – display the bias.
Show_optionsShowOptions
Enum value.
Hour24 –
24 hour time or not (12 hr)
Display_ms – display milliseconds or not.





EnCaseString


String

static EnCaseString(EntryClass
entry, uint offset_options
= SEEBDateClass::DSTADJbool display_bias
= true, uint show_options
= SEEBDateClass::LONGDATE, bool
hour24 = true , bool display_ms
= false)

Converts the
date to the string format using the EnCase “Modify
time zone settings” to set the timezone for each
volume.
Arguments:
Entry – EntryClass object.
Offset_optionsOffsetOptions
Enum value.
Display_bias – display the bias.
Show_optionsShowOptions
Enum value.
Hour24 –
24 hour time or not (12 hr)
Display_ms – display milliseconds or not.




GetTimeZoneBias

int

static GetTimeZoneBias
()

Returns the
local time zone offset in seconds



Year

int

const Year ()

Year value in 4
digit format (1601..2038)




Month

uint

const Month ()

Month value
(1..12)



Day

uint

const Day()

Day value (
1...31 )



Hour

uint

const Hour ()

Hour value
(0..23)



Minute

uint

const Minute ()

Minute value (0..59)



Second

uint

const Second ()

Second value
(0..59)



Millisecond

uint

const Millisecond()

Millisecond
value (0…999)



Ticks

long

const Ticks()

Total number of
ticks



DayOfWeek

uint

const DayOfWeek()

Day of week
value ( 0=Sunday…6)



DayOfWeekString

String

const DayOfWeekString()

Day of week as
string.



MonthString

String

const MonthString()

Month value as
string (January…December)



TotalSeconds

ulong

const TotalSeconds()

Total seconds
from 1/1/1601



EqualTo

bool

 EqualTo (SEEBDateClass value)

Returns true if
== value.



LessThan

bool

LessThan (SEEBDateClass value)

Returns true
if  < value



GreaterThan

bool

GreaterThan(SEEBDateClass value)

Returns true if
> value.



IsLeapYear

bool

static IsLeapYear (uint year)

Returns true if
year is a leap year.



InRange

bool

static InRange (SEEBDateClass Value, SEEBDateClass
min, SEEBDateClass
max, , uint
accuracy_options = SEEBDateClass::SECOND)

Value must be
between min and max, inclusive with accuracy = SECOND or MILLISECOND only..



IsValid

bool

const IsValid ()

Returns true if
the value is valid date.


EntryDate

SEEBDateClass

EntryDate(EntryClass
entry, uint entrydate_options
= SEEBDateClass::CREATED)

Converts the entry
date to SEEBDateClass.
Arguments:
Entry – EntryClass object to obtain dates from mft directly.
Entrydate_optionsEntryDateOptions
Enum..


Null

void

Null()

Allows creation
of null date. 0/0/0 00:00:00.


GetBias

double

static GetBias(EntryClass
entry = null)

Returns entries
bias value.
If null
entry  - function returns default
time zone setting if only one timezone -  or 0..


DstOffset

int

static DstOffset(EntryClass
entry = null)

Returns the
entries DST offset..


ReadWinDate

bool

ReadWinDate (FileClass file)

Construct SEEBDate value from 64 bit time / date stamp.
Arguments:
file – FileClass object.



ReadUnixDate

bool

ReadUnixDate (FileClass file)

Construct SEEBDate value from 32 bit (C / Unix) time / date stamp.
Arguments:
file – FileClass object.



UnixDate

double

UnixDate(ulong value)

Construct SEEBDate value from 32 bit (C / Unix) time / date stamp.
Arguments:
value


DateToMilliseconds

ulong

static DateToMilliseconds(SEEBDateClass date)

Covert a SEEBDate into total milliseconds for comparisons.


Now

void

Now ()

Sets the value
to the current system date and time


Set


void

Set(uint day , uint month, uint yr, uint hr, uint min, uint sec, uint ms = 0)

Sets the date
directly.


Compare

int

Compare (const SEEBDateClass &Value, uint accuracy_options = SEEBDateClass::SECOND)

Returns < 0
if value is lexically less than, 0 if equal, > 0 if greater.
Arguments:
Value – SEEBDateClass object.
Accuracy_optionsaccuracy_options
enum value i.e. second, minute, millisecond..


TimeSpanString

String

static TimeSpanString (SEEBDateClass
date1, SEEBDateClass date2)

The time span
between two dates in days + hours + minutes + seconds.


TimeSpan

ulong

static TimeSpan (SEEBDateClass date1, SEEBDateClass date2)

The time span
between two dates in  seconds



/*

Example - Prints todays date and time

*/

class MainClass {

  void Main() {

    SEEBDateClass date();

    date.Now();

    Console.WriteLine("Today's date is " + date.DayOfWeekString() + " " +

                       date.MonthString() + " " + date.Day() + ", " + date.Year());

    Console.WriteLine("Current Time In Los Angeles:" + date.GetString(-8));

    Console.WriteLine("Current Time In New York:" + date.GetString(-5));

    Console.WriteLine("Current Time In Moscow:" + date.GetString(3));

    Console.WriteLine("Current System Time:" + date.Now());

  }

}

Computer Forensics, Malware Analysis & Digital Investigations

Random Articles