Can every process deny access to PROCESS_VM_READ? - windows

I recently asked a question about privileges required in Windows to read any user-mode program's memory contents. I learned from documentation linked in some of the comments:
Apparently PROCESS_VM_READ is required but documentation doesn't seem to explain under which conditions such a trait is attributed to a process. Apparently, ACLs are involved:
When you call the OpenProcess function, the system checks the
requested access rights against the DACL in the process's security
descriptor. When you call the GetCurrentProcess function, the system
returns a pseudohandle with the maximum access that the DACL allows to
the caller
But another user asks about "C++: reading memory of another process" and receives an answer linking this github repo:
https://github.com/T-vK/Memory-Hacking-Class
Now I am just learning C++ as a beginner now, so I can look through this code but I can't say I understand it, so I apologize if the answer is obvious.
I'm guessing from what I've learned so far this code only works against processes which allow PROCESS_VM_READ access. But if that's true, I don't understand why every game executable wouldn't just stop cheats by denying that access. There must be something to this picture that I'm missing.

Related

Access denied error when using VirtualQueryEx

So, I wrote a program which is able to successfully read memory from most of processes using VirtualQueryEx. However, I've come across a process for which this function fails. It's not a system process, just a game process. Without Debug privileges I couldn't even open the process's handle. With them I am able to get the process's handle but still get access denied for VirtualQueryEx.
I'm not sure but maybe the process is private? If that's the case, what should I do to successfully use VirtualQueryEx function?
I've also read somewhere that I might have to suspend whole process's threads before running VirtualQueryEx, but so far I didn't need that... And when I used function Thread32First to get the first thread it gave me an error: ERROR_BAD_LENGTH...
I would be very grateful for any help in this matter!
How are you opening the process handle? From the doc:
The handle must have been opened with the PROCESS_QUERY_INFORMATION
access right, which enables using the handle to read information from
the process object.
Another possibility is that the target process and your process are different bitness (32 vs 64). In that case you either need to use MEMORY_BASIC_INFORMATION32 or something like VirtualQueryEx64 from wow64ext library.

Hooking or Monitoring Service Creation

I am at the end of my rope here. I have been trying for three weeks now to get this information. Before I continue I want you to know I am not writing malware here. I am however writing a binary analysis tool that monitors the behavior of malware.
What I am trying to accomplish is either to hook or monitor CreateServiceW and CreateServiceA. The reason is I want to know what process invoked CreateService and what the binary is that is being registered as a service by the call.
I am tried everything from writing hook ZwRequestWaitReplyPort to intercept the LPC message, to writing a proxy DLL for advapi32.dll, and writing an inline hook for the CreateService function. None of these approaches have yielded results though. The proxy DLL was promising in testing, but didn't work when the official DLL in system32 was replaced with the proxy (BSOD). The inline hook would work if I could gain write access to the mapped area of memory the DLL lies in. But regardless my time is running out and I am desperately in need of an alternative.
I have looked at SetWindowsHookEx and it seems plausible that it might be able to intercept messages sent from the process to services.exe ...but I am not certain.
Can anyone point me in a good direction...I'm begging you.
"The inline hook would work if I could gain write access to the mapped area of memory the DLL lies in."
If it's a system that you fully control, why don't you have write access to the memory?
Use VirtualProtect to change the permissions to RWX and put your hook in. The ADVAPI32 CreateService routines are just stubs forwarded to sechost.dll via api-ms-service-management-l1-1-1.dll (due to MinWin) so there is already easy call instruction to hook.

How to read data using ReadFile when file has disabled sharing on read

I have a problem, i have a file who opened other process and this process defined in CreateFile non file sharing, then i have other application and i want read data from this
file in same time, but how to do.
I can't change file sharing in first application.
I can reach computer administrator right's, i can do changes in system, but probably "code" solution will be better for this problem if this can be done by code.
Can anyone help me?
How about using EasyHook and hook in the API to the CreateFile routine, in effect, your code will intercept the API and possibly change the dwShareMode parameter to make it FILE_SHARE_READ bitwise or FILE_SHARE_WRITE i.e. (FILE_SHARE_READ|FILE_SHARE_WRITE) and call the original hook to allow the CreateFile to work normally...
Use the backup API if you have sufficient privilege. Otherwise, note that these flags exist for a reason. If someone disabled sharing, it's disabled.
You want to call BackupRead, and MSDN notes the following:
a backup
application must have access to the
system-level access control settings,
the ACCESS_SYSTEM_SECURITY flag must
be specified in the dwDesiredAccess
parameter value passed to CreateFile.value passed to CreateFile.
parameter value passed to CreateFile.
One of the options is to use our RawDisk product, which lets you bypass system security restrictions and open files, which have been opened exclusively or the ones for which you don't have access rights. Note, that installing RawDisk itself requires admin rights, so RawDisk can't be used for intrusion to other's computer.
Another option is to use backup API, i.e. above mentioned BackupRead() Windows API function. Doing google search for BackupAPI will give you not just description of this function, but also several comments from users about what's involved in using this backup API

Is passing a windows security token between processes permitted

Imagine I have an existing process running under windows as a particular user. Would it be permitted for that process to take its current token (with something like OpenThreadToken and DuplicateTokenEx), pass it to another process on the same machine (perhaps through a network socket or some other IPC), and then expect that process to be able to use it to call CreateProcessAsUser?
From the documentation I have read (http://msdn.microsoft.com/en-us/library/ms682429%28VS.85%29.aspx), I've seen nothing which prohibits this but perhaps the token can only be used by the thread or process which created it.
(Why would you? I want to has a web request come to IIS, be authenticated, have IIS arrange the impersonation of the remote user and then pass the impersonation token to another server process (on the same machine) so that the server process can perform some security checks in the context of the remote user)
Yes, that is possible. You can use DuplicateHandle to get a handle that is valid for the target process (send the new handle value to the target process, so it knows it.).
However, the target process must still have the privileges to use the token accordingly. E.g. SE_IMPERSONATE to impersonate the user and SE_ASSIGN_PRIMARY to be used by CPAU. Of course there are some exceptions that you can read in MSDN for ImpersonateLoggedOnUser and CPAU.
I haven't tried it, but it seems that this is the same question asked here. The description seems to make sense. Pass the process ID via whatever mechanism you choose (e.g., IPC), then call OpenProcess, OpenProcessToken, and finally ImpersonateLoggedOnUser. The resulting handle could be passed to CreateProcessAsUser. Well ... I know it could be passed to that function but whether it would have the desired result I do not know. Interesting question, though.
Why not just use named pipes, and then call ImpersonateNamedPipeUser() - it's safe and secure and easy! Note that the process doing the impersonation MUST have the Impersonation privilege.

Setting Access permissions on Semaphore?

I am assuming that once a semaphore is created by a process, it will be accessible by any process/user.
Is it possible to put access restrictions on a particular semaphore so that it can be accessible by only certain processes/users or only certain processes can release the semaphore.
I see some problems if we make a semaphore accessible by all processes.Eg: a dummy process can read the semaphore and release the lock at wish making a false signal to the actual process that is really waiting for the semaphore lock.
All these questions are arising as I am getting very weird output with the following code snippet:
use Win32::Semaphore;
$sem = Win32::Semaphore->new(0, 1,"reliance2692")
or print "Can't create semaphore\n";
$sem = Win32::Semaphore->open("reliance2692")
or print "Can't open semaphore\n";
print "Semaphore:" . $sem . "\n";
By running the above program, I am getting the following output
Can't create semaphore
Can't open semaphore
The output shows that its failed to create a semaphore and even failed to open semaphore.
creating a semaphore might have failed if a semaphore already exists with the given name.
I don't understand why opening a semaphore failed.
Can some clarify the scenario where both creating semaphore & opening semaphore fails.
Win32::Semaphore->new calls the Windows API function CreateSemaphore and gets the process's default security descriptor, which usually means that processes running as the same user as your script can have full access whereas processes running as other accounts get no access. So, for starters, your assumption is false.
The name you choose in your Perl code is passed directly to the API function, so it's subject to the same namespace rules as all other Win32 kernel objects.
Win32::Semaphore provides no interface for specifying access restrictions. Even if it did, Windows does not provide per-process permissions. Permissions are attached to the user, not the process.
If you're getting "access denied" from new, then that suggests there's another program running that chose to use that same name for something else — maybe another semaphore, or maybe something else, like an event or a mutex — and that process is running as a different user.
If you're getting "access denied" from open, then, in addition to the possibilities for new, it could be that another process has already opened a semaphore with the same name but has not granted full permissions to other users. Win32::Semaphore->open requests SEMAPHORE_ALL_ACCESS permission.
If the semaphore has already been opened by a process running as the same user, then you should not get "access denied." Neither new nor open should fail in that case, although $^E might hold 183 (ERROR_ALREADY_EXISTS) anyway.
For the record, I'm the author of Win32::Semaphore. As mobrule and Rob have explained, Windows security is user/group based. It's not possible to have a semaphore that only certain processes can access. If any process belonging to a user can access a semaphore, then any process of that user can access that semaphore.
Normally, the default access allows only the current user to access the semaphore. Nobody's ever requested the ability to have Win32::Semaphore specify a non-default security descriptor, and the associated API is non-trivial. If somebody created a module to manage a SECURITY_ATTRIBUTES structure, I'd be happy to add support for that to Win32::Semaphore and the related IPC modules. Win32-Security does not appear to be that module, although it might be a start.
If you need a semaphore to work across multiple users, your only solution right now is to create the semaphore outside of Win32::Semaphore, passing an appropriate SECURITY_ATTRIBUTES pointer. You could do that with a small helper program written in C, or using Inline::C. (Remember that once created, a semaphore exists as long as any process has an open handle to it, so your helper program needs to keep the semaphore handle open until you've called Win32::Semaphore->open on it.)
From Win32::Semaphore pod
$semaphore = Win32::Semaphore->new($initial, $maximum, [$name])
Constructor for a new semaphore object. $initial is the initial count, and $maximum is
the maximum count for the semaphore. If $name is omitted or undef, creates an unnamed
semaphore object.
If $name signifies an existing semaphore object, then $initial and $maximum are ignored
and the object is opened. If this happens, $^E will be set to 183
(ERROR_ALREADY_EXISTS).
If I'm reading this correctly, if your call to Win32::Semaphore->new refers to an existing semaphore, then the new call will open the semaphore as well, and the subsequent open call will be redundant (it's not clear to me from the pod what should happen if you open a sempahore that is already open).
Perhaps you could step through the code, checking the value of $sem as well as $! and $^E at each step.
Additional reply: the Windows API does have methods for setting access control of semaphores, but
they don't appear to be exposed in the Perl Win32::Semaphore module
access control can't be set unless it was already allowed by the other process that created the semaphore
I don't know if you have any good options for this problem. Can you modify the process that creates the semaphore to relax access restrictions? Ask the Win32::Semaphore author to update his module? Try to fix Win32::Semaphore yourself?

Resources