Sunday, August 13, 2023

Creating Disks Without Disks

 If you are playing around with disk forensics and want to look at tools like SleuthKit and Autopsy, along with other commercial tools, you need disk images to play with. While it's easy enough to get external disks to tinker with, you can also create virtual disks in Linux that will give you an image without having to generate one from a real disk. The first thing you need to do is to generate a file. We can use the disk dump command in Linux, dd, to do that. We're going to use a pseudodevice that generates random numbers, /dev/urandom, though you could also easily use /dev/zero. 

kilroy@badmilo ~ $ dd if=/dev/urandom of=mydisk.img bs=1M count=128

128+0 records in

128+0 records out

134217728 bytes (134 MB, 128 MiB) copied, 0.269739 s, 498 MB/s

kilroy@badmilo ~ $ 

Once we have a file, we can partition it just as you would an actual device. While you can use any disk partitioning program you want, you can see the use of fdisk here. 

kilroy@badmilo ~ $ fdisk mydisk.img 

Welcome to fdisk (util-linux 2.39.1).                                        

Changes will remain in memory only, until you decide to write them.          

Be careful before using the write command.

Device does not contain a recognized partition table.

Created a new DOS (MBR) disklabel with disk identifier 0x1ecaf971.

Command (m for help): n

Partition type

   p   primary (0 primary, 0 extended, 4 free)

   e   extended (container for logical partitions)

Select (default p): p

Partition number (1-4, default 1): 

First sector (2048-262143, default 2048): 

Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-262143, default 262143): 

Created a new partition 1 of type 'Linux' and of size 127 MiB.

Command (m for help): w

The partition table has been altered.

Syncing disks.

You'll want to pay attention to the location of the first sector. The program fdisk defaults the first partition to start at the 2048th block. We're going to use that information shortly, since we need to format the partition. When you format a disk, if you don't provide an offset, it will write over the first blocks on the disk, virtual or otherwise. Writing over the first blocks blows away the partition table, which means you don't have any partitions after you have formatted the disk. We just want to format a partition and not an entire disk. Here, we are going to format the disk as an EXT4 partition and provide the starting block for the partition. 

kilroy@badmilo ~ $ mkfs.ext4 mydisk.img -E offset=$((2048 * 512))
mke2fs 1.47.0 (5-Feb-2023)

Warning: offset specified without an explicit file system size.
Creating a file system with 130048 blocks but this might
not be what you want.

Discarding device blocks: done                            
Creating filesystem with 130048 1k blocks and 32512 inodes
Filesystem UUID: eb9e3f13-66c8-4fe8-9922-69b32ded088c
Superblock backups stored on blocks: 
        8193, 24577, 40961, 57345, 73729

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done 

While you could provide the actual byte offset, in this case we are calculating the byte offset. There are 512 bytes in a block and the block offset was 2048 so we multiply one by the other to figure out the actual byte location on the disk. Because everything we are doing so far has been on files I own, there has been no need to elevate privileges. What we do next, however, will require privilege elevation. We're going to mount the disk. 

In this case, I've created a mountpoint, which is an empty directory, in my home directory to mount to. We're going to loopback mount, which is a way of mounting a file as though it were a block device, like an actual hard disk. A file is a character device, but we can't mount character devices and use them as though they were disks. So, we use a loopback mount and the file acts as though it's an actual disk. 

kilroy@badmilo ~ $ sudo mount -o loop -o offset=$((2048*512)) mydisk.img mnt

Now we have our file mounted as though it were a disk, we can use it as though it were a disk. You can copy files to and from, though since it's a new disk there is nothing on it to copy from at this point. 

Once you have this mounted device, you can use any forensics tools on it you like. Or just use it as a way to store files in a single place that can be copied around or compressed. As it's just a file, maybe no one will think to check it for actual content. The giveaway will be if someone uses the file utility on it, since it looks like a boot record to file, as you can see here. 

kilroy@badmilo ~ $ file mydisk.img
mydisk.img: DOS/MBR boot sector; partition 1 : ID=0x83, start-CHS (0x0,32,33), end-CHS (0x10,81,1), startsector 2048, 260096 sectors, extended partition table (last)


Friday, September 28, 2018

VNC Over AWS

If you followed the instructions from the last post, you have a Kali instance running in AWS. The problem is that you are limited to SSH access, which is the management protocol allowed by default through the AWS security groups. You really want to be able to get GUI access so you can run the pretty tools. Well, there are a couple of ways to do that. One way is a bit more complicated, though it doesn’t involve adding rules to your security group. It requires that you install an X server on your local desktop and then turn on X11 forwarding through your SSH session. If you are using PuTTY, this is fairly simple. Getting an X-server isn’t very complex. Xming works pretty well, though there are others. Ideally, if you enable X forwarding, your display host will be set to your X server on your local system so any program that requires a screen, keyboard and mouse will be thrown back to your X server and displayed on your local system. While I’ve used this approach for … well, decades … I find it’s not foolproof. Sometimes the variable doesn’t get set and often pushing X-based programs back through an SSH session can be just plain clunky. So, we’ll try another approach. 

This will be fairly easy and straightforward, as well, though it does require altering the security group in AWS to allow a port through to your Kali instance. The first thing you want to do, though, is to open an SSH session to your Kali instance. Once you are there, run sudo vi /etc/init.d/vncserver to create a script that will be used to start the VNC server at boot that we are going to be using. Once you have vi running (you need to use sudo because you are editing in a directory where you need to have administrative privileges), paste in the following code:

#!/bin/sh
### BEGIN INIT INFO
# Provides: vncserver
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start VNC Server at boot time
# Description: Start VNC Server at boot time.
### END INIT INFO

USER=root
HOME=/root

export USER HOME

case "$1" in
start)
echo "Starting VNC Server"
#Insert your favoured settings for a VNC session
/usr/bin/vncserver :0 -geometry 1280x800 -depth 16 -pixelformat rgb565
;;

stop)
echo "Stopping VNC Server"
/usr/bin/vncserver -kill :0
;;

*)
echo "Usage: /etc/init.d/vncserver {start|stop}"
exit 1
;;
esac

exit 0

Kali Linux uses the newer systemd startup process, though you can still use init scripts with Kali. Once you have the script created (use ‘I’ to insert, then paste the code using Ctrl-V as you normally would, then hit ESC followed by ‘:wq’ to get the text entered and saved — skip the ‘ characters when typing), we need to make sure that Kali uses it when the system boots. In order to do that, run the following:

ec2-user@kali:~$ sudo chmod 755 /etc/init.d/vncserver
ec2-user@kali:~$ sudo update-rc.d vncserver defaults
ec2-user@kali:~$ sudo /etc/init.d/vncserver start

Your Kali instance will add the service as a startup script in the default run levels, which is all we need to do. When you start the VNC server for the first time, you will be asked to set a password. This is a password you will be asked to enter when you connect to the VNC server, so it’s a minimal amount of security to keep unauthorized users out. The last thing to do is allow the VNC traffic through the security group, which is essentially a firewall where you create rules for traffic control. We need to allow TCP port 5900 in. Below, you can see what those rules look like. From the left hand side of the AWS portal, go to Security Groups. You should see one where the Group Name says something that includes Kali Linux. Right-click on that and select Edit Inbound Rules. Once you are there, you can add the rule just the way it’s shown below.

SecurityGroup

If you happen to know the public IP that you are using through your ISP, you can enter that into the Source field but don’t go too crazy or you’ll just end up locking yourself out. If your IP address changes, you will need to change it here to allow yourself VNC access. Once you have saved it, it becomes active. There is nothing further to do.

All you need to do now is to start a VNC client to connect to your server. There are a number of clients, including Screen Sharing on a macOS system. On Windows, you can use the RealVNC client as a reasonably good application to connect to VNC servers. You will be asked for the password you created when you started the VNC server when you are configuring the settings. You will also need the public IP address. When you go to the AWS portal and select your running Kali instance, at the bottom, you will see two lines. One is for the Public DNS (IPv4) and the other is IPv4 Public IP. You can use either of those. Both will likely change when you shut down and start up your Kali instance. Use either the hostname (DNS name) or the IP address and the password you created then connect to your VNC server. You will be presented with a desktop running XFCE, so it doesn’t look like the same desktop as if you were running it locally in a VM. However, it is still a fully functional instance of Kali with the desktop and access to all the applications. 

 

Thursday, September 27, 2018

Kali on AWS

Kali Linux is an incredibly useful distribution for security testing and also open source intelligence gathering. While you can certainly install Kali on a hardware-based system or even in a virtual machine, you can also take advantage of the work other companies have already done. This includes Amazon Web Services (AWS). You don’t have to build an image or install a hypervisor. You just connect to AWS and launch an EC2 instance from the AWS marketplace. We’re going to work through that here, showing you how simple the process is.

This assumes you have an AWS account, which is very easy to setup if you already have an Amazon account and who doesn’t have one of those? I assume everyone else is spending entirely too much money buying stuff that just shows up at your door, just because it takes no thought and almost no effort. I’m not going to walk through the process of creating an account. It should be straightforward enough.

Once you have logged into the AWS portal, you should go to the Instances page from the link on the left hand side. From there, you will see a big blue button that says Launch Instance. This will take you to Step 1 where you will select an AMI image. If you search for Kali, you will find there are several community images as well as one marketplace image. Use the marketplace image, as you can see below.


Once you have selected Kali Linux as your AMI, you will need to select the size of your system. You can definitely select as large a machine as you want, but if you want to go cheap and don’t plan on doing a lot of high-intensity computing, you can use the free tier system, as shown below. This is a t2.micro type with a single CPU and only 1G of memory. You aren’t going to be doing a lot with a system this small but for just playing around with Kali, it should be ample.


This will create a new instance of the Kali Linux image, after which you will need to create authentication credentials. This is done, under Linux, with SSH keys. If you happen to have keys already stored in AWS, you can use them. Otherwise, you can create a new set, just as you can see being done below. Once you have provided a name, you will need to download the key file. This will be Privacy Enhanced Mail (pem) file, containing a certificate that has the encryption keys necessary to establish an encrypted SSH session, as well as authenticate you.


We’re almost done at this point. Your instance will start up after you have downloaded your .pem file and then clicked Launch Instances. You can’t Launch until you have downloaded the key pair, so the Launch button will remain disabled until then. As soon as you launch your instance, it will get provisioned. It takes a couple of minutes or so to start up the instance. Once that happens, it will show up as Running in your instance list. If you right-click, you can select Connect and you will get a window like the one shown below.


In my case, I’m working from a macOS system so I have an ssh client available through the command line (I use iTerm for command line access). Below, you can see changing the permissions on the key file, since ssh won’t make use of the key file unless access to it has been restricted. After that, I just ssh into the remote system. Because I’ve let Amazon do all the work for me, I don’t have to make any modifications to security policies in AWS. It took care of allowing SSH to the public-facing IP address that it allocated for me.


kilroy@binkley  ~/Downloads  chmod 400 Kali.pem

kilroy@binkley  ~/Downloads  ssh -i "Kali.pem” ec2-user@ec2-34-213-11-105.us-west-2.compute.amazonaws.com

The authenticity of host 'ec2-34-213-11-105.us-west-2.compute.amazonaws.com (34.213.11.105)' can't be established.

ECDSA key fingerprint is SHA256:Rv7rErLsH6pch8jxJc6HL+VmzTxZ3TQw7iwm1mJaLok.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'ec2-34-213-11-105.us-west-2.compute.amazonaws.com,34.213.11.105' (ECDSA) to the list of known hosts.

Linux kali 4.17.0-kali1-amd64 #1 SMP Debian 4.17.8-1kali1 (2018-07-24) x86_64

The programs included with the Kali GNU/Linux system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

ec2-user@kali:~$


And that’s all that it takes to get a Kali instance running in AWS! Enjoy!


Kali on AWS

Kali Linux is an incredibly useful distribution for security testing and also open source intelligence gathering. While you can certainly install Kali on a hardware-based system or even in a virtual machine, you can also take advantage of the work other companies have already done. This includes Amazon Web Services (AWS). You don’t have to build an image or install a hypervisor. You just connect to AWS and launch an EC2 instance from the AWS marketplace. We’re going to work through that here, showing you how simple the process is.

This assumes you have an AWS account, which is very easy to setup if you already have an Amazon account and who doesn’t have one of those? I assume everyone else is spending entirely too much money buying stuff that just shows up at your door, just because it takes no thought and almost no effort. I’m not going to walk through the process of creating an account. It should be straightforward enough.

Once you have logged into the AWS portal, you should go to the Instances page from the link on the left hand side. From there, you will see a big blue button that says Launch Instance. This will take you to Step 1 where you will select an AMI image. If you search for Kali, you will find there are several community images as well as one marketplace image. Use the marketplace image, as you can see below.


Once you have selected Kali Linux as your AMI, you will need to select the size of your system. You can definitely select as large a machine as you want, but if you want to go cheap and don’t plan on doing a lot of high-intensity computing, you can use the free tier system, as shown below. This is a t2.micro type with a single CPU and only 1G of memory. You aren’t going to be doing a lot with a system this small but for just playing around with Kali, it should be ample.


This will create a new instance of the Kali Linux image, after which you will need to create authentication credentials. This is done, under Linux, with SSH keys. If you happen to have keys already stored in AWS, you can use them. Otherwise, you can create a new set, just as you can see being done below. Once you have provided a name, you will need to download the key file. This will be Privacy Enhanced Mail (pem) file, containing a certificate that has the encryption keys necessary to establish an encrypted SSH session, as well as authenticate you.


We’re almost done at this point. Your instance will start up after you have downloaded your .pem file and then clicked Launch Instances. You can’t Launch until you have downloaded the key pair, so the Launch button will remain disabled until then. As soon as you launch your instance, it will get provisioned. It takes a couple of minutes or so to start up the instance. Once that happens, it will show up as Running in your instance list. If you right-click, you can select Connect and you will get a window like the one shown below.


In my case, I’m working from a macOS system so I have an ssh client available through the command line (I use iTerm for command line access). Below, you can see changing the permissions on the key file, since ssh won’t make use of the key file unless access to it has been restricted. After that, I just ssh into the remote system. Because I’ve let Amazon do all the work for me, I don’t have to make any modifications to security policies in AWS. It took care of allowing SSH to the public-facing IP address that it allocated for me.


kilroy@binkley  ~/Downloads  chmod 400 Kali.pem

kilroy@binkley  ~/Downloads  ssh -i "Kali.pem” ec2-user@ec2-34-213-11-105.us-west-2.compute.amazonaws.com

The authenticity of host 'ec2-34-213-11-105.us-west-2.compute.amazonaws.com (34.213.11.105)' can't be established.

ECDSA key fingerprint is SHA256:Rv7rErLsH6pch8jxJc6HL+VmzTxZ3TQw7iwm1mJaLok.

Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'ec2-34-213-11-105.us-west-2.compute.amazonaws.com,34.213.11.105' (ECDSA) to the list of known hosts.

Linux kali 4.17.0-kali1-amd64 #1 SMP Debian 4.17.8-1kali1 (2018-07-24) x86_64

The programs included with the Kali GNU/Linux system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

ec2-user@kali:~$


And that’s all that it takes to get a Kali instance running in AWS! Enjoy!


Tuesday, October 17, 2017

Password Policies

While this has been in process for a while and the guidance has been out for a while, the guidance NIST published in June related to identity management seemed long overdue. For me, this came to a head a few years ago with a client I was working with. They had the then-recommended (best practice to the rescue again) password policies in place. Strong passwords — letters, numbers, different cases, symbols, appropriate length. Passwords rotated every 30 days. No repeat password before 12 passwords had been reused. At least 7 days between password changes. Strong password policy, right? What I told them at the time was they were begging their users to write their passwords down just to keep track of their current one. That, of course, entirely defeated the purpose of the password policy to begin with.

What was even worse was that the administrators and management of the company I was working with had no idea what the purpose of the password policy was to begin with. What exactly is the purpose of rotating passwords and making sure they are incredibly complex? For a start, you make the complex so they can’t be guessed. Unfortunately, with so much horsepower readily available and with rainbow tables so easy to get hold of, even complex passwords that are 8 characters (a common minimum) may be easily cracked by a determined attacker. That’s why you have complex passwords — to make sure they can’t be guessed or determined in a brute force attack. Since it’s possible to crack them anyway, that idea is a bit behind the time.

The reason for rotating them is based on an assumption that someone is getting in using the password. If you rotate the password on a regular basis, you limit the amount of time that an attacker can stay in your system. The assumption also was that with a regular rotation scheme and lower horsepower systems, it could take as long as the rotation time to crack the password. Ultimately, it was about limiting potential access using the password. The reality is that attacks and access are far more likely to take place using social engineering attacks or other ways of gaining access without needing the password.

One of the reasons for writing this up was reading Bruce Schneier’s Crypto-Gram e-mail from this month. He quite rightly points out that the idea of password policy stemmed from attempts to try to fix the users rather than trying to actually resolve the problems that existed. As a result, we as information security professionals have spent a lot of time trying to enforce and detect lapses in security policy compliance.

This is yet another example, to me, of the solution coming before the problem. Without really understanding where the threats were (what the problem was), there was a drive to implement password policies. Worse than that, when businesses implemented strong password policies, they felt they were protected against attack. The reality is that they were left exposed because they had no idea what problem they were trying to solve and they spent time implementing and enforcing password policies rather than truly understanding where their threats and exposures were.

This is a soapbox I get on a lot. It is absolutely essential that time is spent defining and understand the problem to be solved in order to make sure that when a solution is arrived at, it is the right solution and not a red herring that makes people feel like they’ve done something.

Tuesday, October 3, 2017

Chasing Data Using Sleuth Kit

Working on a new set of videos for O'Reilly Media -- basically updating one of the first video titles from back when it was Infinite Skills. In the process, I had to refresh my memory on a number of things. One of them was using The Sleuth Kit tools to run through a disk image to locate the contents of a file. Sure, you could just pop it open in a browser using some commercial tool but where's the fun in that? Autopsy you say? Yeah, but ultimately, Autopsy uses The Sleuth Kit tools to begin with even if you don't see it. Why not just learn what it is that Autopsy does so you can be ahead of the game? Having said that, let's step through how you might go about this.

We're going to be working with a disk image taken from a Linux system and the partition on the disk was formatted with ext4. However, the same steps will work for a Windows disk, particularly if the partition was formatted with NTFS. Since we have a disk image and not a partition image, the first thing we need to do is determine where the partition actually starts. In order to do that, we are going to use the program mmls, which lists all of the partitions in a disk or disk image. We could also use fdisk -l to do essentially the same thing.


What we discover here is that the partition we are looking for starts at byte 2048. The other Sleuth Kit tools we will be using will need to be told what offset to start at because they are really looking for the start of the partition in order to parse the data structures that begin there. Once we know where the partition starts, we can get a list of the files that are in the partition. For this, I'm just going to get a list of active files and not worry about doing a recursive listing down through all the directories (adding a -r). We also aren't going to deleted files (adding a -d). For our purposes, it doesn't much matter whether we have those or not. We are going to use fls and we need to add a -o 2048 to indicate that the offset to where the partition starts is 2048 bytes.


We now have a listing of the small number of files that are in the root directory of this partition. What we get from this listing is whether the entry is a directory (d/d) or a regular file (r/r). The second column is the inode where the metadata for the file is located. The metadata for the file not only includes date information but also, more importantly, the data blocks that belong to the file. Those data blocks are where can get access to the contents of the file. In order to get the data blocks, we are going to use the program istat. This will give us all of the information that the inode has related to the file. Keep in mind that while you think about the file in the context of the filename, on a UFS-based system (ext inherits a lot from UFS, the UNIX File System that goes back to the 70s and 80s with BSD, the Berkeley Systems Distribution), a file is just a collection of related data blocks. We could have multiple filenames that all point to the same "file" on the disk.

Running istat, we provide the offset to the start of the partition, just as we did with fls. Additionally, we provide the image that we are searching and also the inode that we want to interrogate. You can see the results of this below.


Among other things, we can see that the inode has been allocated. It's not free space because it refers to a file. You can see the date and time information. You can also see the permissions that are associated with the file. Additionally, as I mentioned above, different filenames can point to the same set of data blocks (the same inode). The "num of links" entry indicates the number of filenames that point to this inode, and by extension, the data that the inode points to. This is where the "Direct Blocks" entry is important. The direct blocks tells us where to get the contents of the file. For this, we use the blkcat command.


Again, we have to provide the offset because blkcat expects to start with the beginning of the partition, as fls and istat do. We provide the image name then the block number where the data is located. This is followed in this case by the number of blocks we want to extract. By default, we only pull one but since all of the blocks for the file are consecutive, we can pull all of them at once. Beneath that, you can see the contents of the file.

While it's several steps, using mmls to get the partition start, fls to get a listing of files, istat to get the data block address and finally blkcat to extract the file contents, it does help to highlight how the filesystem is put together. Being able to follow this chain, no matter the file or the filesystem, will help with the understanding of the workings of a filesystem such that no matter what tool you are using, you know the process.

Thursday, January 26, 2017

Password Management

Recently, there was a piece on password managers on The Today Show on NBC. The tech guy was blazing through a number of apps for phones since he has such a short period of time to cover what is apparently a lot of ground. Normally, I would have ignored such a presentation. It is generally just so much fluff, after all, relegated to the third or even fourth half hour of a morning newstainment program. Anything even remotely non-fluffy happens in at least the first hour and if it’s actually grounded in reality and based on actual, topical events, it’s in the first half hour. Here we have a short piece that’s essentially lifestyle in nature. No big deal, right? However, there was a big red flag for me that was just inaccurate that needed to be addressed.

The presenter, who shall remain nameless so I don’t besmirch his knowledge or character here, told Matt Lauer that password managers are great so you have all of your passwords (because we all use a different password for every login and Web page we use, right?) in one place. This means you don’t forget them. All you need to do is be able to get into the password manager. Here’s the rub, though. Because you have very helpfully collected them all in one place, you have made it considerably easier for an attacker. All the attacker needs to do is get into your password manager.

Not so fast, you say, as said the aforementioned presenter. You have been informed that the very strongest of encryption is in use within this password manager, making it impregnable. This is the delusion and misunderstanding when it comes to encryption. Encryption is only helpful if someone comes across a file or a disk by itself that has been encrypted. If you run across a stray disk that has been encrypted using something like the Advanced Encryption Standard (AES) with a very large key, say 256 bits, you are going to have a very hard time getting into the drive, unless the key has been somehow attached to the drive. And this is where we have a problem with devices and files that have been encrypted.

In essence, the key is stored with the encrypted data. All someone needs to do is gain access to the password manager using your credentials and the data is unlocked. Just as it would be for you, because the app has no idea it’s not you. Password managers that use a single password, regardless of how strong it is, are vulnerable to attack because all someone needs to do is get that one password and they have your entire cache of passwords. That’s it. It doesn’t matter whether then underlying file is encrypted. Or even if each individual password is encrypted. The passwords will need to be presented to you in the clear if they are to be of any value so if you can authenticate to the password manager, so can the attacker.

Aha, you say! You use your fingerprint. Biometrics to the rescue. The problem with that particular theory is that while your fingerprint may be yours and yours alone, your fingerprint can be acquired. And used against you. Fake fingerprints can be used to fool fingerprint scanners on mobile devices and frankly most any device looking for your fingerprint. You use your fingerprint to get into your password manager but you leave your fingerprints all over the place. It’s not that challenging to acquire your fingerprint and if an attacker can get your phone — either because you left it on your desk while you stepped out of your office for a moment or because they simply stole it from your pocket or purse — they can get access to your passwords from your password manager.

This is not to say that you shouldn’t use a password manager. A determined attacker is probably going to find a way to get your passwords. If it’s not you, it will be someone else and they may get your password by gaining access to a system by way of that someone else. However, if someone gains clear text access to your passwords, it won’t matter a bit how strong they are. You can use a 32-character passphrase with upper and lower case, numbers and symbols. If it’s stored in your password manager and an attacker gets access to your password manager, strength of password doesn’t matter.

If your password manager stores your passwords on an Internet-based storage medium (sometimes called “in the cloud,” though the term is misleading to say the least), there is now a second way an attacker can get access to your data. This is especially true if there is a Web portal for you to look at your passwords or pull them down to use in Web forms through your browser. Now your fingerprint is no longer in play. It’s just down to that username and password combination.

Ideally, sites you visit regularly that store data you actually care about (aside from the throwaway e-mail address you use to log into sites you don’t much care about, for instance) would support two-factor authentication. This means a username and password (something you know) as well as either a soft token (Google Authenticator, Facebook Code Generator) or a text message to your cell phone (something you have). These two factors together can help protect your login access by requiring the attacker to both know your password and either have your phone or be able to intercept data like a text message.

Being aware of the potential challenges of various applications can help you make informed decisions. If you don’t understand what you are signing up for, you are not engaged in informed consent and you certainly are not engaged in managing the risk.

Friday, August 19, 2016

On Fear

“Mine is the last voice that you will ever hear. Do not be afraid.” Perhaps apropos that this came up in a song tonight. It got me thinking again about something that has been troubling me for quite a while. The context for the quote is that it came out of some civil defense preparedness training films in England in the late 70s and early 80s. If you are a fan of 80s music, and especially the 12” or remix, you may be familiar with the quote as being a sample used in remixes of Frankie Goes to Hollywood’s Two Tribes. Sometimes, it’s just the first sentence and sometime’s it’s the whole thing. The idea of using it here was to drive the point home about what the song was about. Two Tribes is essentially a political song talking about the Cold War that was probably at its height when the song was recorded with a trigger-happy Reagan in the White House and an inscrutable and rapidly rotating collection of Soviet premiers in the Kremlin. The uncertainty and the us vs. them mentality was either at its worst or it just seemed it with the rhetoric being broadcast around the world as cable TV made everything more immediate.

The Cold War was just another way to bring people in line with a particular way of thinking. If you drive people to fear the enemy with a lot of language about how they are coming over to take everything away from you and kill everyone, you can get those people to get behind a lot of policies that may not be in their best interests. As it turned out in the end, the Soviets really had no ability to do anything at all to come after us. Their technology and their infrastructure was completely inadequate and they had their hands full with their neighbors. The Russian bear, as it turns out, had no bite. Same thing with Iraq and Saddam Hussein. The more things change, the more they stay the same.

We continue to be afraid of everything, simply because no one is asking the right questions. Why are you voting for the candidate you are voting for this fall? Because the other candidate would be worse. The entire campaign for both candidates will likely be entirely based around how bad the other one will be. They are using our instinct for fear of the unknown against us. How does that help us get ahead in the end? How do we ever focus on the right answers when all we are encouraged to do is be afraid of everyone else? Of course, the news media doesn’t help at all here. You get people afraid and they are more inclined to watch your product so they can know all the ways they need to be afraid. Fear almost seems to be addictive.

I see the same thing in the way we approach the problem of information security. If you present even people who have experience in the information technology (IT) field about something relating to infosec, they will often a) jump straight to a solution even before they’ve heard or understood the problem, and b) base their decision in fear of what is going to happen. Rather than taking a rational and logical approach, the immediate instinct appears to be “what is the worst thing I can imagine happening and multiply that by 10?” It’s utterly illogical and irrational. You can’t make a case for protecting yourself by saying “all the badness!!!” Hyperbole simply doesn’t help make your case. You can’t scare a business into spending a lot of money on people and technology you have no justification for.

One of my favorite questions when I do anything with risk in an online class is just having students identify a risk from their daily lives. It takes the whole concept out of the technology space. From this perspective, and if you look at the dictionary, risk is defined as exposure to the potential for loss or damage. We are talking about potential, which means you factor in probability to really get an idea of risk. I’ve had students who say that driving is a risk because they could die. Well, you’ve jumped to an extreme situation but what is the likelihood of that. Just because death may be involved doesn’t make it more of a risk. What it means is that is an outcome that you are the most afraid of but that doesn’t mean the risk increases because the probability of you dying on the road is really quite low. Think about the number of hours you have been driving over the course of your life and you haven’t died yet. The vast majority of people on the roads have an accumulation of driving time the measures in … years? They haven’t died. This means that it’s a very low probability, which dramatically lowers the overall risk.

Jumping straight to the thing that could lead to something you really fear is not an understanding of risk. Focusing on fear is how we currently live our lives in the modern world, though. It’s what we are encouraged to do. Look at the news. Zika virus!! Be afraid!! It’s coming to your neighborhood real soon now!! Think about all of the incidents that the news has incited us into a complete lather about going back decades. The Communists are coming! (they didn’t) The Communists are infiltrating our government! (they didn’t in reality and certainly no more so than we did in the other direction, so perhaps a bit hypocritical) There are razor blades in the apples you get at Halloween! (there weren’t) The Advil is poisoned! (or was it Tylenol? I forget. either way, it wasn’t) We are programmed to react to fear. It’s a pretty serious motivator.

Wouldn’t life be so much easier if we just opted to not react everytime someone attempted to provoke us to fear? Wouldn’t it be better if you were able to think critically about whether it’s realistic or probably and, thus, something to actually be concerned enough to do something about? A lack of understanding is not a risk and also not an opportunity to be afraid. It’s just an opportunity to educate yourself.

Saturday, March 26, 2016

Analyzing Virtual Images

The Sleuth Kit can be used to investigate disks and disk images but the images don’t actually have to be copied from a real, physical disk. You can analyze a virtual image that you have created just as easily. The Sleuth Kit includes a number of very useful command line utilities that can be run on Windows, Linux and Mac OS X systems. For our purposes, this is being done on a Mac OS X system where the program was built using the Xcode Command Line Utilities that need to be installed before you can build The Sleuth Kit. First, let’s take a look at an image that was created on a Windows system using diskpart to create a virtual disk image and then format it. Before we do anything, we need to take a look at the partition table in the image to see where the partitions are. Without that information, we can’t go much further.


You can see from the screen capture above that we have used the mmls utility from The Sleuth Kit to get the partition table. mmls tells us that this is a DOS partition table. We aren’t restricted to the type of partition table that’s on the disk, though. Let’s take a look at another virtual disk image that was created using the Mac OS X Disk Utility program. Using mmls on that, we can see a GUID partition table.


In either case, you need to locate the partition that you want to investigate. In order to get file system statistics, we can use fsstat but we need to point fsstat at the actual partition using -o to indicate the offset within the image. In our case, we are looking at the fifth slot from mmls, which has a starting offset of 40 so that’s what we tell fsstat.


From this, we can see that it’s an HFS+ file system that was last mounted by Mac OS X and it was journaled, meaning that the operating system was keeping track of changes to the filesystem in case anything bad happened so the changes could be redone to reconstruct a clean copy of the the data, including the metadata indicating where all of the files were located. While this is all very interesting, what we probably want to get at is the actual files within the image. For that, we can use fls. This will give us a file listing of the partition. Let’s go back to the Windows image from earlier, since it had a different partition type, file system and offset. Looking at the mmls output above, the third slot is the only one that actually carries a filesystem, so that’s the one we will use. Again, we need to provide the offset to get to the actual filesystem and in this case, the offset is 128.

Once we have the list of files that were stored in the file table, which in this case is the Master File Table (MFT) from the NT File System (NTFS), we can do a bit more digging into files if we chose to. What you see here are the entries within the file table only and with the MFT, there is a lot more information to be gathered. First, we need to know where to look. Find the entry for Diskpart1.png above. We can see that this is a regular file. There are two r’s there indicating that the filename and the metadata for the file agree. These would normally be identical, though if a file were deleted you may see a difference between them. Keep in mind that if a file has been deleted, it still remains on the disk — both the data and, in some cases, the metadata within the filesystem. There is then a chain of three numbers. The first indicates which entry in the file table we want to look at. The 128-1 indicates that this is an NTFS entry and we can ignore that. Where we want to look next is the entry in the MFT and we can get to that using istat.


The istat utility extracts and decodes all of the information from the MFT entry for that file. You can see the filename and then the other attributes associated with it, including the $DATA attribute at the bottom. This attribute includes a list of blocks where we should be looking for the file data. The metadata (filename, permissions, access dates and times, etc) is kept entirely separate in most cases from the actual data that’s contained in the file. If all you did was to gather the contents of the file, you wouldn’t have the filename. If all you did was look at the metadata, you wouldn’t have any idea what was in the file. The two are separate but both necessary. Our starting point to gather the data for the file is in block 8346. We can use blkcat to extract the data from that block. According to fsstat for this virtual disk, we have a cluster/block size of 4096 bytes. blkcat will take care of that for us and only grab a single cluster.


Just as with the other tools, you have to tell blkcat where the actual partition starts by providing an offset within the file. This tells blkcat where the filesystem itself is, meaning the BIOS Parameter Block from which it can locate the file table. When you look at the output here, which has been piped into xxd to do the ASCII decoding for us, you can see that this is a PNG file. We knew that from the filename but filenames can lie. You are not required to use .png as a file extension for a PNG file. Windows systems maintain a list of file associations so they know what programs to launch when you want to just open the file from the Windows Explorer. That’s simply a convenience. As a result, it’s always good to verify that what you have in terms of data is what the filename and file extension tell you that you have.

One thing we didn’t look at here is the case where you may have deleted files. Typically, if a file is deleted, you would see * between the r/r and the file table entry. If you see that, it doesn’t mean the data is gone. It just means that the file has been flagged as deleted and so the entries can be recycled at some point.

Creating Disk Images

Let’s say you want to play around with disk analysis but you really want something small to use. You just want to tinker around with some forensics tools, why do you want to play around with even a multi-gigabyte USB stick? It’s much easier to just create a small disk image to use, though you won’t be able to put many files on it. If you don’t need that, there are easy ways to create disk images on each of the three primary operating systems — Windows, Linux and Mac OS X. Of course, the quickest way is to use a virtual machine. Using a virtual machine, you can add a second hard disk that you can make use of from inside a guest operating system that you are running your forensics tools on. Using Parallels, virtualization software for Mac OS X, you can add an additional hard drive by customizing the virtual machine, as you can see below.


If you don’t want to use virtualization but just use the operating system you came with, you can use tools that are already built in. On the Windows side, you would use DiskPart. DiskPart is a command line program. Launching the Command Prompt program, found in various places in the menus, depending on the version of Windows you are running from. DiskPart can be used to create a virtual image. DiskPart uses an interactive shell to issue commands. As a result, you start up DiskPart and it dumps you into the shell. Once you are there, you tell DiskPart to create a virtual disk image, as you can see below.


Once the virtual disk is created, we have to attach it to the system. Once it’s attached, you create a partition, assign it a drive letter and format it. Once you have done all of that, as you can see in the capture below, you have a working disk that is attached to your Windows system with a drive letter and it will show up in Windows Explorer. Once you have created the partition and assigned the letter, Windows will pop up a message saying there is an uninitialized disk and would you like to initialize it. You can initialize it using the dialog box or just type format in DiskPart and you have a formatted drive that is really just a file.


Using Linux requires multiple utilities as opposed to the single utility that Windows provides. Using Linux, we can create an empty file using dd. In the screen capture below, you can see dd creating a file using /dev/zero as the input source. This is a logical device that just generates 0s. We set the block size to be 512 which is mostly meaningless other than it tells us the size in conjunction with the count. 512 bytes * 200000 gives us a file that’s roughly 100M. Once we have the file, we can partition it just as you would a regular disk device.


As soon as we have partitioned it, we need to format it. Before we do that, we need to create a device file. We do that using losetup. Since there was already a loop device, the first thing is to delete the existing one using losetup -d as you can see in the screen capture below. We need to skip by the master boot record and the reserved sectors, which we do using —offset. Then you provide losetup with a device file, which we are calling /dev/loop0, since devices belong in the /dev directory. Once you have the device setup, you can format and mount it. You can format it with any format that you would like but in the screen capture below, you can see that it is formatted using the ext4 filesystem. As soon as we have formatted it, it’s ready for use but we need to mount it to a mountpoint within the filesystem. In the example below, we’ve mounted it to /mnt. As soon as it’s mounted, you can use it just as you would any other directory and start copying files to it, though keep in mind that in our example we are limited to 100M.


Mac OS X has Disk Utility, which is a graphical program that can create virtual disk images which you can then mount. You can see the creation of a new disk image in the screen capture below.


Once you have selected new image, you will be prompted for the size, format, encryption, read/write properties and the name. You can also specify whether you want to use a GUID partition map or master boot record partition table. The moment you have created the disk image on any of the operating systems you can start writing to the image as though it were a regular disk and you can also start to perform a forensic analysis using a variety of forensics tools. However, that’s another write-up so stay tuned.


Tuesday, November 3, 2015

Policy and Compliance Are Not Enough

The information security business seems to have strayed a bit from its roots. The roots of digital information security really began decades ago by the people who built and maintained systems. They may have wanted to either protect information or keep people out. While our nature as humans is more sharing and collaborative than it is secretive and isolationist, the reality is that we all have times when we need our secrets and spaces where we can store information that no one else can get to unless we specifically allow it. The problem comes when you start allowing a lot of users into the system or if you start connecting a lot of systems together into networks. Then we need additional protections in place to make sure everyone’s little corral of horses stays their own little corral of horses, unless they choose to set up a petting zoo.

Ultimately, there are competing priorities when it comes to information security. There is the pure security-focused no one gets in unless they are specifically allowed in priority. On the other end, there is the perspective that the business owns everything and so it gets to set the rules. The problem that arises here is that rather than these two ends working together to find a middle, the money for the security end is tied up in the focus on the business priorities.

This is where we find a conundrum. Sure, you can say that without the business, there are no systems to protect. As a result, the business should always set the priorities. This has the potential to work well if the business truly owns its resources and has a stake in protecting them. The problem arises when the business has no stake in the resources that are under the control of the information technology and information security people. I’m losing you, right? Okay, let’s talk about case studies.

Using a very simple scenario that can be extrapolated to much higher levels. Let’s say you are a company who wants to start up a loyalty card for your customers. This will allow you to learn a lot about the people who spend money with you and you can feed a little back in discounts or other goodies. Without the goodies, what is to entice people to sign up for your loyalty card so you can gather all of that data? Suddenly, though, your business has a resource that it has no stake in. You are storing names, addresses and phone numbers of a large number of your customers. What happens to your business if that information is stolen? It could be that absolutely nothing happens. If you aren’t storing credit cards or other financial data with those records, it could be you don’t even need to let anyone know, depending on the breach notification laws where you do business.

Even if you do have to notify someone, what has actually been lost? Some names and addresses. No big deal, right? If there is no downside to the business if that information is lost, what is the incentive to do everything possible to protect that information? This is where the problem of business-driven security comes in. The information that has been stolen doesn’t actually belong to the business. It belongs to the customers of the business. Since it doesn’t belong to the business and there is no actual impact to the business from its loss — maybe you have to shut down your loyalty card program, which doesn’t lose sales. It just means less marketing information that you can make use of to be more effective.

Business-driven security starts with the security policy. This is a very high-level statement of expected outcomes. There is nothing at all about implementation in the policy. That comes in a set of standards that fall out of the policy. An acceptable use policy, which is common, may simply say that anyone making use of a company resource like a computer and the enterprise network will do so in a business-appropriate manner. That’s it. That’s the policy. There are countless ways to implement that policy. The standards that are defined underneath that policy will get into more detail but still won’t get into specific technologies and implementations. Instead, you get a more fine-grained set of requirements for what meeting that policy should look like.

The notion of making sure that you are achieving your policy goals is called compliance. This is also a word used in relationship to meeting regulatory requirements. Some businesses may need to meet requirements set down by the Payment Card Industry (PCI) if they deal with credit or debit cards. Others may have requirements set down by the Federal Depositors Insurance Corporation (FDIC). This would be common with banks and other similar financial companies. Making sure that you are meeting these requirements is also called compliance. As a result, compliance is big business. Meaning, there is a lot of money in auditors coming in to make sure you are following the appropriate rules.

Meeting a set of rules, however, that are very high level statements of expected outcomes may not necessarily be the right things to be paying attention to. Here’s an example. A business has a security awareness training program for all its users. Every user has to take this training. An auditor may come in and determine whether the business is really getting all of its users through security training. If the business has a goal of getting, say 97% of users through training in a month and they hit 98%, they have achieved their objective.

Is this the right objective, though? Are the right topics being covered in the training? How is retention of the training being measured? Does this training actually help improve the overall security posture of an organization?

These are all questions that are not answered in this scenario but they are potentially far more important than the question of the percentage of users who have successfully made it through training. What it comes down to is clearly defining the problem. If you haven’t identified the problem well enough, your measurements are likely to be meaningless.

Large businesses are often driven by this compliance mentality and auditors and security professionals are often driven by meeting objectives that bear no relation to improving the security posture of an organization. A business can meet all of its compliance objectives and still be breached. This happens all of the time. The large companies you have read about all have robust security policies and compliance programs in place. The problem is that the security policies are all around protecting the business.

So, back to the scenario from above. If the business is about protecting the business but the business is storing information about a third party (its customers), where does the third party get a say in protecting its information? Once the information is stolen, it’s too late to walk away from the business and research shows that in most cases, businesses are not impacted financially by these breaches. Certainly, their stock prices are not impacted over the long term. Where is the place at the table for the stakeholders who have the most to lose from a security breach?


Tuesday, June 30, 2015

Hiding Between Partitions

One of the challenges of digital forensics is the number of places that someone who knows what they are doing could hide data they didn’t want to be found. Fortunately, the vast majority of cases don’t fall into that category. Most of the time, this will be a case of files sitting in the Documents folder where they belong or maybe in the Recycle Bin or Trash, depending on the system you are looking at. This requires some experience with the different operating systems to know where to look for documents.
Of course, if someone wanted to be a little sneaky, they may create a folder somewhere else on the drive and hide their illicit documents, like their collection of Justin Beiber MP3s, in that folder. This would, of course, be outside of the standard document repositories for users. You might, for example, stuff a folder into the Windows directory structure. This would require administrative rights to the drive but on most personal desktop systems, the user would have those rights. However, you are not restricted to the filesystem itself. If you know what you are doing a little bit, you can make use of the entire drive to store data.
Let’s say that you were to create a little slack space on your drive where you didn’t have a partition defined. Remember that a partition is a collection of consecutive blocks or sectors on a drive. A partition can then be formatted with a filesystem so it can then be used by the operating system to store files on. If you have a blank space before a partition or after a partition, that’s space that the operating system can’t use within a filesystem. That makes it fair game to stuff data into. You can see in the figure below, a drive that has two partitions defined on it with a large gap between the two partitions.



The end sector for the first partition is 1000000 but the beginning of the next sector is 1500000. This leaves 500000 sectors unused. Each sector is 512 bytes. That gives us something around 250M to store information into. This is a small drive and that value is close to a quarter of the drive. On larger drives, it may be a lot easier to carve a decent chunk out of the middle or the end of the drive and not have it be noticed.
The problem with this space is that it’s unorganized. I can’t just copy files to it and expect those files to be placed nicely so they can be retrieved easily. If I have a few files that I
want to put up there, I could manually place them one at a time and keep track of where I positioned them within that space. That requires figuring out how many blocks the files take up and remembering where they are. Instead, another way to do it is to simply concatenate the files together. There are a number of utilities you can use to do that. Under Linux, which is where I did this work, you can just use the cat utility. Perhaps one thing you want to do is to put a separator file between the files you want to store. That will allow you to extract the original files later on.
Once we have the concatenated file with all of the data we want to store in it, we can just dump it up to the slack space on the drive. In the figure below, you can see that I took my file as my input to the dd (disk dump) command and then wrote out to a sector in the slack space between the two partitions.

 

You will notice that when I was writing out to the slack space, I used the seek parameter. That’s because I needed to seek into the output file. If I want to go to a particular location in the input file, I would use skip, as you can see in the next invocation of dd where I extract the data. You will also notice in the output, I get 56+1 when I write the data out. That’s because I am writing 56 complete blocks plus 1 partial block. I didn’t file the last 512 byte sector when I wrote the file out. When I read in, then, I need to read in all 57 blocks to get the complete file.
Since I have the original file as well as the recovered file, I can compare one against the other. diff shows an insignificant difference regarding a newline at the end of the file. When I check the line count, I get the same line count between the two. These two comparisons tell me that the file I retrieved is substantially the same as the file that I put up into the disk.
Of course, I could also check to see if there is a specific piece of content in the entire file system using grep but on large disks, that can take a while. There are other tools that can be used to ferret out such things, especially if you can afford the commercial forensics tools.
While this is all very manual, this could be performed programmatically as well. Perhaps another time.

Saturday, April 25, 2015

To Frag or Not To Frag, That's Hardly A Question

In the beginning, for there certainly was once a beginning, the gods created the Arpanet and saw that it was good. Skip ahead several years and they further begat TCP, then IP, then UDP and so on and so forth. Considering that they always had in mind the notion that data would be sent in small packages of a size that could be easily determined, they decided to call these packets. Because, sure, why not? However, not everything was called a packet. It all depended on where the chunking up took place as to what you called the end results. In the case of chunking at the Internet Protocol (IP) layer, the result was indeed called a packet. IP then needed to be able to handle this idea of packets and be able to put them back together again. This meant knowing the size and where they needed to be placed, much like putting a puzzle back together. If you try to simply jam all the little dangly bits into holes on other pieces, you ran the risk of having gaps in the resulting puzzle where the dangly bits didn’t cleanly go into holes. Not to mention, the resulting image probably just won’t look right.

Let’s say, for example, that you have this chunk of data that’s 100 bytes, as you can see in the figure below. Maybe it gets broken up into chunks of 20, 30 and 50 bytes each. For ease of reference, let’s call each A, B and C. If what you are sending starts with abcdefghijklmnopqrstuvwxyz, which is 26 bytes. Only 20 of them would fit into the first chunk of data, or packet. If I were to send that to my friend Allan, but if I were to send them in separate packets (maybe think of them as envelopes), he would need to know which to open first and how to arrange them. Because of that, it’s helpful to have some sort of identifier associated with them. This puts us back to A, B and C.

If I were to receive C first, followed by A then B, I would know, because I know my alphabet, that A comes first, then B, then C. One of the problems with fragmentation is that I can’t tell what’s really going on by looking at a single fragment. Maybe I catch the one that says uvwxyz. I don’t know what that means. I suppose it could be the tail end of the alphabet, but that’s just guessing. What really comes before or after? It’s this uncertainty that opens the door to some bad behaviors. The utility fragroute, written by Dug Song, allows us to establish some rules that can actually cause fragmentation of messages. In the IP world, we have an expression for the names A, B and C that we used above. There is a field in the IP header called the IP identification field that associates a lot of related messages together. From there, we have a second field called an offset that tells the receiving end where that particular part of the message slots in. You can see a sample IP header below showing the IP identification field (IPID) and the Fragment offset field. The receiving end needs both of these in order to pull the entire puzzle together with all the pieces in the right order.


Let’s say, though, that you were sitting in the middle looking at all of the puzzles that were going through and you needed to determine whether they were bad puzzles or not. Maybe, in the case of me mailing letters to my friend Allan, I have put a single sheet of paper into an envelope and sent them to him. Maybe out of order, maybe one a day at a time. The complete thing is the Anarchist’s Cookbook with bomb making recipes and so forth in it. Once he has it, he can do bad things. You might want to stop him, and if you knew Allan, that might be a really wise idea. You’d have to know that what he is getting is really bad. You’d need the entire collection of papers, potentially, before you could make a determination. If we are talking about a network device, though, you need all of the fragments before you can determine whether to send it on. If fragments come in out of order or delayed, that means the receiving application is going to be delayed and that’s often unacceptable. So, maybe if it’s fragmented, you just send the fragments along because you don’t have enough information to make a decision from each individual fragment. Rather than holding up the train, which may cause users to be upset, you just push everything through.

We can take advantage of this with fragroute. Using fragroute, we can grab messages from applications and fragment and otherwise mangle them before they get sent on their merry way. Let’s try this as a ruleset.

delay random 10

dup random 20

ip_frag 48

ip_ttl 3

print

You may be able to figure most of this out on your own but let’s step through just to be sure. The first line says to delay random messages by 10 milliseconds. The next line says to duplicate random messages with a 20 percent chance to perform the duplication. The next line is the one that we’ve been talking about. Fragment each message at 48 bytes. Finally, set the IP time to live field to be 3 and then print out what has happened.

Below is one of the frames (another way of talking about messages that have been broken up but this is each chunk of data that is seen on the wire) that results from running fragroute. You can see that the total length of the frame is 68 bytes. Out of that 68 bytes, 20 of them are just the IP header. The other 48 bytes are the actual data. Based on looking at the fragment offset, it looks as though each fragment was 48 bytes, just as we had set in the fragroute rules. The offset is a multiple of 48, indicating that this is the third fragment (0-47, 48-95).


You may notice that there is no indication here what the data indicates. Normally, you would have some indication of what protocol was being used. The problem is that we don’t have the TCP header in this fragment. You can see from the IP header that the next layer protocol is TCP but we don’t know what the protocol above that is. If you look at the very bottom of the Wireshark window above, you can see the actual data. This suggests a user agent from an HTTP request. But without the actual TCP header, we can’t determine for sure that it’s an HTTP request. Other requests can use a user agent and there is really nothing else to suggest that this is HTTP. We certainly don’t have a port number, because of the lack of TCP header.

You can see from this why fragmented packets is such a problem. We can pull it all together, of course. You can see the message in Wireshark that the entire message is reassembled in frame 3765. I can also follow the conversation by looking at frame 3765 and I find the following.


This is clearly an HTTP request. The section highlighted in red is the request that we were looking at a fragment from. The section highlighted in blue is the response. This doesn’t look at all like anything worth getting worried about. It’s just a standard HTTP request and response. But just from the fragment we saw, it was hard to say. In this case, the entire conversation was fractions of a second. We could easily have delayed the frames by quite a bit, which would have required a lot of hold up. This is why fragmentation attacks can be challenging when it comes to detection and certainly when it comes to prevention.



Tuesday, March 24, 2015

Math Lessons

While you might not think this really has anything to do with forensics or other security-related issues, the reality is that math is your friend. And my friend. And when you have to calculate the byte offset on a hard drive to locate the cluster where a particular file is located, you will really want to know a little about the basics of math. 

You may have guessed that the origination of this topic is all of the nonsense spreading around on social networking sites like Facebook. Based on the number of times variations on these math problems show up and the number of times I see wrong answers, it seems as though a large number of folks really could stand a brief math lesson and while I am neither a math instructor in real life, nor do I play one on TV, I am going to take this one on because it will make me feel better. 

The acronym to remember here, and it’s really quite simple, is PEMDAS. Make up whatever mnemonic you want to remember, what it really means is parentheses, exponents, multiplication, division, addition and subtraction. This is the officially approved order of operations. When you see a very long chain of mathematical operations, you might think that you should just work left to right and as a general rule, that’s not a bad instinct. However, in order to come up with a consistent and mathematically accurate answer, you should apply the order of operations first. Then you can move on to left to right. You will also find that it’s generally easier to do a simple replacement. Let’s illustrate with an equation I’ve been seeing recently on Facebook. 

7 + 7 / 7 + 7 * 7 - 7

For those of you unfamiliar with two of those symbols, the / is a division sign for cases where we don’t have the horizontal line with a dot above and below, as in a computer keyboard. The * is a multiplication symbol, which is commonly used in place of a X or an x because those might be confusing in algebraic equations. So, let’s apply the order of operations and then re-write the equation after substituting. 

7 + 1 + 49 - 7

7 divided by 7 is 1, so I swapped in a 1 for the division operation I did. 7 multiplied by 7 is 49 so I swapped that value in. That leaves us with the equation above. There are a couple of ways to do this at this point. I could certainly go left to right and add the first three numbers then subtract the last but you may have noticed that two of them cancel each other out. If I were to re-write the equation above as follows, it quickly becomes a lot easier. 

7 - 7 + 1 + 49

This leaves me with adding 1 to 49 resulting in 50. See how easy that was? Keep in mind that the order of operations is really important. I suppose I could get into the history of why someone determined that multiplication and division were more important than addition and subtraction but it would likely bore you to tears. It would take far more of my time to come up with something coherent than I feel like putting in at the moment, so let’s skip it and move on to series. Let’s say you see the following:

10  =  50

9  =  38

8  =  27

7  =  17

5  =  ?

There are two things you should notice right away. The difference between 50 and 38 is 12. 38 to 27 is 11. 27 to 17 is 10. So, the next in the series should be 8 because we were decreasing the right hand side by one less each time. Since the last difference was 10, the next difference will be 8. 17 - 8 is 9. This leads us to the next thing you really should notice. The value on the left skipped one. The value of 6 should be 8. I’m asking for the value of 5. Keep the series going. I decrease the difference on the right hand side by 1, meaning that as I decrease by one on the left, I will be decreasing by 8 on the right hand side. This means that 5 = 0. When you see a series like this, there is generally a trick. They have skipped a value out of the series. This doesn’t mean that you just assign the correct right hand value (the next one in the series) to the wrong left hand value. It means you apply the right hand series twice and assign that value to the left hand side. 

A little bit of math, folks, will take you a very long way. I hope this has been a little bit of help. I know it’s made me feel better to share it with you. 


Tuesday, July 29, 2014

More Fun With Python

Since I’m in the middle of trying to get a title completed on Python scripting for security professionals for Infinite Skills, I’ve been doing a lot of writing little scripts that do interesting things. So, in order to dump my head and also get something somewhat recent and potentially interesting up here, I thought I’d write up one of those scripts here. This could be a useful foundation for someone who wanted to do a little security testing using Python scripts. It is also useful for forensics professionals since you may want to write custom tools that are capable of parsing data in a way that makes sense to you rather than relying on tools that represent data in a way that made sense to someone else. Being able to parse simple data structures, for example, is a very useful skill for both network programming and also forensics programming. One case where there was a lot of parsing to do that came up both in terms of the video training I am doing but also in the next book I am writing is dealing with the information in the master boot record, including the partition table. 

So, let’s take a look at a program that I threw together to do some quick parsing of the partition table in a master boot record. 

#!/usr/bin/python3

#  (c) 2014, WasHere Consulting, Inc

import struct

 

f = open("mbr.dd", "rb")

 

mbr = bytearray()

try:

    mbr = f.read(512)

finally:

    f.close()

 

x = struct.unpack("<i", mbr[0x1B8:0x1BC])

print("Disk signature: ", x[0])

x = mbr[0x1BE]

if x == 0x80:

    print("Active flag: Active")

else:

    print("Active flag: Not active")

 

lbastart = struct.unpack("<i", mbr[0x1C6:0x1CA])

print("Partition Start (LBA): ", lbastart[0])

lbaend = struct.unpack("<i", mbr[0x1C9:0x1CD])

print("Partition End (LBA): ", lbaend[0])

For the purposes of this program, I have grabbed an image of the master boot record so I can get to the partition table. I did this by using the UNIX/Linux utility dd. You simply grab the first 512 byte block with dd if=/dev/sdb of=mbr.dd bs=512 count=1 and you end up with an image of the master boot record you can use various tools with. So, the program opens up the disk image called mbr.dd as a binary file then creates a byte array to store all of the bytes from that disk image into. Once I have a byte array, called mbr, I can start to pull the bytes out that I want as long as I know where the offsets are. 

Something to keep in mind, though, is that the master boot record is stored as little endian so if I have a file with an image or copy of that master boot record, all of the multi-byte values are going to be backwards. We need to use struct.unpack to get the bytes out and in the correct order. So, we tell struct.unpack that we have a little endian integer with the parameter <i and then we have to provide a range of bytes out of the byte array that struct.unpack should use to create that integer out of. The thing to keep in mind when you are providing a range is that the top end is not inclusive. For the disk signature, I am grabbing bytes 1B8, 1B9, 1BA, 1BB. Even though the last byte in the range indicated in the program is 1BC, we don’t get that last byte because it’s not included based on the Python syntax. 

Once we have the basics of pulling data out of the byte array, the rest is trivial. I can grab the single byte indicating whether a partition is active (bootable) or not and then compare that value with what I know about that flag. If it’s 0x80, I know the partition is active. If it’s not, then it’s not active so I can print out the results based on that byte. I can also get the starting logical block address and the ending logical block address by grabbing the bytes from my byte array and converting them into integers, again using the struct.unpack method. 

This is a simple technique that can then be applied to other binary data structures. Whether that data structure is the rest of the master boot record or if it’s the BIOS parameter block or the structures associated with a GUID Partition Table disk.