How I cracked the iTunes 7 DRM, Pt III

November 20th, 2007 Greg

After last time’s failure, things started to become personal. I started exploring all kinds of new avenues and employing many techniques that aren’t so commonly used. In parallel, I drew up a map of the inner-workings of iTunes 7.0.2.16 and began coding up a framework from which to launch a full-scale attack once I knew how.

The program map was an uninteresting flow-chart full of hex strings (mostly addresses of key points) and crossings-out, but the framework was quite a sight to behold. I had no idea that it was such heavy overkill at the time, but so as to keep all bases covered I ended up with two distinct but inseparably linked programs, codenamed DRMBugger and DLLBugger.

DLLBugger is a tool-kit DLL, designed for injection into iTunes so I could execute arbitrary code from within its address-space and hook functions to my heart’s content.

DRMBugger is a purpose-built debugger. When you fire it up, it locates and attaches to any running instance of iTunes as a user-mode debugger, keeping track of all internal goings-on. It wouldn’t take much effort to convert this into a full-blown ring3 debugger, as it has support for module and memory-page enumeration, hardware breakpoints and run-tracing, along with a rather unreliable disassembler.

With the combined power of these two, iTunes was truly at the mercy of my twisted will. If only I knew what I needed to make it do.

My First Stream

I can’t emphasise enough just how much code is executed in the seemingly idle state of iTunes’s AAC playback, but for days on end I would see OllyDbg’s familiar disassembly window whenever I closed my eyes. After tracing backwards, forwards, using stochastic pausing to find the bottlenecks (like a primitive manual code-profiler), comparing run-traces and hit-traces and analysing dead-listings of programs known to use QuickTime’s DRM code; I finally struck gold.

At 0×0062914D, iTunes.exe (7.0.2.16 for Windows XP) calls a function at 0×005C1B20, passing a pointer to a structure containing the address of an encrypted chunk of AAC, along with a pointer to the pseudo-1024-bit decryption key. It was pretty clear that the AAC data was an entire chunk as defined in the stbl atom directory. It was also evident that the key is retrieved from ‘Documents and Settings\All Users\Application Data\Apple Computer\iTunes\SC Info\SC Info.sidb’ using some of the udta atom’s values as an index. I could have investigated this further, but decided that the details are unimportant if DLLBugger can just use this function black-box-style.

So I got straight to writing an inline patch. The idea was simple: Each time this ‘decrypt’ function is called, dump the decrypted buffer to a previously VirtualAlloced array. And sure enough, after waiting for my protected track to play beginning-to-end, I ended up with an encryption-free copy of the AAC stream. I was confident that this had worked, as the data chunks looked the part, according to my limited knowledge of AAC format, but it wasn’t so straightforward to verify. Decrypting the stream is the hard part, sure, but this stream is useless without the remainder of the MP4 file to house it. I spent a little while in a hex-editor piecing things back together and wasn’t surprised when iTunes refused to play the new file. As far as iTunes was concerned, the MP4 file (even with its new m4a extension) still had all the descriptors of an encrypted file, and as you’d expect, decrypting the stream twice didn’t produce anything meaningful.

Fortunately, this frustrating period didn’t last too long. I had to remove all evidence of DRM-related atoms before things got up-and-running, but that means only overwriting a contiguous block of the file with zeros. As it happened, I had already written a fairly complete atom parsing engine into DRMBugger, so rather than let this go to waste, I took things a step further and removed & reshuffled some of these atoms so that the resulting file was indistinguishable from a true ‘m4a’. Reassuringly, the file played just fine in WMP, WinAmp and VLC, as well as iTunes, so things were really starting to look up. The only problem is that it had taken me two and a half hours to remove the DRM from this file (a little trivia: it was ‘The Rejection’ by Dangerous Muse). The next thing on the agenda, after a night of celebration, was to automate the process.

RST decomposition of a general skew-free 3D transformation

November 18th, 2007 Greg

First of all, I refer you to D3DMatrixDecompose. If you want to break a standard 3D transformation matrix into its rotational, translational and scaling parts, without caring how it’s done, then look no further. If your needs are a little more specific and you’re sure you aren’t reinventing this wheel, then read on.

There is nothing clever about this decomposition, but it’s a question that comes up more often than I’d expect, so here’s the lowdown. I assume that your matrix is in DirectX-standard row-vector representation (so vout = vinM) and that the skew components are zero (M14 = M24 = M34 = 0). You should visualise the matrix like this:

RST Matrix

First, we extract the translation:

vtranslation = (M41, M42, M43)

Then the scaling factors:

sx = √(M112 + M212 + M312)
sy = √(M122 + M222 + M322)
sz = √(M132 + M232 + M332)

The rotation matrix is then the upper-left 3×3 minor, after scaling back to unity.

Mrotation = M;

// Remove translation
Mrotation41 = 0;
Mrotation42 = 0;
Mrotation43 = 0;

// Normalise
Mrotation11 /= sx;
Mrotation21 /= sx;
Mrotation31 /= sx;

Mrotation12 /= sy;
Mrotation22 /= sy;
Mrotation32 /= sy;

Mrotation13 /= sz;
Mrotation23 /= sz;
Mrotation33 /= sz;

DLL injection via CreateRemoteThread

November 15th, 2007 Greg

This isn’t exactly news, but I thought I’d briefly run through the now standard method of injecting a DLL of your choice into an arbitrary process under 32-bit Windows. It will serve as a foundation for the upcoming post on function hooking via DLL injection.

So you have analysed a target program, know how it works and what you’d like to make it do, but there isn’t enough room for an inline patch. Or maybe you need to hook an existing function in order to spy on or modify data being passed back and forth. Perhaps add some functionality or a status window? If any of this sounds familiar then you should consider DLL-based code-injection. It is the cleanest method of injection (if there ever were such a thing) and it offers a lot of scalability and maintainability that a quick-and-dirty inline/diversion patch lacks.

The idea is simple, but very clever. We abuse CreateRemoteThread to call LoadLibrary on a string that was injected by means of WriteProcessMemory. The method hinges on the fact that LoadLibrary takes a single parameter. In eight steps:

  1. Locate the target process in terms of its process-id. Depending on the situation, any of EnumProcesses, CreateProcess, FindWindow and GetWindowThreadProcessId may come in handy.
  2. Acquire a handle to it by calling OpenProcess. This isn’t necessary in certain cases, such as when the target is spawned using CreateProcess, which returns a handle automatically.
  3. Allocate some space in the target process for a string containing the path of the DLL, using VirtualAllocEx. Remember to make enough room if using Unicode strings.
  4. Fill the new buffer out with the path of the DLL by means of a call to WriteProcessMemory.
  5. Call GetProcAddress to get a pointer to LoadLibrary. While there are no guarantees in the Win32 process specification that this function will be in the same place for every process, a little reverse-engineering and common-sense makes it a very safe bet. If the next XP Hotfix were to change the base of kernel32, user32 or ntdll - none of which are relocatable - then a considerable amount of both Microsoft and non-Microsoft code will break and all hell would break loose.
  6. Call CreateRemoteThread on the target process, passing the address of LoadLibrary as the LPTHREAD_START_ROUTINE and the address of the newly initialised string buffer as the parameter. Technically, CreateRemoteThread wasn’t designed to deal with this, but in terms of implementation everything is kosher.
  7. When LoadLibrary returns, the thread terminates with the return-value as its exit code. So if we call GetExitCodeThread, the result will be the base of the DLL in the target process, or NULL if the call failed.
  8. VirtualFreeEx will take care of the now useless string buffer and the process handle should be freed if no more magic needs doing.

This seems like quite a lot of work for such a common operation, so it’s a good idea to code it up in a reusable way. Here’s the implementation as pasted from the DLL-hooking interface I’m working on:

HMODULE DLLInjection::InjectDLL(DWORD process_id) {
    // Open Process
    process_handle = OpenProcess(PROCESS_ALL_ACCESS, false, process_id);
    if (process_handle == 0) return NULL;
 
    // Allocate space for string to contain the DLL Path
    SIZE_T path_length = dll_path.size() + 1;
    void* remote_buffer = VirtualAllocEx(process_handle, NULL, path_length * sizeof(char), MEM_COMMIT, PAGE_READWRITE);
 
    bool success = false;
    if (remote_buffer != NULL) {
        SIZE_T bytes_written = 0;
        WriteProcessMemory(process_handle, remote_buffer, dll_path.c_str(), path_length, &bytes_written);
        if (bytes_written == path_length) {
            DWORD thread_id = 0;
            HMODULE kernel32 = GetModuleHandleA("Kernel32");
            LPTHREAD_START_ROUTINE remote_lla = reinterpret_cast <LPTHREAD_START_ROUTINE> (GetProcAddress(kernel32, "LoadLibraryA"));
            if (remote_lla != NULL) {
                HANDLE thread = CreateRemoteThread(process_handle, NULL, 0, remote_lla, reinterpret_cast <void*> (remote_buffer), 0, &thread_id);
                if (thread != NULL && thread_id != 0) {
                    WaitForSingleObject(thread, 5000);
                    DWORD exit_code = 0;
                    GetExitCodeThread(thread, &exit_code);
                    if (exit_code != 0) {
                        success = true;
                        remote_base = reinterpret_cast <void*> (exit_code);
                    }
                }
            }
        }
        VirtualFreeEx(process_handle, remote_buffer, dll_path.size() + 1, MEM_RELEASE);
    }
 
    if (success) return reinterpret_cast <HMODULE> (remote_base);
    return NULL; // Fail
}

LDR tone-mapping and how to do it properly

November 13th, 2007 Greg

I’m a huge fan of post-processing in games. It seems that no matter what I’m writing, I can’t resist the temptation to install an over-the-top bloom effect and some tone-mapping. And that’s me being conservative. The great thing about tone-mapping is that you can throw it on the end of just about any rendering pipeline and instantly glitz up the visuals, giving it that ‘digitally remastered’ feel.

Tone-Mapping

So what is tone-mapping? Well, it’s a post-processing effect that remaps the render’s colour-dynamics to change the overall appearance of the game. Some of the more common tone-mapping operations are contrast & brightness, saturation and HDR exposure. HDR tone-mapping is an art unto itself and it can only be used for HDR pipelines (with floating-point render-targets and HDR textures), so I’ll restrict the conversation to the more universal LDR tone-mapping.

The Conjugate Transform

If you plan on doing anything interesting in a tone-mapping pass, then it’s rather necessary, for the sakes of performance, readability and maintainability, to convert to a more suitable colour-space than RGB. The first such space that springs to mind is HSL, and indeed tone-mapping in HSL is like a gentle walk in the park, but it’s wise to look a little further afield to YCC. But why YCC? Sure, it does offer a luma component for brightness & contrast mapping, but the saturation is tied up in the two chroma components. Granted, this is a bad thing, but it’s not nearly as bad as the cost of a full RGB->HSL->RGB conversion.

The Problem With HSL

I spent a fair while trying to optimise this HSL-detour code in HLSL, hoping that I could make it viable for small shaders, but came out rather disappointed. Despite the availability of vector SIMD instructions, the piecewise-linear nature of the transformation demands a worryingly large number of conditional branches, and unless you have the luxury of Shader Model 4’s true branching, this amounts to a horror story of register-juggling and lerp operations. I didn’t try too hard, but believe it’s impossible to complete the transformation-and-back through HSL in under 100 ps_3_0 operations, which immediately rules out the possibility of assembling on a Shader Model 2 target platform.

YCC To The Rescue

Contrast this with the simplicity of the truly linear RGB->YCC->RGB transformation. If there’s one thing that the GPU does best, it’s vector-matrix multiplication, and that’s exactly what this boils down to:

float4x4 RGBToYCC = 
{ 0.299,  0.587,  0.114,  0.000,
  0.701, -0.587, -0.114,  0.000,
 -0.299, -0.587,  0.886,  0.000,
  0.000,  0.000,  0.000,  1.000};
 
float4x4 YCCToRGB = 
{ 1.000,  1.000,  0.000,  0.000,
  1.000, -0.509, -0.194,  0.000,
  1.000,  0.000,  1.000,  0.000,
  0.000,  0.000,  0.000,  1.000};
 
float4 PS_LDRToneMap(float4 tex_coord : TEXCOORD) : COLOR
{
    float4 RGBA = tex2D(linear_sampler, tex_coord);
    float4 YCCA = mul(RGBToYCC, RGBA);
 
    // Work goes here
 
    RGBA = mul(YCCToRGB, YCCA);
    return saturate(RGBA);
}

This assembles to a handsome 9 instructions, leaving plenty of room even with the arcane ps_1_4’s instruction limit.

The Prize

My current project makes use of this code to ramp the contrast and saturation up and down, according to the scene. The code is simple, and the results rather dramatic.

// Contrast
YCCA.x -= contrast_midpoint;
YCCA.x *= contrast_gain;
YCCA.x += contrast_midpoint;
 
// Chroma
YCCA.y -= chroma_red_midpoint;
YCCA.y *= chroma_red_gain;
YCCA.y += chroma_red_midpoint;
 
YCCA.z -= chroma_blue_midpoint;
YCCA.z *= chroma_blue_gain;
YCCA.z += chroma_blue_midpoint;

LDR Tone-Mapping

How I cracked the iTunes 7 DRM, Pt II

November 11th, 2007 Greg

So I had the motivation; it was time for action. The first step in undertaking such a large project is to research: Research like a maniac until Google dries up. It took me three days (on top of work) until I was happy that there was no more pre-invented wheel to take advantage of. The fruits of my labour boiled down to two busy flowcharts, each occupying a full page, which I kept pinned at head-level on the notice-board next to me for the following six weeks. Unfortunately, they seem to have been lost in the process of moving back from university, which isn’t surprising considering how much paper is ‘archived’ after finals.

Just to make sure everyone’s on the same page, here’s a quick overview of some of my findings:

  • The iTunes Store’s music is distributed exclusively under their ‘m4p’ file extension, as opposed to ‘m4a’ which is the default for music encoded by iTunes. Presumably, ‘a’ stands for ‘audio’ and ‘p’ for ‘protected audio’.
  • There is nothing special about an m4a file other than the extension. It is just a common or garden MP4 file with a single AAC audio stream.
  • MP4 files consist of a nested structure of ‘atoms’, which are variable-sized general-purpose binary data structures whose contents are identified by a four-character string. There was very little available information about the atomic structure of m4p files, so I had to throw together a C# program to display the tree of identifiers (96kB exe download).
  • Deep inside this tree-structure lies the ‘mdat’ atom containing the AAC audio stream, which occupies the majority of the file.
  • The only consistent differences between an ‘m4a’ and an ‘m4p’ are:
    • The AAC stream is encrypted for DRMed files, using a proprietary variant of the Rijndael cipher.
    • An ‘iods’ (Initial Object Descriptor) atom is present only for protected files (at moov/mvhd/iods). This turns out to be insignificant for our purposes, but from what I gather it is generated by the software that installs the protection scheme, to store some information about the original file.
    • The seemingly innocent ‘udta’ (User Data) atom contains a rogue null dword to trick most atom viewers into thinking it has no contents.
    • The DRMed ‘moov/udta/meta/ilst’ atom actually contains a whole new set of undocumented atoms that tell iTunes all about your iTunes Store account, encryption keys and so on.
New udta atoms

The first hurdle was convincing iTunes to run under a debugger. Many released programs don’t like the idea of being debugged, ’cause it almost always means bad news. Fortunately, iTunes didn’t put up much of a fight and after NOPing a couple of calls to IsDebuggerPresent, iTunes and OllyDbg became like peas and carrots.

In the absence of any meaningful variable or function names (other than imported DLL functions), my first thought was to trace backwards from the opening of the media file towards the decryption routine. From here, I could analyse the algorithm and attempt to rewrite it to decrypt the files on disc. So I started out with a breakpoint on CreateFileW, to catch the point where iTunes loads in the ‘m4p’ file, waited for kernel32.dll to do its thing, then set a conditional breakpoint on ReadFileExW (the extended version is used because the file is read asynchronously). This landed me immediately in QuickTime’s audio-playback engine. I spent a while flicking back-and-forth between QuickTime and iTunes code before I found a very loop-heavy function full of SSE instructions. It could only be the decryption routine or, more likely, the AAC decoder. After an hour or so of manual stepping and comparing run traces of m4p and m4a playback, I determined that it was indeed the AAC decoder, and began to get a good feel for the intricate details of the playback engine.

This is the part where I omit a day’s worth of results, because the minute I realised that what I’d been analysing for what felt like forever was actually just a tiny fraction of the system I’d set out to understand, I fled like a little girl. This monster was clearly a lot more complex than I had initially anticipated. So I returned to the drawing board, not feeling defeated, but optimistically empowered. This DRM wasn’t going to fall very easily. I simply didn’t have the man-power or insight for the usual divide-and-conquer approach (nobody knows how DVD Jon does it - he’s a glitch in the matrix). If I was ever to succeed then I’d need to work smarter, not harder. So that’s exactly what I did, but not before taking a day off.

Compatible X-file HLSL-based vertex-blending with D3DX

November 9th, 2007 Greg

On the whole, D3DX does a great job of making our lives easier, us Direct3D 9 programmers. But one topic that has generated a lot of confusion yet very little documentation is the correct usage of the BLENDINDICES shader semantic.

If you’re having trouble getting your CPU and GPU to communicate blend-indices correctly, the first thing to do is make sure that your source data is valid. If you’re using a custom mesh-loading routine then you’re on your own, but certainly under D3DXLoadMeshHierarchyFromX you can save yourself a lot of potential grief by prototyping with a reliable X-file. Support for X-file exporting is very shaky for most 3D modelling suites, but the SDK’s tiny.x sample is as close as you’ll get to a standard model. Once Tiny is happily running around in her fighter-pilot’s uniform you can start thinking about trying out your own models.

Nobody seems to be sure just what went wrong when the late ARB drafted up the usage semantics of blending parameters, but many current video cards lack hardware support for the UBYTE data type needed to store the indices. For this reason, developers have found themselves hammering unsigned-byte-quadruplets into the shape of D3DCOLORs, lying about the data content and praying that the vertex pipeline will have magically transformed the output into something that can be jimmied back into a tuple of UBYTEs. As far as I can see, this is the mother of all DirectX hacks, but it also seems to be the universal standard. That’s the only reason I’ll sleep at night after posting this.

After successfully calling ID3DXSkinInfo::ConvertToIndexBlendedMesh, the blend-index data is all present and correct. The challenge is to pipe it to the shader without misinterpretation. For that, I found it necessary to set all index data in the vertex declaration to be passed as D3DCOLOR data (DWORDS in disguise). By the way, if you are still using FVFs for something as finicky as GPU skinning then you don’t deserve any help: bite the bullet and write out those overly verbose, but oh-so-flexible vertex declarations.

// Fix UBYTE4 Support
D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
skinned_mesh->GetDeclaration(decl);
{
    int i = 0;
    while (decl[i].Method != 0xFF)
    {
        if (decl[i].Usage == D3DDECLUSAGE_BLENDINDICES)
        {
            decl[i].Type = D3DDECLTYPE_D3DCOLOR;
            break;
        }
        ++i;
    }
}
skinned_mesh->UpdateSemantics(decl);

This takes care of the program code. All that remains is to interpret the data accordingly in the shader. For this, Microsoft generously provided us with the D3DCOLORtoUBYTE4 macro. HLSL (as of SM3) doesn’t have true integer support, let alone unsigned byte support, so we use their emulated int4 vector.

VS_OUTPUT VS_SkeletalBlend
(float3 pos           : POSITION0,
 float1 blend_weight  : BLENDWEIGHT0,
 float4 blend_indices : BLENDINDICES0,
 float3 normal        : NORMAL0,
 float2 tex_coord     : TEXCOORD0)
{
    int4 indices = D3DCOLORtoUBYTE4(blend_indices);
 
    float weight0 = blend_weight;
    float weight1 = 1 - weight0;
    int ind0 = indices.x;
    int ind1 = indices.y;
 
    // ...
}

Notice that the semantic here is BLENDINDICES, even though the vertex declaration says D3DCOLOR. Note further that the type becomes, somewhat wastefully, a float4 as all colour values are passed as such. The sample here is for a two-weights-per-vertex animation, but it’s easy enough to scale this up to four. If you need more than four weights then you need to have a word/fight with your artist, but the idea is the same, only you pass another parameter just like the first. Now I’m not certain that this is the best configuration - it certainly looks like a horrid mess - but it’s the only combination I know to work, after hours and hours of painful Googling. Suggestions for improvement are welcome.

How I cracked the iTunes 7 DRM, Pt I

November 7th, 2007 Greg

Of the many programs I’ve taken the time to probe and dissect, none has instilled me with such a love-hate sensation as iTunes. My favoured media player by some distance, it is beautiful, easy to use, cleanly written, reliable, and all the rest. But with the iTunes (Music) Store came iDRM, as DVD Jon famously termed it. Apple make it pretty clear that they don’t like DRM any more than the users do, but that their hands are tied, and I respect that. Why then do they insist on doing such a bloody good job of making it very difficult to crack? Everybody knows that it will be broken sooner or later, so why go to all the effort - and it is a lot of effort - to choose ‘later’?

After months of sitting quietly while Apple’s DRM remained unbroken, with my previous encounters with iTunes encryption in mind (maybe I’ll write about them some day) I felt compelled, maybe even prepared, to take matters into my own hands. This was the birth of DisaRM, my home-grown iDRM-removal tool.

DisaRM Screenshot

Why have you never heard of it? Well, call me a selfish coward but I didn’t want the attention or bother of being responsible for maintaining such a keenly sought taboo. And why didn’t I release the source code? Partly because my method was so awfully hacky, as you’ll see, that most programmers would run a mile. As it happened, QTFairUse6 was released mere days after I produced a working prototype (and well before DisaRM was ready for human consumption) so the onus was lifted.

For the sake of education, and self-indulgence, I’ll take a few posts to describe the story of DisaRM, gory details included.

The SxS Headache

November 5th, 2007 Greg

DLL Hell, SxS libraries, manifest files, ‘The application configuration is incorrect’.
Oh my!

It seems that every C++ blogger and his dog is talking about the side-by-side hell that Microsoft have cooked up, but after having a hard enough time finding answers myself, I figured that it’s best to be part of the solution. If you’ve stumbled upon this post from a Google search, it’s likely that you’re one of the many poor souls who has no idea why their program refuses to run on any computer other than the one it was compiled on.

[Side-by-side error message]

The necessity for all of this incompatibility is clear when you consider how many different versions of the Windows kernel interfaces are floating around, but it’s still a pain for those of us who just want to compile a program for personal use. The most correct way to address the situation is to package your application with the MSVC++ runtime library. This way, the executable can’t be used without running an installer that ensures all the appropriate DLLs are present. But for most of us this is unnecessary bloat, and VC++EE doesn’t even offer a means of producing such a setup package.

There is a lot of talk about determining the dependencies with a PE-viewer or the dependency-walker, copying the appropriate SxS DLLs from Windows/WinSxS/ to a carefully-crafted directory hierarchy, and manually editing an XML manifest file to tell the OS how to find them. This is error-prone, beginner-unfriendly and seems to be causing more confusion than good.

But the solution that Microsoft have kept quiet is somewhat cleaner. If you configure the Visual C++ IDE to statically link against the multithreaded libraries (Project | Properties | Configuration Properties | C++ | Code Generation | Runtime Library := Multithreaded [Debug]) then the program will never have any such unpredictable external dependencies and so avoids the problem altogether. This will of course mean that you have an extra 150kB of PE to carry around, which may be undesirable for widely-distributed DLLs, but for small-time projects it’s a worthwhile trade.

Vaughn Of The Dead Pt II: Meet Vaughn

November 5th, 2007 Greg

There’s something uncomfortable about setting up a machine to be as insecure as possible, but that’s what I’ve been doing today. Not being the sort to have sacrificial computers lying around, I settled for a virtual machine. So after a quick and easy installation of the VMare Workstation trial, I got straight to setting up Vaughn, my computer-within-a-computer.

The oldest non-biblical version of Windows I have is XP Pro SP1. While it isn’t that old, it’s still vulnerable to the RPC exploit responsible for the 2003 Blaster Worm epidemic, and is still one of the most popular avenues for the black-hat hacker. So after installing the OS, automatic updates were turned off and the bridged network connection was added to my router’s demilitarised zone, to make sure that Vaughn was fully exposed to the internet. XP SP1 didn’t distribute with a firewall, so that’s not a problem. Some essential pieces of software were installed including my full RCE toolkit and the excellent Wireshark packet analyser. Even though no outbound connections are made on the VM’s part, simply being on an active LAN is enough to invite some network traffic, so I had to set up a filter to remove the unrelated packets picked up by Wireshark. So as to prevent Vaughn participating in anything he shouldn’t, I installed an upstream-bandwith throttler and configured the connection to filter any known DoS traffic.

So now we wait, for as long as it takes. Maybe forever. Or at least until my VMware trial expires.

Vaughn Of The Dead Pt I: The Plan

November 4th, 2007 Greg

While universally troublesome and inherently evil, there’s something exciting, even sexy, about zombie networks. The idea that somewhere out there is a global army of dormant computers, their owners blissfully unaware, which could spring to life at the whim of a bedroom hacker and coordinate DDoS attacks to take down a country’s internet presence, distribute unimaginable quantities of spam, or crack a 56-bit DES key in minutes – it’s the stuff of science fiction. Only it isn’t, and the Storm botnet is testament.

Many of us grey-hat hackers fantasise about controlling such power but don’t have the time, skills, lawyers or lack of moral-fibre to do anything about it. So what’s the next best thing? Well that would be to play with somebody else’s illegal toy.

The first step is to get hold of the worm. You’d think it would be easy enough to get hold of a program whose primary goal is to spread to the ends of the earth, but it’s actually trickier than you might imagine to come by a sample or network that isn’t already tainted by the holy paws of the antivirus companies of the world. So rather than giving myself a headache, I plan to let the worms do the work and wait for them to come to me.

In the coming days, I’ll be setting up a honeypot and crossing my fingers. I have promised to analyse and, if necessary, publicly humiliate any interesting malware that comes my way. With a little skill and a lot of luck, I may even find myself to be the proud owner of a zombie, albeit a neutered one.