In Windows for instance, and all operating systems, file priveleges exist that "prevent" a file from being written to if that rule is set.
This is hard to describe but please listen. People coding in a C language obviously would use some form of framework to easily modify a file. Using the built-in .Net framework, Microsoft obviously would put prevention into their classes checking file permissions before writing to a file. Since file permissions are stored via software and not hardware, what really prevents a file from being tampered with?
Let's hop over to Assembly. Suppose I create an Assembly program that directly accesses hard drive data and changes the bytes of a file. How could file permissions possibly prevent me from doing this? I guess what I am trying to ask is how a file permission really stays secure if the compiled program does not check for file permissions before writing to a file?
Suppose I create an Assembly program that directly accesses hard drive data and changes the bytes of a file. How could file permissions possibly prevent me from doing this?
If you write in assembly, your assembly is still run in a CPU mode that prevents direct access to memory and devices.
CPU modes … place restrictions on the type and scope of operations that can be performed by certain processes being run by the CPU. This design allows the operating system to run with more privileges than application software.
Your code still needs to issue system calls to get the OS to interact with memory not owned by your process and devices.
a system call is how a program requests a service from an operating system's kernel. This may include hardware related services (e.g. accessing the hard disk), creating and executing new processes, and communicating with integral kernel services (like scheduling).
The OS maintains security by monopolizing the ability to switch CPU modes and by crafting system calls so that they are safe for user-land code to initiate.
Related
I understand that an Operating System forces security policies on users when they use the system and filesystem via the System Calls supplied by stated OS.
Is it possible to circumvent this security by implementing your own hardware instructions instead of making use of the supplied System Call Interface of the OS? Even writing a single bit to a file where you normally have no access to would be enough.
First, for simplicity, I'm considering the OS and Kernel are the same thing.
A CPU can be in different modes when executing code.
Lets say a hypothetical CPU has just two modes of execution (Supervisor and User)
When in Supervisor mode, you are allowed to execute any instructions, and you have full access to the hardware resources.
When in User mode, there is subset of instructions you don't have access to, such has instructions to deal with hardware or change the CPU mode. Trying to execute one of those instructions will cause the OS to be notified your application is misbehaving, and it will be terminated. This notification is done through interrupts. Also, when in User mode, you will only have access to a portion of the memory, so your application can't even touch memory it is not supposed to.
Now, the trick for this to work is that while in Supervisor Mode, you can switch to User Mode, since it's a less privileged mode, but while in User Mode, you can't go back to Supervisor Mode, since the instructions for that are not permitted anymore.
The only way to go back to Supervisor mode is through system calls, or interrupts. That enables the OS to have full control of the hardware.
A possible example how everything fits together for this hypothetical CPU:
The CPU boots in Supervisor mode
Since the CPU starts in Supervisor Mode, the first thing to run has access to the full system. This is the OS.
The OS setups the hardware anyway it wants, memory protections, etc.
The OS launches any application you want after configuring permissions for that application. Launching the application switches to User Mode.
The application is running, and only has access to the resources the OS allowed when launching it. Any access to hardware resources need to go through System Calls.
I've only explained the flow for a single application.
As a bonus to help you understand how this fits together with several applications running, a simplified view of how preemptive multitasking works:
In a real-world situation. The OS will setup an hardware timer before launching any applications.
When this timer expires, it causes the CPU to interrupt whatever it was doing (e.g: Running an application), switch to Supervisor Mode and execute code at a predetermined location, which belongs to the OS and applications don't have access to.
Since we're back into Supervisor Mode and running OS code, the OS now picks the next application to run, setups any required permissions, switches to User Mode and resumes that application.
This timer interrupts are how you get the illusion of multitasking. The OS keeps changing between applications quickly.
The bottom line here is that unless there are bugs in the OS (or the hardware design), the only way an application can go from User Mode to Supervisor Mode is through the OS itself with a System Call.
This is the mechanism I use in my hobby project (a virtual computer) https://github.com/ruifig/G4DevKit.
HW devices are connected to CPU trough bus, and CPU does use to communicate with them in/out instructions to read/write values at I/O ports (not used with current HW too much, in early age of home computers this was the common way), or a part of device memory is "mapped" into CPU address space, and CPU controls the device by writing values at defined locations in that shared memory.
All of this should be not accessible at "user level" context, where common applications are executed by OS (so application trying to write to that shared device memory would crash on illegal memory access, actually that piece of memory is usually not even mapped into user space, ie. not existing from user application point of view). Direct in/out instructions are blocked too at CPU level.
The device is controlled by the driver code, which is either run is specially configured user-level context, which has the particular ports and memory mapped (micro-kernel model, where drivers are not part of kernel, like OS MINIX). This architecture is more robust (crash in driver can't take down kernel, kernel can isolate problematic driver and restart it, or just kill it completely), but the context switches between kernel and user level are a very costly operation, so the throughput of data is hurt a bit.
Or the device drivers code runs on kernel-level (monolithic kernel model like Linux), so any vulnerability in driver code can attack the kernel directly (still not trivial, but lot more easier than trying to get tunnel out of user context trough some kernel bug). But the overall performance of I/O is better (especially with devices like graphics cards or RAID disc clusters, where the data bandwidth goes into GiBs per second). For example this is the reason why early USB drivers are such huge security risk, as they tend to be bugged a lot, so a specially crafted USB device can execute some rogue code from device in kernel-level context.
So, as Hyd already answered, under ordinary circumstances, when everything works as it should, user-level application should be not able to emit single bit outside of it's user sandbox, and suspicious behaviour outside of system calls will be either ignored, or crash the app.
If you find a way to break this rule, it's security vulnerability and those get usually patched ASAP, when the OS vendor gets notified about it.
Although some of the current problems are difficult to patch. For example "row hammering" of current DRAM chips can't be fixed at SW (OS) or CPU (configuration/firmware flash) level at all! Most of the current PC HW is vulnerable to this kind of attack.
Or in mobile world the devices are using the radiochips which are based on legacy designs, with closed source firmware developed years ago, so if you have enough resources to pay for a research on these, it's very likely you would be able to seize any particular device by fake BTS station sending malicious radio signal to the target device.
Etc... it's constant war between vendors with security researchers to patch all vulnerabilities, and hackers to find ideally zero day exploit, or at least picking up users who don't patch their devices/SW fast enough with known bugs.
Not normally. If it is possible it is because of an operating system software error. If the software error is discovered it is fixed fast as it is considered to be a software vulnerability, which equals bad news.
"System" calls execute at a higher processor level than the application: generally kernel mode (but system systems have multiple system level modes).
What you see as a "system" call is actually just a wrapper that sets up registers then triggers a Change Mode Exception of some kind (the method is system specific). The system exception hander dispatches to the appropriate system server.
You cannot just write your own function and do bad things. True, sometimes people find bugs that allow circumventing the system protections. As a general principle, you cannot access devices unless you do it through the system services.
This might be a dumb question, but I'm struggling to find resources that clearly explain how a VFS is different from an NFS. Can they both be used for the same purpose?
Bonus question: Can you watch a VFS with inotify like you can an NFS?
"NFS" is a network filesystem that's been around for decades. Wikipedia has you covered on that front.
"VFS" is a more generic term that simply means "virtual filesystem". Within the context of Linux, it refers to the part of the kernel with which your user-space programs actually interact when they interact with "files". The VFS layer then passes requests to a concrete filesystem driver -- such as NFS, for example, or ext4, or others.
Read more here and here.
A virtual file system (VFS) is an abstraction layer on top of a more concrete file system.The purpose of a VFS is to allow client applications to access different types of concrete file systems in a uniform way, Where as Network File System (NFS) is a distributed file system protocol originally developed by Sun Microsystem in 1984, allowing a user on a client computer to access files over a computer network much more like local storage is accessed
A VFS can be used to access local and network storage devices transparently without the client application noticing the difference. It can be used to bridge the differences in Windows, Mac and Unix file systems, so that applications can access files on local file systems of those types without having to know what type of file system they are accessing Where as, NFS like many other protocols, builds on the Open Newtork Computing Remote Procedure Call (ONC RPC) system. The NFS is an open standard defined in Request for comments (RFC), allowing anyone to implement the protocol.
"VFS" is the name given to the entire layer in the kernel situated between the system calls and the filesystem drivers; it is not a filesystem in its own right.
I want to create thread or process that would have its own virtual address space (It would probably would have to be separate process) without system libraries in the address space. My goal is to create an execution environment for foreign origin code.
I would like to create a thread with no system libraries, just few executable pages where user's code would be copied and the thread entry point would be placed and also few RW pages for stack and data exchange with main thread.
Is it possible to completely unmap all system libraries on windows (or possibly Linux) from virtual memory from application level?
Unmapping system libraries will not prevent the binary from performing system calls by itself. To catch all operations which you are trying to prevent, some form of binary translation is necessary. You might want to have a look at libdetox and fastBT (Google Tech Talk about fastBT)
Depending on what you want to achieve, it might be easier to run the foreign code within a User-Mode Linux, qemu, VMware or other virtualization solution (using a fresh copy of the virtual hard disk for each run, not providing any network interfaces, etc.).
Here's the scenario:
A central machine running Linux is a "data store" for a number of instruments.
The instruments each have a PC, and each one has a remote mount (SMB) on the data store to which it write data files captured by the instrument.
The instrument PCs run a wide range of operating system including some really old ones.
The instrument PCs hardware clocks are not synchronized, and synchronizing would be problematic for a number of reasons.
Various other fixes (e.g. not using SMB, upgrading instrument operating systems, developing stuff to run on the instruments) are likewise problematic.
What we want to write is a "grabber" application that notices when an instrument writes a file to the data store via its remote mount, and then quickly copies the file somewhere else. The current plan is to use the Linux inotify subsystem to watch for file system events on the directories / trees that the files are likely to arrive in, and then do the copying.
My concern is that the fact the fact that we don't have synchronized clocks is going to be a problem. Is this concern justified?
The concern is not justified.
Linux inotify is an user space API that exposes the Linux fsnotify sub-system. This kernel file system is wired into the general file system layer of the kernel (called VFS). It gets the notification of a creation of a new file directly from the file system code by a callback function, and not by comparing the creation or access dates of the files in a directory. As such, it will not be influenced at all by the time stamps on the files, so the clocks on the different client machine would not matter at all.
To be sure you audit the code for the inotify_should_send_event() send event function, that checks whether an event needs to sent for a tracked file or directory (see here: http://lxr.linux.no/linux+v3.0.4/fs/notify/inotify/inotify_fsnotify.c#L144). Note there is no reference whatsoever to time. In the same spirit the main fsnotify function (http://lxr.linux.no/linux+v3.0.4/fs/notify/fsnotify.c#L296) in the kernel does not reference time stamps anywhere, so clocks will not affect this interface at all.
I hope this helps.
I am looking at some code that uses a function detour package called DetourXS. My application is targeted for Microsoft Server operating systems. Microsoft Research also has a Detours package and they have an article on how it works. They patch the machine code that is loaded in memory and insert code that makes an unconditional jump into the newly injected code.
If this code works by modifying the machine code at run time, they should be facing security restrictions by the Operating System. This would be a serious security lapse on the OS as I can modify any critical DLL like kernel32 to do anything I want. My understanding is that if a user process attempts to modify the code of a dll already loaded into memory, it should be stopped by the OS. Is there a setting in Widows Server OS to enable/disable this check?
How do they overcome this?
Does anybody have experience on using this kind of detour packages in any application in enterprise production environment?
First important thing is that with detours you modify the instructions of your own process. In your process - you can do whatever you want anyways and you don't even have to detour anything, from OS point of view userspace code (e.g. code in your DLL and code in system's kernel32.dll loaded into your process) is exactly the same from security point of view. The reason is simple - hacking security of OS is not the same as changing some code of your process in userspace. OS secures itself by not giving your process too much power (unless you're running as an administrator). For security purposes it is more interesting how to modify code of another process (to achieve its privileges or interesting data, like passwords), but it is a subject for a different discussion.
Secondly, detouring had been considered as a way to implement hot-patching, i.e. patching critical system services on the fly, without reboot. I don't know whether it is currently used/supported by Microsoft (according to google it is), but it is not by chance that standard prolog has length of 5 bytes (yes, it is ideal for putting your jmp instruction).
Despite its name, kernel32.dll is not actually the kernel; it contains the entry points to Win32 API functions that implement Win32's interface to NT system calls.
Furthermore, Windows (like any modern OS) supports copy-on-write, so if you use detours to patch a shared DLL like kernel32.dll, the OS will first make a private copy for your process and patch that. The NT kernel itself is perfectly safe.