jhshukla
asked on
Impersonate as SYSTEM
I want to access files stored under "X:\System Volume Information" but I cannot do so even with Admin provoleges. I have seen virus scanners (McAfee to be specific) scan that folder even when a "User" is loggen on. I bet the process runs with SYSTEM privileges - a bit higher than Admin. How can I impersonate the SYSTEM account?
the actual goal is to read file information from that folder. so if there is a way to access that info without impersonation that would be much better from security standpoint. I am looking for a solution in .NET but C/C++ would work.
the actual goal is to read file information from that folder. so if there is a way to access that info without impersonation that would be much better from security standpoint. I am looking for a solution in .NET but C/C++ would work.
ASKER
ok that makes sense. is there a way to impersonate the SYSTEM without getting a list of processes?
ASKER
I got to the point where i can get process handles from PID but OpenProcessToken fails with GetLastError = 5 (Access denied). here is relevant code (C#):
private void Impersonate()
{
int pid = GetSystemPID();
const int TOKEN_IMPERSONATE = 0x0004; // copied from WinNT.h
const int READ_CONTROL = 0x00020000; // copied from WinNT.h
const int PROCESS_QUERY_INFORMATION = 0x0040; // copied from WinNT.h
int tokenHandle = 0;
int proc = OpenProcess(READ_CONTROL | PROCESS_QUERY_INFORMATION, false, pid);
bool returnValue = OpenProcessToken(proc, TOKEN_IMPERSONATE, ref tokenHandle);
if ( returnValue == true )
{
MessageBox.Show("Token Obtained");
}
else
{
MessageBox.Show(String.For mat("Error {0}", GetLastError()));
}
...
}
private int GetSystemPID()
{
System.Diagnostics.Process [] procs = System.Diagnostics.Process .GetProces ses(); // lists ALL running processes, even those that don't appear in TaskMgr
for ( int i=0; i<procs.Length; i++ )
{
if ( procs[i].ProcessName.Compa reTo("Syst em") == 0) // THE system process other than SysIdleProc. PID = 4
return procs[i].Id;
}
return -1;
}
private void Impersonate()
{
int pid = GetSystemPID();
const int TOKEN_IMPERSONATE = 0x0004; // copied from WinNT.h
const int READ_CONTROL = 0x00020000; // copied from WinNT.h
const int PROCESS_QUERY_INFORMATION = 0x0040; // copied from WinNT.h
int tokenHandle = 0;
int proc = OpenProcess(READ_CONTROL | PROCESS_QUERY_INFORMATION,
bool returnValue = OpenProcessToken(proc, TOKEN_IMPERSONATE, ref tokenHandle);
if ( returnValue == true )
{
MessageBox.Show("Token Obtained");
}
else
{
MessageBox.Show(String.For
}
...
}
private int GetSystemPID()
{
System.Diagnostics.Process
for ( int i=0; i<procs.Length; i++ )
{
if ( procs[i].ProcessName.Compa
return procs[i].Id;
}
return -1;
}
ASKER
one more piece of info. gives me the same error even if i try to get the token from the current process.
Hm, what account are you running that under?
Also, would be using a service too much effort?
Also, would be using a service too much effort?
ASKER
Admin account, and where did i say i run a service? it is just a regular .NET application.
>>and where did i say i run a service?
Nowhere, I brought that up earlier, since services run under 'LocalSystem' natively and therefore can access that directory.
Nowhere, I brought that up earlier, since services run under 'LocalSystem' natively and therefore can access that directory.
ASKER
yes it would be too much effort. this program just reads and reports disk usage for all folders on given drive. too much effort to run the program. not too much to change the settings to make a service.
another thing that is noticed was that mcconsol.exe (GUI to McAfee) ran as admin and was still able to access SysVolInfo. I wonder if it was using a service to get raw data.
another thing that is noticed was that mcconsol.exe (GUI to McAfee) ran as admin and was still able to access SysVolInfo. I wonder if it was using a service to get raw data.
ASKER
I had to combine TOKEN_IMPERSONATE | TOKEN_QUERY to get the token for a process. I can impersonate as admin through any other process started by admin but I am still unable to impersonate as the localsystem.
Bad news here, too. I did some experiments (even though I did not mention that here, sorry) and checked some earlier projects, but the security set on that process does not seem to allow to get an impersonation token even from a process that runs as admin. What I did in the past to overcome that all ends up with having a service running and communicate with that one, so that ends up in a circle...
ASKER
okay, I do not plan to release the prog to anyone else. it will be running only on my machine and i know that i will have certain services running all the time. is it possible to impersonate the system using token from any other process? i haven't had luck so far. I have been requesting minimal privileges:
HANDLE hProc = OpenProcess(READ_CONTROL | PROCESS_QUERY_INFORMATION, false, PID);
retVal = OpenProcessToken(hProc, TOKEN_IMPERSONATE | TOKEN_QUERY | STANDARD_RIGHTS_READ, &hToken);
HANDLE hProc = OpenProcess(READ_CONTROL | PROCESS_QUERY_INFORMATION,
retVal = OpenProcessToken(hProc, TOKEN_IMPERSONATE | TOKEN_QUERY | STANDARD_RIGHTS_READ, &hToken);
ASKER
another thought. what if i create an on-demand service? will that service run with localsystem privileges? what i plan to do is create a launcher application that will start the service and the service will do whatever my original application was supposed to do.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>>what if i create an on-demand service? will that service run with localsystem privileges?
Yes, that's what I am having in mind and currently am working on... it's just not non-trivial, and I am quite busy, so bear with me.
Yes, that's what I am having in mind and currently am working on... it's just not non-trivial, and I am quite busy, so bear with me.
ASKER
>> Easiest way to impersonate system is with the built-in scheduler service.
>> Just run at (current time + 2 minutes) /interactive cmd.exe
how? where?
>> it's just not non-trivial
do two negations mean it is trivial?
>> Just run at (current time + 2 minutes) /interactive cmd.exe
how? where?
>> it's just not non-trivial
do two negations mean it is trivial?
The command called "at"....
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.
AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
[ /EVERY:date[,...] | /NEXT:date[,...]] "command"
\\computername Specifies a remote computer. Commands are scheduled on the
local computer if this parameter is omitted.
id Is an identification number assigned to a scheduled
command.
/delete Cancels a scheduled command. If id is omitted, all the
scheduled commands on the computer are canceled.
/yes Used with cancel all jobs command when no further
confirmation is desired.
time Specifies the time when command is to run.
/interactive Allows the job to interact with the desktop of the user
who is logged on at the time the job runs.
/every:date[,...] Runs the command on each specified day(s) of the week or
month. If date is omitted, the current day of the month
is assumed.
/next:date[,...] Runs the specified command on the next occurrence of the
day (for example, next Thursday). If date is omitted, the
current day of the month is assumed.
"command" Is the Windows NT command, or batch program to be run.
The AT command schedules commands and programs to run on a computer at
a specified time and date. The Schedule service must be running to use
the AT command.
AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]
AT [\\computername] time [/INTERACTIVE]
[ /EVERY:date[,...] | /NEXT:date[,...]] "command"
\\computername Specifies a remote computer. Commands are scheduled on the
local computer if this parameter is omitted.
id Is an identification number assigned to a scheduled
command.
/delete Cancels a scheduled command. If id is omitted, all the
scheduled commands on the computer are canceled.
/yes Used with cancel all jobs command when no further
confirmation is desired.
time Specifies the time when command is to run.
/interactive Allows the job to interact with the desktop of the user
who is logged on at the time the job runs.
/every:date[,...] Runs the command on each specified day(s) of the week or
month. If date is omitted, the current day of the month
is assumed.
/next:date[,...] Runs the specified command on the next occurrence of the
day (for example, next Thursday). If date is omitted, the
current day of the month is assumed.
"command" Is the Windows NT command, or batch program to be run.
ASKER
isn't it equivalent to "scheduled task"?
ASKER
thanks both of you guys.
The "at" command and scheduled tasks both use the scheduler service, but they give you different options. I don't know any way using at to schedule for startup, shutdown, or idle, which you can do with the scheduled tasks property page. At does let you run as SYSTEM and interact with the program graphically, which Scheduled Tasks doesn't/
The easiest way would IMO be a small service that - by default - runs as 'LocalSystem' to gather that information. Youcould also obtain a token from a process that is running under that account(services.exe or svchost.exe is a good choice <s>). You'll need the PID to call 'OpenProcess()', then 'OpenProcessToken()' with 'TOKEN_IMPERSONATE' access. See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q175030 ("HOWTO: Enumerate Applications Using Win32 APIs (Q175030)") on how to get that PID - it comes with sample code. Then, once you have the token, you have to call 'ImpersonateLoggedOnUser()