InstaTech_Client | screen sharing application for providing remote tech support
kandi X-RAY | InstaTech_Client Summary
kandi X-RAY | InstaTech_Client Summary
Compatibility: Windows 7, 8, and 10. The WPF version is a small, portable EXE for Windows. It contains the Windows Service and can be used from the command line in the same way.
Support
Quality
Security
License
Reuse
Top functions reviewed by kandi - BETA
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample of InstaTech_Client
InstaTech_Client Key Features
InstaTech_Client Examples and Code Snippets
Community Discussions
Trending Discussions on InstaTech_Client
QUESTION
I've been banging my head against this for several hours, so I figured it's time to ask. I'll start with a high-level description of the situation. You can find the entire source code at https://github.com/Jay-Rad/InstaTech_Client. This question only pertains to the project in "/InstaTech_Service/".
Overview
The InstaTech client is a remote control app that uses websockets and makes an outbound connection to an ASP.NET server for relay with the viewer. I have different versions, but they all function roughly the same (the Electron version tries WebRTC first before using raw websockets). The viewer portion of the app is web-based, and a demo can be found here: https://instatech.org/Demo/Remote_Control
The WPF (C#) and Electron versions present a GUI with a random ID that they must provide to the person remoting into their computer (similar to TeamViewer). Once a session is started, they capture the screen in different ways. For C#, I'm using a pinvoke to BitBlt to copy the image to an in-memory graphic, which is then sent through the websocket. Subsequent screen captures are compared to the previous one to create a box that encompasses the changed pixels, then that cropped section is sent. Mouse and keyboard inputs are received by the client and executed via pinvoke to keybd_event and mouse_event. These are working great.
The service I created works in similar fashion, but here are the differences. The service itself runs in session 0 under System account. It connects to the server and listens on the websocket. When a connection is made and screen viewing is requested, it launches a separate interactive process in the user's session in WinSta0\Default. Once the new process's websocket is connected, the server begins relaying messages between it and the viewer instead of the service and the viewer.
Although the new process is launched interactively in the user's session, it's running under the System account. This is achieved by a pinvoke to CreateProcessAsUser and duplicating the winlogon.exe access token.
The Problem
This solution works fine if someone is already logged in, even if via RDP. However, if nobody is logged in or the computer gets locked, I can't interact with the logon screen. When doing the screen capture, I'm detecting if the capture fails, which would mean the WinSta0\Default desktop is no longer active. Since I'm using CreateProcessAsUser, I can switch desktops to the WinSta0\Winlogon just fine. I can still see it (even if no one is logged in), but it won't take any inputs. I understand that this is by design for security reasons. Well, strangely, some mouse movements "slip through" if I'm moving it around and cause the cursor to reposition, but the rest get sent to the Default desktop and execute once logged back in.
So the problem is that I can't get an account logged into the computer with this setup. If it matters, I don't care to interact with the Winlogon desktop if someone else is already logged in and locked the computer. I only want to be able to log in if no one else is using it, or it's my account that's logged in and at the lock screen.
Attempted Solutions
I'm assuming that there's no way to circumvent the inability to send simulated inputs to the Winlogon desktop. (Correction: That is, using mouse_event and keybd_event functions. I've seen other applications do it, like TeamViewer and Microsoft SCCM Remote Control. I'm not sure how they do it, though.) If it is somehow possible, I think that'd be the most direct route. But here are some things I've looked into that focus on getting a new logon session started.
Pinvoke to LsaLogonUser. I'm not sure if this would accomplish what I'm after, but I tried anyway. However, even though the call to LsaLogonUser reports success, the handle I'm getting from LsaRegisterLogonProcess (out to lsaHan) is 0. I'm not sure what I'm doing wrong. I'm not too familiar with Win32 calls and trying to pick it up as I go. Maybe the calling process doesn't have the necessary rights. I've tried calling this from the service in session 0 and from the process running in the interactive session. An example of what I'm doing is below.
Microsoft Terminal Services Active Client COM library. I haven't dug too deeply into this, but I wonder if it might be possible to use this to initiate an RDP logon session. Once an RDP logon session is made, spawn a new InstaTech process in that session and connect to it. I doubt this would work if the RDP connection is being attempted from the same computer, though.
Credential Provider. I came across credential providers while researching. I'm not sure if creating one would solve the problem, but it sounds like it'd be a terribly complicated undertaking.
Does anyone have any suggestions? Or am I missing something entirely?
If you'd like to recompile the service and test things, I created a temporary admin account on the server. Any computer with the service installed will show up there, and you can log in using this account. Please keep in mind that anyone reading this post will be able to access any computers running the service, so make sure it's in an isolated environment.
Username: admin
Password: plzh@lpm3purdyplz
The service is self-installing. Pass the -install switch to install, -uninstall to uninstall. The EXE is copied to %programdata%\InstaTech, and the service starts it from there.
Thank you!
Reference Code
...ANSWER
Answered 2020-Feb-16 at 02:34I got SendInput to work on the logon desktop (and, as it turns out, the UAC secure desktop). SetThreadDesktop must not give you the same privileges as if you'd initially started the process in the target desktop.
So when I detected a desktop change, instead of calling SetThreadDesktop, I launched yet another process in the new desktop with CreateProcessAsUser. Then I signaled for the viewer to switch and closed the current process.
Edit (years later): I ended up being wrong about this. You just need ensure your current thread doesn't have any open windows or hooks in the current desktop. And since this only sets the desktop for the calling thread (not the process), subsequent threads will need to call this as well.
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install InstaTech_Client
Support
Reuse Trending Solutions
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesStay Updated
Subscribe to our newsletter for trending solutions and developer bootcamps
Share this Page