Tuesday, September 6, 2011

Something you should know about talloc

Talloc is an excellent memory management system for C that provides hierarchical memory pools with other cool tricks like destructors. It's written by Tridge for Samba and I really like it. If you are writing a complex system in C you could do worse than to replace your calls to malloc with calls to talloc.

So that's talloc, but the thing you really should know about talloc is right there at the bottom of the project page. In particular:

when using talloc_enable_leak_report(), giving directly NULL as a parent context implicitly refers to a hidden "null context" global variable, so this should not be used in a multi-threaded environment without proper synchronization.

I've spent many days recently hunting down a bug, the bug would have been much easier to find if I had read the above line. Suddenly I was sharing contexts all over the place and very very rarely there'd be a synchronization problem that would lead to a null pointer deref. 

By the way talloc_enable_leak_report() is an excellent feature of talloc. Excellent. 

Monday, August 8, 2011

Authenticode and Antivirus Detection part 2

Update Nov 2013: Another follow up post: Authenticode and Antivirus Detection Revisited

After Shane's comments on the Authenticode and Antivirus Detection post I thought I'd run some more tests. I wanted to try and figure out how much of the observed detection difference were because some extra bytes had been added and how much was due to special handling of signed binaries.

I found an archive of malware online and created four sets of samples. Set one was the malware without any changes, set two was after the binaries had been signed with the TEST1 certificate, set three was signed with a TEST2 certificate that was similar to TEST1 but was only valid from 1975 - 2009 and set four had a random blob of 32 bytes appened to the end. Using the VirusTotal API and Bryce Boe's python script I ran each of the sets against the VirusTotal antivirus suite.

The resulting statistics are here, showing the number of AV positives, the format is:
 "HASH [SET1, SET2, SET3, SET4] [SET1 - SET2, SET1 - SET4]"

And here are the first 10 entries (ordered by decreasing "SET1 - SET2" value):

DB1D5E...34573 ['28', '10', '16', '22'] ['18', '6']
FDFB86...1FE0C ['34', '18', '18', '27'] ['16', '7']
6D48A7...F4880 ['36', '20', '22', '33'] ['16', '3']
CA9C3E...ED072 ['31', '16', '16', '23'] ['15', '8']
8798FA...8755B ['35', '20', '20', '32'] ['15', '3']
1011ED...0DB18 ['35', '20', '20', '33'] ['15', '2']
DA01D0...C899D ['31', '17', '16', '28'] ['14', '3']
CC3B7D...228D1 ['37', '23', '23', '34'] ['14', '3']
CADD90...CE9C4 ['35', '21', '21', '31'] ['14', '4']
B6BBE8...8CD10 ['32', '18', '18', '29'] ['14', '3']

General observations:
  • Adding either an authenticode signature or random data would defeat several engines
  • Very rarely would the signing certificate's validity influence the score
  • For some reason adding the random data occasionally resulted in more signatures being hit and considering that the same data was added to each sample I'm not sure what happened there.
  • This test primarily tests the AV signature engines and not their runtime or heuristic scanners
  • The VirusTotal API limit of 20 requests each 5 minutes sounds like a lot until you run tests like this.
Really what I've learnt from this is that AV signatures are even more fragile than I realised. To get a proper look at how AV treats authenticode signed binaries I think I'd need to evaluate all of each AV's modules and not just the signature engine.

Saturday, August 6, 2011

Tavis Ormandy's Sophail paper

On the topic of antivirus, Tavis Ormandy has recently released a paper looking into the internals of Sophos. It's quite scathing and very interesting, check it out: Sophail: A Critical Analysis of Sophos Antivirus

Authenticode and Antivirus Detection

Update Nov 2013: Follow up posts: Authenticode and Antivirus part 2, Authenticode and Antivirus Detection Revisited

It turns out that many antivirus engines white list authenticode signed binaries regardless of the trustworthiness of the signature. Here's an experiment that I performed, feel free to play along at home (remember to be careful when working with malware).

Step 1: Find some malware
This was actually the most time consuming step, a lot of places talk about malware and offer large archives of malware samples to download. Even so, it took me a good 15 minutes to find a malicious windows executable that I could download from a site without a password, registration or other nonsense. In the end I found a site that lists live drive by download sites and I grabbed an EXE before the particular malware host went down. Sadly I can't find the link to the index site I was using, I'm sure a little bit of Googling will allow you to retrace my steps.

I ended up with freedom.exe md5sum: ba87b562c829b7095bfb9e0db7a39890

Step 2: Confirm that it is detected by Antivirus
For this to work you need to know that your malware sample is detected by antivirus engines so I recommend submitting it to VirusTotal or similar service. Alternative if you have the resources run it against your local battery of antivirus installs.

Freedom.exe was detected under a variety of names, Microsoft Security Essentials calls it Trojan:Win32/Danginex. The results were 36/43 (83.7%) considered Freedom.exe malware.

Step 3: Generate a code signing certificate
I don't have a proper code signing certificate handy so I thought I'd generate a self-signed certificate for the test. I used makecert.exe and pvk2pfx.exe from the Windows SDK 7.1 and the following commands:

makecert -r -pe -$ individual -n CN=TEST1 -sv test1.pvk test1.cer
pvk2pfx -pvk test1.pvk -spc test1.cer -pfx test1.pfx

Step 4: Sign the malware sample
Copy the sample to a new filename and then use signtool.exe to add the authenticode signature saying that TEST1 is responsible for this file.

signtool sign /f test1.pfx freedo-signed-test1.exe

Step 5: See what AV thinks of this new file
Submit your new file to VirusTotal and see what happens. In the case of Freedom.exe the detection rate fell from 83.7% to 27.9% (12/43). Most of the big names in the AV community (with a couple of notable exceptions) were quite happy to ignore Freedom.exe once it had been signed.

The Antivirus engines that changed their minds about freedom.exe are:
AhnLab-V3, AVG, BitDefender, CAT-QuickHeal, Comodo, Emsisoft,
F-Secure, Fortinet, Ikarus, K7AntiVirus, McAfee,
McAfree-GW-Edition, Microsoft, Norman, nProtect, PCTools, Rising,
Sophos, Symantec, TheHacker, TrendMicro, TrendMicro-HouseCall,
VIPRE, ViRobot

Notably Kaspersky flagged both the original and modified samples as Trojan-Clicker.Win32.Agent.shx and ClamAV among 7 others did not flag either sample.

Conclusion: What have we learnt?
Signed executables are more likely to be considered benign by antivirus engines. Signed executables are probably excluded by policy for performance reasons but it is possible (but unlikely) that instead that the addition of the Authenticode block at the end of the file is disrupting the signatures used by the engines. I hope that in the future that if vendors are going to exclude signed binaries that they at least check to see if the certificate used to sign the binary is trusted.

Thursday, May 26, 2011

GitHub additions!

I've ported some of my old projects over to git and uploaded them to github.
A much better solution than hosting raw source files on my web server!

The projects that have been ported:
talklikewarren A twitter bot that posts things that sound like Warren Ellis.
fakemiddleman - A twitter bot that posts things that sound like The Middleman.
hottest100 - A python script that created a live music video channel out of The Triple J Hottest 100.
top1m A squid redirector that prevents clients from visiting sites outside of the Alexa top 1 million.
twitbot - An example of how one might use twitter as a channel for command and control of malware.

Saturday, May 14, 2011

py360 - A speed increase (mostly)

I've updated py360 (from the patch note):

Changed the Partition class from preprocessing the entire partition during its constructor, instead it now will resolve files and directories on demand and store the results for later. Basically trading precomputation for memoization. gamertags.py runs about 90x faster, report360.py runs about the same (since it touches every file) and mounting is about 100x faster. These improvements are at the cost of all first time reads being slightly slower but no wasted preprocessing is done.

What isn't mentioned is that this will also make it much more likely that corrupted partitions will mount (which was why I started looking at this change at all). Also, gamertags.py and report360.py have been changed to be compatible with the new changes. The main difference is that using partition.allfiles does not necessarily return all files but rather all the processed files, use partition.walk() to get all files. The old behaviour is still available by passing in precache=True to the Partition constructor. 

This is a fairly experimental patch so let me know if it doesn't work for you. Next on the dev list remains better output from report360.py (and STFS / XDBF).

I also hope to write some posts unrelated to py360 soon too!

Tuesday, May 10, 2011

py360 - Update!

Thanks to the feedback and test data provided by some excellent people (Thanks Juri, Matt and DC) I've managed to fix several bugs in py360 and it should now be a smoother experience.

The biggest fix is in the STFS parser which would naively assume that all filelisting blocks were contiguous, this fix means that STFS files with large numbers of files inside them will now work (e.g. Profiles that see a lot of use). Now report360.py should run cleanly on (hopefully) all images and the only errors you will see will be from trying to parse deleted files (they are recognisable by the ~ that precedes their name).

Next up on the dev list is to investigate the unicode parsing problems that occasionally appear and cause extraneous bytes (usually nulls) to appear in the output. Worst case I plan on changing report360.py to remove the null bytes, best case I find the underlying cause and sort that out.

If you would like to help with py360 I'd like to hear from you. I'm really interested in hearing about your experiences with py360 and especially tell me of any errors of inconsistencies that you encounter. If you're a programmer and really keen feel free to contribute code —especially example programs and bugfixes— I won't turn you away!

Saturday, May 7, 2011

py360 - An example to print out gamertags

EDIT: The code below is obsolete check github for an updated version.

To help people get started with py360 I written a simple example (simple at least compared to report360.py). gamertags.py takes an Xbox 360 disk image and prints out the gamertags of all the profiles present.

It produces output like:
Gamertag: Han Solo, Type: Gold (Paid)
Gamertag: Chewbacca, Type: Silver (Free)

The code is simple enough that I've included it below, it's also now in the git repository.

# An example of using py360 to extract all the GamerTags on a drive.

# Where does this data live?
# GamerTags are inside the Account block of a user STFS container
# located on the XTAF partition. 

# How do you find user STFS containers?
# Gamer profiles are located in the /Content directory in subdirectories
# named with 16 hex characters starting with an 'E' such as
# E00012DD5A4FAEE5. The STFS container is located in the 
# FFFE07D1/00010000 subdirectory and is named the same as the
# profile directory.
# Example: /Content/E00012DD5A4FAEE5/FFFE07D1/00010000/E00012DD5A4FAEE5 

from py360 import partition, stfs, account
import sys

# First, open the xbox 360 image
part = partition.Partition(sys.argv[1])

# Second, find profile STFS containers
for directory in part.allfiles['/Content'].files:
  if len(directory) == 16 and directory[0] == 'E':
    # Open each STFS container and look for the Account block
    # The STFS class can take either an actual file or a file-like object,
    # we're using an file-like object to avoid having to use a temp file.
    path = '/Content/%s/FFFE07D1/00010000/%s' % (directory, directory)

    # This test is to exclude deleted profiles and defunct directories
    if path in part.allfiles:
      profile = stfs.STFS(filename = None, fd = part.open_fd(path))

      # The account block is always at /Account in the STFS archive
      # we'll read it in, decode it and then print out the gamertag
      acc = account.Account(profile.read_file(profile.allfiles['/Account']))
      print "Gamertag: %s, Type: %s" % (acc.get_gamertag(), acc.live_type)

Saturday, April 16, 2011

py360 - Xbox 360 File System Tools

I'm releasing the code and docs that I wrote during my Xbox 360 research.

py360 is a FUSE filesystem driver and associated file parsers for reading Xbox 360 hard drives. It is designed to aid forensic examination of the Xbox 360. The main components are a FUSE file system for mounting the XTAF file system and a set of python classes for parsing the the STFS, XDBF and Account block file formats and the XTAF file system.

py360 is available from github and I've written a brief user guide.

Additionally the results of my look into these data structures is available.

This project would not have been possible without the existing work of the Free60 project.

Thursday, March 24, 2011


I'm still around, the Xbox 360 story will be completed soon!

I've submitted my research, it has been accepted and I will graduate.

I've been holding off on finishing the posts until I'd gotten it all submitted and I was in a place where I could post my results and some of my code. There may even be a google code project available at the end of all this.

Patience please everyone!

By the way, the image from the right is from http://www.trustocorp.com/ who amuse me to no end. Go have a look.

Friday, January 28, 2011

Xbox 360 Forensics: Part 4

In our last episode I had just about given up on x360 after spending a week or so digging around its code base, where did I go from there?

Well I decided to sit down with the Free60.org pages on XTAF and on Xbox 360 File Systems, the source code of a couple of XTAF implementations (x360 and utaf.c), a hex editor and python and I started over. This was a fun project, it turns out that in my time patching x360 I'd learnt almost everything I needed to implement my own parser and some mucking around with a hex editor and the Free60.org docs got me the rest of the way. At that point I started reading about the FUSE bindings for python which are poorly documented but still make filesystem development super easy, I now want to implement everything as a filesystem!

This was the beginnings of my py360 python module (which may one day see public release, bear with me!) and it was good. The first thing I did with my new filesystem and library was to take a recursive directory listing and perform a 'find . -type f -exec sha1sum {} \;' on the filesystem. When this went swimmingly I moved on to the next problem, which was to unleash libmagic (through file) on the filesystem but to my disappointment the mighty libmagic came back with nothing, everything showed as data. This was a problem and certainly not one that I had seriously anticipated. The next step was to see if I could make any sense out of these files quickly and the utility strings is my goto tool in these situations. Strings revealed that while there was a fair amount of ASCII text there was also a very large amount of UTF16 (big-endian) including what looked like the text of game achievements, unfortunately I couldn't find much of a reference to the gamertag of the user on this image nor any other stuff of interest. This is when I resigned myself to doing things the hard way... stay tuned!

Saturday, January 22, 2011

Xbox 360 Forensics: Part 3

I've been on a little bit of a hiatus but we're back for part 3 of the story.

Last we heard I had just (finally) succeeded in taking a dd image of an Xbox 360 hard drive for analysis. I had previously settled on x360 as a platform for analysis and I ran the following series of commands:

svn co http://x360.googlecode.com/svn/trunk x360-read-only
sudo apt-get install libfuse-dev
cd x360-read-only
mkdir /tmp/mnt
sudo ./x360 -o debug,uid=1000 /mnt/data/201010.bin /tmp/mnt

This seemed to work ok except that in large directories such as /Cache many of the files would not have any attributes and if I tried to read them I would get a file not found error, also reading other files would cause x360 to crash and to top it all off even when I mounted an image in read only mode one crash ended up damaging the image. I'm sad to say that these problems absorbed a large amount of my time because there were several related bugs that got in the way, including:

  • The type size_t was assumed to always be 64 bits though on my x86 platform it is only 32 bits 
  • An integer overflow cause roughly a quarter of the FAT to be mmaped instead of all of it (see size_t issue)
  • Multi-cluster directory support was implemented in directory listing code but not in the file reading code
  • The mmap call for reading the FAT did not respect read-only options
  • Some read operations caused the file system to crash (possibly due to a pread parameter typing issue)
Except for the last dot point I managed to fix them but without fixing all of the points above I didn't feel confident using x360 for forensics purposes. (Note to the author of x360: I do have some patches that I meant to submit but since I couldn't get everything in a working state I'm not sure if they'd be useful)

The debugging of x360 was useful as I learnt a lot about XTAF by trying to fix the code and my skills with gdb increased significantly as well. This process took almost all of the time available in my first research-sabbatical and the whole project was put on hold for a couple of months while I returned to my day job and contemplated solutions.

Wednesday, January 5, 2011

Xbox 360 Forensics: Part 2

A bit of a detour from my story,  I thought it'd be good to talk about the Xbox 360 file system briefly. The filesystem is called FATX or sometimes XTAF. As the name suggests it's a descendent of the venerable File Allocation Table (FAT) file system that's been around on DOS based operating systems for about 20 years. FATX removes some legacy support and mandates certain values that previously have been optional. FATX is also the file system used by the original Xbox. The only difference between the original and 360 file systems is that due to the processor architecture change Microsoft elected to use big endian numbers for the 360 which is why it sometimes called the XTAF file system.

Quick refresher, what do we mean by big endian? Computers store data as a sequence of zero and one bits usually in groups of 8 bits (a byte) with the right most bit being the least significant. Numbers are stored this way with each bit representing a power of 2. For example 00010000 represents the number 16 since the 5th least significant bit is turned on (2^4 = 16). Easy enough except that using 8 bits the largest number you can represent is 255 (2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 = 255). The way to represent larger numbers is to add more bytes, unfortunately there isn't a standard on how to represent these numbers. The two options are big endian and little endian which differ by which side the least significant byte is on. For example the 16 bit number 00000001 00000000 could represent the number 1 in a little endian system and 256 in a big endian system. Most personal computers - all Intel and AMD processors including recent Apple computers - are little endian but there is a significant minority of devices that are big endian including the Xbox 360 and older Macs. 

This means that even though the Xbox and Xbox 360 use the same file system you require a different file system driver to interpret them. There are some other quirks to FATX too such as the absence of the '.' and '..' directory entries so that you can't ascend to a parent directory without remembering what it's called which also require some changes to existing FAT drivers. There are a variety of tools available to process FATX drives including the popular Xplorer360 which provides an FTP style interface to the drive for Windows users, the utilitarian uxtaf.c which gives the unix user a custom shell that can access a FATX partition and x360 which uses FUSE to mount a FATX partition on your computer so that you can access it the same way you can access any file on your system. After a bit of reading I decided that x360 was the best choice for me and that's what I started using to look at these file systems but as I hinted in my previous post it didn't go quite to plan.

As an aside it would be amiss of me to fail to mention the Free60.org which taught me almost everything that I know about FATX.

Tuesday, January 4, 2011

Xbox 360 Forensics: Part 1

My research activity is coming to a head and I thought I'd let you all know how it is going. My early explorations were plagued by a plethora of hardware and software failures. The Xbox 360 thoughtfully provided to me by my University had a damaged hard drive which took me longer than it should to diagnose because I had to eliminate my procedure and imaging equipment as possible sources of errors. My setup is a little weird since I'm studying on the road, I'm using an Ubuntu virtual machine on my Dell Laptop and a cheap Xbox 360 -> USB hard drive connector and I was worried about issues arising from the level of indirection. The error that manifested was quite strange, the first 40Gb or so of the image would copy fine and if copying in a reverse order the last 40Gb would also copy fine. I tried imaging from the host OS, tried using a different USB adapter and even directly attached the drive using SATA. My tentative conclusion is that the middle platter of the 120Gb drive was damaged and any reads on it would fail. During this stage I voided some warranties (always fun) and learnt that inside the fancy casing Xbox 360 hard drives are standard laptop drives. I replaced the pictured drive with a 60Gb drive from a local games store and I was in business. A quick:

       dd if=/dev/sdc of=/mnt/data/image.bin 
   ./x360 /mnt/data/image.bin /mnt/xbox -o uid=1000,gid=1000

and I was in business... or so I thought (to be continued!)