我有一个可以发送的二进制文件netcat
:
$ nc -l localhost 8181 < my.dat
该文件包含以下内容:
$ xxd my.dat
0000000: 0006 3030 3030 4e43 ..0000NC
我真正想做的是直接发送十六进制字符串。我试过这个:
$ echo '0006303030304e43' | nc -l localhost 8181
然而,上面的命令只是将 ascii 字符串直接发送到nc
.
答案1
我用的是-r和-p开关用于xxd:
$ echo '0006303030304e43' | xxd -r -p | nc -l localhost 8181
感谢 @Gilles 回答的启发,这里有一个 Perl 版本:
$ echo '0006303030304e43' | perl -e 'print pack "H*", <STDIN>' | nc -l localhost 8181
答案2
这里有一个没有xxd
or 的解决方案perl
:
如果echo
你的 shell 的内置支持它(bash
并且zsh
这样做,但不dash
),你只需要使用正确的反斜杠转义:
echo -ne '\x00\x06\x30\x30\x30\x30\x4e\x43' | nc -l localhost 8181
如果你有/bin/echo
来自GNU 核心工具(几乎是 Linux 系统上的标准)或者您也可以从 busybox 使用它。
使用sed
您可以生成转义模式:
$ echo '0006303030304e43' | sed -e 's/../\\x&/g'
\x00\x06\x30\x30\x30\x30\x4e\x43
综合:
echo -ne "$(echo '0006303030304e43' | sed -e 's/../\\x&/g')" | nc -l localhost 8181
答案3
如果你有xxd
,那就很简单:它可以在十六进制之间进行转换。
echo '0006303030304e43' | xxd -r -p | nc -l localhost 8181
我认为没有一种合理(且相当快)的方法可以仅使用 POSIX 工具将十六进制转换为二进制。在 Perl 中这可以相当容易地完成。以下脚本将十六进制转换为二进制,忽略任何不是十六进制数字的输入字符。如果输入行包含奇数个十六进制数字,它会抱怨。
#!/usr/bin/env perl
$^W = 1;
$c = undef;
while (<>) {
tr/0-9A-Fa-f//cd;
if (defined $c) { warn "Consuming $c"; $_ = $c . $_; $c = undef; }
if (length($_) & 1) { s/(.)$//; $c = $1; }
print pack "H*", $_;
}
if (!eof) { die "$!"; }
if (defined $c) { warn "Odd number of hexadecimal digits"; }
如果您确实需要坚持使用 POSIX(例如在嵌入式设备上),我建议使用Base64而不是十六进制。您可以使用乌德码解码 Base64。输入必须具有由以下方式生成的标题格式和结束行uu编码,它不能是原始 Base64。
uudecode <<EOF | nc -l localhost 8181
begin-base64 644 -
AAYwMDAwTkM=
====
EOF
答案4
我编写了一个工具,可以从标准输入执行各种转换并将结果输出到标准输出。cryptocli dd
只会进行这些转换,而不会执行其他操作。
echo -n 0006303030304e43 | cryptocli dd -decoders hex | nc -l localhost 8081
将为你工作。
该工具是开源的,您可以在这里找到它:https://github.com/tehmoon/cryptocli
编辑:
您还可以使用我的工具直接编码为十六进制:
cat my.dat | cryptocli dd -encoders hex | nc -l localhost 8081