converter uma string hexadecimal em binário e enviar com netcat

46

Eu tenho um arquivo binário com o qual posso enviar netcat:

$ nc -l localhost 8181 < my.dat

O arquivo contém isso:

$ xxd my.dat
0000000: 0006 3030 3030 4e43                      ..0000NC

O que realmente quero fazer é enviar a sequência hexadecimal diretamente. Eu tentei isso:

$ echo '0006303030304e43' | nc -l localhost 8181

No entanto, o comando acima apenas envia a string ascii diretamente para nc.

Chris Snow
fonte

Respostas:

55

Eu usei a opção -r e -p no xxd :

$ echo '0006303030304e43' | xxd -r -p | nc -l localhost 8181

Graças à inspiração da resposta @Gilles, aqui está uma versão perl:

$ echo '0006303030304e43' | perl -e 'print pack "H*", <STDIN>' | nc -l localhost 8181
Chris Snow
fonte
Funciona muito bem no formato hexadecimal bytea do Postgres, uma vez que o \ x inicial é eliminado.
Nathancahill
Obrigado! Funciona muito bem também para verificar os resumos dos dicionários do Firefox no manifesto! md5sum ../it/manifest.json | awk '{print $1}' | xxd -r -p | hd
Avio
26

Aqui uma solução sem xxdou perl:

Se o echobuiltin do seu shell o suportar ( bashe o zshfaz, mas não dash), você só precisa usar as escapes da barra invertida direita:

echo -ne '\x00\x06\x30\x30\x30\x30\x4e\x43' | nc -l localhost 8181

Se você tiver /bin/echode coreutils GNU (quase padrão em sistemas Linux) ou de busybox você pode usá-lo também.

Com sedvocê pode gerar um padrão de escape:

$ echo '0006303030304e43' | sed -e 's/../\\x&/g'
\x00\x06\x30\x30\x30\x30\x4e\x43

Combinado:

echo -ne "$(echo '0006303030304e43' | sed -e 's/../\\x&/g')" | nc -l localhost 8181
jofel
fonte
solução muito boa!
Chris Neve
2
Substituir echopor printfremove o trabalho de adivinhação se o eco suportar recursos estendidos ou não. printf "$(echo '0006303030304e43' | sed -e 's/../\\x&/g')" | nc -l localhost 8181.
9338 Jaakko
12

Se você tiver xxd, é fácil: pode converter de e para hexadecimal.

echo '0006303030304e43' | xxd -r -p | nc -l localhost 8181

Eu não acho que exista uma maneira razoável (e razoavelmente rápida) de converter hexadecimal em binário usando apenas ferramentas POSIX. Isso pode ser feito facilmente no Perl. O script a seguir converte hexadecimal em binário, ignorando qualquer caractere de entrada que não seja um dígito hexadecimal. Ele reclama se uma linha de entrada contém um número ímpar de dígitos hexadecimais.

#!/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"; }

Se você realmente precisa seguir o POSIX (por exemplo, em um dispositivo incorporado), recomendo usar o Base64 em vez do hexadecimal. Você pode usar o uudecode para decodificar o Base64. A entrada deve ter o formato do cabeçalho e a linha final produzidos pelo uuencode , não pode ser Base64 bruto.

uudecode <<EOF | nc -l localhost 8181
begin-base64 644 -
AAYwMDAwTkM=
====
EOF
Gilles 'SO- parar de ser mau'
fonte
1

Semelhante a este: https://stackoverflow.com/questions/1604765/linux-shell-scripting-hex-string-to-bytes/47253233#47253233

Eu escrevi uma ferramenta que executa várias transformações de stdin e cospe o resultado em stdout. cryptocli ddsó fará essas transformações e nada mais.

echo -n 0006303030304e43 | cryptocli dd -decoders hex | nc -l localhost 8081

Trabalhará para você.

A ferramenta é de código aberto, você pode encontrá-lo aqui: https://github.com/tehmoon/cryptocli

Editar:

Você também pode codificar diretamente para hexadecimal usando minha ferramenta:

cat my.dat | cryptocli dd -encoders hex | nc -l localhost 8081
tehmoon
fonte
(1) O que isso 616263tem a ver com esta pergunta? Por favor, use os dados da pergunta. (2) Você pode explicar como isso funciona? Por favor, não responda nos comentários, edite sua resposta para torná-la mais clara e completa.
G-Man diz 'Reinstate Monica'