Hooking into Windows File System and Insert Virtual File System - hook

I'm working on an application similar to a program called Mod Organizer. Essentially what the program does is let people download and install mods to the game, Skyrim. However, Mod Organizer does something interesting; rather than install the mods directly to the game's data directory (like other mod managers), MO installs each mod to its own directory in some other arbitrary location and then loads all the mods together once the game launches. This is important because it makes mod managing much less of a hassle.
My question is: how might I create this on the fly file system or make Windows "pretend" a directory full of mod files is somewhere else.
At first I thought of creating symlinks with my code, but This guide put me onto the trail of "hooking," and specifically recommended trying EasyHook. While I think can understand the underlying concept of hooking (essentially intercepting signals from the OS and redirecting them for whatever purpose), I don't really know how to make the hook actually redirect files.
If anyone knows a good resource for this kind of hooking or has better approach to my problem, I'd appreciate the help.

What you have described in done with a filesystem filter driver. This driver intercepts requests to the filesystem and inserts additional information, such as tells the system about the files and directories which don't really exist on the disk. If the files are preset somewhere on the disk, the request can be simply redirected to the existing file or directory.
Filesystem filter driver is a kernel-mode driver, not easy to implement. You can use a pre-created driver that lets you perform tasks in user mode API, eg. our CBFS Filter.

Related

How to share files between two (desktop) applications in a secure way

The problem is that I need to share files between 2 programs, but I don't want that those files are accessible by the user of the computer and other programs than these 2. So the flow of the files are like this: Program A (which I will code myself) recieves a file from the internet and puts somewhere on the computer. Then Program A calls Program B (which I didn't code and can't change). Program B reads the downloaded file and does some things with it and produces another file which Program B puts also somewhere on the computer. Then Program A reads that file and uploads it to the internet.
What I have found
I thought that maybe Windows Sandbox was interesting, but the problem with Windows Sandbox is that it's only available to windows 10 pro and windows 11, and that it is virtualised, and performance is quite important for Program B... So any virtualised software is not very usable, unless it is close to native performance.
For Linux, I found FreeBSD jails. But this seems more focussed on keeping the applications in the jail prohibited to access files outside the jail than to prohibit the programs outside the jail from reading and writing to files in the jail. So actually I need the opposite...
Another interesting concept was to keep the files stored in RAM like mmap in Linux, but since I can't change Program B, I don't know how to implement that. Is there some kind of container application that encapsulates the IO of Program B and redirects it to a file in RAM?
Does anyone have some suggestions? Thanks!
You can't really prevent the user/owner of the computer from reading the file if you are storing it on their disk. You can try to make it more difficult to access the content (which is what DRM does) but ultimately you the user can always bypass your controls given sufficient motivation and resources. Even if you store the files purely in RAM, a user with administrative permissions can dump your program's memory, and extract the files from there.

File read(i.e. using vfs_read()) from LKM init_module()

I would like to read files from my LKM "initialization" function so that I can config the LKM from some configuration files.
I'm wondering if it is not a good practice to read files even from the initialization function of LKM; I heard that it is NOT recommended to read files from LKM after all kernel was initialized.
Please advice me.
Thank you.
Daum
Reading from/writing to files from the kernel is definitely not recommended.
The Kernel Newbies wiki page describes it quite nicely.
For several reasons:
Selecting where and in what format to read/write data is a policy and policy does not belong to kernel. A userland daemon is much
easier to replace with one that receives or sends the data over a
network, generates or converts them from/to different format etc.
Filesystem operations need a user context (i.e.: current != NULL). You can't be sure you're in user context so you can't write something
from (for example) an interrupt handler.
The kernel allows multiple filesystem namespaces for user processes. Which one should it use? How do you make sure it indeed
uses the one you want?
Kernel should not depend on particular layout of a filesystem nor on availability of writable filesystem. The location of the file is
a policy decision and policy decisions should be done in userspace.
Maybe you want to dump the kernel output in a remote MySQL server
tomorrow, that kind of policy is so much easier in userland.
Kernel code should be kept simple and stupid, because any bug in it is likely to have serious consequences. Working with files requires
being aware of various locking issues and would add unnecessary
complexity.
If you want to configure the behaviour of the kernel module you're writing, you can pass module parameters that configure it on start up. Alternatively, your module can expose interfaces to sysfs that can be used to configure it at run time.

Win32API/Win drivers: How to detect if file is accessed

I would like to create something like "file honeypot" on Windows OS.
The problem I would like to answer is this:
I need to detect that file is accessed (Malware wants to read file to send it over internet) so I can react to it. But I do not know how exacly tackle this thing.
I can periodically test file - Do not like this sollution. Would like some event driven without need to bother processor every few ms. But could work if file is huge enought so it cannot be read between checks.
I could exclusively open file myselve and somehow detect if file is accessed. But I have no idea how to do this thing.
Any idea about how to resolve this issue effectively? Maybe creating specialized driver could help but I have little experience in this.
Thanks
Tracking (and possibly preventing) filesystem access on Windows is accomplished using filesystem filter drivers. But you must be aware that kernel-mode code (rootkits etc) can bypass the filter driver stack and send the request directly to the filesystem. In this case only the filesystem driver itself can log or intercept access.
I'm going to assume that what you're writing is a relatively simple honeypot. The integrity of the system on which you're running has not been compromised, there is no rootkit or filter driver installation by malware and there is no process running that can implement avoidance or anti-avoidance measures.
The most likely scenario I can think of is that a server process running on the computer is subject to some kind of external control which would allow files containing sensitive data to be read remotely. It could be a web server, a mail server, an FTP server or something else but I assume nothing else on the computer has been compromised. And the task at hand is to watch particular files and see if anything is reading them.
With these assumptions a file system watcher will not help. It can monitor parts of the system for the creation of new files or modification or deletion of existing ones, but as far as I know it cannot monitor for read only access.
The only event-driven mechanism I am aware of is a filter driver. This is a specialised piece of driver software that can be inserted into the driver chain and monitor access to files. With the constraints above, it is a reliable solution to the problem at the cost of being quite hard to write.
If a polling mechanism is sufficient then I can see two avenues. One is to try to lock the file exclusively, which will fail if it is open. This is easy, but slow.
The other is to monitor the open file handles. I know it can be done because I know programs that do it, but I can't tell you how without some research.
If my assumptions are wrong, please edit your question and provide additional information.

How can I sandbox filesystem activity, particularly writes?

Gentoo has a feature in portage, that prevents and logs writes outside of the build and packaging directories.
Checkinstall is able to monitor writes, and package up all the generated files after completion.
Autotools have the DESTDIR macro that enables you to usually direct most of the filesystem activity to an alternate location.
How can I do this myself with the
safety of the Gentoo sandboxing
method?
Can I use SELinux, rlimit, or
some other resource limiting API?
What APIs are available do this from
C, Python?
Update0
The mechanism used will not require root privileges or any involved/persistent system modification. This rules out creating users and using chroot().
Please link to the documentation for APIs that you mention, for some reason they're exceptionally difficult to find.
Update1
This is to prevent accidents. I'm not worried about malicious code, only the poorly written variety.
The way Debian handles this sort of problem is to not run the installation code as root in the first place. Package build scripts are run as a normal user, and install scripts are run using fakeroot - this LD_PRELOAD library redirects permission-checking calls to make it look like the installer is actually running as root, so the resulting file ownership and permissions are right (ie, if you run /usr/bin/install from within the fakeroot environment, further stats from within the environment show proper root ownership), but in fact the installer is run as an ordinary user.
Builds are also, in some cases (primarily for development), done in chroots using eg pbuilder - this is likely easier on a binary distribution however, as each build using pbuilder reinstalls all dependencies beyond the base system, acting as a test that all necessary dependencies are specified (this is the primary reason for using a chroot; not for protection against accidental installs)
One approach is to virtualize a process, similar to how wine does it, and reinterpret file paths. That's rather heavy duty to implement though.
A more elegant approach is to use the chroot() system call which sets a subtree of the filesystem as a process's root directory. Create a virtual subtree, including /bin, /tmp, /usr, /etc as you want the process to see them, call chroot with the virtual tree, then exec the target executable. I can't recall if it is possible to have symbolic links within the tree reference files outside, but I don't think so. But certainly everything needed could be copied into the sandbox, and then when it is done, check for changes against the originals.
Maybe get the sandbox safety with regular user permissions? So the process running the show has specific access to specific directories.
chroot would be an option but I can't figure out how to track these tries to write outside the root.
Another idea would be along the lines of intercepting system calls. I don't know much about this but strace is a start, try running a program through it and check if you see something you like.
edit:
is using kernel modules an option? because you could replace the write system call with your own so you could prevent whatever you needed and also log it.
It sounds a bit like what you are describing is containers. Once you've got the container infrastructure set up, it's pretty cheap to create containers, and they're quite secure.
There are two methods to do this. One is to use LD_PRELOAD to hook library calls that result in syscalls, such as those in libc, and call dlsym/dlopen. This will not allow you to directly hook syscalls.
The second method, which allows hooking syscalls, is to run your executable under ptrace, which provides options to stop and examine syscalls when they occur. This can be set up programmatically to sandbox calls to restricted areas of the filesystem, among other things.
LD_PRELOAD can not intercept syscalls, but only libcalls?
Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs
Write Yourself an Strace in 70 Lines of Code

User-dependent file content

For some unfortunate reasons, I have to convert a proprietary and binary library from a one-user per workstation to a multi-user per workstation setup.
Current setup. A user uses a program linked against a library. This library reads a system wide configuration file (using an hard-coded path, ie /usr/local/thelib/main.conf ) which itself contains several paths to several working directories. The wdir are themselves containing a bunch of user data files.
Desired outcome. Being able to manage several users on the same workstation. Of course, a user shall not be able to read nor alter any other user's data through the library, which should be taken care of by unix rights if I manage to feed the library a different working directory for each user.
The library might be used by several users at the same time so ln-ing the configuration file in /usr/local at runtime is not an option.
I was thinking of using FUSE in order to provide a different content for the file /usr/local/thelib/main.conf, depending on an environnement variable or the current unix user. The environnement var would then be used as a switch inside the code producing the configuration file.
I'm confortable using Python, Perl or C.
The workstation is running an up-to-date GNU/Linux Debian or Ubuntu distribution with a pretty recent kernel.
So. What do you think :
would you use FUSE ?
would you produce another kind of wrapper - using chroot(2) was suggested below per janneb - ?
use something else allowed by Linux ?
I kinda know that I would be able to produce something functional but I'll get the community advice since I don't want to reinvent the wheel right now.
Thanks.
Florian
you could use LD_PRELOAD to load a small stub that intercepts open() calls, and opens ~/.main.conf (assuming this is a shared object). Then in your application startup routine, check that LD_PRELOAD is set to the correct value, and if not, restart the app with the correct environment.
A simple way would be for the app to call chroot() before calling the library init function(s). E.g. if you chroot into $HOME/theapp then each user can have a private own config file in $HOME/theapp/usr/local/thelib/main.conf as well as private working dirs somewhere under $HOME/theapp.

Resources