-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Different window stations assumed as aliases #6
Comments
Can you illustrate this? Nevermind this initial reply :) The reason why it happens is because OpenWindowStation takes Winstation name as parameter. They are the same in this case. Thank you for reporting this issue. |
Here's the problem: on my computer, these properties windows contain absolutely the same information for both WinSta0. The process list, the security descriptor and so on. If I change the security in the one properties window it will automatically change in the other. See a screen recording of this problem. |
I'm afraid there will be no real workaround as OpenWindowStation API doesn't have ability to specify object path. So it will always open current session id winsta. We can try however NtUserOpenWindowStation (which have OBJECT_ATTRIBUTES as parameter) but it is unexported until Windows 10 RS1 and undocumented at all. |
I've monitored API calls and that's what I've got. In both cases, OpenWindowStationW assumes the directory from the current session, so the call tree looks like this (NtUserOpenWindowStation or whatever opens the resultant handle is missed): That's why it shows the same information in the properties window. However, using a debugger I was able to change "\Sessions\2\Windows\WindowStations" to "\Windows\WindowStations" on the fly and it worked fine (I was able to access and change the security of zero session's WinSta0). So it is possible even on Windows 7. The question is how to achieve this properly... |
OpenWindowStation expects that lpszWinSta belongs to current Session. This is stated even on MSDN. Internally as you see in your API call log OpenWindowStation prepares directory path to current session directory object then it opens directory with NtOpenDirectoryObject. Next this handle used as RootDirectory in OBJECT_ATTRIBUTES parameter that passed to NtUserOpenWindowStation. OBJECT_ATTRIBUTES -> then it calls NtUserOpenWindowStation It goes to Win32k, here after preliminary sanity checks ObOpenObjectByName called from _OpenWindowStation internal routine. Referenced handle returned to user mode as result of API call. What will be if we attempt to directly open WinSta object from different session? As you said when you changed object directory path OpenWindowStation returned correct handle to requested object. What is the side effect of this which stops me from implementing this as a fix. You can't close returned WinStation handle if the object you opened not belong to your session. Why this happens. CloseWindowStation is a syscall NtUserCloseWindowStation which goes to win32k. This system service basically does the following (Win7/Win8.1 at least): First it validates hWinSta parameter. It refences opaque undocumented win32k WINSTATION object by calling ObReferenceObjectByHandle. Then it does the following check - SessionId from this object and current process SessionId must be the same. If they are different STATUS_INVALID_HANDLE will be returned and execution returns back from service. This mean that you cannot use CloseWindowStation for WinSta handles if they are not belong to current session. There is no system workaround except manual hack via direct object dereference from driver code. So this is limitation by OS design. From current system Win32 API design point of view we should not be able to open different session WinStation objects (leaving undocumented backdoor for system use with NtUserOpenWindowStation behavior). Yes currently WinObjEx64 think WinSta from different sessions are the same because of OpenWindowStation implementation. So additional object path check before calling this API is required as fix. |
See commit f5e8d75 in dev_alpha branch. However it will have all the above described problems with handle leak so commented code won't be pushed to the master branch. |
Wow, that's impressive :)
And what about NtClose instead of CloseWindowStation? It definitely can close this non-typical handle.
Or, if the trick with NtClose is not applicable (for some reasons unknown to me), what about just opening only one instance of this handle with MAXIMUM_ALLOWED access for all purposes related to another session's window station instead of opening and closing these handles on the fly? In my opinion, one additional handle for the entire duration of the program is not actually a leak. |
Value returned by NtUserOpenWindowStation is a typical handle, not pseudo-handle, not pointer to object and it is managed by Object Manager as any other typical handle. So yes, normally NtClose should work. However, Microsoft implemented special routines to work with Winstation/Desktops/Composition objects handles. It must be done on purpose. OS wants to do additional checks before calling ObpCloseHandle for example. This handling is done via object type procedure. In case of WindowStation it is ExWindowStationObjectType->OkayToCloseProcedure (ExpWin32OkayToCloseProcedure). This procedure may block closing handle if required. It is common procedure for several object types so first it determine which type of object it should handle and then use Win32k callout (PsInvokeWin32Callout) passing type and requested operation index to Win32k callback. Win32k handles this in W32CalloutDispatch routine. Here you can find OkayToCloseWindowStation routine for example. It does several checks over handle bits and EPROCESS values and also may block handle closure. Same btw goes to ExWindowStationObjectType->OpenProcedure it also triggers win32 callout WindowStationOpenProcedure. Everything here is completely undocumented and subject of change between Windows versions. How does this unusual way of work (NtUserOpenWindowStation+NtClose) will affect system is something I don't really want to investigate, especially in case of Windows 10 where things are changing rapidly. However, you can use version from dev_alpha branch, replace supOpenWindowStationFromContext with commented code and replace all CloseWindowStation calls with NtClose. At your own risk of course. |
Hi, quick question. If \Sessions\2\Windows\WindowStations\WinSta0 handle in within a process (wow64) is a driver required to open that handle and use it to read the process rather than opening my own handle? Previously this has required using csrss or something else (driver) but it seems possible from usermode. Thanks |
OS: Windows 7 x64
WinObjEx64: 1.5.2
There are two window stations that are named WinSta0 that are situated in different locations:
The one, in which the interactive user works:
\Sessions\1\Windows\WindowStations\WinSta0
And the other, for services:
\Windows\WindowStations\WinSta0
These are two different window stations but WinObjEx64 shows them as if they are represented by the same object. As a result, it is not possible to view information and change security for the second window station and its desktops.
The text was updated successfully, but these errors were encountered: