Is there a way to prevent another process from detecting my process by using CreateToolhelp32Snapshot?
If you are in a environment where you need to protect users from themselves then these users need to be non-admin users and you can simply create a service or task that runs as a different user so it cannot be killed.
If you absolutely need to hide the process and your chosen method is injection & hooking then there are at least 6 things you need to hook in user-mode:
The toolhelp API
The NT4 process API in psapi.dll
The undocumented native NT API
The terminal server API
Performance counters
WMI
A "better" solution is to remove your process from the PsActiveProcessHead list but you need to be in kernel-mode to do that and that means writing a custom driver. If you go down this route your program will be labeled as malware/rootkit by some security tools (and rightly so).
Related
I'm implementing API which allows to launch other apps (using NSTask) inside VFS (FUSE on macOS). After VFS is mounted a bunch of processes start accessing launched VFS in which my app works, and I'd like to implement some kind of filtering mechnism which will allow to detect whether process which is accessing the VFS is created by system (and potentially safe) or not, and if so it'll be granted an access to the file system where my app runs.
So far I'm able to get basic information of the process by it's pid. For example: process path, uid, ppid, code signature of the process etc (using Security framework, libproc etc)
I've done a couple of tests and see that there are process with uid != 0 and still critical for my app to run (if I deny access to them app which is started in VFS crashes) (e.g. /usr/libexec/secinitd, /System/Library/CoreServices/Dock.app/Contents/MacOS/Dock), so looks like approach with filtering processes by pids, uids, ppids might not work.
So the question is: is it possible to distinguish whether process which is accessing my app was created by system and is potentially safe? I also don't want to do too much work by denying accees to critical system processes which will allow the app to successfully start and run in VFS.
Judging from the comment thread, your threat model is data theft via malware etc.
In this case, you can trust almost nothing, so the best way is probably to maintain an explicit whitelist of processes which are allowed to access your mount point, and block access to everything else by default. Log any processes to which access is denied, and allow the user to reverse that decision and add them to the whitelist. In other words, let the user decide what applications they consider safe.
Your said that according to your inspection, there were several processes which were mandatory for the process to run, so why won't use try-and-error approach.
You deploy you FUSE drive on clean environment and record all processes that attempt to access your files - try to prevent each process and keep only those which crash your apps, and add them to a white-list.
Of course that this list is subject to change in different macOS versions, but it can give you the general idea.
Alternatively, you can break your app into couple of parts. for example, put the sensitive logic inside separated dylib file, and prevent access to this file only.. since dylib is not the main executable in your app, I believe fewer processes require mandatory access it.
I have some .NET code in a COM+/Enterprise Services serviced component. I communicate with this component from a WPF application and also from a legacy VBA application.
This arrangement works well when only one user is logged on to a machine. The component starts in its own process when either the .NET or the legacy application instantiates one of its COM objects.
The system also works for the first user to try to run it on a terminal server installation. However, when another user logs on, he/she is unable to use the application. I had hoped that each session would run in isolation, and that one host process would run per session. Am I wrong in this expectation?
In Component Services on the Activation tab my application is configured to run as a "Server application". On the Identity tab, "Interactive user" is selected. On the Security tab, "Enforce access checks for this application" is unchecked.
There isn't session isolation as you describe, instead process ownership limits what you have access to.
Your conclusion seems correct & you will need to determine a suitable mechanism to exchange data with the service.
I used WCF to create a service with a net named pipe listener https://learn.microsoft.com/en-us/dotnet/framework/wcf/index
The idea of using proxies to make rpc calls is attractive, but I found the proxy definitions and stubs to link it all together quite clumsy to use.
If you have events that may be triggered at either end then keeping client/service in sync becomes problematic.
AIUI you cannot invoke a rpc method that ends up invoking an rpc back at the originating end, although that could be a named pipe limitation.
If I was doing this again I would use a socket server in the service & the websocket protocol for biderectional data transfer, even though you might need to implement some thread handling to avoid the listener thread blocking whilst servicing requests.
Hard to find anything authoritative on this. For standard COM you can set the identity to 'Launching user'. The same is not available for COM+.
According to this archived post,
A COM+ application can be configured to run under the logged in account, or
a specified account. Under the application properties, see the Identity tab.
...
Once set however, it remains under that account until the application shuts
down, so you can't have multiple users using the same COM+ application under
different IDs.
That seems to match what is said in this knowledge base article too.
My conclusion is, I should probably accept that my component must run once per machine rather than once per session. It will need to be modified to accommodate this. Since it needs to start new processes in individual sessions, it will have to run as a Windows service under the Local System account (giving due attention to the security implications).
First off, I know some proper ways of making a truly interactive Windows Service.
The situation is, I do have a tool that does not interact with the user as such. However, it does display non-blocking notifications both via popup windows and via the Windows Notification Area (aka System Tray). It also writes a logfile of the notifications it displays.
This tool is normally spawned by a main user application and as long as the main application is a normal application, these notifications do work as intended.
When this tool is spawned by a Windows Service, no notifications are displayed, naturally. (The Desktop Session for the service isn't visible.) But this would be OK, we have the logfile and these notifications are just - notifications, nothing the user absolutely must see under all circumstances.
The question now becomes: Is a process running in the context of a Service (the Service itself or any process it starts) "allowed" to make Windows API calls that display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session of the service?
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
And yes, calling ::MessageBox is a bad idea because it will block. But I can handle these calls.
And yes, this could be designed better, but it's what I have at the moment and it would be nice if I hadn't to rip the whole tool apart to make sure no GUI related code is run in the service.
GUI elements from a Windows Service are shown on Session 0. On Windows XP & 2003, users were allowed to log in to Session 0 and interact normally with the windows created by a service, but Microsoft put a knife in the heart of interactive services in Vista (and beyond) by isolating Session 0.
So, to answer your specific questions:
Is a process running in the context of a Service (the Service itself
or any process it starts) "allowed" to make Windows API calls that
display a visible GUI?
Will most Windows API calls (e.g. creating and showing a window, using Shell_NotifyIcon, etc.) behave the same in the invisible session
of the service?
Yes, GUI calls are allowed and should succeed as normal. The only notable exceptions that I know of are those related to tray icons because the process providing the task bar (explorer.exe) is not running in the isolated Session 0.
Or would I have to make sure throughout the source code, that no GUI displaying/modifying stuff is called in the context of the service?
That should not be necessary, though you should proceed cautiously with any GUI interaction from your service. Test thoroughly!
I would like to provide some info wrt. Raymonds Chen's comment to the other answer
You should avoid presenting UI in a service because you may trigger
the UI Detection Service which will switch the user to your service UI
temporarily. – Raymond Chen
I find these good articles:
What is Interactive Services Detection and Why is it Blinking at Me?
Inside Session 0 Isolation and the UI Detection Service, Part1, Part2
Where one can find explanation on what the UI detection service (UI0Detect) is and does and how it's supposed to work.
Interactive Services Detection (the blinking button on the taskbar) is
a mitigation for legacy applications that detects if a service is
trying to interact with the desktop. This is handled by the
Interactive Services Detection (UI0Detect) service.
However, one must note that this only can work if the service that is trying to view a GUI has the flag "Allow service to interact with desktop" set, because only then the service process will be running on WinSta0of Session0 even allowing it to show anything at all.
Alex Ionescu mentions this:
If UI0Detect.exe ...
the SCM has started it at the request of the Window Hook DLL. The
service will proceed ...
The service first does some
validation to make sure it’s running on the correct WinSta0\Default
windowstation and desktop and then notifies the SCM of success or
failure.
So, to come back to Raymond's comment: As far as I can see, as long as a service doesn't tick the type= interact option (see sc.exe), and normally you don't tick this, the UI0Detect service doesn't do anything and there shouldn't be any "danger" of triggering it.
Note: The information above is based on my limited research and tests on only a single Windows 7 PC.
Say I have a Windows GUI applications with a buttons on it. I am able to simulate a click on that button by using sendMessage winapi calls with BM_CLICK as the parameter to the call.
Now, from a security perspective, I do not want this to happen. i.e. my target process should ignore sendMessage calls from another process. Is there a provision to do this at all ? A way to authenticate the sendMessage calls ?
EDIT: In other words, how can I prevent applications such as Enabler, TurnitOn http://www.raymond.cc/blog/how-to-enable-and-access-disabled-grayed-out-buttons-windows-and-checkboxes/ from accessing functionality that is not meant to be accessed by the user ?
If the application is running in the user's own context, then it can only do what the user can do. The corollary of this, often overlooked, is that anything that the application can do, the user can do.
So there's not really any point in worrying too much about whether a button on such an application is "really" disabled or not. The user can always find another way to do whatever the button was going to do anyway. (This might be by using a registry editor, obtaining another application with the same functionality, or, if nothing else is convenient, they can run the application inside a debugger and force it to re-enable the button.)
The appropriate solution depends on the context:
In many cases, the most appropriate solution is to stop worrying about it. You should be able to trust your users, and if you can't, that's an HR problem, not a technical problem.
If the application is providing an interface to something running in a higher context, such as, for example, the front end for anti-virus software, then the security decisions (is the user allowed to do this?) should be happening at the back end. That is, the security decisions need to be taken by code that isn't in the user's control.
If you're a system administrator trying to lock down a kiosk machine - a machine that is going to be used by untrusted users, typically using a single guest account of some sort - then you use AppLocker or Software Restriction Policy to define which applications the user is allowed to run. Since Enabler and TurnItOn won't be on your list, the user won't be able to run them to bypass your security policy.
I maintain a variety of managed userlabs on a university campus. These machines all currently run Windows XP and we have a windows service that is used to "lock" a machine by blocking any keyboard or mouse input. The locking happens during our scripted OS installation so that users aren't able to accidentally halt or break the process. It is also used to prevent users from logging into machines until they are checked out at the front desk of a given lab. Ctrl+Alt+Del is blocked via a keyboard filter driver and the rest of the keys and mouse are currently blocked using the BlockInput() function from user32.dll.
In XP, the service runs as Local System and the checkbox for "Allow service to interact with desktop" must be enabled from the BlockInput() call to succeed. Under Vista, this no longer works I'm guessing because of the Session 0 isolation changes. The call succeeds, but input is not actually blocked.
The keyboard filter driver still works just fine and we can use that to block the whole keyboard instead of just Ctrl+Alt+Del. But I'm at a loss as to how we're going to block the mouse now. I'm not even entirely sure the Session 0 isolation is to blame.
Can anyone recommend a fix or a workaround to allow us to block mouse input from a service in Vista and beyond? I've looked for alternative win32 API's without luck. Assuming Session 0 isolation is to blame, is there a legitimate way to call the function from Session 1 or would that sort of defeat the purpose of the isolation? Will I have to rely on an elevated companion exe that runs on user login and communicates with the service?
From a service, you can use WTSEnumerateSessions to get all logged on user sessions, WTSQueryUserToken to get the logged on user's token, and then use CreateProcessAsUser with that token to get code running on the user's desktop. This has the disadvantage that the code will run as the logged on user. Since all input is disabled, this is probably safe enough and is at least as safe as the existing XP solution.]
EDIT: BlockInput requires a high mandatory integrity level. You could try adding this group to the token, but then you have code with higher privileges running on the desktop and potentially open to attacks.
An alternative might be to use your service just to disable all HID class devices on the machine.