แปลงสตริงฐานสิบหกเป็นไบนารีและส่งด้วย netcat


46

ฉันมีไฟล์ไบนารีที่ฉันสามารถส่งด้วยnetcat:

$ nc -l localhost 8181 < my.dat

ไฟล์นี้ประกอบด้วย:

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

สิ่งที่ฉันต้องการทำจริงๆคือส่งสตริง hex โดยตรง ฉันเคยลองแล้ว:

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

อย่างไรก็ตามคำสั่งดังกล่าวเป็นเพียงแค่ส่งสตริง ASCII ncโดยตรง

คำตอบ:


55

ฉันใช้สวิตช์-rและ-pเป็นxxd :

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

ขอบคุณแรงบันดาลใจจากคำตอบ @Gilles นี่เป็นเวอร์ชั่นที่เป็นภาษา:

$ echo '0006303030304e43' | perl -e 'print pack "H*", <STDIN>' | nc -l localhost 8181

ใช้งานได้ดีสำหรับรูปแบบ hex bytea hex ของ Postgres เมื่อเครื่องหมาย \ x นำหน้าถูกตัดออก
nathancahill

ขอบคุณ! ใช้งานได้ดีสำหรับการตรวจสอบพจนานุกรมย่อยของ Firefox อย่างชัดเจน! md5sum ../it/manifest.json | awk '{print $1}' | xxd -r -p | hd
Avio

26

นี่คือทางออกที่ไม่มีxxdหรือperl:

หากechobuiltin ของเชลล์สนับสนุน ( bashและzshทำ แต่ไม่ใช่dash) คุณเพียงแค่ใช้เครื่องหมายแบ็กสแลชขวา:

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

ถ้าคุณมีcoreutils/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

ทางออกที่ดีมาก!
Chris Snow

2
การแทนที่echoด้วยprintfจะลบการเดาออกหาก echo รองรับคุณสมบัติเพิ่มเติมหรือไม่ printf "$(echo '0006303030304e43' | sed -e 's/../\\x&/g')" | nc -l localhost 8181.
แจค

11

ถ้าคุณมี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แทนเลขฐานสิบหก คุณสามารถใช้uudecodeเพื่อถอดรหัส Base64 อินพุตต้องมีรูปแบบส่วนหัวและบรรทัดสุดท้ายที่สร้างโดยuuencodeซึ่งไม่สามารถเป็น Base64 แบบดิบได้

uudecode <<EOF | nc -l localhost 8181
begin-base64 644 -
AAYwMDAwTkM=
====
EOF

1

คล้ายกับสิ่งนี้: https://stackoverflow.com/questions/1604765/linux-shell-scripting-hex-string-to-bytes/47253233#47253233

ฉันเขียนเครื่องมือที่ดำเนินการแปลงต่าง ๆ จาก stdin และแยกผลลัพธ์ออกเป็น stdout cryptocli ddจะทำการเปลี่ยนแปลงเหล่านั้นและไม่มีอะไรอื่นอีกแล้ว

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

จะทำงานให้คุณ

เครื่องมือนี้เป็นโอเพนซอร์สคุณสามารถค้นหาได้ที่นี่: https://github.com/tehmoon/cryptocli

แก้ไข:

คุณสามารถเข้ารหัสโดยตรงไปยัง hex โดยใช้เครื่องมือของฉัน:

cat my.dat | cryptocli dd -encoders hex | nc -l localhost 8081

(1) 616263คำถามนี้เกี่ยวข้องกับอะไร? กรุณาใช้ข้อมูลจากคำถาม (2) คุณอธิบายได้ไหมว่ามันทำงานอย่างไร โปรดอย่าตอบในความคิดเห็นแก้ไขคำตอบของคุณเพื่อให้ชัดเจนและสมบูรณ์ยิ่งขึ้น
G-Man กล่าวว่า 'Reinstate Monica'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.