added BitShade
This commit is contained in:
@@ -14,3 +14,4 @@
|
|||||||
* [Image Transfer](./it.sh): a more convenient wrapper around dd for writing and reading removable media images
|
* [Image Transfer](./it.sh): a more convenient wrapper around dd for writing and reading removable media images
|
||||||
* [Mount Manager](./mm.sh): a simple script to mount/unmount removable media partitions
|
* [Mount Manager](./mm.sh): a simple script to mount/unmount removable media partitions
|
||||||
* [PNGizer](./pngizer.sh): an utility (and a shell library) to convert any file or directory to/from a PNG image
|
* [PNGizer](./pngizer.sh): an utility (and a shell library) to convert any file or directory to/from a PNG image
|
||||||
|
* [BitShade](./bitshade.sh): a steganographic tool for hiding any data file inside a PNG image
|
||||||
|
|||||||
Executable
+79
@@ -0,0 +1,79 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# BitShade: a simple POSIX-compatible tool for
|
||||||
|
# image-based steganography
|
||||||
|
# Depends on od, paste, dd, awk, sed, ImageMagick and pngcrush
|
||||||
|
# Usage:
|
||||||
|
# - encoding: bitshade.sh e [cover image] [file to hide] [output PNG]
|
||||||
|
# - decoding: bitshade.sh d [container PNG] [output file]
|
||||||
|
# Created by Luxferre in 2026, released into public domain
|
||||||
|
|
||||||
|
# encode raw file as a netstring
|
||||||
|
to_netstring() {
|
||||||
|
printf '%d:' "$(cat "$1" | wc -c)"
|
||||||
|
cat "$1"
|
||||||
|
printf ','
|
||||||
|
}
|
||||||
|
|
||||||
|
# decode a raw file from a netstring (inside another file)
|
||||||
|
from_netstring() {
|
||||||
|
# get the container length
|
||||||
|
flen=$(head -n 1 "$1" | cut -f 1 -d :)
|
||||||
|
# skip the length itself and the : char
|
||||||
|
dd if="$1" of="$2" skip=$((${#flen} + 1)) bs=1 count=$flen
|
||||||
|
}
|
||||||
|
|
||||||
|
# for every input byte, print its bits
|
||||||
|
conv_input() {
|
||||||
|
to_netstring "$1" | od -An -tu1 -v -w1 | awk '{n=int($0);for(i=0;i<8;i++){print(n%2);n=int(n/2)}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# assemble a file bit by bit
|
||||||
|
collect_bits() {
|
||||||
|
outfile="$1"
|
||||||
|
tfile2=$(mktemp)
|
||||||
|
tfile3=$(mktemp)
|
||||||
|
awk 'BEGIN{n=0;b=1} {n+=b*int($1);b*=2;if(b==256){printf("\\%03o",n);n=0;b=1}}' > $tfile2
|
||||||
|
printf "$(cat $tfile2)" > $tfile3
|
||||||
|
from_netstring $tfile3 "$1"
|
||||||
|
rm -f $tfile2 $tfile3
|
||||||
|
}
|
||||||
|
|
||||||
|
# stego_encode cover_image hidden_text out.png
|
||||||
|
stego_encode() {
|
||||||
|
coverfile="$(mktemp)"
|
||||||
|
infile="$(mktemp)"
|
||||||
|
tfile="$(mktemp)"
|
||||||
|
temp_ppm="$(mktemp)"
|
||||||
|
magick $1 -compress none ppm:$temp_ppm
|
||||||
|
cat $temp_ppm | head -n 3 > $tfile
|
||||||
|
cat $temp_ppm | tail -n +4 | sed 's/\s\+/\n/g' > $coverfile
|
||||||
|
conv_input "$2" > $infile
|
||||||
|
paste $coverfile $infile | awk '{print(NF>1?int(int($1)/4)*4+int($2)*2+(rand()>0.5?1:0):$1)}' >> $tfile
|
||||||
|
magick ppm:$tfile png:$3
|
||||||
|
pngcrush -ow $3
|
||||||
|
rm -f $coverfile $infile $temp_ppm $tfile
|
||||||
|
}
|
||||||
|
|
||||||
|
# stego_decode in.png out_file
|
||||||
|
stego_decode() {
|
||||||
|
temp_ppm="$(mktemp)"
|
||||||
|
magick $1 -compress none ppm:$temp_ppm
|
||||||
|
cat $temp_ppm | tail -n +4 | sed 's/\s\+/\n/g' | awk '{x=int($0)%4;print(x<2?0:1)}' | collect_bits "$2"
|
||||||
|
rm -f $temp_ppm
|
||||||
|
}
|
||||||
|
|
||||||
|
# entry point
|
||||||
|
|
||||||
|
if [ "$1" = "e" ]; then
|
||||||
|
[ -z "$2" ] && echo 'No cover file specified! Exiting...' && exit 1
|
||||||
|
[ -z "$3" ] && echo 'No input file specified! Exiting...' && exit 1
|
||||||
|
[ -z "$4" ] && echo "No output file specified! Exiting..." && exit 1
|
||||||
|
stego_encode "$2" "$3" "$4"
|
||||||
|
elif [ "$1" = "d" ]; then
|
||||||
|
[ -z "$2" ] && echo 'No input file specified! Exiting...' && exit 1
|
||||||
|
[ -z "$3" ] && echo "No output file specified! Exiting..." && exit 1
|
||||||
|
stego_decode "$2" "$3"
|
||||||
|
else
|
||||||
|
echo 'Invalid mode! Use e for encoding or d for decoding'
|
||||||
|
fi
|
||||||
|
|
||||||
Reference in New Issue
Block a user