private bool IsAuthorized(int clientPid, int allowedPid) { var callingExe = SymbolicLinkSupport.ResolveSymbolicLink(Process.GetProcessById(clientPid).MainModule.FileName); var allowedExe = SymbolicLinkSupport.ResolveSymbolicLink(Process.GetCurrentProcess().MainModule.FileName); // if (callingExe != allowedExe) { Logger.Instance.Log($"Invalid Client. Rejecting Connection. \nAllowed: {allowedExe}\nActual: {callingExe}", LogLevel.Error); return(false); } if (allowedPid == -1) { return(true); } while (clientPid > 0) { if (allowedPid == clientPid) { return(true); } else { clientPid = ProcessExtensions.ParentProcessId(clientPid); } } Logger.Instance.Log($"Invalid Client Credentials. Rejecting Connection. \nAllowed Pid: {allowedPid}\nActual Pid: {clientPid}", LogLevel.Error); return(false); }
public NamedPipeServer(int allowedPid, string allowedSid, bool singleUse) { _allowedPid = allowedPid; _allowedSid = allowedSid; _singleUse = singleUse; _allowedExe = SymbolicLinkSupport.ResolveSymbolicLink(ProcessHelper.GetOwnExeName()); if (new Uri(_allowedExe).IsUnc) { _allowedExeLength = -1; // Workaround for #27: Running gsudo from mapped drive. (see IsAuthorized) // If we were invoked from a network drive, once elevated we won't be able to read the network drive because is not connected on the elevated session, // therefore this protection is disabled, or else it always fails. } else { var fileInfo = new System.IO.FileInfo(_allowedExe); _allowedExeTimeStamp = fileInfo.LastWriteTimeUtc; _allowedExeLength = fileInfo.Length; } #if !DEBUG _exeLock = File.Open(ProcessHelper.GetOwnExeName(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite); #endif }
private bool IsAuthorized(int originalClientPid, int allowedPid) { int clientPid = originalClientPid; Process clientProcess = null; ProcessModule clientProcessMainModule = null; clientProcess = Process.GetProcessById(clientPid); clientProcessMainModule = clientProcess.MainModule; if (_allowedExeLength != -1) { var callingExe = SymbolicLinkSupport.ResolveSymbolicLink(clientProcessMainModule.FileName); var fileInfo = new System.IO.FileInfo(callingExe); var callingExeTimeStamp = fileInfo.LastWriteTimeUtc; var callingExeLength = fileInfo.Length; if (callingExe != _allowedExe || callingExeLength != _allowedExeLength || callingExeTimeStamp != _allowedExeTimeStamp) { // I'm not checking the SHA because it would be too slow. Logger.Instance.Log( $"Invalid Client. Rejecting Connection. \nAllowed: {_allowedExe}\nActual: {callingExe}", LogLevel.Error); return(false); } } #if !DEBUG if (clientProcessMainModule != null) { // Check if a malicious process is attached to the client. Results are only valid if we are elevated and the malicious process is not. // But still a futile attempt since the user can Attach, bool isDebuggerAttached = false; if (!Native.ProcessApi.CheckRemoteDebuggerPresent(clientProcess.SafeHandle, ref isDebuggerAttached) || isDebuggerAttached) { Logger.Instance.Log($"Rejecting to avoid process tampering. ", LogLevel.Error); return(false); } } #endif if (allowedPid == 0) { return(true); } // TODO: Decide if I want to allow all children and grandsons, or only direct children. // It's trivial on Windows to fake a your parent PID. // So this "security" check is easily avoidable for advanced hackers. // Only allow direct child. /* * clientPid = ProcessHelper.GetParentProcessIdExcludingShim(clientPid); * if (AllowedPid == clientPid) * return true; */ /* Recursive allow all childrens*/ while (clientPid > 0) { if (allowedPid == clientPid) { return(true); } else { clientPid = ProcessHelper.GetParentProcessId(clientPid); } } //--* / Logger.Instance.Log( $"Invalid Client Credentials. Rejecting Connection. \nAllowed Pid: {allowedPid}\nActual Pid: {originalClientPid}", LogLevel.Error); return(false); }