BackTrack – Internals
BackTrack is a great Linux distribution tailored specifically for penetration testing, security auditing, reverse engineering, and much more. This powerful distribution was build with portability in mind, and that’s why BackTrack is based on the Slax distribution, which has amazing portability features. Slax is minimalistic distribution that is completely modularized; every single part of the OS is build using modules which are layered on top of each other to form the end file system(think of a photoshop document, all the layers in the document form the final image). The aufs file system is the key component that enables this extensibility.
The aufs file system
The aufs file system is a completely rewritten Unionfs. It is a stackable unification filesystem, which unifies several directories into a single merged directory. What this mean is that directories are stacked upon themselves to create the final directory. Here is a simple example:
Directories 1: Direcory1 and 2: Directory1 are merged together to form the directory 3: Directory1 . As you can see using this method of stacking we can build a entire filesystem(the directories being different root’s). Each layer of this merged directory can be packaged into modules and then at runtime merged. That’s exactly how BackTrack is build. The / directory is build using the following modules located in the BT3/base directory: bin.lzm, etc.lzm, home.lzm, lib.lzm, pentest.lzm, sbin.lzm, etc… Each module contains a small portion of the entire / directory. At boot time all those modules are merged together to form the entire system. The neat thing about using this type of file system is that we can build a base system, and then without modifying it, we can customize it layering other modules on top of it. That exactly why BackTrack has a BT3/modules directory. All customizations to the base file system are made using the modules in that directory(for example the nvidiadriver.lzm module add NVidia driver support to the system).
Another key feature of aufs is that changes to the base file system(the final merged directory) can be recorded in a special directory. This special directory contains all the modification made to the base system. This is great because if the distribution was running off of a cdrom, you can record all the changes you have made and then save them to a module, which you can then load at the next startup.
So what is a module? A module is simply a special file system stored in a file. The file system used is called squashfs and is compressed using the lzm algorithm (hence the .lzm extension).
The squashfs file system
Squashfs is a compressed read-only file system, which compresses files, inodes and directories. This file system is used when space is a priority, like putting modules on to a CD that has limited capacity. Squashfs is very popular in the embedded market, where space scarce. Usually squashfs uses the gzip compression format, but lzm support was added by the author of the Slax distribution because it has a higher rate of compression.
Modularity using modules
Modularity of the system is achieved by being able to load and unload modules dynamically. Because the system is layered, we can add or remove functionality from the system without modifying the base. This is especially helpful when running the OS from a read-only medium like CD or DVD. Also we can shadow(hide) files or directories with our own. So for example you want to add a new app to BackTrack but don’t want to reburn the iso image, well you can easily create a temporary root directory, populate it with the files you want, and then turn it into a module and load it. Here is a example where we want to install 2 cool scripts, one that sets up the system while the other is a utility we wrote:
Now I’m going to explain these commands. First we created are root directory, this directory will emulate the location of the files on the real system(think of it like a chroot). Next go into the root and create the directory structure where we want our file to be in. Then we copy the 2 files to their appropriate location. Once we have finished we use dir2lzm to create a module named myScripts.lzm .
# mkdir tmpRoot
# mkdir –p etc/rc.d/
# mkdir –p usr/local/bin
# cp /tmp/myUtility usr/local/bin
#cp /tmp/rc.local etc/rc.d/
# cd ..
# dir2lzm tmpRoot myScripts.lzm
# activate myScripts.lzm
Optionally we also loaded the new module into the live system using the activate command.
The net effect o loading this module is that our live system will have 2 new files added. Now if we add this module to the BT3/modules directory, every time the system starts up, our script files will also be loaded, and because the loading of modules is before the system initialization, the rc.local script will be executed at boot time. On thing to note is, if there was a rc.local file before the module was loaded, when our modules gets loaded it will overshadow the previous rc.local file.
As I explained before changes made to live system are recorded in a special directory called changes. This directory is usually located at /mnt/live/memory/changes/. If you look into that directory you will the all the files that were modified since the filesystem was loaded. This directory is a replica of the root file system, but with only modified files/directories. So for example if we create the file /etc/inputrc and change the file /etc/HOSTNAME, the /mnt/live/memory/changes/ will have those 2 file with their entire directory structure replicated:
An easy way to store the changes we have made is to use the dir2lzm command. We can turn the /mnt/live/memory/changes/ directory into a module and then added into our BT3/modules directory. So when we boot next time all our changes will be there. One thing to note, if a module is loaded no changes will occur in the changes/ directory. So if you want to keep you changes from boot to boot using this method you will have to create new modules, because you cant append to moduels. One solution to that would be extracting all the modules you want to merge, together into one module, into a single directory using the lzm2dir command, and then creating a new module from the merged directory using dir2lzm command.
Saving changes using the method described above is tedious and manual, fortunately BackTrack has the ability save our changes using the changes=<changes_location> kernel parameter. Appending this to this to the kernel at boot time tell BackTrack to load and save the changes to that place. Here is a entry within syslinux.cfg(/boot/syslinux/syslinux.cfg) with the changes kernel parameter:
This kernel parameter can also be added at boot time in the boot loader by pressing TAB and appending changes=<changes_location>.
MENU LABEL BT3 Graphics mode with Persistent Changes
APPEND vga=0x317 initrd=/boot/initrd.gz ramdisk_size=6666 root=/dev/ram0 rw changes=/changes/slaxsave.dat autoexec=xconf;kdm