简体   繁体   English

使用命令行参数将任意二进制数据从C#应用程序传递到另一个应用程序

[英]Passing arbitrary binary data from C# application to another application using command line arguments

For academic purposes I want to try to exploit an strcpy function with a buffer overflow attack using C#, by passing some arbitrarily long string, that contains a specific binary data (raw bytes). 出于学术目的,我想通过传递一些包含特定二进制数据(原始字节)的任意长字符串,来尝试使用C#使用带有缓冲区溢出攻击strcpy函数。

I am trying something similar to this C# code, but that obviously doesn't work: 我正在尝试与此C#代码类似的东西,但是显然不起作用:

static void Main(string[] args)
{
    string cPath = @"C:\Debug";
    var strCmdText =
        "0xCA" + "0xCA" + + "0xCA" + "0xCA" + "0xCA" + ...;
    string filename = Path.Combine(cPath, "Buffer.exe");
    var proc = System.Diagnostics.Process.Start(filename, strCmdText);
}

We assume that the target application uses single-byte characters as its argv . 我们假设目标应用程序使用单字节字符作为其argv So... 所以...

1. Test application 1.测试应用

Our test application is called Buffer.exe and its source code is: 我们的测试应用程序称为Buffer.exe,其源代码为:

void print_str(char* str)
{
    size_t length = strlen(str);
    printf("Line: '%s'\n", str);
    printf("Len : '%d'\n", length);
    printf("Hex :", length);

    for (size_t i = 0; i < length; i++)
    {
        printf("\t0x%02x", str[i]);
    }

    printf("\n");
}


int main(int argc, char* argv[])
{
    for (int i = 1; i < argc; i++)
    {
        char* str = argv[i];
        printf("Argument #%d:\n", i);
        print_str(str);
    }

    printf("Press enter to exit\n");
    getchar();
}

It just prints the passed arguments both as strings and as hex values, so for arguments "a1" "b2" it will print 它只是将传递的参数打印为字符串和十六进制值,因此对于参数“ a1”和“ b2”,它将打印

 Argument #1: Line: 'a1' Len : '2' Hex : 0x61 0x31 Argument #2: Line: 'b2' Len : '2' Hex : 0x62 0x32 Press enter to exit 

2. Main "ingredients" 2.主要“成分”

What we need are: 我们需要的是:

  1. A way to turn bytes to analogous "single byte characters" (actually they will still be 2-byte UTF-16 chars on the C# side, but [OS should pass them to our receiver]/[Buffer.exe should interpret] as single byte characters with the same binary value we started on the C# side) - for that we need Encoding.Default (as corrected by @Tom Blodget) property and its Encoding.GetString method. 一种将字节转换为类似的“单字节字符”的方法(实际上,它们在C#端仍为2字节UTF-16字符,但是[OS应该将它们传递给我们的接收器] / [Buffer.exe应该解释]为单字节)具有从C#端开始的相同二进制值的字节字符)-为此,我们需要Encoding.Default (由@Tom Blodget纠正)属性及其Encoding.GetString方法。
  2. A way to ensure that our argument line is correctly escaped (so that 0x20-Space won't split our big argument into multiple and other particularities won't affect the command line either) - for simplicity we will just escape an entire line with quotes, but for a proper solution (at least on Win32) see https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ . 确保我们的参数行正确转义的一种方法(以便0x20-Space不会将大参数拆分为多个参数,其他特殊性也不会影响命令行)-为简单起见,我们将用引号将整个行转义,但有关正确的解决方案 (至少在Win32上是),请参阅https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/

3. Implementation 3.实施

Our argument creating application is the following: 我们的参数创建应用程序如下:

public static String BytesToCommandLineArgument(Byte[] array)
{            
    var ascii = Encoding.Default.GetString(array);
    // "Escape" it here. Disclaimer - it is actually a wrong way to escape a command line argument.
    // See https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ 
    // for a way to do it correctly at least on Win32
    return String.Format("\"{0}\"", ascii); 
}

public static  void Main()
{
    try
    {
        var bytes = new Byte[] { 0x10, 0x31, 0x13, 0x61, 0x20 };

        using (var process = Process.Start(
            fileName: "Buffer.exe",
            arguments: BytesToCommandLineArgument(bytes)))
        {
            process.WaitForExit();
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc);
    }
    Console.WriteLine("Press any key...");
    Console.ReadKey(true);
}

4. Testing 4.测试

As you can see our test byte array contains spaces and newlines, so we can at least be sure that our solution won't strip them (though as I've said something like quote on the end will break it). 如您所见,我们的测试字节数组包含空格和换行符,因此我们至少可以确保我们的解决方案不会剥离它们(尽管正如我在最后所说的那样,它会破坏它)。

 Argument #1: Line: '►1‼a ' Len : '5' Hex : 0x10 0x31 0x13 0x61 0x20 Press enter to exit 

PS1: Don't forget that this solution escapes command line incorrectly - https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ ! PS1:请不要忘记此解决方案会误解命令行-https: //blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/ It may not cause any issues on most of the data in the possible dataspace, but it will certainly do on some data. 它可能不会对可能的数据空间中的大多数数据造成任何问题,但是肯定会对某些数据造成影响。

PS2: How do you convert Byte Array to Hexadecimal String, and vice versa? PS2: 如何将字节数组转换为十六进制字符串,反之亦然? may be of use for you if you have a need to input the data dynamically. 如果您需要动态输入数据,则可能对您有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM