我可以执行以下操作在 netcat 中发送二进制数据:
echo -e '\x80' | nc host port
但我不想这样做,我想要的是连接到服务器:
nc 192.168.1.115 12345
然后发送一些文本:
aaaaaaaaaabbbbbbbbbbccccccccccc
然后发送一些二进制数据:
0x80 0xF4 0x12
我怎样才能做到这一点?
答案1
注意:遵循此解决方案时,除非另有说明,否则请在单个 shell 会话中键入命令(或使用单个脚本)。这是因为它使用变量和文件描述符,它们不能在其原始会话之外直接使用。
创建临时 fifo。创建临时文件的正确方法是使用mktemp
。不幸的是,它不能创建 fifo。但是它可以创建一个临时目录:
tmpd="$(mktemp -d)"
tmpf="$tmpd"/fifo
mkfifo "$tmpf"
printf "%s\n" "$tmpf" # just to know the path to the fifo, it may be useful later
或者,您也可以在某个固定或临时位置手动创建命名 fifo。这取决于您。
创建一个后台进程,读取 fifo 并将数据传递到服务器:
nc 192.168.1.115 12345 < "$tmpf" &
ncpid=$! # PID may be useful later
注意nc
不要过早退出。假设连接本身和服务器都没有问题,上述后台命令将保持连接,直到您完成通过 fifo 发送第一批数据。但您希望它保持打开状态并接受多个写入,因此请打开 fifo 并且不要(暂时)关闭它:
exec 3> "$tmpf"
现在你可以通过 fifo 发送任何你喜欢的内容并且后台连接仍然保持:
echo abcd >&3 # sends text
echo -e '\x80' >&3 # sends "binary"
cat /etc/issue >&3 # sends file
cat >&3 # type whatever you want, terminate with Ctrl+D
只要您知道路径,就可以使用 fifo 路径而不是 来调用这些命令中的任何一个&3
。知道路径后,您可以从同一个或其他shell 会话:
cat > /path/to/the/fifo # type whatever you want, terminate with Ctrl+D
或者,您可以以与原始会话类似的方式在另一个会话中打开描述符。无论您以何种方式写入 fifo,它nc
都会通过单个连接将其传递给远程服务器。
但要小心竞争条件。在单个 shell 会话中使用单个描述符是避免竞争条件的好方法。
传递所需的数据后,终止nc
并关闭原始 shell 会话中的描述符:
kill "$ncpid"
exec 3>&-
请注意,在某些情况下,仅后一个命令就足以退出后台nc
;这取决于您执行了什么以及您仍在对 fifo 执行什么操作。出于这个原因,我选择nc
明确地终止该命令。
删除临时目录及其内容(即 fifo):
rm -r "$tmpd"
最后说明:
nc
首先,没有必要将其置于后台。您可以在一个终端中运行它,从另一个终端写入 fifo(知道其路径)。这样您就可以轻松监视其状态。根据您的需求定制此解决方案。
答案2
以下似乎有效:
while read -r; do echo -en "$REPLY" | nc ...; done
这使你可以\xNN
在正常数据中包含转义序列,如下所示:
aaaaaaaaaabbbbbbbbbbccccccccccc\x80\xF4\x12
请记住,在文本输入中,任何文字字符都要双写\
。请注意,使用read -r
and$REPLY
代替变量会停止删除前导和尾随空格。
这不会在缓冲区末尾添加换行符,因此您需要n
从命令中省略选项或者在需要换行符的位置echo
键入。\x0a
nc
我目前无法设置,但我已经测试过:
while read -r; do echo -en "$REPLY" | cat | xxd; done
od -ct x1
为了测试,如果您没有 ,则可以使用xxd
;或者od -c
如果您乐意看到八进制的二进制字符,则使用。您可以cat |
从管道中省略:我将其包括在内,因为它可能更好地模拟了 的使用nc
。
答案3
您可以通过命名管道获得帮助来完成此操作,但需要一些技巧:
remote$ nc -v -n -l -p 8888 > /tmp/data
Listening on [0.0.0.0] (family 0, port 8888)
Connection from 10.0.3.1 47108 received!
local:1$ mkfifo /tmp/fifo
local:1$ nc -v -n <>/tmp/fifo 10.0.3.66 8888
Connection to 10.0.3.66 8888 port [tcp/*] succeeded!
以读写方式打开 fifo 非常重要(或者使用其他中立进程,例如sleep 9999 >/tmp/fifo
保持打开状态以进行写入),否则第一次(结束)写入将结束 netcat 的读取循环。因此<>
。
local:2$ echo aaaaaaaaaabbbbbbbbbbccccccccccc > /tmp/fifo
local:2$ cat /bin/ls > /tmp/fifo # sends the binary contents of the file /bin/ls, which would probably garble the input or output
local:2$ cat > /tmp/fifo
Some more interactive text
(local:1$ )
^C
remote$ od -c /tmp/data|head -4
0000000 a a a a a a a a a a b b b b b b
0000020 b b b b c c c c c c c c c c c \n
0000040 177 E L F 002 001 001 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000060 003 \0 > \0 001 \0 \0 \0 0 T \0 \0 \0 \0 \0 \0
答案4
如果您提前知道这两条数据,那么请尝试以下操作:
$ ( echo "aaabbbccc"; echo -en "\x80\xf4\x12" ) | hexdump -Cv
00000000 61 61 61 62 62 62 63 63 63 0a 80 f4 12 |aaabbbccc....|
0000000d
如果您希望能够拥有更多的控制权(使用键盘等),请尝试以下操作:
$ ( cat; cat | xxd -r -p ) | hexdump -Cv
aaabbbccc
80f412
00000000 61 61 61 62 62 62 63 63 63 0a 80 f4 12 |aaabbbccc....|
0000000d
注意:你需要按Ctrl+D来结束每个cat
...所以我在这里输入(包括Returns - EOT 必须出现在行首):
aaabbbccc
^D
80f412
^D