System Forensics - Part 3

(Ref Id: 1434380191)

One of the first tests you'll want to run with a body of code is to gauge how customizable it is. There are a couple of approaches you might want to consider.

Direct versus Indirect

Any person can simply modify source code (provided it is available and it should be). Going in and changing the source code directly and recompiling, if needed, we will refer to as direct system modification. It is quick and gets the job done which is why it is likely the most frequently used form of customization.

The second method of customization -- the indirect method -- requires the ability to overload whatever mechanism the system uses to find its own libraries. This way the provider's code is left intact, the customizations are all separate, and upgrades are easier to perform.

Modifying Include Paths

When a software program calls upon the resources in a library it normally relies upon some kind of global path variable to tell it where to look. Most modern languages allow for more than one location to be included. You can place your custom libraries before the provider's and the system will appear to prefer them over the originals. This is a useful technique because it allows for clearer separation between what your organization developed and what it did not.

In Java this string of locations is known as the classpath. In Perl the contents of the @INC array are checked. PHP uses an include directory but there is a bit of a caveat -- if you write your include/require statements in a certain way it will not be able to take advantage of the include_path and will instead default to the current directory.

Example

In Open-LIMS shortly after the original script, index.php, we wind up in main.php at line 68 where the core database class is required. The require call here is as follows:

require_once("core/db/db.php");

This is good since it is relative to the starting script's location. If we set the include_path to use our custom directory require statements in this manner it will work. Now let's dig deeper to find a call that will not help us. Let's look inside of the database class (db.php) line 52:

require_once("postgresql.php");

This style of call will not work for our customization efforts because there isn't enough information here to allow for the override. Here this require statement should be rewritten like this,

/* require_once("postgresql.php"); */
require_once("core/db/postgresql.php");

For our overriding of the include path to have the best effect we will need all paths in PHP require/include statements to be relative to the starting script's location -- index.php or ajax.php at the top level directory. When they are written without this PHP defaults to the calling script's directory which will always be the provider's version. Now when we do the following we can have the system call our custom postgresql.php rather than the original one:

cd /tmp
cp ~/Downloads/open-lims_0.4.0.0.tar .
tar -xvf open-lims_0.4.0.0.tar
mkdir custom-folder
cd custom-folder
mkdir core
cd core
mkdir db
cd db
cp /tmp/open-lims_0.4.0.0/core/db/postgresql.php .

Here we copied the open-lims_0.4.0.0.tar to the /tmp directory and expanded it. Then we created a custom folder and made a path for an alternate postgresql.php in /tmp/custom-folder/core/db/. Now what's left is to modify the include_path in our main script:

ini_set("include_path", "/tmp/custom-folder" . ":" .
get_include_path());

Good for Forensics

Many web-based applications have one or more main entry points because each request to the application must be verified as being part of a particular session. So a common pattern is to have each request start in the same place and effectively be handed over to another process for execution. A good way to evaluate a system comprehensively is to remove its head and call the other parts of the system directly to see how they behave.

For Open-LIMS index.php and ajax.php make up the main entry points. If we override these and start calling the other parts of the application we can extend, reduce, or otherwise avoid certain functionality altogether.

Good for Development

Some commercial vendors actually train their customers to modify the include path for the libraries in a similar fashion as in the above example. It makes it easier to differentiate between the customizations of one customer/deployment versus another. All one has to do is package up the custom folder and ship it to the vendor or system provider. It becomes the functional equivalent of saying, 'here are all the things that were broken and some other things that we needed that were missing in your application.' If there is no vendor or provider you can publish anything that is not sensitive online.

When the vendor or provider releases the next version one can compare the new version against the last set of customizations. The vendor/provider will have accepted some changes and incorporated them into their standard release. For those you will be able to simply discard your customized file version. Be aware that sometimes vendors do not accept your changes because they are written in a style that is very different from their own. Trying to make your code look and feel as much like the vendor/provider's -- particularly solving problems in a way that they would likely have done -- greatly increases your chances of getting a customization accepted. Also, reducing the size of your change by focusing on what is actually needed helps as well.

Series Wrap

We started looking at system forensics as a study of those unique convergences of technical and social forces that drive individuals and organizations to undertake the development of a LIMS. System development often takes a series of starts and stops mainly due to funding issues. Luckily releasing systems to the rest of the world via the World Wide Web with an appropriate Open Source license means that someone else can pick up the pieces and start the next phase. Doing this however means that the system may be in an incomplete state and somewhat poorly documented. That means that some process must be employed to identify whether the code base, as it stands, is worth the time/effort needed to help move it along. Here is where you would consider using forensics techniques.

You learned about migrating all of the source code files into single documents to make it easier to reference and to search for particular constructs. In order to reduce what you have to read you've learned to skip over relatively unimportant files like exceptions, interfaces, pure database read/write files, etc. to get at the core system logic.

Today you learned to take an active role in working with the system by modifying the include path for the system's libraries and making them behave in different ways. You can now confidently communicate back with the system's provider/vendor and recommend or sponsor changes for the next release.

Go Back

Citation: System Forensics - Part 3. (2015). Retrieved Sun Oct 22 02:26:12 2017, from http://www.limsexpert.com/cgi-bin/bixchange/bixchange.cgi?pom=limsexpert3;iid=readMore;go=1434380191