Tuesday, September 11, 2007

EnScript Tutorial - Part II

This is the second part of the EnScript tutorial I started in September 4th, 2007. In the first part, we reviewed what the differences are between EnScripts, Filters, Conditions and Queries. In this part, we will begin to learn the EnScript programming language.

First, I want to review the various panes in EnCase and their respective names so when I refer to a particular tab or pane, you understand where I am referring. The EnCase program is generally divided into four panes or sub-windows.



The upper left pane (A) is referred to as the “tree pane”. The upper right pane (B) is referred to as the table pane. The lower left pane (C) is referred to as the view pane and the lower right pane (D) is the EnScripts/Filter pane. The table pane generally shows you all the “objects” or files & folders in a particular piece of evidence. The view pane is used to see the contents of a specific file or folder in various formats (text, hex, doc viewer).

Writing your first EnScript:
What programming tutorial would be complete without the traditional “hello world” programming example? In the EnScript pane (lower right), make sure the EnScript tab is active and then right-click on the root of the EnScript tree that is displayed. Select “New” and then name the EnScript “Hello World”. A new EnScript should be created with the name you provided. The table pane (upper right) should have automatically made the “code” tab active and you should see the minimum EnScript code generated automatically by EnCase.

As I mentioned in the first part of this tutorial, this is the minimum amount of code that must be present in order to be a valid EnScript. This EnScript will run, but will do absolutely nothing. Every EnScript must have a Main Class as well as a function called “Main”. Take a look at the opening curly braces and then the corresponding closing curly brace. The Main function is contained inside the Main class. In this EnScript, line two and three makeup the entire Main Function, while lines one and four are the beginning and ending portions of the Main class. For now, lets focus on the Main function. Absent a constructor, which I will explain later, the first line of the Main function is where this EnScript begins execution. Line two “void Main (CaseClass c)” is where it will start.

When this EnScript begins, the EnCase program is going to hand your EnScript one variable, named “c”. This variable is of the CaseClass type. This means that when you program begins, you will have a reference to the case that is open and active in EnCase at the time the EnScript was executed. CaseClass refers is a type definition describing what type of variable “c” is. With this one variable, you can obtain additional references or pointers to all the other information you may need in your EnScript. This is your starting point. Generally, program execution stops with the corresponding closing curly brace of the Main function (line three).

Here are some basic formatting rules when writing EnScripts:

• White space is generally ignored (the exception is when inside double quotes). So putting extra spaces between lines of code means nothing and it can help to logically separate various pieces of your code .
• To make comments in your code (for future reference or explanation) you can comment one line of code using two forward slashes “//”. Everything after that will turn blue and be ignored at run time. To comment blocks of code, you can use the ANSI C commenting style of a “/*” and then end your commenting block with the opposite “*/”. Anything in-between those markers will turn blue and will be ignored. Those markers can be on the same line, or then can be 100 lines apart and everything in-between will be ignored.
• Get in the habit of indenting your code inside functions, control structures or conditional statements. It makes your code easier to read and helps when debugging for errors
• When writing code inside EnCase, Control-Z is the hot key for undo. So if you delete something or change a piece of code, but then want to undo your change, Control-Z
• Control-F can be used to find specific text in your EnScript. When working with small EnScripts, finding text is not too difficult, but with larger ones, it helps to find variables, functions or specific text.

In the view pane, there is a tab named “Console”. This tab is an output window for when you want your EnScript to write out information. You generally do not want to write important information, but instead use it as a kind of debugging window to write out the status of your EnScript or to debug. The method of writing to this console tab is “Console.WriteLine()”. So to write “hello world” to the console, you would use :

“Console.WriteLine(“hello world”);

Notice that the text you want to appear in the console tab is inside of double quotes and that the line ends with a semi-colon. You will generally end every line with a semicolon. The exception is control statements and other opening statements (such as the first line of a class declaration or function). Your code should look something like this:

class MainClass {
  void Main(CaseClass c) { // Execution starts here
    Console.WriteLine(“hello world”); // Writes out to the console tab
  } // Execution stops here
}

If you now click on the run button at the top of EnCase and then take a look at the console tab, you should see “hello world”. If you run it again, you will see “hello world” twice, once from the first time you ran it and once from the second time. To programmatically clear the console each time you run an EnScript, you could add “SystemClass::ClearConsole();”

class MainClass {
  void Main(CaseClass c) { // Execution starts here
    SystemClass::ClearConsole(); // Clear the console
    Console.WriteLine(“hello world”); // Writes out to the console tab
  } // Execution stops here
}

Recursion:
The definition of recursion in the programming world is a piece of code that calls itself. When the EnScript language initially came out, you had to use a recursion routine in order to process or list all the files/folders in the evidence. The current version of EnScript makes it much easier. In order to list or process (do something) all the files/folders in the evidence, you first need to create an object that contains a pointer to the top level of the evidence. Information that is listed in the table pane (upper right) windows are members of the EntryClass.

The previous script did not require a case to be open because it was simply writing to the console. The remainder of this tutorial will require you to have a case open and some evidence loaded.

Remember that EnCase hands you one variable when it starts an EnScript: “CaseClass c”. There is a built-in method that is part of the CaseClass that can give you the top-level entry in the evidence using the method “c.EntryRoot()”. You could use the code:

EntryClass entry = c.EntryRoot();

This would get the first (think of how a hierarchical directory works with a top level root directory) root entry in the evidence. You could then print the name of that object out using the Console.WriteLine() function:

class MainClass {
  void Main(CaseClass c) {
    SystemClass::ClearConsole();
    EntryClass entry = c.EntryRoot().FirstChild();
    Console.WriteLine (entry.Name());
  }
}

This code would clear the console, then assign the first object (the first physical or logical device in the evidence)in the evidence to the EntryClass variable named “entry”. Then the next line will print the name of that object out in the console pane.

This is a good beginning, but this only gets us the first object in the evidence. What if we want to print out every file/folder name int he evidence? Luckily there is a internal function that makes this *very* simple. If you are familiar with Perl, you should be familiar with "forall" function that goes through a list or array, one object at a time. In EnCase it works the same way by going through every object in the evidence given the top-level object.

class MainClass {
  void Main(CaseClass c) {
    SystemClass::ClearConsole();
    forall (EntryClass entry in c.EntryRoot()){
      Console.WriteLine (entry.Name());
    }
  }
}

This code clears the console (line 3), then receives the top-level object in the case and assigns it to the variable named "entry". It then executes all the code after the forall statement until the closing curly brace (line 5), then goes back to the forall statement and gets the next object in the case and runs the code in between the curly braces again, until all the objects have been processed.

If you look in the console tab, you should see a complete listing of all the file/folder names from all of the loaded evidence. This technique is a foundational technique that will be used to list/process all files in a case.

In the next tutorial, we will begin to identify and process file/folders based on certain criteria.

Tuesday, September 4, 2007

EnScript Tutorial - Part I

This will be the first tutorial in a series in an attempt to try and teach some basic EnScript concepts. First, some disclaimers: I am not a programmer by profession. I have learned the EnScript language out of necessity to automate processing of evidence and have since written many EnScripts, some of which are now part of the public release version of EnCase and some of which are given to students during EnCase training, but I certainly don't consider myself an expert in writing EnScripts.

The purpose of this tutorial is to try and provide some basic concepts and instruction to an EnCase user who also does not have any programming experience so they can write some basic EnScripts and/or modify existing ones for a specific need.

I have been teaching various EnCase training classes for almost the past 5 years and it amazes me at the answers I get from students when I ask about EnScripts, Filters and Conditions. Most know they are in the lower right pane of EnCase and many know some of the “canned” EnScripts that everyone seems to use (Initialize Case), but very few can describe filter, conditions or queries. So lets first discuss these four topics so you understand their differences and understand which may be the better solution to your automation need.

EnScripts

The EnScript tab gives you access to the built-in EnScript editor and allows you to see the code for the EnScript, as long as it isn’t compiled (EnPack format). An EnScript is the most powerful automation feature but it is also the most raw. “Raw” meaning that the EnCase software does very little for you automatically and your EnScript is responsible for doing everything you want to do, unlike a condition that we will discuss later. The EnScript programming language is very “Java-ish” and C++. If you have any experience with those two languages, then learning the EnScript language should be a snap.

An EnScript can do almost anything you want. It can access just about everything you the user can access or see inside EnCase. It can create folders and files on the local file system (not the evidence, the evidence file can never be altered via EnCase). In the Enterprise Edition, it can create directories and files on remote machines as well as delete them. It can also execute other win32 programs.

When you create an EnScript for the first time, EnCase provides the absolute minimum code for you:

class MainClass {
       void Main(CaseClass c) {
       }
}

This code will run, but does absolutely nothing. It is just the absolute minimum code that must be present to be a valid EnScript. When writing an EnScript, you are responsible for writing everything else. EnCase does nothing automatically for you.

Filters
A filter is an EnScript. It is the same language. The only difference is that a filter is designed for a specific purpose, to filter what you see. The original concept was to filter our files/folders based on some type of criteria; i.e. file extension, size, name, whatever. EnCase treats filters a little different than raw EnScripts. This is because EnCase is actually doing some work behind the scenes for you in an effort to “filter” what you see in the evidence. The code in a filter can do just about anything a raw EnScript can do, but it must answer one important question. Do you want to see files/folders (called entries) that match your criteria? If you do not answer that question in your code, your filter will not run.

EnCase actually does some background processing for you with a filter by automatically recursing all the evidence. Recursing means it looks at every entry in your evidence and then asks you, do you want to see this entry or do you want to hide it from view? Here is the minimum code required for a filter:

class MainClass {
       void Main(EntryClass entry) {
          return true;
       }
}

There are two major differences between this code and the code presented above. First, the parameter being passed to the main function is different (CaseClass c vs. EntryClass entry) and the second being the one added line that states, “return true”. This line is responsible for answering that question I mentioned above, “Do you want to see this entry or hide it from view”? So with a filter, EnCase gets every entry in all your evidence, one by one and then executes this code for every entry. It reads the above code that says “return true”, meaning show me this entry. EnCase then gets the next entry and does it again, until it goes through every entry in your evidence. If you have 20,000 entries in a piece of evidence, then this code will execute 20,000 times. If you changed the line to say, “return false”, EnCase would hide every single entry from your view until you removed the filter.

Conditions
A condition is exactly the same as a filter, except you don’t need to know how to write EnScript programming language. The condition tab allows you to use user-friendly criteria or selections to automagically write a filter. By selecting certain criteria, such as name, contains, “mytext”, EnCase will automagically generate the necessary EnScript code to perform that filter.

Queries
A query is nothing more that two or more filters put together. The filter and condition tab have a limitation that only allow you to apply one filter at a time. By using a query for example, if you have a filter that only shows you files that are larger than 10,000 bytes in size and another filter that only shows you files with the extension of JPG, you could create a query that would take those two filters and apply them simultaneously, the result would be only files with a JPG extension whose size is greater than 10.000 bytes would be displayed.

In the next part, I will begin to explain the EnScript programming language and how to perform simple actions.

Monday, September 3, 2007

Find files based solely on the name - EnScript

I recently read a post on a listserv asking if there was any easy way to find files in an EnCase evidence file based on just the filename and then export those files out. This can easily be accomplished by creating a condition and then when applied, only the files matching the filename(s) you specified will be displayed. The files can then be selected (blue checked) and then exported out.

But what if your filename list contains 5000+ filenames? Well, I tried to create a condition with that many filenames and EnCase choked. That's because it actually writes the filenames that you paste into the text box into the code the condition makes, thus causing several thousand lines of code to be created.

So I wrote an EnScript that will do this pretty quickly by reading a simple (non-Unicode) text file containing one filename per line, and then recurses through all the loaded evidence and bookmarks any files that match the filename(s) you provided in the text file. I added an "Export" check box that will automatically export the found files to the default export folder, if selected. It will also hash the found files and then when exported, rename the file to the original filename with the hash appended so you could sort in Windows Explorer and then see if two or more files with the same name are duplicates or different.

When run, the following dialog box will require you to point to a text file containing the filename(s) you wish to locate, and then a name of a bookmark folder you wish to create (the default is the name of the script with the date & time):



Once run, the EnScript will bookmark any files that match the filename(s) you provided (it is not case sensitive). If you select the export option then it will export every occurrence of the file that matches the filename list you provided and then hash the file and append the hash to the filename (the number on the end is just a counter for uniqueness):



The console will report how many filenames were read from the file you provided and the full path of the files that match.

This EnScript actually has some useful application in Intrusion type investigations. I am constantly struggling to keep an updated hash set of hacker tools. Every time a new tool version is released I have to make sure and add that into my hash sets. Many times though, I have found that the intruder does not even rename his/her tools, he/she instead just hides them somewhere where we will never think to look (the system32 folder ;).

So, you could create a simple text file that contains all the names of the bad hacker tools that you would want to know if they exist in your evidence and then run this script at the beginning of the exam to possibly identify any low-hanging fruit, and jump start your investigation. This way if you don't have an complete updated hash set, you could still identify files whose name is clearly identifiable as a hacking tool. I call these contraband type tools. In other words the mere name of the file is bad and it should peak your interest, i.e. pwdump.exe, fport.exe, cain.exe, psexec.exe, etc...

This EnScript is compiled (EnPack) so it will only work in V6.
Download Here

Computer Forensics, Malware Analysis & Digital Investigations

Random Articles