Bash 进程对象在Mono中不起作用
我试图运行一个简单的转义命令,但没有得到响应,没有输出缓冲区,但是如果我删除$symbol,效果会很好。我该怎么办Bash 进程对象在Mono中不起作用,bash,mono,Bash,Mono,我试图运行一个简单的转义命令,但没有得到响应,没有输出缓冲区,但是如果我删除$symbol,效果会很好。我该怎么办 public class Executor { private Process proc; public Executor () { this.proc = new Process(); this.proc.StartInfo.UseShellExecute = false; this.proc.StartI
public class Executor
{
private Process proc;
public Executor ()
{
this.proc = new Process();
this.proc.StartInfo.UseShellExecute = false;
this.proc.StartInfo.RedirectStandardError = true;
this.proc.StartInfo.RedirectStandardInput = true;
this.proc.StartInfo.RedirectStandardOutput = true;
}
public String call(String command){
this.proc.StartInfo.FileName = "/bin/bash";
this.proc.StartInfo.Arguments = "-c $'" + stringToHexEscape(command) + "'";
this.proc.Start();
String result = this.proc.StandardOutput.ReadToEnd ();
this.proc.WaitForExit();
this.proc.Close ();
return result;
}
public String stringToHexEscape(String buffer){
byte[] ba = Encoding.Default.GetBytes(buffer);
String hexString = BitConverter.ToString(ba);
if (String.IsNullOrEmpty (hexString))
return "";
return ("\\x" + hexString.Replace("-", "\\x")).Trim();
}
}
在命令行中,请尝试:
Executor executor = new Executor ();
String result = this.executor.call (
"[ -f ~/.ssh/id_rsa.pub ] && echo \"Found\" || echo \"Not found\""
);
Console.WriteLine("stdout: {0}", result);
但结果是空字符串。来自bash的工作原理很好:
me@Unknow:~$ /bin/bash -c $'echo \x61'
a
已更新编辑的问题:
当前的核心问题是子进程I/O std/err重定向到父进程。如果将其设置为true,则可以通过UseShellExecute查看:
Process.StartInfo.UseShellExecute = true;
您将能够执行您正在尝试“执行”的目标,但实际上您正在使用内置程序进行bash评估。当然,在这种情况下不能使用shell重定向,因为这在Process类中是不可能的。创建一个控制台测试应用程序,使用UseShellExecute=true,无需重定向,您将看到您的评估按预期工作,现在您只需捕获该输出
有许多方法可以解决这个问题,许多方法使用Bashim技术,例如使用coproc和/或其他子进程输出重定向,即使用exec创建另一个输出并重定向子输出。哪条路更好。。。如果你经常在你的应用程序中这样做,有些人会说使用posix外壳,它不会像dash那样进行子进程替换。。。但再一次,个人偏好
这是一种管道技术,我已经使用了很多次,因为我不必修改bash计算字符串,只需重定向我感兴趣的部分或全部输出
顺便说一句:也许我错过了什么。就防止注入而言,任何拥有进程权限的人都可以对任何系统调用(包括这些)进行扫描,从而监视您的shell/bash调用,并通过gdb将代码注入到这些进程中
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
namespace consoleEcho
{
class MainClass
{
[DllImport ("libc")]
private static extern int system (string exec);
public static void Main (string[] args)
{
Process.Start ("mkfifo", "/tmp/fifo");
system (" [ -f ~/.ssh/id_rsa.pub ] && echo 'Found' >/tmp/foobar || echo 'Not found' >/tmp/foobar ");
var proc = new Process ();
proc.StartInfo.FileName = "cat";
proc.StartInfo.Arguments = "/tmp/foobar";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
String result = proc.StandardOutput.ReadToEnd ();
proc.WaitForExit();
proc.Close ();
Console.WriteLine(result);
Process.Start ("rm", "/tmp/fifo");
}
}
}
外壳输出:
我的ssh文件不在标准位置
问题更新前的原件:
您正在启动一个新的bash/shell解释器,而您已经在其中,即:
bash -c echo -e '\x61'
或
从bash的CLI运行时,两者都返回空字符串
跳过启动第二个解释器并直接调用echo:
剪切/粘贴示例:
问题是:只有一行要执行,例如.execshell[-f~/.ssh/id_rsa.pub]&&echo\Found\| | echo\Not Found\并以十六进制进行解析以防止注入:proc.StartInfo.Arguments=-c$'+stringtohexescescapecomand+;您能否更新您的问题,以包括您实际试图做的事情,因为您的示例正在注释格式中丢失-
bash -c echo -e '\x61'
bash -c echo $'\x61'
proc.StartInfo.FileName = "echo";
proc.StartInfo.Arguments = " '\x61' ";
using System;
using System.Diagnostics;
namespace consoleEcho
{
class MainClass
{
public static void Main (string[] args)
{
Process proc = new Process();
proc.StartInfo.FileName = "echo";
proc.StartInfo.Arguments = " '\x61' ";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
var output = proc.StandardOutput.ReadToEnd ();
Console.WriteLine("stdout: {0}", output);
}
}
}