1. [WinInternals] Reverse Engineering of kdbgctrl - How are builded Kernel Triage Dumps


    In this little blog post I'm going to reverse kdbgctrl.exe an handy tool delivered with Windows Debugging Tools kit (windbg package). This tool has the handy functionality to allow Kernel Triage Dumps building, also from a non /DEBUG bootted machine.

    As written before, from nynaeve, Triage Dump writing make able the kernel to create small dump files which contains the basical and usual informations of a Dump, like processes with associated threads and relative stacks.

    There is not many documentation about the usage of kdbgctrl, we have only a basical:
    kdbgctrl -td pid file

    Let's now see how internally works kdbgctrl.exe; why this?..curiosity and the potentiality to know which functions are used and became able to rewrite it, and also (as asked by some people) to show a subset of considerations that make you able to fastly and effectively reverse the functionality of an application.

    What we have is an application that takes two arguments, one of them is a filename, so after disassembling it we can immediately search for File Management Operations, like CreateFile and WriteFile, at this point we can trace back to the origins, locating the requestor and consecutively identify the functions that provide data dumped into file.

    .text:0100340F loc_100340F:                            ; CODE XREF: sub_1003310+BF j
    .text:0100340F                 push    0               ; hTemplateFile
    .text:01003411                 push    80h             ; dwFlagsAndAttributes
    .text:01003416                 push    2               ; dwCreationDisposition
    .text:01003418                 push    0               ; lpSecurityAttributes
    .text:0100341A                 push    0               ; dwShareMode
    .text:0100341C                 push    40000000h       ; dwDesiredAccess
    .text:01003421                 mov     ecx, [ebp+lpFileName]
    .text:01003424                 push    ecx             ; lpFileName
    .text:01003425                 call    ds:CreateFileA
    the first line denotes a Cross Reference, so let's follow it:

    .text:010033AE loc_10033AE:                            ; CODE XREF: sub_1003310+84 j
    .text:010033AE                 lea     eax, [ebp+nNumberOfBytesToWrite]
    .text:010033B1                 push    eax
    .text:010033B2                 mov     ecx, [ebp+dwSize]
    .text:010033B5                 push    ecx
    .text:010033B6                 mov     edx, [ebp+lpAddress]
    .text:010033B9                 push    edx
    .text:010033BA                 push    24h
    .text:010033BC                 lea     eax, [ebp+var_44]
    .text:010033BF                 push    eax
    .text:010033C0                 push    1Dh
    .text:010033C2                 call    ds:NtSystemDebugControl
    This is the heart of kdbgctrl algorithm, the Triage Dump is obtained by calling NtSystemDebugControl, we have now to uncover its parameters to be able to reproduce the code.
    IN PVOID InputBuffer OPTIONAL,
    IN ULONG InputBufferLength,
    OUT PVOID OutputBuffer OPTIONAL,
    IN ULONG OutputBufferLength,
    OUT PULONG ReturnLength OPTIONAL );
    In our case SYSDBG_COMMAND has the value 1D, with a little research we can discover that this value belongs to SysDbgGetTriageDump, and immediately after the involved struct

    typedef struct _SYSDBG_TRIAGE_DUMP
        ULONG Flags;
        ULONG BugCheckCode;
        ULONG_PTR BugCheckParam1;
        ULONG_PTR BugCheckParam2;
        ULONG_PTR BugCheckParam3;
        ULONG_PTR BugCheckParam4;
        ULONG ProcessHandles;
        ULONG ThreadHandles;
        PHANDLE Handles;
    Immediately before NtSystemDebugControl we meet:

    .text:0100336C                 mov     [ebp+var_40], 69696969h
    .text:01003373                 mov     [ebp+dwSize], 400000h
    .text:0100337A                 push    4               ; flProtect
    .text:0100337C                 push    1000h           ; flAllocationType
    .text:01003381                 mov     edx, [ebp+dwSize]
    .text:01003384                 push    edx             ; dwSize
    .text:01003385                 push    0               ; lpAddress
    .text:01003387                 call    ds:VirtualAlloc
    69696969 belongs to the tipical BugCheck of Triage Dumps. A bit upper we have

    .text:0100335D                 push    ecx
    .text:0100335E                 call    sub_1002EB0
    .text:01003363                 test    eax, eax
    .text:01003365                 jz      short loc_100336C ;Prosecute with Dumping Process
    .text:01003367                 jmp     loc_100357C    ;Jump Out
    Let's see what happens inside call sub_1002EB0

    .text:01002EE3                 push    offset aDbgeng_dll ; "dbgeng.dll"
    .text:01002EE8                 call    ds:LoadLibraryA
    .text:01002F45                 push    offset aDebugcreate ; "DebugCreate"
    .text:01002F4A                 mov     edx, [ebp+arg_8]
    .text:01002F4D                 mov     eax, [edx]
    .text:01002F4F                 push    eax             ; hModule
    .text:01002F50                 call    ds:GetProcAddress
    The DebugCreate function creates a new client object and returns an interface pointer to it, the parameters passed to DebugCreate are the same as those passed to IUnknown::QueryInterface, and they are treated the same way.

    .text:0100307A                 call    sub_1004D90
    .text:0100307F                 push    eax
    .text:01003080                 push    offset aAttachprocessF ; "AttachProcess failed, %s\n"
    .text:01003085                 call    ds:printf
    kdbgctrl attempts to a Debug Attach by using the pid inserted by user.

    .text:010030BA                 call    sub_1004D90
    .text:010030BF                 push    eax
    .text:010030C0                 push    offset aWaitforeventFa ; "WaitForEvent failed, %s\n"
    .text:010030C5                 call    ds:printf
    and waits for events.

    .text:010030FA                 call    sub_1004D90
    .text:010030FF                 push    eax
    .text:01003100                 push    offset aGetnumberthrea ; "GetNumberThreads failed, %s\n"
    .text:01003105                 call    ds:printf
    Retrieve the number of Threads, this value is necessary to define the limits of a cycle that will perform a per thread scan.

    .text:010031AB                 call    sub_1004D90
    .text:010031B0                 push    eax
    .text:010031B1                 push    offset aGetthreadidsby ; "GetThreadIdsByIndex failed, %s\n"
    .text:010031B6                 call    ds:printf
    .text:010031BC                 add     esp, 8
    .text:010031BF                 jmp     loc_1003252
    GetThreadIdsByIndex belongs (Like GetNumberThreads) to the interface IDebugSystemObjects, the GetThreadIdsByIndex method returns the engine and system thread IDs for the specified threads in the current process.
    .text:010031E8                 call    sub_1004D90
    .text:010031ED                 push    eax
    .text:010031EE                 push    offset aSetcurrentthre ; "SetCurrentThreadId failed, %s\n"
    .text:010031F3                 call    ds:printf
    .text:010031F9                 add     esp, 8
    .text:010031FC                 jmp     short loc_1003252
    The currently indexed thread, became the Current Thread, at this point we can know the thread handle, by calling GetCurrentThreadHandle.

    This enumeration routine provides all informations that will be stored into the Triage Dump.

    Should be now clear how is builded a Triage Dump, just an hint if you want to uncover other kdbgctrl functionalities, as you have seen the core function is NtSystemDebugControl, so easly list all xRefs of this function.

    See you to the next post..
    Giuseppe 'Evilcry' Bonfa
  2. Debugging the Debugger - Reversing kldbgdrv.sys and Potential Usages

    After various articles on malware analysis I decided to talk about a little different topic, due to the fact that I'm involved into Kernel Mode Coding the Windows Internals Research become a truly important aspect of my Research. As the title suggests, this time I'm going to Study and Reverse a particular component used by the Windows Debugging System, more precisely a Device Driver involved into Local Kernel Debugging.

    Not many people is aware that is possible to perform Local Kernel Debugging, one of the most used Debugging Configurations is the Remote Debugging. Local Kernel Debugging can offer many important vantages, like valuable informations on the Status of the Kernel and Inspect Kmode Components. LKD (Local Kernel Debugging) can be acheived by booting in Debug Mode, both kd and windbg fully supports LKD.

    The essential question now is, How the Debugging Engine, let's consider for example Windbg, is able to obtain informations about the kernel by running from usermode?

    The reply to this question not only will uncover the problem itself but also will open new interesting questions and possibilities, such as:

    #1 - "It's possible to develop an application that can use the same
    technology ?"

    #2 - "How to access the involved components and what are parameter to
    have access?"

    To begin the study of this problem, we have in first instance to reproduce the environement necessary to start a Local Debugging Session.

    I've used for these tests Windows 7 32-Bits Ultimate Edition and Windbg.

    First step is to enable debug mode by running:

    bcdedit -debug on then reboot.

    At this point we have literally to debug our debugger to be able to reveal the mechanism and component involved in communication between the Debug Engine and Kernel.

    In the past Windows Editions, the function used was NtSystemDebugControl, but from Windows Vista to Higher Versions this function is not immediately available.

    To trace windbg activities I've used a great tool for professional API Tracing, called Blade API Monitor.

    The hypothesis was, if windbg runs at usermode and accesses a kernel component it's obvious that will be used a Device Driver, by assuming true this statement, every application that deals directly with Device Drivers will use:

    * CreateFile -> For Driver Opening
    * ReadFile / WriteFile -> Device Driver Communication
    * DeviceIoControl -> Data exchange between Driver and umode application
    * NtSystemDebugControl

    After setting the proper filter for these functions, let's run a Local Kernel Debugging Session and watch the results from API Monitor.

    When debugger is loaded, we can launch some command, like:


    From API Log emerges an important result, we have two threads:

    #- First Thread

    CreateFileW(wchar_t* lpFileName = C:\Windows\Fonts\staticcache.dat,...)

    #- Second Thread

    CreateFileW( wchar_t* lpFileName = C:\Windows\system32\kldbgdrv.sys )
    return value -> void* return = 0x00000128

    WriteFile(void* hFile = 0x00000128, .., unsigned long nNumberOfBytesToWrite = 0x000031F0 )

    CreateFileW(wchar_t* lpFileName = \\.\kldbgdrv)
    return value -> void* return = 0x00000170

    DeviceIoControl(void* hDevice = 0x00000170)
    IOCTL -> unsigned long dwIoControlCode = 0x0022C007
    As you can see, from the second thread we obtain a valuable amount of informations.

    WinDbg creates a driver called kldbgdrv.sys placed in %\system32\ this file is 0x31F0 long.

    Successively this driver is openened and windbg starts to send IOCTL to this driver.

    The IO Control Code used is 0x0022C007.

    When debugging session finishes, kldbgdrv.sys it's deleted.

    To reverse this driver we have obviously to dump it, so the first operation is to locate where is placed and successively carve out this.

    The most probable location where can be located are the resources of windbg or kd executables, so let's explore their PE.

    Between resources of windbg.exe we can see that the last one called "17476" which contains another subdir called "30583" by opening also this last directory finally appears our wldbgdrv.sys (can be easly detected by watching between strings)

    From the starting address of this resource if we add the len of bytes ( nNumberOfBytesToWrite = 0x000031F0) we can easly into a new file kldbgdrv.sys

    Now let's reverse this driver.

    INIT:00010D1F push offset aKdsystemdebugc ; "KdSystemDebugControl"
    INIT:00010D24 lea eax, [ebp+DestinationString]
    INIT:00010D27 push eax ; DestinationString
    INIT:00010D28 call ds:RtlInitUnicodeString
    INIT:00010D2E lea ecx, [ebp+DestinationString]
    INIT:00010D31 push ecx ; SystemRoutineName
    INIT:00010D32 call ds:MmGetSystemRoutineAddress
    INIT:00010D38 mov [ebp+var_1C], eax
    INIT:00010D3B cmp [ebp+var_1C], 0
    INIT:00010D3F jnz short loc_10D4B
    INIT:00010D46 jmp loc_10DF5

    this is a really interesting piece of code, here the driver attempts to obtain the Routine Address of the function KdSystemDebugControl()

    INIT:00010D4B mov edx, [ebp+DriverObject]
    INIT:00010D4E mov dword ptr [edx+34h], offset sub_10A10 ;DriverUnload
    INIT:00010D55 mov eax, [ebp+DriverObject]
    INIT:00010D58 mov dword ptr [eax+38h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D5F mov ecx, [ebp+DriverObject]
    INIT:00010D62 mov dword ptr [ecx+40h], offset sub_10A50 ;DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50
    INIT:00010D69 mov edx, [ebp+DriverObject]
    INIT:00010D6C mov dword ptr [edx+70h], offset sub_10A80 ;DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80
    INIT:00010D73 push offset aDeviceKldbgdrv ; "\\Device\\kldbgdrv"
    INIT:00010D78 lea eax, [ebp+DeviceName]
    INIT:00010D7B push eax ; DestinationString
    INIT:00010D7C call ds:RtlInitUnicodeString
    INIT:00010D96 call ds:IoCreateDevice

    Here the device it's created \\Device\\kldbgdrv and

    There are also four MajorFunctions associations:

    DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_10A10;
    DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_10A50; // IofCompleteRequest(Irp, 0)
    DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_10A80; // Suddenly Reversed
    Let's check the latest Dispatch Routine:

    PAGE:00010AEE push edx
    PAGE:00010AEF push eax ; PrivilegeValue
    PAGE:00010AF0 call ds:SeSinglePrivilegeCheck
    PAGE:00010AF6 movzx ecx, al
    PAGE:00010AF9 test ecx, ecx
    PAGE:00010AFB jnz short loc_10B09
    PAGE:00010AFD mov [ebp+var_3C], STATUS_ACCESS_DENIED
    PAGE:00010B04 jmp loc_10C5B
    PAGE:00010B09 mov [ebp+var_4], 0
    PAGE:00010B10 mov edx, [ebp+var_30]
    PAGE:00010B13 mov [ebp+var_48], edx
    PAGE:00010B16 cmp [ebp+var_48], 22C007h ; IOCTL = 22C007h
    PAGE:00010B1D jz short loc_10B24
    PAGE:00010B1F jmp loc_10C2B

    When the IOCTL = 22C007h it's sent the first operation is to check if the action has the proper privileges "SeSinglePrivilegeCheck", successively this dispatch routine validates and sanitizes parameters sent with the IOCTL, by using MmUserProbeAddress and ProbeForWrite.

    Finally we can say that kldbgdrv.sys works as wrapper for KdSystemDebugControl.

    This function belongs to NtSystemDebugControl but can be accessed only at kernel mode.

    Here it's prototipe:

    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID OutputBuffer,
    ULONG OutputBufferLength,
    PULONG ReturnLength,
    KPROCESSOR_MODE PreviousMode
    _SYSDBG_COMMAND it's an enum, let's suppose we want SysDbgReadVirtual we have the corresponding struct:

    typedef struct _SYSDBG_VIRTUAL
    PVOID Address;
    PVOID Buffer;
    ULONG Request;
    At this point we have all elements to use with success kldbgdrv.sys, that means the possibility to have access to the kernel ...
  3. Rootkit Agent.adah Anatomy and Executables Carving via Cryptoanalytical Approach

    Today I'm going to expose how to perform the preliminar analysis of a Rootkit Application both via the classical Reverse Engineering approach and Crytpanalysis one.

    We will inspect a recent threat commonly detected as Rootkit Agent.adah, this rootkit is delivered in the usual form of executable (.exe) via Compromised or Malicious Websites.

    Usually the main executable is delivered in packed/compressed form and presents other executables embedded as resources, in other cases we can have blocks of encrypted data that will be decrypted on fly by the main executable.

    In the first step we are going to see how is structured the executable. CFF reveals us that the application is packed with UPX v3.0;

    Due to the nature of UPX, that is essentially a compressor, we will see a pattern almost constant, stabilized at high levels of entropy. Here a graph plot

    As should be evident, the internal structure and presence of embedded data is protected cause the constancy of the Entropy along the executable. In other words in this case the contribution from knowledge of entropy does not help us to have additional information. We have to perform more specific inspections, this time by using Floating Frequency Analysis.

    Let's spend some word about what mean Floating Frequency..

    The floating frequency of a document is a characteristic of its local information content at individual points in the document. The floating frequency specifies how many different characters are to be found in any given 64-character long segment of the document. The function considers sequences of text in the active window that are 64 characters long and counts how many different characters are to be found in this "window". The "window" is then shifted one character to the right and the calculation is repeated. This procedure results in a summary of the document in which it is possible to identify the places with high and low information density. A document of length n > 64 bytes has n-63 such index numbers in its characteristics.

    This is how work, implicitly should be clear enough how to interpret a Floating Frequency Graph,
    high values which deviate markedly from the background in an executable suggest that encrypted data or even cryptographic keys will be found in those places.

    Let's inspect the first graph:

    As you can see, with floating frequency we are now able to distinguish the PE Header that presents a low Differences Ratio, suddenly after the PE Header we can see UPX at work, plot is constant and uniform, near the end happens an interesting thing, a marked decrease of frequency that remains stable and uniform for a certain offset range, at the end of this isolated behaviour we register another abrupt decrease, this is the end of PE and obviously of the file.

    The isolated behaviour is truly interesting, the offset of this 'object' is placed in .rsrc section and presents a strong entropy due the evident density of Floating Freq. plot. A good compression algo introduces a significative increase of entropy, but if the block has already an high entropy this increase obviously cannot happen.We may think that the resource is compressed/encrypted. For example we could have another packed exectable.

    After this preliminary inspection we unpack the main malicious executable and inspect in the same way the unpacked one.

    Here the Entropy Plot of unpacked sample:

    As you can the, now the situation is different, emerges the evidence of PE Header, after a normal ammount of entropy, globally lower that the previous graph, a central drop caused by Zero Padding for PE Alignment, sucessively an increase long a defined amount of bytes (a block) and suddenly after an evident increase of entropy that reaches the RED Level. This mean that our previous observations on floating frequency plot was correct, here the 'object' that certainly is packed/compressed. Finally we have a classical slow down caused by the intrinsic structure of PE Format.

    Again let's perform the Floating Frequency inspection of the unpacked executable, here how changes the graph:

    Again Floating Frequency reveals us more details, or better (in this case) highlights better the structure of the whole executable plus the conformations of the two objects. If you pay attention to the first one, you can see that this corpse is truly similar to the global look of the unpacked executable, in other words we can state that the first object is effectively another merged executable!
    The second one is certainly a compressed object, the reason is clear just lookup the previous explaintions.

    Now let's see practically the whole body of our unpacked executable, from a classical Reverse Engineering point of view. We said that the two objects are placed into .rsrc section, let's look with Great CFF (I love this Tool ) if this is true.

    Bang! correct, the two merged resources are definitely two executables!
    The first one is a clean .sys, this is clear due to the presence of INIT in the PE Header.
    Also the second resource corresponds to our predictions, we have an UPX packed executable.

    Now should be trivial to carve these two executables, just locate the starting offset and by delimiting with Block Start/End function of CFF we obtain the executable size that added to the starting offset give us the final offset where to cut.

    The Block End corresponds obviously with the end of first/second resource.

    The .sys is the core file of our rootkit, I'll reverse it in a future post, the second executable, when unpacked become clear that is a DLL, if we take a look to some function name for exampe this:

    _NF_STATUS __cdecl nf_addRule(struct _NF_RULE *)

    became clear that this DLL acts as Network Filter by using NetFilterSDK ( http://netfiltersdk.com/ )

    But this is matter of future blog post.

    Hope you enjoyed this little paper

    Giuseppe 'Evilcry' Bonfa'

    Updated January 30th, 2010 at 09:17 by evilcry

  4. Advanced Signature Writing via FuzzyHashing

    Hi there,

    In this period I'm heavy working on Signature Generation for big malware families, this mean that there is a large amount of binaries to be checked for Static Patterns recurrences, you should understand that this work can't be done by hand on families of 400+k number of samples, and hashing would not help, this because Hash Algorithms respects the Avalanche Effect via its most famous generalization the SAC ( Strict Avalanche Criterion ), this mean that, this property it is satisfied if, whenever a single input bit is complemented, each of the output bits changes with a probability of one half.

    In other words a minimum little change will deeply change the hash result and we can't come back to similarities, so we need a technology that does not respect the SAC, also in this case the wonderful cryptography help us

    We have the CTPH that mean Context Triggered Piecewise Hashes, called also Fuzzy Hashes, this will help us to match inputs that have homologies like sequences of identical bytes in the same order.

    Here an interesting paper about CTPH Identifying almost identical files using context triggered piecewise hashing


    and here an open source implementation of fuzzyhashing called DeepToad


    Giuseppe 'Evilcry' Bonfa
  5. DNAScan Malicious Network Activity Reverse Engineering


    This is a paper splitted into two episodes, the first two can be readed here


    Here the Third Part.

    In this blog post we will investigate deeply the effective functionalities of DNAScan,
    that can be seen as a set of Threads that accomplish different networking functionalities like:

    • * Server Functionalities
    • * Client Functionalities
    • * Malicious File Exchange
    • * Generic Backdoor

    Let's start from the beginning of network functionalities setup, initially from the main thread is called WSAStartup used to initiate the Winsock DLL, successively is called a classical socket() and immediately after WSAIoctl

    0040A0EE PUSH 2600
    0040A0F3 PUSH EAX
    0040A0F4 PUSH EBX
    0040A0F5 PUSH EBX
    0040A0F6 PUSH 4004747F
    0040A0FB PUSH ESI
    0040A0FC CALL DWORD PTR DS:[41526C];WSAIoctl

    The WSAIoctl function controls the mode of a socket, works like DeviceIoControl so we have a suite of IO Control Codes, in our case the Control Code is 4004747F that corresponds to SIO_GET_INTERFACE_LIST

    Returns a list of configured IP interfaces and their parameters as an array of INTERFACE_INFO structures. After setting socket options and binding we have another WSAIoctl this time with code 98000001 in this way the socket normal working parameters are modified, indeed 98000001 corresponds to SIO_RVALL that enables a socket to receive all IP packets on the network, to use this application need to be in RAW mode using IP protocol and bound to a specific local adapter. Finished this the first thread is created:

    0040A089 PUSH EAX
    0040A08A PUSH ESI
    0040A08B PUSH EDI
    0040A08C PUSH OFFSET srcdll.00409FCD; Look here to know what thread does
    0040A091 PUSH ESI
    0040A092 PUSH ESI
    0040A093 CALL DWORD PTR DS:[415130]

    after opening this thread the first socket is closed. Now the next important function called is SHGetFolderPath witch sets as folders \user\cookies, finally execution jumps to a secondary thread that contains a recvfrom

    00409F89 PUSH EDI
    00409F8A PUSH EDI
    00409F8B PUSH EDI
    00409F8C PUSH 4000
    00409F91 PUSH ESI
    00409F92 PUSH DWORD PTR SS:[EBP+8]
    00409F95 CALL DWORD PTR DS:[415268];recvfrom

    by watching the buffer out (second parameter) we can see what arrives to DNAScan

    001644B8 E..a......=
    00164518 ACACACACACABN.SMB%.............
    00164538 ............................
    00164558 ......V......\MAILSLOT\BRO
    00164578 WSE...........................

    this recvfrom is repeated until certain conditions that depends from watch application receives,
    under certain conditions sento from server reacts. After setting this is builded another thread that makes use of a classical server architecture

    • * Socket
    • * Listen
    • * Accept

    Next networking operation is the Pipe building

    00407DCF PUSH 0
    00407DD1 PUSH 0
    00407DD3 PUSH 400
    00407DD8 PUSH 400
    00407DDD PUSH 0FF
    00407DE2 PUSH 0
    00407DE4 PUSH 3
    00407DE6 PUSH OFFSET srcdll.004025B4; ASCII "\\.\pipe\ie_down_pipe"
    00407DEB CALL; Jump to kernel32.CreateNamedPipeA
    00407DF0 CMP EAX,-1
    00407DF3 JNE SHORT 00407DF7
    00407DF5 JMP SHORT 00407E58
    00407DFA MOV DWORD PTR SS:[EBP-8],0
    00407E01 PUSH 0
    00407E03 PUSH DWORD PTR SS:[EBP-4]
    00407E06 CALL; Jump to kernel32.ConnectNamedPipe
    This creates a named pipe \\.\pipe\ie_down_pipe and successively Enables a named pipe server process to wait for a client process to connect to an instance of a named pipe.

    At this point is assembled the following string

    00401620 http://%s%s?user_id=%.4u&version_id=%s&passphrase=%s&socks=%lu&v
    00401660 ersion=%lu&crc=%.8x.URL: sniffer_ftp_%s..ftp_server=%s&ftp_login
    004016A0 =%s&ftp_pass=%s&version=%lu.URL: sniffer_pop3_%s..pop3_server=%s
    004016E0 &pop3_login=%s&ftp_pass=%s.URL: sniffer_imap_%s..imap_server=%s
    00401720 &imap_login=%s&imap_pass=%s.URL: sniffer_icq_%s..icq_user=%s&icq
    00401760 _pass=%s.SharedAccess.wscsvc.=.GET_COOK.VER.EXE.DL.DL_EXE.DL_EXE
    004017A0 _ST.REBOOT.\%lu.exe./upd %lu
    as you can see there are a couple of interesting strings like

    • * ftp_pass=%s
    • * imap_pass=%s
    • * sniffer_pop3_%s
    • * sniffer_icq_%s

    0040587D PUSH EAX
    0040587E PUSH DWORD PTR SS:[EBP-4];take a look here
    00405881 PUSH 0
    00405883 CALL; Jump to wininet.FindFirstUrlCacheEntryA

    this api enumerates the Internet cache, to see what comes out just watch the second parameter

    0040588F MOV EAX,DWORD PTR SS:[EBP-4]
    00405892 MOV ECX,DWORD PTR DS:[EAX+4]
    00405895 PUSH ECX
    00405896 PUSH DWORD PTR SS:[EBP+8]
    00405899 PUSH ECX
    0040589A CALL; Jump to shlwapi.StrStrIA
    0040589F POP ECX
    004058A0 OR EAX,EAX
    004058A2 JE SHORT 004058AA
    004058A4 PUSH ECX
    004058A5 CALL; Jump to wininet.DeleteUrlCacheEntry
    004058AA MOV DWORD PTR SS:[EBP-8],1000
    004058B1 LEA EAX,[EBP-8]
    004058B4 PUSH EAX
    004058B5 PUSH DWORD PTR SS:[EBP-4]
    004058B8 PUSH DWORD PTR SS:[EBP-0C]
    004058BB CALL; Jump to wininet.FindNextUrlCacheEntryA
    004058C0 JMP SHORT 0040588B
    004058C2 PUSH DWORD PTR SS:[EBP-0C]
    004058C5 CALL; Jump to wininet.FindCloseUrlCache
    this piece of code scans Url Cache to find the previously seen IP address and if discovered, removes it with DeleteUrlCacheEntry.

    00405937 PUSH EAX
    00405938 PUSH OFFSET srcdll.0040A872; ASCII "
    0040593D PUSH 0
    0040593F CALL; Jump to urlmon.URLOpenBlockingStreamA
    Creates a blocking type stream object from a URL and downloads the data from the Internet. When the data is downloaded the client application or control can read it by using the IStream::Read method.

    By analysing the URL we can extract the following informations:

        * user_id=373125111
        * version_id=17
        * passphrase=fkjvhsdvlksdhvlsd
        * socks=9180
        * version=132
        * crc=00000000
    When you step URLOpenBlockingStreamA be aware that this function presents thread and fiber functionalities to speed up and make an easier analysis approach just detach for one step the New Thread Break Event. If incidentally you have this Event enabled, surf between threads with Execute till Return and Run Actual Thread.

    _Next Thread_

    Here the malicious application scans into C:\Documents and Settings\evilcry\Cookies\ cookie by cookie

    00408305 PUSH DWORD PTR SS:[EBP+8]; ASCII "C:\Documents and Settings\evilcry\Cookies\"
    00408308 PUSH EDI
    00408309 CALL; Jump to kernel32.lstrcpyA
    0040830E MOV EDX,DWORD PTR SS:[EBP-8]
    00408311 LEA EDX,[EDX+2C]
    00408314 PUSH EDX
    00408315 PUSH EDI
    00408316 CALL; Jump to kernel32.lstrcatA
    0040831B PUSH EDI
    0040831C CALL; Jump to kernel32.DeleteFileA
    00408321 PUSH DWORD PTR SS:[EBP-8]
    00408324 PUSH DWORD PTR SS:[EBP-4]
    00408327 CALL; Jump to kernel32.FindNextFileA
    0040832C TEST EAX,EAX
    0040832E JNE SHORT 004082E5
    00408330 PUSH DWORD PTR SS:[EBP-4]
    00408333 CALL; Jump to kernel32.FindClose
    Successively by using ad usual CreateToolhelp32Snapshot and Process32First/Process32Next and WriteProcessMemory DNAScan injects some pieces of code in various system processes. This is essentially not useful for our analysis scopes actually.

    0040795B 55 PUSH EBP
    0040795C 8BEC MOV EBP,ESP
    0040795E 83C4 F8 ADD ESP,-8
    00407961 53 PUSH EBX
    00407962 E8 57F6FFFF CALL 00406FBE
    Inside the call

    00406FC9 PUSH OFFSET srcdll.0040B87E
    00406FCE PUSH 1
    00406FD0 PUSH 0
    00406FD2 CALL; Jump to OLE32.CreateStreamOnHGlobal
    The CreateStreamOnHGlobalfunction creates a stream object that uses an HGLOBAL memory handle to store the stream contents. This object is the OLE-provided implementation of the IStream interface.

    00406FE1 PUSH OFFSET srcdll.0040B87A
    00406FE6 PUSH srcdll.00401B50; ASCII "pstorec.dll"
    00406FEB CALL 00406F71; Loads from pstorec.dll PStoreCreateInstance
    00406FF0 TEST EAX,EAX
    00406FF2 JE SHORT 00407033
    00406FF4 PUSH OFFSET srcdll.0040B882
    00406FF9 PUSH srcdll.00401B73; ASCII "crypt32.dll"
    CALL 00406F71; Loads from crypt32.dll CryptUnprotectData
    00407009 PUSH EAX
    0040700A PUSH EAX
    0040700B PUSH EAX
    0040700C LEA EDX,[40B876]
    00407012 PUSH EDX
    00407013 CALL DWORD PTR DS:[40B87A];PStoreCreateInstance
    Protected Storage (Pstore) is available for use in Windows ...
    Reverse Engineering
  6. Device Drivers Vulnerability Research, Avast a real case

    In the past days I worked intensively on Antivirus’s Device Drivers bugs, at the actual state of art the major part of well known AVs suffer of basical and more hidden bugs. The totality of AVs that I’ve checked presents defects that could be maliciously used to takeover an Antivirus Infrastructure and in some case the entire Operating System with attacks like DoS and/or Remote/Local Privilege Escalation.

    I want to make a precisation here, exists an important difference between Bug and Vulnerability, simply bugs does not affects the integrity of a system and does not constitute a true danger. Vulnerabilities constitutes an effective risk for systems integrity, included informations contained inside it. When we are dealing with applications specifically devoted to security, every bug could be considered a vulnerability, because an attacker could block/kill overcome checks performed by the application itself and propagate in system and produce damages. Just think to a basical crash that could affect an Antivirus could be implemented into a malicious application that checks the presence of AVs and induces the bug.

    In this little post we are going to see some defects of last device drivers used by Avast, I’m precisely talking of

    Build Number: 4.8.1351.0

    Avast loads the following drivers:

    • Aasvmker4.sys
    • aswMon2.sys
    • aswRdr.sys
    • aswSP.sys

    Avast loads the following Drivers could be tested by fuzzing IOCTLs, for this task could be used IOCTL Fuzzer and Kartoffel. Let’s disassemble the first driver, Aavmker4.sys that from DeviceIoControl hook appears to be heavy used. This is the DriverEntry()drivers

    00010748 mov eax, [ebp+DriverObject]
    0001074B push offset NotifyRoutine ; NotifyRoutine
    00010750 mov dword ptr [eax+70h], offset sub_1098C ; DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_1098C;
    00010757 call PsSetCreateProcessNotifyRoutine
    sub_1098C contains the switch statement to handle various IOCTL notifications, essentially IOCTL check is structured in form of nested If and Switches.

    001098C ; int __stdcall sub_1098C(int, PIRP Irp)
    000109C4 mov ecx, 0B2D6002Ch
    000109C9 cmp eax, ecx
    000109CB ja loc_10D12
    000109D1 jz loc_10CE9
    Checks if IOCTL is less or equal to 0×0B2D6002C, if condition is true checks if IOCTL is exactly 0×0B2D6002C a certain task is performed by the device driver and finally ends with a classical

    IofCompleteRequest(X, 0);
    return value;
    By monitoring Aavmker4.sys activity, with a DeviceIoControl hook emerges that the most used IOCTLs are:

    • 0xB2D60030
    • 0xB2D60034

    Now we have two possibilities the first is to fuzz these IOCTLs and check crash dump if happens and after check code for more details, the second possibility is to invert the check order.

    This the xml configuration to test Aavmker4.sys

    launch fuzzer and Avast Scan, as you can see Driver resists to Fuzzing attempts, its time to see code referred to 0xB2D60030 and 0xB2D60034.


    00010D25 cmp eax, 0B2D60030h
    00010D2A jz short loc_10DA8
    00010D2C cmp eax, 0B2D60034h
    00010D31 jz short loc_10D5B
    00010DC5 mov edi, [ebx+0Ch]
    00010DC8 cmp esi, 878h
    00010DCE jz short loc_10DDA ;Check buffer size
    00010DD0 push offset aIoctl_aavm_sta ; “******* IOCTL_AAVM_START_REQUEST_AND_SE”…
    00010DD5 jmp loc_10ABA ;Jump to Io Completion
    If buffer size differs from 878h Dbg Prints an error message, else supplied buffer is correctly sanitized via MmUserProbeAddress, MmIsAddressValid. We can say that this IOCTL is correctly handled.


    00010D5B cmp esi, 8
    00010D5E jnz loc_10AC0 ;If differs from 8 return STATUS_INVALID_PARAMETER
    00010D64 call PsGetCurrentProcessId
    Now let’s test aswSP.sys. In Device Driver vulnerabilty research it’s fundamental to have a complete log of all activities of a driver, this can be obtained by correctly planning a battery of test unit. Each test should correspond to a primitive logic operation performed by an application that makes use of driver. I usually build several mini logs for each activity and finally a complete log. Here a little list of monitoring primitives:

    • On Load
    • On apparent Idle
    • On Working
    • On Shutdown
    • Various, like On Surprise Stop

    This will give us a complete report of all activities and involved IOCTL. In the specific case of aswMon2.sys we can isolate the following:

    • * 0xb2c80018
    • * 0xb2c80014
    • * 0xb2c80020
    • * 0xB2c800C0
    • * 0xB2c800C4
    • * 0xB2c800C8

    From IOCTL Logger we can see that 0xB2c800C0 is heavly used, time to locate Ioctl Dispatcher:

    0001178B and dword ptr [ebx+34h], 0
    0001178F mov dword ptr [ebx+6Ch], offset sub_11FB6
    00011796 mov dword ptr [ebx+28h], offset off_18988
    C like:
    v2->DriverUnload = 0;
    v2->MajorFunction[13] = (PDRIVER_DISPATCH)sub_11FB6;
    v2->FastIoDispatch = (PFAST_IO_DISPATCH)&unk_18988;
    with a bit of research we land to sub_10B82 that contains the switch for Ioctls.

    00010BBD mov eax, 0B2C80018h
    00010BC2 cmp ecx, eax
    00010BC4 push edi
    00010BC5 ja loc_11066
    00010BCB jz loc_10F70
    00010BD1 cmp ecx, 0B2C80008h
    00010BD7 jz short loc_10C3C
    00010BD9 cmp ecx, 0B2C8000Ch
    00010BDF jz short loc_10C16
    00010BE1 cmp ecx, 0B2C80010h
    00010BE7 jz short loc_10BFF
    00010BE9 cmp ecx, 0B2C80014h
    00010BEF jnz loc_111AC
    00010BF5 call sub_108BC
    From logs emerged that the most frequently used is 0B2C8000C so it’s obvious that we will study this for first:


    00010C16 cmp [ebp+arg_C], 1448h
    00010C1D jnz loc_111AC ;check len
    00010C23 mov esi, [ebp+SourceString]
    00010C26 mov ecx, 512h
    00010C2B mov edi, offset dword_18A58
    00010C30 rep movsd
    00010C32 call sub_108F0
    00010C37 jmp loc_112C1 ;go out
    In this case user supplied input is correctly sanitized, so 0xB2C8000C can be excluded from fuzz testing. From the log On Shutdown emerged the massive presence of 0xB2c80018, so let’s fuzz it. Here the configuration for IOCTL Fuzzer:

    <?xml version=”1.0″ encoding=”windows-1251″?>
    The config script allows only 0xB2c80018 sent from aswMon, other drivers are locked. Obviously fuzzing need to follow the log unit that evidenced out IOCTL, so run fuzzer and stop all Avast services.

    Bang..a BSOD, discovered an Avast vulnerability into aswMon2.sys

    From crashdump:

    kd> !analyze -v

    Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
    Arg2: 80042000
    Arg3: 00000000
    Arg4: 00000000_KERNEL_MODE_TRAP_M (1000007f)
    WARNING: Stack unwind information not available. Following frames may be wrong.
    f76f3234 8053d251 f76f3250 00000000 f76f32a4 nt+0×600fa
    f76f32a4 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251
    f76f3328 8052c793 41414141 00000000 f76f377c nt+0×55712
    f76f33a4 804fc700 f76f377c f76f3478 05050505 nt+0×55793
    f76f3760 8053d251 f76f377c 00000000 f76f37d0 nt+0×25700
    f76f37d0 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251
    f76f3854 8052c793 41414141 00000000 f76f3ca8 nt+0×55712
    f76f38d0 804fc700 f76f3ca8 f76f39a4 05050505 nt+0×55793
    f76f3c8c 8053d251 f76f3ca8 00000000 f76f3cfc nt+0×25700
    f76f3cfc 8052c712 badb0d00 20a0a0a1 f76f5658 nt+0×66251
    f76f3d80 8052c793 41414141 00000000 f76f41d4 nt+0×55712
    f76f3dfc 804fc700 f76f41d4 f76f3ed0 05050505 nt+0×55793
    f76f41b8 8053d251 f76f41d4 00000000 f76f4228 nt+0×25700
    f76f4228 8052c712 badb0d00 20a0a0a1
  7. EventPair Reversing, EventPairHandle as Anti-Dbg Trick


    Here my little paper on EventPairs, and EventPairHandle as Anti-Dbg Trick


    Have a nice read,
    Giuseppe 'Evilcry' Bonfa'
  8. RtlQueryProcessHeapInformation as Anti-Dbg Trick


    Directly derived from the previous Anti-Dbg Trick


    Have a nice read,
    Giuseppe 'Evilcry' Bonfa'
  9. RtlQueryProcessDebugInformation as Anti-Dbg Trick

    The following paper will uncover some interesting undocumented functions relative to Windows Heap Enumeration.


    Here the prototypes for each function:

    IN ULONG  Size,
    IN BOOLEAN  EventPair);
    IN ULONG  ProcessId,
    IN ULONG  DebugInfoClassMask,
    IN OUT PDEBUG_BUFFER  DebugBuffer);

    IN PDEBUG_BUFFER  DebugBuffer);
    allocates buffer for storing heap data in case of success, it returns pointer to allocated debug buffer. Here the declaration of debug buffer:

    typedef struct _DEBUG_BUFFER {
    HANDLE  SectionHandle;
    PVOID  SectionBase;
    PVOID  RemoteSectionBase;
    ULONG  SectionBaseDelta;
    HANDLE  EventPairHandle;
    ULONG  Unknown[2];
    HANDLE  RemoteThreadHandle;
    ULONG  InfoClassMask;
    ULONG  SizeOfInfo;
    ULONG  AllocatedSize;
    ULONG  SectionSize;
    PVOID  ModuleInformation;
    PVOID  BackTraceInformation;
    PVOID  HeapInformation;
    PVOID  LockInformation;
    PVOID  Reserved[8];
    After the buffer allocation we can call the Heap Process Debug Information, we can call RtlQueryProcessDebugInformation to load all heap blocks of the process. This function loads entire heap nodes and corresponding heap blocks of the process. Debug Buffer contains the pointer to heap information structure at offset 0×38. First parameter of this heap structure is node count and after that it contains array of DEBUG_HEAP_INFORMATION structure which represent each heap node.

    typedef struct _DEBUG_HEAP_INFORMATION
    ULONG Base; // 0×00
    ULONG Flags; // 0×04
    USHORT Granularity; // 0×08
    USHORT Unknown; // 0×0A
    ULONG Allocated; // 0×0C
    ULONG Committed; // 0×10
    ULONG TagCount; // 0×14
    ULONG BlockCount; // 0×18
    ULONG Reserved[7]; // 0×1C
    PVOID Tags; // 0×38
    PVOID Blocks; // 0×3C Heap block pointer for this node.
    As you should know a debugged process presents different flags respect a not debugged one, here the sample anti-dbg code:

    #define WIN32_LEAN_AND_MEAN
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <Psapi.h>
    #include “defs.h”
    #pragma comment(lib,”ntdll.lib”)
    #pragma comment(lib,”psapi.lib”)
    void QueryDbgBufferMethod(void)
    PDEBUG_BUFFER buffer;
    NTSTATUS ntStatus;
    buffer = RtlCreateQueryDebugBuffer(0,FALSE);
    ntStatus = RtlQueryProcessDebugInformation(GetCurrentProcessId(),
    if (heapInfo->Flags == 0×50000062)
    MessageBoxA(NULL,”Not Debugged”,”Warning”,MB_OK);
    and here ‘defs.h

    typedef LONG NTSTATUS;
    #define STATUS_SUCCESS ((NTSTATUS)0×00000000L)
    typedef struct _DEBUG_BUFFER {
    HANDLE SectionHandle;
    PVOID  SectionBase;
    PVOID  RemoteSectionBase;
    ULONG  SectionBaseDelta;
    HANDLE  EventPairHandle;
    ULONG  Unknown[2];
    HANDLE  RemoteThreadHandle;
    ULONG  InfoClassMask;
    ULONG  SizeOfInfo;
    ULONG  AllocatedSize;
    ULONG  SectionSize;
    PVOID  ModuleInformation;
    PVOID  BackTraceInformation;
    PVOID  HeapInformation;
    PVOID  LockInformation;
    PVOID  Reserved[8];
    typedef struct _DEBUG_HEAP_INFORMATION
    ULONG Base; // 0×00
    ULONG Flags; // 0×04
    USHORT Granularity; // 0×08
    USHORT Unknown; // 0×0A
    ULONG Allocated; // 0×0C
    ULONG Committed; // 0×10
    ULONG TagCount; // 0×14
    ULONG BlockCount; // 0×18
    ULONG Reserved[7]; // 0×1C
    PVOID Tags; // 0×38
    PVOID Blocks; // 0×3C
    // RtlQueryProcessDebugInformation.DebugInfoClassMask constants
    #define PDI_MODULES                       0×01
    #define PDI_BACKTRACE                     0×02
    #define PDI_HEAPS                         0×04
    #define PDI_HEAP_TAGS                     0×08
    #define PDI_HEAP_BLOCKS                   0×10
    #define PDI_LOCKS                         0×20
    extern “C”
    IN ULONG  ProcessId,
    IN ULONG  DebugInfoClassMask,
    IN OUT PDEBUG_BUFFER  DebugBuffer);
    extern “C”
    IN ULONG  Size,
    IN BOOLEAN  EventPair);
    extern “C”
    IN PDEBUG_BUFFER  DebugBuffer);
    Giuseppe 'Evilcry' Bonfa'
  10. Anti-Emulation Tricks


    Thanks to Gunther for ARTeam here we have some new Anti-Emulation open source functions, I’ve uploaded these on my OffensiveCOding section:

    here a quick list of the functions:

    Anti-KAV -> Call this one before WSAStartup(),so sockets wont be initialized.
    Anti-NOD32 -> sse1 instruction which nod32 cannot emulate.
    IsEmulator -> Timings Attack to Emulator Environement.
    IsCWSandBox -> Check if CreateProcess is hooked.
    IsAnubis -> Check whether it is running within Anubis.
    IsAnubis2 -> Check whether it is running within Anubis.
    IsNormanSandBox -> NormanSandBox Awareness.
    IsSunbeltSandBox -> Sunbelt Awareness.
    IsVirtualPC -> VirtualPC Awareness.
    IsVMware -> VMware Awareness.
    DetectVM -> Check whether it is running in VMWare, VirtualBox using registry.
    IsRegMonPresent -> Checking for RegMon by checking if the driver is loaded in memory and by searching for the window handle.

    Here the link:


    See you to the next post..
  11. Netsons killed my Website

    Netsons without any advice, suspended my account, now I don't have a web-space, if possible I'll try to find some Webspace.

    Giuseppe 'Evilcry' Bonfa'
  12. NtSetDebugFilterState as Anti-Dbg Trick

    The following paper will uncover some intersting Undocumented functions relative to Windows Debugging Support. NT is capable of generating and collecting text Debug Messages with an high grade of customization. User-mode and kernel-mode drivers use different routines to send output to the debugger.

    User Mode: Uses OutputDebugString, that sends a null-terminated string to the debugger of the calling process. In a user-mode driver, OutputDebugString displays the string in the Debugger Command window. If a debugger is not running, this routine has no effect. OutputDebugString does not support the variable arguments of a printf formatted string.

    Kernel Mode: Uses DbgPrint, that displays output in the debugger window. This routine supports the basic printf format parameters. Only kernel-mode drivers can call DbgPrint. There is also DbgPrintEx that is similar to DbgPrint, but it allows you to "tag" your messages. When running the debugger, you can permit only those messages with certain tags to be sent. This allows you to view only those messages that you are interested in.

    This operation is called Filtering Debug Messages, how it works is a little bit undocumented, to understand how to go inside this aspect, let's start from DbgPrint / DbgPrintEx.

    In Windows XP, DbgPrint has been extended by adding _vDbgPrintExWithPrefix, in this way DbgPrint and DbgPrintEx became wrappers of this function.

      vDbgPrintExWithPrefix	(
    	IN PCCH	Prefix,
    	IN ULONG    ComponentId,
    	IN ULONG    Level,
    	IN PCCH     Format,
    	IN va_list  arglist
    vDbgPrintExWithPrefix routine sends a string to the kernel debugger if certain conditions are met. This routine can append a prefix to debugger output to help organize debugging results.

    Let's see what ComponentId means:

    The component that is calling this routine. This parameter must be one of the component name filter IDs that are defined in Dpfilter.h. Each component is referred to in different ways, depending on the context. In the ComponentId parameter of DbgPrintEx, the component name is prefixed with DPFLTR_ and suffixed with _ID. In the registry, the component filter mask has the same name as the component itself. In the debugger, the component filter mask is prefixed with Kd_ and suffixed with _Mask.

    Now let's see Level parameter:

    The severity of the message that is being sent. This parameter can be any 32-bit integer. Values between 0 and 31 (inclusive)) are treated differently than values between 32 and 0xFFFFFFFF.
    Filter masks that are created by the debugger take effect immediately and persist until Windows is restarted.

    The debugger can override a value that is set in the registry, but the component filter mask returns to the value that is specified in the registry if the computer is restarted. There is also a system-wide mask called WIN2000. By default, this mask is equal to 0x1, but you can change it through the registry or the debugger like all other components. When filtering is performed, each component filter mask is first combined with the WIN2000 mask by using a bitwise OR. In particular, this combination means that components whose masks have never been specified default to 0x1.

    By inspecting deeply vDbgPrintExWithPrefix we can see that it represent a wrap around NtQueryDebugFilterState that retrieves the state of the selected Debug Filter Mask. By inspecting xRefs we discover that NtQueryDebugFilterState is also used by DbgQueryDebugFilterState()

    NTSTATUS __stdcall DbgQueryDebugFilterState(ULONG ComponentId, ULONG Level)
    0045000C 	ComponentId     = dword ptr  8
    0045000C 	Level           = dword ptr  0Ch
    0045000C     mov     edi, edi
    0045000E     push    ebp
    0045000F     mov     ebp, esp
    00450011     pop     ebp
    00450012     jmp     NtQueryDebugFilterState
    00450012 _DbgQueryDebugFilterState end proc
    As is obvious, DbgQueryDebugFilterState asks for the actual state of Debug Filters. Near the Query function we can see DbgSetFilterState()

    NTSTATUS __stdcall DbgSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
    0045001C     mov     edi, edi
    0045001E     push    ebp
    0045001F     mov     ebp, esp
    00450021     pop     ebp
    00450022     jmp     NtSetDebugFilterState
    00450022     DbgSetDebugFilterState endp
    DbgSetDebugFilterState is a wrapper of a native NtSetDebugFilterState(ULONG ComponentId, ULONG Level, BOOLEAN State)
    As you can understand this is an intersting API cause attempts to modify the Debug Filter Mask:

    0056384C NtSetDebugFilterState(ULONG ComponentId, unsigned int Level, char State)
    0056384C	  mov     edi, edi
    0056384E      push    ebp
    0056384F      mov     ebp, esp
    00563851      mov     eax, large fs:124h       ;KTHREAD
    00563857      movsx   eax, byte ptr [eax+140h] ;KTHREAD->PreviousMode
    0056385E      push    eax             
    0056385F      push    ds:_SeDebugPrivilege.HighPart
    00563865      push    ds:_SeDebugPrivilege.LowPart ;PrivilegeValue
    0056386B      call    SeSinglePrivilegeCheck
    00563870      test    al, al
    00563872      jz      short loc_5638BE ;If PrivilegeValue does not match, exit 							and return 0xC00000022 error
    SeSinglePrivilegeCheck checks for the passed privilege value in the context of the current thread, If PreviousMode is KernelMode, the privilege check always succeeds. Otherwise, this routine uses the token of the user-mode thread to determine whether the current (user-mode) thread has been granted the given privilege.
    Here the rest of the function

    v3 = &Kd_WIN2000_Mask;
     if ( ComponentId >= KdComponentTableSize )
          if ( ComponentId != 0xFFFFFFFF )
            return 0xC00000EF;
          v3 = (int *)*(&KdComponentTable + ComponentId);
        if ( Level <= 0x1F )
          v4 = 1 << (char)Level;
          v4 = Level;
        v6 = v4;
        if ( !State )
          v6 = 0;
        *v3 = v6 | *v3 & ~v4;
        result = STATUS_SUCCESS;
    Now we can implement a little Anti-Debug trick based on Debug State Awareness, indeed with NtSetDebugFilterState we are able to determine if the process is debugged or not:

    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "ntDefs.h"
    #pragma comment(lib,"ntdll.lib")
    int main(void)
    	NTSTATUS ntStatus;
    	ntStatus = NtSetDebugFilterState(0,0,TRUE);
    	if (ntStatus != STATUS_SUCCESS)
    		MessageBoxA(NULL,"Not Debugged","Warning",MB_OK);		
    	return (EXIT_SUCCESS);
    -> ntDefs.h

    typedef LONG NTSTATUS;
    #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
    extern "C"
    ULONG __stdcall 
    					 ULONG ComponentId,
    					 ULONG Level,
    					 BOOLEAN State					 
    Trick is really basilar if the Process is Debugged NtSetDebugFilterState returns STATUS_SUCCESS else returns 0xC00000022 Error Code. May be that this trick is already used, but for sure I haven's seen nothing about NtQueryDebugFilterState/NtSetDebugFilterState =)


    Thanks to #bug channel especially ratsoul 'n swirl

    Giuseppe 'Evilcry' Bonfa'
  13. Backdoor.Win32.UltimateDefender Reverse Engineering


    I've released Backdoor.Win32.UltimateDefender.gtz Reverse Engineering:


    Giuseppe 'Evilcry' Bonfa'
    Reverse Engineering
  14. Trojan.Zhelatin.pk


    Here a little overview of Trojan.Zhelatin.pk one of the first versions of this Malware.


    Have a nice Read

    Giuseppe 'Evilcry' Bonfa'
    Reverse Engineering
  15. On Analysis of Client-Server Software Applications


    Initially was a closed paper, now I rewritten it a bit. Here a little Abstract:

    The principal objective of this paper is to give a good detailed
    panoramic view of the Security aspects involved in Client-Server based
    Applications. The panoramics will be seen from the point of view of a
    Reverse Engineer that should be aware of the Security Problems that are
    directly releated to the Client-Server Software Structure.

    and here the link:


    TechLife , (In)Security
Page 1 of 3 123 LastLast