Start Windows Service from Application Without Admin Right(C++)

Start Windows Service From Application without Admin right(c++)

You just need to change the permissions on the service object, preferably at the same time you install it.

wchar_t sddl[] = L"D:"
L"(A;;CCLCSWRPWPDTLOCRRC;;;SY)" // default permissions for local system
L"(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)" // default permissions for administrators
L"(A;;CCLCSWLOCRRC;;;AU)" // default permissions for authenticated users
L"(A;;CCLCSWRPWPDTLOCRRC;;;PU)" // default permissions for power users
L"(A;;RP;;;IU)" // added permission: start service for interactive users
;

PSECURITY_DESCRIPTOR sd;

if (!ConvertStringSecurityDescriptorToSecurityDescriptor(sddl, SDDL_REVISION_1, &sd, NULL))
{
fail();
}

if (!SetServiceObjectSecurity(service, DACL_SECURITY_INFORMATION, sd))
{
fail();
}

I'm assuming here you've already opened the service handle. You need WRITE_DAC permission.

If you also want non-admin users to be able to stop the service, add the WP right, i.e.,

L"(A;;RPWP;;;IU)"                           
// added permissions: start service, stop service for interactive users

SDDL codes for service rights can be found in Wayne Martin's blog entry, Service Control Manager Security for non-admins.

Windows Service start and stop without admin privileges

I have discovered the way to give a permission to start/stop the service for non admin users. We can provide a group policy for our service so this can be start/stop without administrator privilege.
I found two approach to achieve this task.

Approach 1 :

  1. Create the console from “mmc.exe”
  2. Created the blank security template
  3. Created a security database to store the policy information
  4. Change the service permission to the user which we want to give a permission
  5. Applied new security permission ( I referred this blog)

This approach works perfectly fine, I have created two non admin user account in one virtual machine and set the permission from admin account, I could able to start and stop the service from both non admin user accounts. However this approach was not a complete solution for the problem, It involves lot of manual steps. So I start looking automate this process. Result of that I found the approach 2

Approach 2 :
Grant the permission using “Subinacl.exe”, SubInACL is a command-line tool that enables administrators to obtain security information about files, registry keys, and services, and transfer this information from user to user, from local or global group to group, and from domain to domain.

I followed the same example of create two non admin user account and execute command SUBINACL /SERVICE \DomainName\MyService /GRANT=DomainName\USERS=TOP so this will grant the user to start/stop the service.

Start / Stop a Windows Service from a non-Administrator user account

Below I have put together everything I learned about Starting/Stopping a Windows Service from a non-Admin user account, if anyone needs to know.

Primarily, there are two ways in which to Start / Stop a Windows Service.
1. Directly accessing the service through logon Windows user account.
2. Accessing the service through IIS using Network Service account.

Command line command to start / stop services:

C:/> net start <SERVICE_NAME>
C:/> net stop <SERVICE_NAME>

C# Code to start / stop services:

ServiceController service = new ServiceController(SERVICE_NAME);

//Start the service
if (service.Status == ServiceControllerStatus.Stopped)
{
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10.0));
}

//Stop the service
if (service.Status == ServiceControllerStatus.Running)
{
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10.0));
}

Note 1:
When accessing the service through IIS, create a Visual Studio C# ASP.NET Web Application and put the code in there. Deploy the WebService to IIS Root Folder (C:\inetpub\wwwroot\) and you're good to go.
Access it by the url http:///.

1. Direct Access Method

If the Windows User Account from which either you give the command or run the code is a non-Admin account, then you need to set the privileges to that particular user account so it has the ability to start and stop Windows Services. This is how you do it.
Login to an Administrator account on the computer which has the non-Admin account from which you want to Start/Stop the service. Open up the command prompt and give the following command:

C:/>sc sdshow <SERVICE_NAME>

Output of this will be something like this:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

It lists all the permissions each User / Group on this computer has with regards to .

A description of one part of above command is as follows:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)

It has the default owner, default group, and it has the Security descriptor control flags (A;;CCLCSWRPWPDTLOCRRC;;;SY):

ace_type - "A": ACCESS_ALLOWED_ACE_TYPE,
ace_flags - n/a,
rights - CCLCSWRPWPDTLOCRRC, please refer to the Access Rights and Access Masks and Directory Services Access Rights
CC: ADS_RIGHT_DS_CREATE_CHILD - Create a child DS object.
LC: ADS_RIGHT_ACTRL_DS_LIST - Enumerate a DS object.
SW: ADS_RIGHT_DS_SELF - Access allowed only after validated rights checks supported by the object are performed. This flag can be used alone to perform all validated rights checks of the object or it can be combined with an identifier of a specific validated right to perform only that check.
RP: ADS_RIGHT_DS_READ_PROP - Read the properties of a DS object.
WP: ADS_RIGHT_DS_WRITE_PROP - Write properties for a DS object.
DT: ADS_RIGHT_DS_DELETE_TREE - Delete a tree of DS objects.
LO: ADS_RIGHT_DS_LIST_OBJECT - List a tree of DS objects.
CR: ADS_RIGHT_DS_CONTROL_ACCESS - Access allowed only after extended rights checks supported by the object are performed. This flag can be used alone to perform all extended rights checks on the object or it can be combined with an identifier of a specific extended right to perform only that check.
RC: READ_CONTROL - The right to read the information in the object's security descriptor, not including the information in the system access control list (SACL). (This is a Standard Access Right, please read more http://msdn.microsoft.com/en-us/library/aa379607(VS.85).aspx)
object_guid - n/a,
inherit_object_guid - n/a,
account_sid - "SY": Local system. The corresponding RID is SECURITY_LOCAL_SYSTEM_RID.

Now what we need to do is to set the appropriate permissions to Start/Stop Windows Services to the groups or users we want. In this case we need the current non-Admin user be able to Start/Stop the service so we are going to set the permissions to that user. To do that, we need the SID of that particular Windows User Account. To obtain it, open up the Registry (Start > regedit) and locate the following registry key.

LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

Under that there is a seperate Key for each an every user account in this computer, and the key name is the SID of each account. SID are usually of the format S-1-5-21-2103278432-2794320136-1883075150-1000. Click on each Key, and you will see on the pane to the right a list of values for each Key. Locate "ProfileImagePath", and by it's value you can find the User Name that SID belongs to. For instance, if the user name of the account is SACH, then the value of "ProfileImagePath" will be something like "C:\Users\Sach". So note down the SID of the user account you want to set the permissions to.

Note2:
Here a simple C# code sample which can be used to obtain a list of said Keys and it's values.

//LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList RegistryKey
RegistryKey profileList = Registry.LocalMachine.OpenSubKey(keyName);

//Get a list of SID corresponding to each account on the computer
string[] sidList = profileList.GetSubKeyNames();

foreach (string sid in sidList)
{
//Based on above names, get 'Registry Keys' corresponding to each SID
RegistryKey profile = Registry.LocalMachine.OpenSubKey(Path.Combine(keyName, sid));

//SID
string strSID = sid;
//UserName which is represented by above SID
string strUserName = (string)profile.GetValue("ProfileImagePath");
}

Now that we have the SID of the user account we want to set the permissions to, let's get down to it. Let's assume the SID of the user account is S-1-5-21-2103278432-2794320136-1883075150-1000.
Copy the output of the [sc sdshow ] command to a text editor. It will look like this:

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

Now, copy the (A;;CCLCSWRPWPDTLOCRRC;;;SY) part of the above text, and paste it just before the S:(AU;... part of the text. Then change that part to look like this:
(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)

Then add sc sdset at the front, and enclose the above part with quotes. Your final command should look something like the following:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

Now execute this in your command prompt, and it should give the output as follows if successful:

[SC] SetServiceObjectSecurity SUCCESS

Now we're good to go! Your non-Admin user account has been granted permissions to Start/Stop your service! Try loggin in to the user account and Start/Stop the service and it should let you do that.

2. Access through IIS Method

In this case, we need to grant the permission to the IIS user "Network Services" instead of the logon Windows user account. The procedure is the same, only the parameters of the command will be changed. Since we set the permission to "Network Services", replace SID with the string "NS" in the final sdset command we used previously. The final command should look something like this:

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;NS)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

Execute it in the command prompt from an Admin user account, and voila! You have the permission to Start / Stop the service from any user account (irrespective of whether it ia an Admin account or not) using a WebMethod. Refer to Note1 to find out how to do so.

Detecting registered & running service without administrator rights

You do not need admin rights to query the SCM for service information.

Call OpenSCManager() requesting SC_MANAGER_CONNECT access, then call OpenService() requesting SERVICE_QUERY_STATUS access. That will tell you if the service is installed or not. If so, then call QueryServiceStatus() to find out if it is running or not.

Start a windows service without elevation

I followed torak link and I understand this key difference concerning rights in a service:

  • a service has rights concerning the "Run as" user
  • a service has different permission to control the service (i.e. to start/stop it)

So, to start the service I need to modify the service control permission.

Well, I have done a windows service called Service1 and I made an installer with WIX.
During setup I call ServiceInstall

      <ServiceInstall Id="ServiceInstaller" Type="ownProcess" Vital="yes"
Name="Service1" DisplayName="Service1"
Description="Service1 description"Start="demand"
Account="NT AUTHORITY\LocalService"
ErrorControl="ignore" Interactive="no" >
</ServiceInstall>

Then I have a client program called TestProgram where I try to start the service:

var service = new ServiceController("Service1");
service.Start();

And obviously it doesn't start the service without elevation of TestProgram (that runs under a normal user account).

So the solution is to instruct WIX to allow members of the user group (for example) to start/stop the service, using the PermissionEx tag:

<util:PermissionEx User="Users" ServiceStart="yes" ServiceStop="yes">
</util:PermissionEx>

Hope this helps. Thank you all.



Related Topics



Leave a reply



Submit