Checking file extensions in Mini Filter

I’m having some trouble and doubts checking file extensions in FS Mini Filter. Apparently this can be “spoofed” very easily by renaming the file which breaks my functionality.

At the moment I am checking the Extension part from _PFLT_FILE_NAME_INFORMATION _structure:

PFLT_FILE_NAME_INFORMATION FileNameInfo = { 0 };
FileNameInfo->Extension

However I’ve also tried to use something like the MS example:

BOOLEAN
ScannerpCheckExtension (
    _In_ PUNICODE_STRING Extension
    )
/*++
Routine Description:
    Checks if this file name extension is something we are interested in
Arguments
    Extension - Pointer to the file name extension
Return Value
    TRUE - Yes we are interested
    FALSE - No
--*/
{
    ULONG count;

    if (Extension->Length == 0) {

        return FALSE;
    }

    //
    //  Check if it matches any one of our static extension list
    //

    for (count = 0; count < ScannedExtensionCount; count++) {
        
        if (RtlCompareUnicodeString( Extension, ScannedExtensions + count, TRUE ) == 0) {

            //
            //  A match. We are interested in this file
            //

            return TRUE;
        }
    }

    return FALSE;
}

Regardless of the method used, you can literally “bypass” this by just renaming the file; for example plugin.dll.exe or document.doc.pdf, etc.

Does anyone know a better way of doing this?

Thank you

I don’t understand the question. You appear to be saying “My program tests for specific file extensions and does something, if the file doesn’t have the extension it doesn’t do it”. So your program is working as you meant it to - either the file extension is meaningful or it isn’t.

Or are you asking how to detect a file rename?

@rod_widdowson said:
I don’t understand the question. You appear to be saying “My program tests for specific file extensions and does something, if the file doesn’t have the extension it doesn’t do it”. So your program is working as you meant it to - either the file extension is meaningful or it isn’t.

Or are you asking how to detect a file rename?

Sorry, I may have rushed to post the question. You are correct, “My program tests for specific file extensions and does something, if the file doesn’t have the extension it doesn’t do it”. This is a major problem for me as it breaks the purpose of my filter.

I need to be able to reliably “detect” the file extension even if someone tampers it, so that my functionality is executed at all times on that file.

So the rule is “once found, never lost”? You “just” need to save the FileId (assuming this is NTFS) in some non tamperable location (hint and ADS is a really stupid place, SystemVolumeInformation is much better. Load it up at attach time and scan every file on open. When the file is deleted you can remove the fileId. Good luck keeping it consistent in a crash proof manner.

You probably also need to filter for rename and link creation because a file can be renamed to have your magic extension.

But it seems to me that the real issue is the dependence on the file’s name at any time. There are many way around any code which depends on just a name.

@rod_widdowson said:
So the rule is “once found, never lost”? You “just” need to save the FileId (assuming this is NTFS) in some non tamperable location (hint and ADS is a really stupid place, SystemVolumeInformation is much better. Load it up at attach time and scan every file on open. When the file is deleted you can remove the fileId. Good luck keeping it consistent in a crash proof manner.

You probably also need to filter for rename and link creation because a file can be renamed to have your magic extension.

But it seems to me that the real issue is the dependence on the file’s name at any time. There are many way around any code which depends on just a name.

I understand, however to make things easier let’s just consider Pre/Post (IRP_MJ_CREATE) operation. Here I call FltGetFileNameInformation then FltParseFileNameInformation to get the filename/extension.

If extension matches for example .doc, I want to scan it for whatever I want. But as I explained, I want to detect and scan that “.doc” at all times no matter if the user tries to “trick me”. If that makes sense.

At the moment if you renamed somefile.doc to somefile.doc.dll it will “trick” my check and therefore there will be no scanning done.

What can be done in this context?

To just reinforce what Mr. @rod_widdowson said… Your algorithm is broken. You can’t rely on the file extension as the primary indication of… anything… really. So, you need a different algorithm. That’s a programming challenge for you.

Maybe you care about the name/path of the app that’s reading the file? Maybe there’s some pattern that you can look at in the data of the file? But, no matter, your challenge is to devise an heuristic that’s better than “file extension alone.”

If you’re asking us if there’s some super secret mystic way that Windows knows that a file is a document or a audio file or a spreadsheet, the answer is “no.”

Peter

@“Peter_Viscarola_(OSR)” said:
To just reinforce what Mr. @rod_widdowson said… Your algorithm is broken. You can’t rely on the file extension as the primary indication of… anything… really. So, you need a different algorithm. That’s a programming challenge for you.

Maybe you care about the name/path of the app that’s reading the file? Maybe there’s some pattern that you can look at in the data of the file? But, no matter, your challenge is to devise an heuristic that’s better than “file extension alone.”

If you’re asking us if there’s some super secret mystic way that Windows knows that a file is a document or a audio file or a spreadsheet, the answer is “no.”

Peter

I understand :frowning:

It’s the first time I`m dealing with mini filters so I thought there is some “magic” way.

Sadly… no. There are no “meta-attributes” (or whatever) that immutably indicate the ultimate purpose/content of a file. I’m not saying it wouldn’t be a good idea… I’m just saying there’s no such thing in Windows.

Peter

@“Peter_Viscarola_(OSR)” said:
Sadly… no. There are no “meta-attributes” (or whatever) that immutably indicate the ultimate purpose/content of a file. I’m not saying it wouldn’t be a good idea… I’m just saying there’s no such thing in Windows.

Peter

Ah well… of course there isn’t. :s

good idea or bad idea, it is an impossible idea under any OS - Windows included. Files contain data. Only the programs that access that data ‘understand’ what that means to them - which can be different things to different programs for the exact same data. Even if you had some hypothetical OS / filesystem that verified the well formatted’ness of data written to files with specific naming conventions, it is entirely possible to abuse the structure of one kind of file to store data of a completely unrelated nature. That’s done all the time with HTTP and if you want to think about it more abstractly consider the dancing man problem from Sherlock Holmes - here is a random link that came up

https://www.boxentriq.com/code-breaking/dancing-men-cipher

the point is not about the simplicity of the cipher, or about its direct applicability, but my suggestion that you think about the problem you are working on from a broader perspective

1 Like