As a "thought" experiment following up on the problem posed by Andy, I toyed with building on the Caesar Cipher to create something a bit more difficult to unravel, by re-shuffling the character map randomly, rather than just shifting a number of places.
So here is that "toy", but when I run the resulting script to encrypt, it is having issues with something in the specified sets. I suspect it has something to do with either
- the single quote,
- the open square bracket, or
- the close square bracket.
So, I tried to fix the issue by manually adding the backslash to precede those characters in the set, but that did not work.
Anybody have ideas on how to fix it?
The only idea that I know will work, is to do a pre-mapping of the 3 offending characters (using sed) to 3 alternates not currently in the map (i.e. some graphic elements or icons), do the mapping using those, then post-mapping back to the original 3 offending characters, again using sed.
Here is the script to create the "obfuscator":
#!/bin/sh
### Created by Eric Marceau, Feb 19, 2022
### Copyrighted as Public Domain, no restrictions
now=$( date '+%Y%m%d-%H%M%S' )
OUTPUT="Mapper_${now}.sh"
#echo $OUTPUT
#23456789+123456789+123456789+123456789+123456789+123456789+123456789+123456789+123456789+12345
cat >CharacterArrayInput.txt <<"ScRiPtFiLe"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ,.;:'"`~!@#$%^&*()-_=+[]{}|\<>?!
ScRiPtFiLe
#cat CharacterArrayInput.txt
####################################################################################################
###
### This method emulates the Caesar Cipher, but extends the set of characters
###
####################################################################################################
method1(){
echo "Enter number of charaters shifted => \c" ; read num
awk -v sq="'" -v offset=${num} '{
split("", symbols) ;
}{
aLine=$0 ;
print $0 ;
max=length(aLine) ;
#print max ;
beg=substr(aLine, offset, max-offset+1 ) ;
print beg ;
rem=substr(aLine, 0, offset-1 ) ;
print rem ;
mapping=sprintf("%s%s", beg, rem ) ;
}END{
print "#/bin/sh" ;
printf("#\n#\tVERSION: %s\n#\n", today ) ;
print "case \"$1\" in \n\t\"--encrypt\" )" ;
printf("\t\ttr \t%s[%s]%s \\\n\t\t\t%s[%s%s]%s <\"$2\" \n", sq, aLine, sq, sq, beg, rem, sq ) ;
print "\t\t;; \n\t\"--decrypt\" )" ;
printf("\t\ttr \t%s[%s%s]%s \\\n\t\t\t%s[%s]%s <\"$2\" \n", sq, beg, rem, sq, sq, aLine, sq ) ;
print "\t\t;; \nesac" ;
}' < CharacterArrayInput.txt >"${OUTPUT}"
ls -l "${OUTPUT}"
} # method1()
####################################################################################################
###
### This method uses the 'shuf' utility to randomize the output mapping for the given set of characters.
### The resulting mapping function generated should be mostly unique for every script created.
###
####################################################################################################
method2(){
count=$( expr $( wc -c CharacterArrayInput.txt | awk '{ print $1 }' ) - 1 )
shuf --input-range=1-${count} >CharacterArrayOrder.txt
#cat CharacterArrayOrder.txt
awk -v today="${now}" -v sq="'" -v glyphSet="CharacterArrayInput.txt" 'BEGIN{
abandon=0 ;
split("", glyph) ;;
cdex=1 ;
mapping=""
if( ( getline aLine <glyphSet ) > 0 ){
max=length(aLine) ;
for( i=1 ; i <= max ; i++ ){
glyph[i]=substr( aLine, i, 1 ) ;
} ;
}else{
printf("Could not find file \"%s\" for character map to be used. Abort!\n", glyphSet ) ;
exit ;
} ;
}{
mapping=sprintf("%s%s", mapping, glyph[$1] ) ;
}END{
print "#/bin/sh" ;
printf("#\n#\tVERSION: %s\n#\n", today ) ;
print "case \"$1\" in \n\t\"--encrypt\" )" ;
printf("\t\ttr \t%s[%s]%s \\\n\t\t\t%s[%s]%s <\"$2\" \n", sq, aLine, sq, sq, mapping, sq ) ;
print "\t\t;; \n\t\"--decrypt\" )" ;
printf("\t\ttr \t%s[%s]%s \\\n\t\t\t%s[%s]%s <\"$2\" \n", sq, mapping, sq, sq, aLine, sq ) ;
print "\t\t;; \nesac" ;
}' < CharacterArrayOrder.txt >"${OUTPUT}"
ls -l "${OUTPUT}"
} # method2()
case $1 in
--caesar ) method1 ;;
--random ) method2 ;;
esac
Here is an unmodified sample "obfuscator" generated by the above script, using the "--random" option:
#/bin/sh
#
# VERSION: 20250219-232127
#
case "$1" in
"--encrypt" )
tr '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ,.;:'"`~!@#$%^&*()-_=+[]{}|\<>?!]' \
'[u\E3z`C;x:6L+]#Bk0i*&}m9V~U(D<2H7M @w!g-1%[YtrhQn)l?8>sGvX{a!^O._ePNZFAb'4R|SKW5$ypJcTojq,"=dfI]' <"$2"
;;
"--decrypt" )
tr '[u\E3z`C;x:6L+]#Bk0i*&}m9V~U(D<2H7M @w!g-1%[YtrhQn)l?8>sGvX{a!^O._ePNZFAb'4R|SKW5$ypJcTojq,"=dfI]' \
'[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ,.;:'"`~!@#$%^&*()-_=+[]{}|\<>?!]' <"$2"
;;
esac
The error that is being reported:
ericthered@OasisMega1:/DB001_F4/WORK/crypto$ ./Mapper_20250219-232127.sh --encrypt myCrypto.sh
./Mapper_20250219-232127.sh: line 12: syntax error near unexpected token `-_=+[]{}'
./Mapper_20250219-232127.sh: line 12: ` '[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ,.;:'"`~!@#$%^&*()-_=+[]{}|\<>?!]' <"$2" '
ericthered@OasisMega1:/DB001_F4/WORK/crypto$
The intent is that you would keep track of which "obfuscator" (by date/time) that you used for each instance. So, you could freeze at a single instance for everything, or you could choose to create a unique obfuscator for on-shot cases.