-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Question: has anyone tried or succeeded at converting the client into a Windows Service? #612
Comments
Due to windows service starts as Local System user, which has no access for the UI, we cannot convert Client.exe to a service |
I have been learning about sessions and workstations and desktops, and there are API calls that let me access the desktop of the logged on user.
There is another API that lets me use the security of the local system account (no need to elevate because, as a service, it's already elevated).
So as long as my service is set to interact with the desktop, I can use it to (remotely) run a program, either in the security context of the logged on user, OR as the local system account.
If you want code samples, please let me know :)
On Jul 11, 2017 5:09 AM, santoshcxs <[email protected]> wrote:
Due to windows service starts as Local System user, which has no access for the UI.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#612 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AP6yZm-AyOwt0zU3ShNusdY57-ZpD-k8ks5sMzuYgaJpZM4OAwNz>.
|
Look up WTS API calls and look up winsta0
On Jul 11, 2017 5:09 AM, santoshcxs <[email protected]> wrote:
Due to windows service starts as Local System user, which has no access for the UI.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#612 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AP6yZm-AyOwt0zU3ShNusdY57-ZpD-k8ks5sMzuYgaJpZM4OAwNz>.
|
Please provide me code samples and reference URLs if any. I need to implement the client as windows service. |
While I have made edits, the credit for this code goes to: Pero Matić<https://www.codeproject.com/script/Membership/View.aspx?mid=1298714>, 22 Apr 2009 and it is documented in CodeProject, here:
https://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-and-bit-Archite
Here’s the code for running as local system or as user, on the desktop of the currently logged on user:
public enum ACCOUNT_TYPE : int
{
System,
User
}
public bool StartProcessAndBypassUAC(ACCOUNT_TYPE AccountType, String Executable, String Arguments, out PROCESS_INFORMATION procInfo)
{
bool result = false;
procInfo = new PROCESS_INFORMATION();
switch (AccountType)
{
case ACCOUNT_TYPE.System:
uint winlogonPid = 0;
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;
uint dwSessionId = NativeMethods.WTSGetActiveConsoleSessionId();
Process[] processes = Process.GetProcessesByName("winlogon");
foreach (Process p in processes)
{
if ((uint)p.SessionId == dwSessionId)
{
winlogonPid = (uint)p.Id;
}
}
hProcess = NativeMethods.OpenProcess(Constants.MAXIMUM_ALLOWED, false, winlogonPid);
if (!NativeMethods.OpenProcessToken(hProcess, Constants.TOKEN_DUPLICATE, ref hPToken))
{
NativeMethods.CloseHandle(hProcess);
return false;
}
sa.Length = Marshal.SizeOf(sa);
if (!NativeMethods.DuplicateTokenEx(hPToken, Constants.MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup))
{
NativeMethods.CloseHandle(hProcess);
NativeMethods.CloseHandle(hPToken);
return false;
}
STARTUPINFO si = new STARTUPINFO();
si.cb = (int)Marshal.SizeOf(si);
si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
int dwCreationFlags = Constants.NORMAL_PRIORITY_CLASS | Constants.CREATE_NEW_CONSOLE;
result = NativeMethods.CreateProcessAsUser(
hUserTokenDup, // client's access token
Executable, // file to execute
Arguments, // command line
ref sa, // pointer to process SECURITY_ATTRIBUTES
ref sa, // pointer to thread SECURITY_ATTRIBUTES
false, // handles are not inheritable
dwCreationFlags, // creation flags
IntPtr.Zero, // pointer to new environment block
null, // name of current directory
ref si, // pointer to STARTUPINFO structure
out procInfo // receives information about new process
);
NativeMethods.CloseHandle(hProcess);
NativeMethods.CloseHandle(hPToken);
NativeMethods.CloseHandle(hUserTokenDup);
return result; // return the result
case ACCOUNT_TYPE.User:
IntPtr ppSessionInfo = IntPtr.Zero;
UInt32 SessionCount = 0;
if (NativeMethods.WTSEnumerateSessions(
(IntPtr)Constants.WTS_CURRENT_SERVER_HANDLE, // Current RD Session Host Server handle would be zero.
0, // This reserved parameter must be zero.
1, // The version of the enumeration request must be 1.
ref ppSessionInfo, // This would point to an array of session info.
ref SessionCount // This would indicate the length of the above array.
))
{
for (int nCount = 0; nCount < SessionCount; nCount++)
{
WTS_SESSION_INFO tSessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure(
ppSessionInfo + nCount * Marshal.SizeOf(typeof(WTS_SESSION_INFO)),
typeof(WTS_SESSION_INFO)
);
if (WTS_CONNECTSTATE_CLASS.WTSActive == tSessionInfo.State)
{
IntPtr hToken = IntPtr.Zero;
if (NativeMethods.WTSQueryUserToken(tSessionInfo.SessionID, out hToken))
{
// Launch the child process interactively
// with the token of the logged-on user.
PROCESS_INFORMATION tProcessInfo;
STARTUPINFO tStartUpInfo = new STARTUPINFO();
tStartUpInfo.cb = Marshal.SizeOf(typeof(STARTUPINFO));
result = NativeMethods.CreateProcessAsUser(
hToken, // Token of the logged-on user.
Executable, // Name of the process to be started.
Arguments, // Any command line arguments to be passed.
IntPtr.Zero, // Default Process' attributes.
IntPtr.Zero, // Default Thread's attributes.
false, // Does NOT inherit parent's handles.
0, // No any specific creation flag.
null, // Default environment path.
null, // Default current directory.
ref tStartUpInfo, // Process Startup Info.
out tProcessInfo // Process information to be returned.
);
if (result)
{
NativeMethods.CloseHandle(tProcessInfo.hThread);
NativeMethods.CloseHandle(tProcessInfo.hProcess);
}
else
{
// CreateProcessAsUser failed!
}
// Whether child process was created or not, close the token handle
// and break the loop as processing for current active user has been done.
NativeMethods.CloseHandle(hToken);
break;
}
else
{
// WTSQueryUserToken failed!
}
}
else
{
// This Session is not active!
}
}
// Free the memory allocated for the session info array.
NativeMethods.WTSFreeMemory(ppSessionInfo);
return result;
}
else
{
return false;
// WTSEnumerateSessions failed!
}
}
return false;
}
|
Oops – I sent that too soon – I need to add in the API calls… Whatever I have not listed here, you can find at the CodeProject URL I sent in my last e-mail.
[DllImport("kernel32.dll")]
internal static extern uint WTSGetActiveConsoleSessionId();
[DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
internal static extern bool OpenProcessToken(
IntPtr ProcessHandle,
uint DesiredAccess,
ref IntPtr TokenHandle);
[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
internal extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,
ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool CloseHandle(IntPtr hSnapshot);
[DllImport("WTSAPI32.DLL", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern bool WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] UInt32 Reserved,
[MarshalAs(UnmanagedType.U4)] UInt32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref UInt32 pSessionInfoCount);
[DllImport("Wtsapi32.dll", SetLastError = true)]
static extern bool WTSQuerySessionInformation(
IntPtr hServer,
uint sessionId,
WTS_INFO_CLASS wtsInfoClass,
out IntPtr ppBuffer,
out uint pBytesReturned);
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
internal static extern bool CreateProcessAsUser(
IntPtr hToken,
String lpApplicationName,
String lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandle,
int dwCreationFlags,
IntPtr lpEnvironment,
String lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
|
What I would REALLY love\appreciate is help implementing a remote-desktop feature from this service.
I have code for most of this, but would appreciate it if anyone can\will collaborate with me.
I can also share lots of WMI code I have that affects remote machines without having to install a client:
![image](https://user-images.githubusercontent.com/16691814/28070813-36315d70-661c-11e7-9403-caae06d6180c.png)
![image](https://user-images.githubusercontent.com/16691814/28070896-6ee26f60-661c-11e7-8ad0-8b863a82617e.png)
![image](https://user-images.githubusercontent.com/16691814/28070901-729841f2-661c-11e7-9936-4c569fcf1ba7.png)
![image](https://user-images.githubusercontent.com/16691814/28070904-758ecebc-661c-11e7-8890-bef29abd21e4.png)
![image](https://user-images.githubusercontent.com/16691814/28070912-78a712d0-661c-11e7-9252-5101fb7a20af.png)
![image](https://user-images.githubusercontent.com/16691814/28070918-7b2fc5e2-661c-11e7-963e-5858d2a523d4.png)
|
So, in short, here are my goals:
* Have an application that can manage remote machines without having to install a client (and I have most of this already done)
* For those functions that need a client, have my program install (remotely) a service I have created, and that service can:
- both run programs (elevated and interactive), and
- instantiate an instance of the QuasarRAT client object.
When the service is started, it accepts command-line arguments including the host name and IP address of the machine which installed the service, and that tell the client where to attempt to connect.
What I am working on now is trying to think of a way to convert what exists (a list view which shows all clients connected) to really only managing one machine at a time.
That means I would:
* Choose a target computer
* Install my service on it, passing it my host and IP
* Instantiate the QuasarRAT client, telling it to connect to my computer
* Be able to perform QuasarRAT functions I don’t already have in my existing program.
The ones I am really excited about are the remote command console and remote desktop (not using Windows Remote Desktop).
** Oh, also, I had to take out code in the client piece that allowed for the renaming and hiding of the client.exe – that was triggering Windows Defender.
Sorry for sending so much, but I have been working on this project for more than 2 years, all alone and unsupported, so I would LOVE some collaboration or at least someone\someones with whom to share ideas and knowledge.
|
Wow... Impressive UI changes. |
I would be more than happy to provide any\all code and UI development, but first I think we need to reconcile the basic difference between how my app works and how Quasar RAT works – specifically, RAT shows the list of clients which have connected, while I focus on choosing one target computer at a time, and performing actions on\against it.
The majority of my remote functions don’t require installation of a client\service on the target, so I would only need to do that for certain functions.
Also, I don’t rely on install\uninstall scripts, I install my remote service programmatically from the main app form – since the account used to run it is (by AD security group) already a local admin on all target computers.
I am not necessarily opposed to changing my tool to show the same kind of selection listview RAT does, but once a target computer connected, I would want to change to a form\screen that looks generally like mine does now.
I’ve been through several iterations of interfaces, trying to get to the simplest, easiest to understand UI I can possibly provide.
The folks using this tool where I work run the gamut from HIGHLY technical to “I was promoted from desk-side support, and I am just learning” – which means things that may be intuitive to me\us (navigating a tree, using a wizard, drilling-down) are not for them.
Oh, and I would need to make sure that the code I end up with does not have any aspect of keylogging, recovering passwords, hiding\renaming its own .exe, nor accessing or activating webcams.
Those things would be forbidden where I work.
In exchange (and it doesn’t have to be an equal exchange) for providing my code and UI elements, I would ask for some help\collaboration.
Is that do-able?
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
From: Justin Yanke<mailto:[email protected]>
Sent: Tuesday, July 11, 2017 12:34 PM
To: quasar/QuasarRAT<mailto:[email protected]>
Cc: seancroberts<mailto:[email protected]>; Author<mailto:[email protected]>
Subject: Re: [quasar/QuasarRAT] Question: has anyone tried or succeeded at converting the client into a Windows Service? (#612)
Wow... Impressive UI changes.
Have you considered committing your changes to source control for us or are you keeping it private?
I'd be willing to see what I can do.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#612 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AP6yZjsahFvUqxZYORDKFj_E7za7llFsks5sM6P4gaJpZM4OAwNz>.
|
So, does anyone want to work together\collaborate? |
I would love to help. Unfortunately I cannot code (yet). I want to learn to code and collaborate with this project. Here are a few of my skills that might come in handy for this project:
|
That is very kind of you, thank you.
May we start a discussion with this topic?
What would be the best (we can define this as we go) way to integrate or consolidate the two methods used by our programs into one UI.
At the moment, the Quasar RAT shows a listview of machines on which the client .exe has been installed.
My application looks to select one computer at a time, via AD dialog or history.
Should the first screen by a use be one of these types of approaches? Both? If both, how would you combine them (look at feel)?
Also, if this is not the appropriate forum\method to have a discussion like this, please accept my apology and tell me how\where I should hold it.
Sent from Mail<https://go.microsoft.com/fwlink/?LinkId=550986> for Windows 10
From: Sad Robot<mailto:[email protected]>
Sent: Friday, July 14, 2017 4:23 AM
To: quasar/QuasarRAT<mailto:[email protected]>
Cc: seancroberts<mailto:[email protected]>; Author<mailto:[email protected]>
Subject: Re: [quasar/QuasarRAT] Question: has anyone tried or succeeded at converting the client into a Windows Service? (#612)
I would love to help. Unfortunately I cannot code (yet). I want to learn to code and collaborate with this project.
What I can do right now, is offer myself for testing purposes and giving feedback. I have a lot of old machines (and VMs) I can use as a testing lab. I already have Visual Studio Community Edition 2017 set up and testet a few features of QuasarRAT.
I personally am aiming to use this project for business purposes, so striping out the black hat parts (key logging/surveillance etc.) is also in my interest (and mandatory).
Never the less, I think giving the dev/admin/user of these tools the ability, to decide for themselves what they stripe out should be kept in mind. So the Plug-In system, mentioned here #534> should be considered to be adapted.
Here are a few of my skills that might come in handy for this project:
* basic commandline scripting (bash and batch lin/win)
* basic system/network administration
* setting up services on servers (lin/win)
* artwork creation/editing
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#612 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AP6yZksMmB0_AL3jzyNOxUEsLxZMyY0fks5sNyVggaJpZM4OAwNz>.
|
Closed in favor of #1199 |
I have rights sufficient to install Windows Services on my company's computers, and I already have code that can launch executables as local system or as logged on use.
I also have my service set to interact with the desktop.
Can anyone think if a reason why the client.exe could not be turned into a Service?
The text was updated successfully, but these errors were encountered: