代码之家  ›  专栏  ›  技术社区  ›  GhostSparkles

将非ASCII字符写入tty上程序的stdin(通过ssh)

  •  2
  • GhostSparkles  · 技术社区  · 7 年前

    我将SSHd引入一个具有一些二进制挑战的远程服务器。

    fgets() 阅读 stdin ,我可以在它被复制到的地方溢出,并覆盖附近的变量。

    \x84 \x04 等等。如果我能使用bash,我会 echo -ne "\x84" 或者使用C十六进制数组,但我不能在这里做这种事情。

    您知道在Unix tty上通过ssh将无法用ASCII字符表示的值可靠地写入内存的最佳方法吗?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Barmar 0___________    7 年前

    0x00 0x1f 通过在键盘上键入控制字符。按住 控制 ASCII Chart 获取第一列中的相应代码。

    Ctl-c 要终止进程),可以通过在前面加上 .

    你可以得到 0x7f 通过键入 Ctl-v 删去 退格

    中高音 次优 将发送 0xc1 0x80 | 0x41

        2
  •  3
  •   Peter Cordes    7 年前

    对于高字符,您可能可以复制/粘贴。

    例如 echo -ne "\x84" | xclip -i 如果您的桌面也运行Linux,请在终端模拟器中单击鼠标中键。( ). 或 echo ... | ssh user@host 可以工作。

    ssh -T 或者,任何其他终端模拟器中的等效功能也可能是一个选项,用于“禁用伪终端分配”,因此远程端的程序将具有其 stdin ^s ^v 我觉得很特别。

    相反地 echo foo | ssh -tt 将强制它在远程端请求tty,即使您正在将内容传输到ssh中。


    确保SSH上的二进制数据通过TTY层并传输到 接收程序的第二步是在每个字节之前加一个控件- v (十六进制0x16)。

    lnext stty -a 输出)。你可以在之前使用它 每一个 有效载荷的字节;它甚至在普通字符之前就被接收器中的TTY层剥离了。

    # LANG=C sed to replace every byte with ^V byte
    # using bash $'' to put a literal control-V on sed's command line
    echo "hello" | LANG=C sed $'s/./\x16&/g' | hd
            16 68 16 65 16 6c 16 6c  16 6f 0a                 |.h.e.l.l.o.|
    

    hexdump -C (又名 hd ). 只需在终端中运行它,键入或粘贴一些内容,然后控制-D,直到退出。

    $ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | hd
    00000000  16 01 16 ff 16 99                                 |......|
    00000006
          # yup, correct bytes from sed
    $ echo -ne "\x01\xff\x99" | LANG=C sed $'s/./\x16&/g' | xclip -i
    $ LANG=C hd
    ^A��     (middle click, return, control-d)
    00000000  01 ef bf bd ef bf bd 0a                           |........|
         # nope, that munged my data :/
    
    $ xclip -o | hd
    00000000  16 01 16 ff 16 99                                 |......|
    

    hexdump ? 后者似乎不太可能;可能是粘贴问题。Konsole的“编码”设置为UTF-8。它似乎没有简单的ASCII设置。

    也许试试 LANG=C xterm expect ssh


    fgets 当然不会处理转义序列,就像 strcpy 处理内部转义序列 字符串