Search code examples
c#.netlinuxprocess

Running c# Process with higher privileges and password in Linux


I'm trying to run a c# (.net6) process with higher privileges in Linux with a password that has a dollar sign ($) and it always fails. I've tried:

var stInfo = new ProcessStartInfo
{
    FileName = "echo",
    Arguments = " 'pas$word' | sudo -S ping 127.0.0.1"
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    CreateNoWindow = true,
};

But I receive everything as part of echo, and the stdout is:

'pas$word' | sudo -S ping 127.0.0.1

Then I tried calling bash with the arguments in a similar way as it works for me running from terminal /bin/bash -c "echo 'pas\$word' | sudo -S ping 127.0.0.1":

var stInfo = new ProcessStartInfo
{
    FileName = "/bin/bash",
    Arguments = "-c \"echo 'pas\$word' | sudo -S ping 127.0.0.1\""
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    CreateNoWindow = true,
};

But that doesn't work and reports this over stderr:

[sudo] password for user: Sorry, try again.
[sudo] password for user: 
sudo: no password was provided
sudo: 1 incorrect password attempt

I've tried different Arguments like:

Arguments = "-c \"echo pas$word | sudo -S ping 127.0.0.1\""
Arguments = "-c \"echo 'pas$word' | sudo -S ping 127.0.0.1\""
Arguments = "-c \"echo pas\\$word | sudo -S ping 127.0.0.1\""
Arguments = "-c \"echo 'pas\\$word' | sudo -S ping 127.0.0.1\""
Arguments = "-c \"echo pas\\\\$word | sudo -S ping 127.0.0.1\""
Arguments = "-c \"echo 'pas\\\\$word' | sudo -S ping 127.0.0.1\""

all of them with the same result. I've tried as well using the ArgumentList instead of the Arguments, but same result.

Any idea to get it working?

UPDATE: I've changed the password to one without dollar sign to avoid scaping it, and I continue having the same problem, so the problem is not scaping the dollar sign, but injecting the pwd to the process


Solution

  • Please try this:

    using System.Diagnostics;
    
    class Program
    {
        static void Main()
        {
            var password    = ""; // Replace with your actual password
            var command     = "/bin/bash";
            var sudoCommand = "ping 127.0.0.1";
            var arguments   = $"-c \"echo '{password}' | sudo -S -p '' {sudoCommand}\"";
    
            ExecuteCommand(command, arguments);
        }
    
        static void ExecuteCommand(string command, string arguments)
        {
            var process = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName               = command,
                    Arguments              = arguments,
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    UseShellExecute        = false,
                    CreateNoWindow         = true
                }
            };
    
            process.Start();
    
            // Read the output and error streams
            var output = process.StandardOutput.ReadToEnd();
            var error  = process.StandardError.ReadToEnd();
    
            process.WaitForExit();
    
            // Display the output and error
            Console.WriteLine("Output:");
            Console.WriteLine(output);
    
            Console.WriteLine("Error:");
            Console.WriteLine(error);
        }
    }
    

    I tested this on Ubuntu 22 and everything was fine.