is ??\c:\windows path legitimate - process

I am going to check loading and memory path of process to find malicious processes. for example if csrss.exe is executed from other path than Windows\System32 would be considered malicious. But the result of Volatility for common process such as csrss.exe is as follows:
loading path : \??\C:\WINDOWS\system32\csrss.exe
mapped path : \WINDOWS\system32\csrss.exe
or for smss.exe I have
loading path : \SystemRoot\System32\smss.exe
mapped path : \WINDOWS\system32\smss.exe
So are these two paths equal in these two examples or not ? I.e. is \??\C:\WINDOWS == \WINDOWS
or \SystemRoot\System32 == \WINDOWS\system32

No, a ??\C:\... without the leading \ is not valid, to the best of my knowledge. Perhaps some libraries will accept this as input, however, and convert it appropriately. Or perhaps you missed some bits from the paths you copied and pasted?
Either way we'll stick to the (NT flavored) Windows behavior.
However, \??\C:\... definitely is. You can find a comprehensive discussion here and the official documentation here. Some of the aspects we need to know are also explained here.
Some implementation details
Quoting from the Google Project Zero page above:
There are 7 types of path that the Win32 API distinguishes between,
and potentially does different things with. NTDLL has a function,
RtlDetermineDosPathNameType_U, which, given a Unicode string will
return you the path type. We’ll go through each one of these types in
the next section. The following prototype can be used to call this
function:
enum RTL_PATH_TYPE {
RtlPathTypeUnknown,
RtlPathTypeUncAbsolute,
RtlPathTypeDriveAbsolute,
RtlPathTypeDriveRelative,
RtlPathTypeRooted,
RtlPathTypeRelative,
RtlPathTypeLocalDevice,
RtlPathTypeRootLocalDevice
};
RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path);
To follow along, download WinObj from Sysinternals/Microsoft and start it elevated (right-click + "Run as Administrator").
Potentially valid paths you may see
You have a number of path representations (as discussed in-depth in the linked articles). Let's consider the path C:\Windows\System32\csrss.exe you gave:
Win32 path: C:\Windows\System32\csrss.exe (\Windows\System32\csrss.exe would be a variation that depends on the current directory at the time the path is processed, if it is somewhere on C: they should be identical)
NT native path:
\??\C:\Windows\System32\csrss.exe
\GLOBAL??\C:\Windows\System32\csrss.exe
\SystemRoot\System32\csrss.exe
Local device path: \\.\C:\Windows\System32\csrss.exe
Root local device path: \\?\C:\Windows\System32\csrss.exe
DOS paths: this is relevant for all paths whose individual path segments are longer than the classic 8.3 DOS path name segments. If configured, a 8.3 DOS name will be generated (usually something in the form of C:\LongPathName -> C:\LONGPA~1) ... this may be important for forensic purposes (you quote volatility), but is mostly legacy behavior.
UNC paths also exist and in fact a local device path (\\.\...) looks like a UNC path with server name . which could even be a thing, considering . is the current directory further down in paths, so why not the current machine up top? Either way, go read the articles if you want to know about those in more detail.
Starting at the top, drilling down
C:\Windows\System32\csrss.exe when passed to an API like CreateFile will be converted to \??\C:\Windows\System32\csrss.exe which the object manager then takes in for processing.
If a relative path was given, there will be additionally processing to convert to a full path, basically.
\\.\C:\Windows\System32\csrss.exe when passed to an API like CreateFile will be "converted" to \??\C:\Windows\System32\csrss.exe after some processing. Just like without the \\.\ prefix some additional processing happens before this path is passed down to the object manager.
\\?\C:\Windows\System32\csrss.exe when passed to an API like CreateFile will be "converted" to \??\C:\Windows\System32\csrss.exe. No further processing happens at the Win32 level. This is basically an escape route straight to the object manager (and in the Fun facts section I'll share a related fun fact).
The object manager view
Receiving a path like \??\C:\Windows\System32\csrss.exe the object manager attempts to find \?? first.
\?? used to be an actual item, these days it is a "view" of \GLOBAL?? overlaid with your session-specific DosDevices.
An example of session-specific DosDevices would be mapped network shares.
For a drive letter F: mapped to \\fileserver\Share
Under the hood you will have a session-specific DosDevices object directory like \Sessions\0\DosDevices\00000000-00261e8a which would contain a symbolic link named F:, pointing to \Device\LanmanRedirector\;F:0000000000261e8a\fileserver\Share ... or similar.
So in essence when looking up names in \?? the object manager will look in your session specific DosDevices, followed by \GLOBAL?? (or was it the other way around? 🤔)
Another example would be VeraCrypt mounted volumes. For example your drive letter T: may map to \Device\VeraCryptVolumeT
Having figured out that C: is \GLOBAL??\C: in our case, the object manager checks what C: is. On my Windows 10 it figures out that this is a symbolic link pointing to \Device\HarddiskVolume3.
Having found the device (and implicitly the driver associated with it) the object manager now will pass the remainder of the path (\Windows\System32\csrss.exe) to the device \Device\HarddiskVolume3, whose driver will hopefully do the right thing, create a file object and so on ...
And now that you know this you can follow along on your system for arbitrary paths.
What about \SystemRoot?
Well, on modern Windows versions the behavior differs a little from how it used to be, but \SystemRoot is a symbolic link resolving to the Windows directory on all NT-based Windows versions I am aware of. The Win32 subsystem parrots this in the %SystemRoot% environment variable (albeit in Win32 path notation).
On my Windows 10 \SystemRoot is a symbolic link to \Device\BootDevice\windows and so the path to a driver (which is the typical use case in the registry) can be expressed much more easily for early boot drivers (less processing needed by the object manager).
As a side note: on my system - as you'd expect - \Device\BootDevice maps to \Device\HarddiskVolume3.
Fun facts
The DosDevices object directory cited in the Google Project Zero article is no longer a thing. These days it's a symbolic link to \?? (not \GLOBAL??).
The subst command line utility allows you to create symbolic links inside your session-specific DosDevices object directory to map some directory path to a drive letter (under the hood uses DefineDosDevice()).
Files are unnamed objects, that is they have no name that could be directly processed by the NT object manager. Instead the remainder of a file name - after reparsing etc - will be passed to the driver responsible for the device object representing the file system volume (i.e. partition). That driver then takes care of making sense of the name.
\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem (while this doesn't name a file, it is a perfectly valid native path to what you would see as HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem
That escape routes named \??\ and \\?\
I mentioned before that the prefix \??\ is an escape route. Consider a file/folder path with a trailing dot, something you will not be able to create or access ordinarily from the Win32 subsystem. Similarly the reserved DOS device names (e.g. NUL, COM1 etc.) cannot be created or manipulated ordinarily.
Little experiment ...
start cmd.exe (Win+R)
go to your desktop folder: cd /d "%USERPROFILE%\Desktop"
Now create a new file test.txt. (note the trailing dot): echo . > \??\%CD%\test.txt. (the %CD% refers to the current directory)
Use Windows Explorer to navigate to your desktop folder. Try to open the file test.txt. by double-clicking. Pick Notepad when it asks you what program to use to open it.
You should see:
... please note the path (without trailing dot).
Now try to delete the file from Windows Explorer. It won't work.
NB: Some alternative file managers like Far or Speed Commander won't have trouble with this!
Now switch back to the command line window and use del /f \\?\%CD%\test.txt.
Did you notice something? I sneakily changed from \??\ to \\?\ because apparently the implementation of del doesn't like the former.
Depending on the implementation of your specific program it can vary whether \??\ or \\?\ is successful.
Another experiment would be to create reserved names like NUL or COM1 or tinker with WSL2's per-directory case-sensitivity.
Note
Win32 may sound outdated, but the Win32 subsystem and the respective "Windows personality" implemented through csrss.exe and its subsystem DLLs (kernel32.dll and friends) was called just that. Besides, if you're picky it may bother you particularly to find out that all the native 64-bit binaries on a modern x64 Windows reside in %SystemRoot%\System32 (<- yes, that's a 32 right there 😁). Enjoy!
Further reading
In addition to the articles from the top, I can recommend these books:
Obviously the Windows Internals book series.
Windows System Programming by Pavel Yosifovich also has some details

Related

ADTF SDK: import manifest AND handle it

I'm trying to run a full ADTF configuration from my own C++ command-line application using the ADTF SDK. ADTF version: 2.9.1 (pretty old).
Here's what I have (want) to do:
Load manifest file
Load globals-xml
Load config-xml
2 & 3 are done, using the session-manager service - see ISessionManager interface: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/classadtf_1_1_i_session_manager.html , functions LoadGlobalsFromFile & LoadConfigFromFile.
The problem is that I don't know how to do point 1: currently, instead of loading a manifest, I manually load the list of services myself using _runtime->RegisterPlugin, _runtime->CreateInstance and _runtime->RegisterObject.
What I've managed to do is to load only the namespace service and use the INamespace interface which has a method for loading manifest files: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/classadtf_1_1_i_namespace.html - see ImportFile with ui32ImportFlags = CF_IMPORT_MANIFEST.
But this only loads the manifest settings into the namespace, it doesn't actually instantiate the services. I could do it manually, by:
Do _runtime->RegisterPlugin for every url under
root/plugins/ in the namespace
Do _runtime->CreateInstance for every objectid under
root/services/ in the namespace
But I want this to be more robust and I'm hoping there's already a service that handles the populated namespace subsequently and does these actions. Is there such a service?
Note: if you know how this could be done in ADTF3 that might also be of help for me, so don't hesitate to answer/comment
UPDATE
See "Flow of the system" on this page: https://support.digitalwerk.net/adtf/v2/adtf_sdk_html_docs/page_service_layer.html
Apparently the runtime instance itself handles the manifest file (see run-levels shutdown & kernel) but I don't know how I'm supposed to tell it where it is.
I've tried setting the command-line arguments to be count = 2 and the 2nd = manifest file path when instantiating cRuntime. It doesn't work :).
In ADTF3 you can just use the supplied cADTFSystem class to initiate an ADTF system and then use the ISessionManager interface to load a session of your choice.
Found the answer, not exactly what I expected though. I tried debugging adtf_runtime.exe to find out what arguments it passes to cRuntime.
The result is indeed similar to what I've suspected (and actually tried):
arg1 = adtf_runtime.exe (argv[0] in adtf_runtime)
arg2 = full path to manifest file (e.g. $(ADTF_DIR)\bin\adtf_devenv.manifest)
arg3 = basename of manifest file, without extension (e.g. "adtf_devenv")
While this suggested that cRuntime indeed is responsible with loading and handling the manifest, it turned out to be NOT quite so, passing the same arguments to it did not do the job. The answer came when I noticed that adtf_runtime.exe was actually using an extension of cRuntime called cRuntimeEx which is NOT part of the SDK (at least I haven't found it).
This class IS among the exported symbols of the ADTF SDK library, i.e. a "dumpbin /symbols adtfsdk_290.lib" renders at some point:
public: __cdecl adtf::cRuntimeEx::cRuntimeEx(int,char const * *
const,class ucom::IException * *)
but it is NOT part of the SDK (you won't find a header file defining it).
Among its methods you'll also find this:
protected: long __cdecl adtf::cRuntimeEx::LoadManifest(class adtf_util::cString const &,class std::set,class std::allocator > *,class ucom::IException * *)
Voila. And thus, unfortunately, I cannot achieve what I wanted in a robust fashion. :)
I ended up manually implementing the manifest-loading logic, since cRuntimeEx is not made available within the SDK. Something along these lines:
Use a cDOM instance to load the manifest file
Call FindNodes("/adtf:manifest/environment/variable") to find the environment-variables that need to be set and set them using "cSystem::SetEnvVariable"
Call FindNodes("/adtf:manifest/dependencies/platform") to find library dependencies and use cDynamicLinkage::Load to load the libraries that target the current platform (win32/linux)
Call FindNodes("/adtf:manifest/plugins/plugin") to find the services to be loaded using _runtime->RegisterPlugin (you may also handle "optional" attribute)
Call FindNodes("/adtf:manifest/services/service") to find the services that need to be created using _runtime->CreateInstance and _runtime->RegisterObject (you may also handle "optional" attribute)
And, finally, call FindNodes("/adtf:manifest/manifests/manifest") to (recursively) load child-manifests (you may also handle "optional" attribute)
The only thing you need to do is start the adtf launcher with the meta files (manifest. This works for adtf 2 as well as for adtf 3. It can be done (console) application. If you also want to do a little bit more in adtf 3, you can use adtf control instead of adtf launcher with its scripting interface (see the scripts under examples)

How to register a Property Handler on folders?

I built a virtual filesystem (not a namespace extension) for Windows which acts as a frontend of our document management server consisting of files and folders. In order to be able to display some metadata of the DMS objects in Windows Explorer as additional selectable columns, I successfully provided properties to the Windows Property System by implementing a COM Property Handler. Wheras normal property handlers focus on specific file types for which they feel responsible, my Property Handler adds properties to all files regardless of their type. Because Property Handlers can only be registered on the file type level, I registered my handler for about 30 types under
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\<.Extension>
However, I did not manage to register the Property Handler for folder objects. Since all objects in our file system are virtual I build the property store (IPropertyStore) by implementing IInitializeWithFile instead of IInitializeWithStream. The properties are requested from our DMS with the path of IInitializeWithFile acting as key and were not read from an objects content. This concept would work for folders as well.
For getting called on folders I tried to associate the handler by registering under different well known identifiers like Folder, Directory, AllFileSystemObjects and * instead of the file extension without success.
I also didn’t find anything in the MSDN documentation regarding this aspect.
Is there a way to register a Windows Property Handler on folders? Or is there some other way to add custom columns to folders in Windows Explorer?
I'm not sure if it is possible to do this.
Property handlers are clearly not the right approach, they are system wide and there can only be one per file extension. They should only be implemented by the software that "owns" the file extension and can parse the file to extract properties.
The old column handlers would have been your best bet (IMHO) but they are officially dead and you already said you can't use them.
Have you considered creating a namespace extension? Either as a root item somewhere (Desktop or My Computer) the way My Documents used to work in 2000/XP or maybe something more along the lines of how OneDrive works?
I'm not sure if desktop.ini files work in the root of a drive but it might be worth looking into. You would then find yourself in the poorly documented land of [.ShellClassInfo] and its CLSID, CLSID2 and UICLSID members. The general idea would be to act as a IShellFolder proxy on top of the "real" IShellFolder so you could create a multiplex property store. I think there are some (undocumented?) property keys you can override to change the folders default columns and tooltips as well.
There is also something called a delegated folder that allows you to play with nested PIDLs but the documentation is once again pretty useless so I'm not sure if this is something worth looking into.
A 3rd option is to pretend to be a cloud storage provider. I don't know if this gets you any closer to your goal and you would still have to implement some NSE bits to get to the point where you can layer yourself on top of the underlying IShellFolder. This feature is rather new and only documented to work on Windows 10.
The inner workings of how Explorer/IShellBrowser is connected to the IShellFolder/IShellView is one of the least documented parts of Windows. There are hundreds of undocumented interfaces. Explorer gives DefView special treatment leaving other 3rd-party implementations out in the cold.
My feeling is that there is no clean solution to implement this on top of a drive letter but you might get lucky, if Raymond Chen drops by he might have some tips for you...

How to explain NFS crossmnt argument?

A client of mine discovered that he needs to include 'crossmnt' along with his NFS export options. I am going to write the option into our software, so that he doesn't have to put in a hack and can use crossmnt as a real option.
Is this a correct explanation of crossmnt that I can use in our docs?
Crossmnt allows the NFS client to traverse the directories below the exported root. For example:
etc/exports:
/exports *(fsid=0,ro,root_squash,sync)
/exports/doc *(ro,root_squash,bind=/usr/share/doc)
With crossmnt, the client can see the contents of /exports/doc as the subfolder of /exports, while without crossmnt, doc would appear to be an empty folder.
This video was used for an example:
https://www.youtube.com/watch?v=-9cJciX8dB8
Does that sound right? Thank you.
I believe that there is something missing in this explanation.. what i know from crossmount is that it allows you to see a mounting point inside an exported directory. If the exported directory doesn't have any partition mounted over its subfolders, they should be visible in the client side of the NFS.
For example, if you have an exported directory over "/mnt/testing_dir", with this content:
/mnt/testing_dir/
dir1/
text1.txt
executable.bin
dir2/ (mount point for /dev/sda6)
doc1
doc2
The "dir1" will be visible even if without the "crossmnt" option. However, "dir2", as it is a mounting point, will be visible with the "crossmnt" option, and will be empty without it (unless you use another options like "nohide").
Reference:
crossmnt -
This option is similar to nohide but it makes it possible for clients to move from the filesystem marked with crossmnt to exported filesystems mounted on it. Thus when a child filesystem "B" is mounted on a parent "A", setting crossmnt on "A" has the same effect as setting "nohide" on B.

Firebreath plugin not loading in IE 10

EDIT: See end of post for more information.
I am trying to to get plugins created via the Firebreath framework (1.7.0) to load. I am on Windows 8 in Desktop Mode using Internet Explorer 10. I've reproduced this with the built-in test FBTtestPlugin that comes with Firebreath. The failure is silent in that the object element is created, but fails to have any properties specified by the plugin. How does one go about debugging this? The Microsoft Internet Explorer Compatibility Tool reports that the plugin is failing to load.
(The FBTtestPlugin loads three plugins, hence the three errors.)
I've got other (non-FB) plugins working on the same settings (e.g. the example here: http://msdn.microsoft.com/en-us/library/dd565667(v=vs.85).aspx works fine as do all the examples from this site http://ie.microsoft.com/testdrive/browser/activexfiltering/Default.html ).
I've tried a huge combination of security settings, but here's the most relaxed set I have so far follows:
Tools / Safety / ActiveX Filtering: is unchecked
Internet Options / Security / Internet: "Enable Protected Mode" is unchecked
Internet Options / Security / Internet: is at Custom Level. Under ActiveX everything is "enabled" except restrictive properties such as "Allow ActiveX Filtering"
All sorts of security warnings are visible based on these settings.
Note: I don't intend to keep these settings. I just want to get the plugin working, then work backwards re-enabling security settings.
UPDATE
I figured this out partly and can now run the FB test FBTestPlugin. To make debugging easier for IE, I defined the registry key HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth as 0 to limit the browser to use one process. Unfortunately, with IE10 both iexplore.exe in Program Files and Program Files (x86) direct to the 64-bit version of IE. This prevents 32-bit plugins from running (see http://support.microsoft.com/kb/2716529 ), and the symptom is silent failure.
However, my plugin still fails to load in IE and the retitled question above is otherwise still open. The problem is still silent load failure. However, I think it may have something to do with plugin configuration. The CLSID listed in the Compatibility Test Tool (like the example shown above) is listed as all 0's instead of a valid GUID. Moreover the registry looks funky: The key HKCR\Company.Name exists as does HKCR\Company.Name.1, but both are empty (instead of having a CLSID child as in normally working plugins). The expected GUID does exist, but under a bogus name "applications.'". I am now digging into the code that gets called when regsvr32 is run.
Thanks all!
I am providing this answer in the hopes that someone can use the result.
IE was not loading the plugin for two reasons.
1) The TabProcGrowth registry key and the 32/64 bit issue with IE 10. ( http://support.microsoft.com/kb/2716529 )
Don't define this key.
2) My plugin description used an apostrophe (e.g. "Gluttco's Plugin") and this messed up the registration of the component.
DETAILS ON 2):
I traced through the DllRegisterServer code and found that the phoney registry entries are due to the fact that my plugin description contained an apostrophe. E.g. "Joe's plugin". The generator (fbgen.py/cmake), generated a malformed FBControls.rgs file (it't didn't escape the quotes and thus contained a string literal such as (s 'Joe's cool plugin'). The DllRegisterServer code (called from regsvr32) used the contents of this file (embedded?) when (deep in atlbase.h). Oddly, the parser did not detect the error (or somehow erroneously recovered). From Process Monitor I could see a bunch of bogus keys being added, before it started adding good registry keys again.
For now Firebreath plugin descriptions should not contain apostrophes (probably other characters are illegal too). It might be sensible to make fbgen.py check for these characters and possibly escape, reject, or replace them.
Searching found this: http://msdn.microsoft.com/en-us/library/dd565667(v=vs.85).aspx
Do you have any group policies in place that could affect it? I don't think this is related directly to FireBreath, rather to the activex configuration...
I also found http://social.technet.microsoft.com/Forums/windows/en-US/90c3202c-448b-42b7-acf7-dab8dba7b000/one-or-more-activex-controls-could-not-be-displayed-because-either which has a few things you could try.

Replacing a .NET dll

I have a dll which is installed with the initial installation of my app (via an msi file). The dll contains a user key and this is 'demo' for the initial installation. When a user buys a licence he is provided with another dll which contains his name. The second dll is simply the first, rebuilt with a different name so it is the same GUID and file name.
This works fine on my win7 test machine, I can replace the dll in my apps dir and it runs correctly. I have recently provided a user dll to a new client but the replace method doesn't seem to work. He is quite IT literate so I think he is following the emailed instruction (replace the userdata.dll in your app directory with the attached) it does not seem to change the dll. He is using Win8(pro).
I had thought of sending him an Inno setup to copy the user dll into the app dir, Flags:ignorereversion regserver sharedfile
Can anyone suggest a solution or an explanation?
Later...
I have now sent him an Inno setup for the updated dll and this works. If I used the second dll method (a good idea) I would still need to have the user install it.
Rather than replacing the original .dll, why not provide a second .dll with the customer's specific info? The 2nd .dll will unlock features in the original .dll.
For instance, in your original .dll you might check for Customer.dll:
if(TryLoadAssembly("Customer.dll", out assembly)) {
if(Validate(assembly)){
IsUnlocked = true;
}
}
Further recommendations (and untested samples) - have Customer.dll contain a single object implementing an interface:
class Customer : IToken {
GUID Guid {get;}
// other fields
}
To validate:
bool Validate(Assembly assembly){
Type type = assembly.GetType("Customer");
IToken customerToken = (IToken)Activator.CreateInstance(type);
// check some properties
return customerToken.Guid == application.Guid;
}
You say it doesn't appear to be replacing the DLL. Is it UAC redirecting his filecopy into local storage?
If this is the case then the easiest way to deal with it would be to either
1) supply a batch file that can do the file copy, along with instructions to launch the batch file by right clicking on it anc choosing "run as administrator".
2) supply an executable that can do the file copy. You can either include instructions to run the exe as an administrator like the batch file, or you can include a manifest with the application to instruct windows that the file needs to execute as an administrator.
A last option, which might be worth while for troubleshooting would be to get the user to turn off UAC and try the file copy again. If that works then this user will be happy and you know what the problem is and can find an elegant solution for future customers.
I've just looked on my Win 8 laptop and the option for UAC is in Control Panel - User Accounts - User Accounts - Change user account control settings. This will give a slider which can be slid all the way to the bottom to turn off UAC.
(User Accounts really is listed twice.)