我将SSHD带入远程服务器,并带有一些二进制挑战。
在某一时刻,它要求我输入文本。我知道它正在使用fgets()
读取stdin
,并且可以将其复制到并覆盖附近变量的位置。
问题是我不知道如何键入所需的地址值,x84
和x04
等。如果我能够使用bash,我将使用echo -ne "x84"
或使用C HEX数组这里的东西。
我尝试使用十六进制对ASCII转换器并复制二进制字符,并使用期望脚本发送二进制值,但都有相同的问题。X84添加了额外的字符,X04根本不会写。
任何想法是可靠地将值写入内存的最佳方法,而在unix tty上无法通过ssh代表的内存?
您可以通过在键盘上键入控件字符来在0x00
到0x1f
范围内编写字符。在此ASCII图表的第三列中键入字符时,请按住控制键,以在第一列中获取相应的代码。
某些控件字符对终端驱动程序具有特殊的含义(例如 ctl-c 杀死该过程),您可以通过使用 ctl-v 在字面上键入它们。
您可以通过键入 ctl-v delete 获得0x7f
(这是向后删除字符,可能是babeld backspace ,不是可能在单独的键盘中删除)。
我不确定是否有任何简单的方法可以在此上方输入字符。根据终端仿真器中的设置,您可以在键入相应的ASCII字符时按住 alt 键来获得高位设置。例如。 alt-a 将发送0xc1
(0x80 | 0x41
)。
对于高字符,您可以复制/粘贴。
例如。echo -ne "x84" | xclip -i
,然后单击终端模拟器中的中单击,如果您的桌面也在运行Linux。(或也许不是,请参见下面的)。或echo ... | ssh user@host
可以工作。
ssh -T
或任何其他终端模拟器中的等效物也可能是"禁用伪终端分配"的选项,因此遥控方面的程序将其stdin
是SSHD的管道,而不是伪终端的管道, 我认为。我认为这将禁用^s
和^v
之类的内容。
相反,echo foo | ssh -tt
将迫使它在偏远的一侧请求TTY,即使您将其输送到SSH中。
确保SSH上的二进制数据通过TTY层和接收程序的stdin
的一种较不侵入性的方法是使用控制v
(HEX 0x16)。
正如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 |.h.e.l.l.o.|
您可以通过输入hexdump -C
(又称hd
)来在本地测试所有这些。只需在终端运行它,然后键入或粘贴一些东西,然后控制D直到退出。
$ echo -ne "x01xffx99" | LANG=C sed $'s/./x16&/g' | hd
00000000 16 01 16 ff 16 99 |......|
00000006
# yup, correct bytes from sed
$ echo -ne "x01xffx99" | 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
的途中,它会被Konsole弹出吗?后者似乎不太可能。可能是一个糊状问题。Konsole的"编码"设置为UTF-8。它似乎没有普通的ASCII设置。
也许尝试使用LANG=C xterm
或其他内容,或者仅正确地将expect
正确发送到ssh
而不是逃生代码。
fgets
当然不会处理逃生序列,比strcpy
更重要。一般而言,C函数不会;但是在C中 compiler 过程中的字符串文字内部的序列在编译时间。