【问题标题】:How to pass \x00 as argument to program?如何将 \x00 作为参数传递给程序?
【发布时间】:2011-09-06 07:17:15
【问题描述】:

我有一个小程序,我希望将 shellcode 作为参数传递。在 shellcode 中,有必要传递 \x00。我尝试了以下命令:

./program `python -c 'print "\x01\x00\x00\x00\x9c\xd8\xff\xbf"'`

但是 \x00 根本没有被注册!传递给程序的参数是“\x01\x9c\xff\xbf”。

我认为这不是 python 的问题,而是传递参数的 shell 的问题。我正在使用 bash shell。

现在,我如何强制 shell 传递参数 '\x00'?

感谢和问候,
赫里希凯什·穆拉利

【问题讨论】:

    标签: shell command-line shellcode


    【解决方案1】:

    一点也不。 Unix 使用 C 风格的字符串作为调用命令的参数,它们是 NUL 终止的字符序列。

    您可以做的是重写您的程序(或找到一个调用变体)以接受其标准输入中的参数。 NUL 字节在那里工作得很好,事实上,它被广泛使用,通常作为文件名的分隔符,因为它们几乎是文件名中唯一不能包含的东西。请参阅find-print0 开关和xarg 的开关-0,了解可以说是最流行的示例。

    【讨论】:

    • 谢谢!但是我无法控制程序,因此我无法更改它。不改程序就可以做到吗?
    • 没有。您需要在相当基本的细节上更改操作系统。
    【解决方案2】:

    如果你检查wc,你会发现NUL字符确实通过了:

    $ python -c 'print "\x00"' | wc -c
    2
    

    要去掉末尾的换行符:

    $ python -c 'import sys; sys.stdout.write("\x00")' | wc -c
    1
    

    这个数据传递给脚本的,但问题是NUL不能是变量值的一部分。

    要了解如何,请尝试将其传递给脚本:

    $ cat test.sh 
    #!/usr/bin/env bash
    echo ${#1}
    $ ./test.sh "$(python -c 'import sys; sys.stdout.write("\x00")')"
    0
    

    走了。但是有一种方法可以挽救这一天 - 从标准输入中读取,使用重定向或管道:

    $ cat test2.sh 
    #!/usr/bin/env bash
    wc -c
    $ ./test2.sh < <(python -c 'import sys; sys.stdout.write("\x00")')
    1
    $ python -c 'import sys; sys.stdout.write("\x00")' | ./test2.sh
    1
    

    【讨论】:

      【解决方案3】:

      带有 --null 选项的 xargs 命令可以提供帮助:

      python -c 'print "\x30\x00\x31"' | xargs --null ./program
      

      我试过了,效果很好。

      【讨论】:

        【解决方案4】:

        我相信这是因为 Bash 丢弃了空字符。

        为了测试这一点,我使用了od 命令以八进制格式转储参数,使用以下脚本:

        $ cat script.sh
        
        #!/bin/bash
        echo "$@" | od -c
        

        并使用:

        $ script.sh `python -c 'print "\x01\x00\x00\x00\x9c\xd8\xff\xbf"'`
        0000000 001 234 330 377 277  \n
        0000006
        

        不打印空字符。

        要解决此问题,请传入 hexdump,然后在您的程序中反转它。示例:

        $ cat script.sh
        
        #!/bin/bash
        echo "$@" | xxd -r -p | od -c
        
        $ script.sh `python -c 'print "\x01\x00\x00\x00\x9c\xd8\xff\xbf"' | xxd -p`
        0000000 001  \0  \0  \0 234 330 377 277  \n
        0000011                                    
        

        现在您看到空字符被打印出来了。

        【讨论】:

        • 上述程序 (xxd) 并没有按原样传递 shellcode,而是将 shellcode 的 ascii 表示形式作为参数传递。这和输入“print "10009cd8ffbf"”一样好。
        • 是的,我就是这么说的。你不能传入一个空字符,所以你必须先将它编码成十六进制,使用xxd
        • Bash 对此无能为力(否则,我们可以创建一个包装程序来调用目标而不涉及 shell),它与标准的 execvp 调用套件相关联,它们只需将char** 作为参数列表即可。只是没有办法通过那里获得 0 个字节。
        【解决方案5】:

        您可以尝试将 shellcode 放入文件中,然后将其读回并将其传递给可执行文件。

        类似:

        $ cat shellcode.txt
        \xb5\x06\x40\x00\x00\x00\x00\x00
        
        $ perl -e ' $a = `cat shellcode.txt`; chomp($a); print $a x 10; '
        \xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00
        \x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00
        \xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00
        \x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00\xb5\x06\x40\x00\x00\x00\x00\x00
        

        使用上面的 perl cmdline 作为程序的参数

        $ ./program $(perl -e ' $a = `cat shellcode.txt`; chomp($a); print $a x 10; ')
        

        【讨论】:

          【解决方案6】:

          你可以试试这个,

          main.out `perl -e 'print "xxxxssssdd\x23\x00\xaf"'`
          

          perl -e 'print "xxxxssssdd\x23\x00\xaf"' | wc -c
          13
          

          证明\x00通过了。

          顺便说一句,我发现 c 程序在我的测试中肯定会在 argv 中添加 \00。您可以检查 argv,例如,

           x /8sb 0x7fffffffe46a
          0x7fffffffe46a: "/home/victor/Documents/CDemo/overflow/shellcode2/shellcode_host.out"
          0x7fffffffe4ae: '\220' <repeats 21 times>, "\353#YUH\211\345@\200\354\200H\211M\220H1\300H\211E\230H\211\302H\215u\220H\213}\220\260;\017\005\350\330\377\377\377/bin/sh\200\337\377\377\377\177"
          0x7fffffffe4fb: "LC_PAPER=zh_CN.UTF-8"
          

          所以我猜 shell 或 c 程序可以自动提示 \x00 字符。也许有人可以解释为什么会发生这种情况。

          但我们还有其他技术可以避免 shellcode 中出现 \x00。

          mov     $59, %al # not %rax 
          sub    $0x80, %spl  # not %rsp
          xorq    %rax,  %rax # construct 0 value with rax
          

          你可以参考这篇文章。 https://www.exploit-db.com/docs/english/13019-shell-code-for-beginners.pdf

          【讨论】:

            猜你喜欢
            • 2022-11-24
            • 1970-01-01
            • 2022-11-25
            • 2015-03-01
            • 2015-09-10
            • 2014-08-13
            • 1970-01-01
            • 2020-11-14
            • 1970-01-01
            相关资源
            最近更新 更多