INVALID KERNEL HANDLE by KasperSky installation

Hi,
I have a file system minifilter driver that protects Office Word files by encrypting data and attaching a header file (contains special keys and other information) to it.
First, minifilter driver creates a kernel handle of file object. This handle is Valid in PreCreate operation. All things is successful, there isn?t any error in all pre and post operations after it.

After I install KasperSky in the windows, in PreSetInformation operation that occurs immediately after PreCreate to SetEndOfFileInformation, I get STATUS_INVALID_HANDLE from ObReferenceObjectByHandle function.

Note: This is occurred even if protection of kaspersky disabled or trusted application and files, folders are defined. Bug occurred by installing Kaspersky.
In logs of ProcMon there isn?t any operation from kasper application between PreCreate and PreSetInfo operations.

Any idea to solve the problem is helpful to me.

I’m assuming you’ve confirmed the handle *value* is the same, correct? And
you’re 100% sure you’re creating a kernel handle? Should be something like
0x0`8000xxxx

Assuming the above are correct, then I would try setting an access
breakpoint on the handle count of the file object. Start by translating the
handle into a file object:

1: kd> !handle 800002f4

Kernel handle table at fffff8a0000016b0 with 532 entries in use

800002f4: Object: fffffa801bb4fa20 GrantedAccess: 00020003 (Protected)
Entry: fffff8a000003bd0
Object: fffffa801bb4fa20 Type: (fffffa8018e18de0) File
ObjectHeader: fffffa801bb4f9f0 (new version)
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name:
\Windows\ServiceProfiles\NetworkService\NTUSER.DAT {HarddiskVolume1}

Then get the offset of the HandleCount field from the object header:

1: kd> dt nt!_object_header fffffa801bb4f9f0
+0x000 PointerCount : 0n1
+0x008 HandleCount : 0n1

And set the access breakpoint:

1: kd> ba w8 fffffa801bb4f9f0+8

I’m not sure why your handle would be getting closed, but it’s a place to
start at least.

Definitely report back anything you find.

-scott
OSR
@OSRDrivers

Yes, It’s a kernel handle.

I tested your command. It’s correct, there is a close on my handle that I didn’t expect it.

How can below command help me?
1: kd> ba w8 fffffa801bb4f9f0+8

I checked procmon logs for kaspersky app. My driver does not allow to other applications that open special files. driver calls CreateFile on special file and get file handle, immediately kaspersky try to CreateFile this file, but my driver returns ACCESS DENIED to it. Later, Kaspersky try to ReadFile and WriteFile and this is successful !!! Finally, Kasper close this handle.

It seems my handle stolen by Kasper.

Minifilter’s code has a CleanupContext function that defines as ContextCleanupCallback for FLT_CONTEXT_REGISTRATION array. In this function, I don’t have access to FLT_CALLBACK_DATA to access process Id and decide about it.

Any idea can help me.

Antivirus software can be nasty. It’s possible they’re directly calling the
underlying file system to open the file and thus bypassing your filter.

I’d track down where the handle close is coming from before making any
further assumptions about what they’re doing.

Using my example file object, that would put a write access breakpoint on
the HandleCount field of the object. This breakpoint should fire when the
handle is closed. The call stack might provide you some useful information.

-scott
OSR
@OSRDrivers

Scott, Thanks for your response.

I want to get process ID in CleanupContext and send it to user mode application to trust it. Driver prevent to call FltClose on handle, If it’s KasperSky. But i don’t have access to FLT_CALLBACK_DATA in this function to get processID.

How can get processID in CleanUpContext? (It’s PFLT_CONTEXT_CLEANUP_CALLBACK in FLT_CONTEXT_REGISTRATION)

Very interesting scenario, but how/why would they “steal” your handle ?
Could it be some scenario you are missing ?

In context cleanup just use PsGetCurrentProcess(Id) since this callback can
potentially occur in arbitrary thread context, or at least you are not
guaranteed that the system or other filters don’t also hold an open handle
or reference to your file object and your FltClose triggers some other
threads to close as well and the context cleanup could appear arbitrary.

If Kaspersky are trying to “reuse” you handle then there is probably a bug
in their code where they also close the handle where they should leave that
up to the creator, but this is a bit weird for me. If the FileObject is
created and usable why would you create a handle, but more importantly why
would you not simply call ObOpenObjectByPointer and get a handle for
yourself to use.

I guess another way you could track this down is through the IRP_MJ_CLEANUP
routine which you should receive upon the last handle close.
Just add a field in your StreamHandleContext ( for the FO you want to
track) like DebugContext and set it to True for the file object you are
interested in ( even from the debugger at the moment of creation ) and from
IRP_MJ_CLEANUP break into the debugger when you see your streamhandle
context with this bit set. This should catch the last Close of the handle
as it happens and you can analyze the stack a bit and see who is closing
the handle.
Hope this helps.

Cheers,
Gabriel

On Tue, May 22, 2018 at 9:21 AM xxxxx@gmail.com
wrote:

> Scott, Thanks for your response.
>
> I want to get process ID in CleanupContext and send it to user mode
> application to trust it. Driver prevent to call FltClose on handle, If it’s
> KasperSky. But i don’t have access to FLT_CALLBACK_DATA in this function to
> get processID.
>
> How can get processID in CleanUpContext? (It’s
> PFLT_CONTEXT_CLEANUP_CALLBACK in FLT_CONTEXT_REGISTRATION)
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>


Bercea. G.</http:>

Do not confuse ContextCleanup with IRP_MJ_CLEANUP. Your context cleanup
callbacks have nothing to do with user activity. They are called when the
underlying system controlled object is destroyed (e.g. File Object, Stream,
etc.). You should not care what PID you’re in when these callbacks execute.

Please set the access breakpoint on the HandleCount field and show the call
stack. Unless you can definitively show where the handle is being closed
then you’re just chasing random things.

-scott
OSR
@OSRDrivers

Hi, thanks Gabriel & Scott

I understand there is a FltObjects->FileObject in postCreate with null parameters except FileName.
We call FltSetStreamHandleContext for this fileObject, but returns STATUS_NOT_SUPPORTED (because FsContext is null). I try to prevent this call. Now, save in file is successful.

APIMonitor logs show NtDuplicateObject before this CreateFile over the handle. How can prevent from DuplicateHandle in minifilter driver???

In PostCreate check the Status of the operation in Data->IoStatus.Status.
The fact that you got in PostCreate and FileObject fields are NULL it most
likely means that the operation has failed.

Anyway, there is no way you can prevent that duplication from happening. Of
course you could if you were part of the Ob callbacks,
which are only now supported to Process and Thread objects (not file
objects), but even then, what you would get is a handle with 0 access. So
basically you
cannot do that. Handle creation is managed by the Ob Manager and has no
ties with the file system specifically, hence you cannot control it
from a minifilter.

But the more fundamental question you should ask yourself, and maybe answer
to us is what are you trying to achieve and also why would an
operating system mechanic or feature, part of the Ob Manager in this case,
which is supposed to work system wide bother you in your development.
Your filter or your driver in general should be able to run and in the same
time everything that the operating system has to offer still needs to work.
Your encryption filter simply cannot depend on a process calling
DuplicateHandle, furthermore, there could be a lower filter making this
system call without
you even knowing about it.

As I see it you create a handle, in the minifilter which is valid in a
subsequent PreCreate. I would obtain the file object ( of the handle I
created ), and close the
handle myself and then use the FltCalls and FileObjects instead of handles.
So if you forward the preCreate and it should fail, you simply dereference
your file object.

The call that you see to DuplicateHandle suggests to me that most likely
you are leaking the handle somehow or close it yourself rather than
Kaspersky “stealing it”
and closing it themselves, otherwise why would they call DuplicateHandle. I
doubt they parse the process handle table and close all handles that refer
to the failed
Create. That would be highly risky, unstable and cannot possibly
synchronize it. Also if that is a kernel handle there is no process table
to associate it as it work in km
only ( which is probably the case here ).

Anyway, make sure you are not the one leaking/closing the handle
unexpectedly somehow. Maybe the Create is denied by Kaspersky and you make
assumptions that it would
work. There is not a lot of info you gave us on that so all I can do is
speculate.

Regards,
Gabriel

On Mon, May 28, 2018 at 11:49 AM xxxxx@gmail.com
wrote:

> Hi, thanks Gabriel & Scott
>
> I understand there is a FltObjects->FileObject in postCreate with null
> parameters except FileName.
> We call FltSetStreamHandleContext for this fileObject, but returns
> STATUS_NOT_SUPPORTED (because FsContext is null). I try to prevent this
> call. Now, save in file is successful.
>
> APIMonitor logs show NtDuplicateObject before this CreateFile over the
> handle. How can prevent from DuplicateHandle in minifilter driver???
>
>
> —
> NTFSD is sponsored by OSR
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>


Bercea. G.</http:>