Filter Monitor 1.0.1

October 17th, 2009 by Daniel Pistelli

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.

“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.

CFF Explorer bug-fix

September 30th, 2009 by Daniel Pistelli

Fixed a bug reported by icy. It was causing crashes in executables without sections when calculating their PE size.

Qt’s GUI Thread

September 19th, 2009 by Daniel Pistelli

If you’re a Qt developer, you surely are aware of the fact that you can only display GUI elements and access them from the main thread. This limitation as far as I know is mostly bound to the limitations of X and it isn’t to exclude that multithreading support for GUIs will be added soon.

This limitation never caused me any trouble, since the signal & slots mechanism is thread-safe and communicating between threads and GUI elements can be achieved through it. However, yesterday I needed to show a messagebox in a method and, in case the code is not executing in the main thread, show a native win32 MessageBox instead of a QMessageBox (of course, only on Windows can I do that, on other platforms when I’m not in the main thread, I won’t show anything).

Anyway, here’s a simple method to establish if we’re running the GUI thread:


bool isGuiThread()
{
    if (QCoreApplication::instance()->thread() == QThread::currentThread())
        return true;
    return false;
}

As you can see this is a pointer comparision, but can we rely on the value returned by currentThread? Yes, we can since the pointer is associated with the thread itself as we can see from the code of the method:


QThread *QThread::currentThread()
{
    QThreadData *data = QThreadData::current();
    Q_ASSERT(data != 0);
    return data->thread;
}

// thread_win.cpp

QThreadData *QThreadData::current()
{
    qt_create_tls();
    QThreadData *threadData = reinterpret_cast<QThreadData *>(TlsGetValue(qt_current_thread_data_tls_index));
    if (!threadData) {
        QThread *adopted = 0;
        if (QInternal::activateCallbacks(QInternal::AdoptCurrentThread, (void **) &adopted)) {
            Q_ASSERT(adopted);
            threadData = QThreadData::get2(adopted);
            TlsSetValue(qt_current_thread_data_tls_index, threadData);
            adopted->d_func()->running = true;
            adopted->d_func()->finished = false;
            static_cast<QAdoptedThread *>(adopted)->init();
        } else {
            threadData = new QThreadData;
            // This needs to be called prior to new AdoptedThread() to
            // avoid recursion.
            TlsSetValue(qt_current_thread_data_tls_index, threadData);
            threadData->thread = new QAdoptedThread(threadData);
            threadData->deref();
        }

        if (!QCoreApplicationPrivate::theMainThread) {
            QCoreApplicationPrivate::theMainThread = threadData->thread;
        } else {
            HANDLE realHandle = INVALID_HANDLE_VALUE;
#if !defined(Q_OS_WINCE) || (defined(_WIN32_WCE) && (_WIN32_WCE>=0x600))
            DuplicateHandle(GetCurrentProcess(),
                    GetCurrentThread(),
                    GetCurrentProcess(),
                    &realHandle,
                    0,
                    FALSE,
                    DUPLICATE_SAME_ACCESS);
#else
                        realHandle = (HANDLE)GetCurrentThreadId();
#endif
            qt_watch_adopted_thread(realHandle, threadData->thread);
        }
    }
    return threadData;
}

qt_create_tls just calls once for every thread TlsAlloc and if the data for the current thread hasn’t been set yet, it is set with TlsSetValue. So, we can rely on a pointer comparision.

Server Bug: Reupload

August 19th, 2009 by Daniel Pistelli

Today I received the following email from my hosting provider:

[...] Security is our highest priority and the last years we have taken dramatic measures to build the most secure hosting environment around.

Unfortunately we have however been affected by the Linux kernel vulnerability (CVE-2009-2692) for a 24 hour period. Due to our architecture this exploit did not compromise personal data and all customer records are safe.

After updating the kernel on our systems we scanned all customer accounts and found that your index was removed. Therefore we kindly ask you to check your webpage and reupload your index page if it is missing.

We sincerely apologize for this incident and will take measures to ensure to prevent such incidents in the future.

The index pages of both rcecafe and ntcore were missing in fact. For precaution I reuploaded both pages completely.

Native Blocks Pre-Alpha

June 30th, 2009 by Daniel Pistelli

Here’s a presentation of my new tool. I called it Native Blocks. It’s a re-assembler basically. Since a written presentation would take me too much time I prepared a video presentation.

Again, this is a pre-alpha. This tool will soon support other technologies such as java, actionscript and maybe even x86. Right now it only supports .NET (and even .NET support will be hugely improved, like for instance supporting the direct modification of assemblies without having to use Rebel.NET).

The development of this tool depends mainly on the interest of people.

As I can be considered a student from now on, I would like to earn some extra money by writing tools such as this one. I have still my job as consultant, but it’s a very limited partime, because I just became a student.

This tool is in my opinion pretty good, it is not only good for deobfuscation purposes but also patching and assembling on the fly.

If this tool can be sold, then the support of technologies will depend on requests. I think I’ll add Java immediately and after that maybe x86/x64. Again it depends.

Suggestions and comments are welcome.

.NET MetaData Tables Reports

May 30th, 2009 by Daniel Pistelli

I updated the scripting language of the old CFF Explorer which now provides a function to automatically create reports of .NET metadata tables. The function is called LogPrintStruct and is to be used along with the logging functions the scripting provides. Here’s a small script you can find in the “Scripts” directory of the CFF Explorer which creates a report of all .NET tables contained in an assembly:


-- this script generates a report of a PE's .NET metadata tables.

filename = GetOpenFile("Open...""All\n*.*\nexe\n*.exe\ndll\n*.dll\n")

if filename == null then
    return
end

hPE = OpenFile(filename)

if hPE == null then
    return
end

if GetOffset(hPE, PE_DotNETDirectory) == null then
    MsgBox("The current is not a valid .NET assembly.", "Error", MB_ICONEXCLAMATION)
end

repname = GetSaveFile("Save Report As..""Text File\n*.txt\n")

if repname == null then
    return
end

hReport = CreateLog(repname)

if hReport == null then
    return
end

fieldsToLog = {
    PE_MetaDataTable_Module,
    PE_MetaDataTable_TypeRef,
    PE_MetaDataTable_TypeDef,
    PE_MetaDataTable_Field,
    PE_MetaDataTable_Method,
    PE_MetaDataTable_Param,
    PE_MetaDataTable_InterfaceImpl,
    PE_MetaDataTable_MemberRef,
    PE_MetaDataTable_Constant,
    PE_MetaDataTable_CustomAttribute,
    PE_MetaDataTable_FieldMarshal,
    PE_MetaDataTable_DeclSecurity,
    PE_MetaDataTable_ClassLayout,
    PE_MetaDataTable_FieldLayout,
    PE_MetaDataTable_StandAloneSig,
    PE_MetaDataTable_EventMap,
    PE_MetaDataTable_Event,
    PE_MetaDataTable_PropertyMap,
    PE_MetaDataTable_Property,
    PE_MetaDataTable_MethodSemantics,
    PE_MetaDataTable_MethodImpl,
    PE_MetaDataTable_ModuleRef,
    PE_MetaDataTable_TypeSpec,
    PE_MetaDataTable_ImplMap,
    PE_MetaDataTable_FieldRVA,
    PE_MetaDataTable_Assembly,
    PE_MetaDataTable_AssemblyProcessor,
    PE_MetaDataTable_AssemblyOS,
    PE_MetaDataTable_AssemblyRef,
    PE_MetaDataTable_AssemblyRefProcessor,
    PE_MetaDataTable_AssemblyRefOS,
    PE_MetaDataTable_File,
    PE_MetaDataTable_ExportedType,
    PE_MetaDataTable_ManifestResource,
    PE_MetaDataTable_NestedClass,
    PE_MetaDataTable_GenericParam,
    PE_MetaDataTable_MethodSpec,
    PE_MetaDataTable_GenericParamConstraint
    }
   
fieldNames = {
    "Module",
    "TypeRef",
    "TypeDef",
    "Field",
    "Method",
    "Param",
    "InterfaceImpl",
    "MemberRef",
    "Constant",
    "CustomAttribute",
    "FieldMarshal",
    "DeclSecurity",
    "ClassLayout",
    "FieldLayout",
    "StandAloneSig",
    "EventMap",
    "Event",
    "PropertyMap",
    "Property",
    "MethodSemantics",
    "MethodImpl",
    "ModuleRef",
    "TypeSpec",
    "ImplMap",
    "FieldRVA",
    "Assembly",
    "AssemblyProcessor",
    "AssemblyOS",
    "AssemblyRef",
    "AssemblyRefProcessor",
    "AssemblyRefOS",
    "File",
    "ExportedType",
    "ManifestResource",
    "NestedClass",
    "GenericParam",
    "MethodSpec",
    "GenericParamConstraint"
    }
   
LogPrint(hReport, ".NET metadata tables report for \"" .. filename .. "\"\n\n")
loggedTables = 0
for i = 0, #fieldsToLog - 1 do
    if GetOffset(hPE, fieldsToLog[i]) != null then
        if loggedTables > 0 then
            LogPrint(hReport, "\n\n\n")
        end
        LogPrint(hReport, fieldNames[i] .. " Table\n")
        LogPrint(hReport, "---------------------------------------------\n\n")
        LogPrintStruct(hPE, hReport, fieldsToLog[i])
        loggedTables = loggedTables + 1
    end
end

-- Open the report?

CloseLog(hReport)

nRet = MsgBox("Open report file?", ".NET Tables Report", MB_ICONQUESTION | MB_YESNO)

if nRet == IDYES then
    ExecuteAppAndWait(@"C:\Windows\System32\notepad.exe", GetShortPathName(repname))
end

A generated report file looks like this:


.NET metadata tables report for "K:\Explorer Suite\Setup\Signature Explorer.exe"

Module Table
---------------------------------------------

1.
Generation: 0
Name: 1 (Signature Explorer.exe)
Mvid: 1
EncId: 0
EncBaseId: 0


TypeRef Table
---------------------------------------------

1.
ResolutionScope: 6
Name: 18 (Control)
Namespace: 20 (System.Windows.Forms)

2.
ResolutionScope: A
Name: 35 (Enum)
Namespace: 3A (System)

3.
ResolutionScope: 6
Name: 41 (Button)
Namespace: 20 (System.Windows.Forms)

4.
ResolutionScope: 6
Name: 48 (Form)
Namespace: 20 (System.Windows.Forms)

5.
ResolutionScope: A
Name: 4D (Object)
Namespace: 3A (System)

6.
ResolutionScope: A
Name: 54 (ValueType)
Namespace: 3A (System)

etc.

I included this new feature because many developers asked me to. Reading the generated report files is much easier than manually reading the raw .NET format. The current scripting system won’t be implemented in the newer CFF Explorer, I only inserted this new feature because it will take me much more time to release the newer CFF Explorer.

Thanks to CodeRipper for signalling a corrupted .NET assembly which caused the CFF Explorer to crash when opening it. I improved the integrity checks.

Data Execution Prevention (NX) flag

April 10th, 2009 by Daniel Pistelli

As you probably know the DEP (Data Execution Prevention) was introduced in XPSP2 and it prevents code to be executed from data sections.

Let’s consider this code snippet:


unsigned char b = 0xC3; // ret

int _tmain(int argc, _TCHAR* argv[])
{
    void *addr = &b;
    __asm call addr;
    getchar();
    return 0;
}

This code sample will crash if the DEP is enabled. DEP is a very important security improvement against buffer overlow exploits, but it might be generate incompatibility with older applications which rely on executing code inside the data section.

The DEP can be disabled individually for an executable. The only thing which needs to be done is to unset the “NX Compatibility” flag inside “Optional Header -> Characteristics”.

Make sure to have the latest CFF Explorer release. I also updated the flags of the “Characteristics” field, because they were outdated. Among the new flags there is the ASLR flag (DLL can move), which enables the executable to be relocated at a random (256 possibilities) address if it contains a relocation table.

Both the ASLR and the DEP flag are enabled by default in Visual C++.

Another flag is the “Code Integrity” one. This flag when set checks the digital signature of the executable and runs it only if the signature is correct.

Kernel: 3rd edition

April 2nd, 2009 by Daniel Pistelli

I don’t want to show too much, this is just a small preview. Yes, it’s running on Ubuntu and it runs on OSX just as well.
I don’t know if I’m going to ship a Linux and an OSX version apart from the Windows one, maybe not immediately. It also depends on the number of requests for it.

Some insights into the new kernel:

- The kernel is now stream based, this means it can read files, memory, disks etc.
- Complete multithread support.
- A CFFStream can be shared among CFFObjects even if they’re owned by a different thread.
- The same CFFObject can be shared among threads.
- Complete endianess support: every file format has a default endianess but can be loaded with a different one. For instance: it is possible to load a PE file with all fields in big endian.
- Support for all most common string encodings.
- Support for integer types of infinite size.
- Support for multiple file formats.
- Easily exposable to scripting languages.

There is more and an impressive amount of work has still to be done, although the kernel is about to be finished. I won’t tell all the new features of the GUI, because it’s way too soon.

Multiple Updates

February 19th, 2009 by Daniel Pistelli

A serious bug in the CFF Explorer, Rebel.NET and Phoenix Protector has been fixed. The bug affected the ExportedType .NET metadata table where the member TypeDefID was declared as a TypeDef index, while it’s a dword. The table is declared correctly in my .NET article, but somehow I wrote the wrong type in the code.

Many thanks to Yaroslav Liulko for reporting the bug.

x64 SEH & Explorer Suite Update

January 19th, 2009 by Daniel Pistelli

Yesterday I took a bit of time and updated the Explorer Suite. One important new feauture is the addition of the Exception Directory. I’m no longer working on the old CFF Explorer. However, I thought this feature was too important for people to wait for the new CFF Explorer. Here’s a screenshot of the Exception Directory UI:

CFF Exception Directory

If you have no idea how the x64 Structured Exception Handling works, you can briefly read this article on osronline or my article about Vista x64. There’s also a pretty in depth quantity of information in a series of posts on Ken Johnson’s blog. However, don’t hope to find too much information on the web about the real physical layout of the Exception Directory. The MSDN information is incomplete if not wrong and even the SDK doesn’t help. This post isn’t a complete guide to x64 exceptions, I just want to explain how to analyze them inside the CFF Explorer.

In the screenshot above you can see two arrays of tables. The first one is an array of RUNTIME_FUNCTION structures. The last column isn’t part of this structure though: it shows the five high bits of the first byte of the UNWIND_INFO structure refrenced by the UnwindData member of RUNTIME_FUNCTION. This is the declaration of UNWIND_INFO:


typedef struct _UNWIND_INFO {
    UBYTE Version       : 3;
    UBYTE Flags         : 5;
    UBYTE SizeOfProlog;
    UBYTE CountOfCodes;
    UBYTE FrameRegister : 4;
    UBYTE FrameOffset   : 4;
    UNWIND_CODE UnwindCode[1];
/*  UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) & ~1) - 1];
*   union {
*       OPTIONAL ULONG ExceptionHandler;
*       OPTIONAL ULONG FunctionEntry;
*   };
*   OPTIONAL ULONG ExceptionData[]; */

} UNWIND_INFO, *PUNWIND_INFO;

The flags represent the type of handlers. An exception flag represents __try/__except blocks, while the termination flag represents __try/__finally blocks.

The second is an array of scope records. An UNWIND_INFO can contain more than one scope records. Let’s consider this little code sample:


__try
{
    __try
    {
        // code
    }
    __finally
    {
        // code
    }
   
    __try
    {
        // code
    }
    __finally
    {
        // code
    }
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
    // code
}

As you can see from the screenshot, it results in 3 scope records. The HandlerAddress in a scope record structure can be an RVA to a C_exception_handler function. Or it can be a simple value like EXCEPTION_EXECUTE_HANDLER (which is 1). The last scope record represents the __except statement. Don’t confuse the exception handler (or filter) with its code.

The JumpTarget member, if not 0, is an RVA to the exception code. It’s possible to see if a particular address has an entry inside the Exception Directory by right clicking on the first table and then clicking ‘Is Address Handled’ in the pop-up menu. Nevertheless, remember that exception handlers can be added at runtime with APIs like RtlAddFunctionTable and RtlInstallFunctionTableCallback.

I fixed some minor bugs in the CFF Explorer and one major bug in the Task Explorer. I noticed this bug years ago but never took time to fix it. It showed only when trying to dump the region of an x86 process using the 64 bit version of the Task Explorer. However, x64 is becoming very used and so the bug is now fixed. Also, I thought it would be a good idea on 64-bit platforms to install a 32-bit version of the Task Explorer and a 64-bit one. Thus, the installer now behaves accordingly.