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

我被SSH连接到一个带有一些二进制挑战的远程服务器。

有一次它要求我输入文字。 我知道它正在使用fgets()来读取stdin ,并且我可以溢出它被复制到的地方并覆盖附近的变量。

问题是我不知道如何键入我需要的地址值, \x84\x04等。如果我能够使用bash我会echo -ne "\x84"或使用Chex数组但我可以’在这里做那种事。

我尝试使用hex到ASCII转换器并复制二进制字符,并使用expect脚本发送二进制值,但两者都有相同的问题。 x84添加了额外的字符,x04根本不会写入。

任何想法是可靠地将值写入内存的最佳方法,这些内容在Unix tty上通过ssh无法用ASCII字符表示?

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

例如echo -ne "\x84" | xclip -i 如果桌面也在运行Linux,则echo -ne "\x84" | xclip -i然后在终端模拟器中单击鼠标中键。 ( 或者可能不是,见下文 )。 或echo ... | ssh user@host echo ... | ssh user@host可以工作。

ssh -T或任何其他终端仿真器中的等效项也可能是“禁用伪终端分配”的选项,因此远程端的程序将其stdin作为来自sshd的管道,而不是伪终端,我认为。 我认为这会禁用像^s^v这样^s东西。

相反, echo foo | ssh -tt echo foo | ssh -tt将强制它在远程端请求tty,即使你正在将东西输入ssh。


通过SSH获取二进制数据通过TTY层和接收程序的stdin的一种较少侵入性的方法是在每个字节之前使用control- v (hex0x16)。

正如Barmar指出的那样,这是文字下一个字符( stty -a输出中的lnext )。 您可以在有效负载的每个字节之前使用它; 它甚至在普通字符之前被接收器中的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 |.hello| 

您可以通过键入hexdump -C (aka 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 |......| 

因此,X选择本身是正确的,但是当我粘贴时,它会被Konsole或者从Konsole到hexdump的路上的TTY层进行调整? 后者似乎不太可能; 可能这是一个粘贴问题。 Konsole的“编码”设置是UTF-8。 它似乎没有纯ASCII设置。

也许尝试使用LANG=C xterm或其他东西,或者只是脚本expect正确地将实际的二进制数据发送到ssh ,而不是转义代码。


fgets当然不会处理转义序列,只不过strcpy会。 一般来说,C函数没有; 但在C中, 编译器在编译时处理字符串文字内的转义序列。

您可以通过在键盘上键入控制字符来写入0x000x1f范围内的字符。 在此ASCII图表的第三列中键入字符时按住Control键以获取第一列中的相应代码。

一些控制字符对终端驱动程序具有特殊含义(例如, Ctl-c用于终止进程),您可以通过在Ctl-v之前字面输入它们。

您可以通过键入Ctl-v Delete来获得0x7f (这是后向删除字符,可能标记为Backspace ,而不是可能位于单独键盘中的前向删除)。

我不确定是否有任何简单的方法可以在上面输入字符。 根据终端仿真器中的设置,您可以通过在键入相应的ASCII字符时按住Alt键来设置高位。 例如, Alt-A将发送0xc10x80 | 0x41 )。