Advertisement
FlyFar

bash_obfus.pl

Jul 13th, 2023
1,094
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.76 KB | Cybersecurity | 0 0
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use feature ':5.10';
  5.  
  6. sub print_usage() {
  7.     say "$0 is a bash shell script minifier/obfuscator.";
  8.     say "It deletes full line comments, whitespaces and tabs, and obfuscates variable names.";
  9.     say "Usage:";
  10.     say "\t $0 -h \t This help message.";
  11.     say "\t $0 -i <input_file> -o <output_file> [-V <new_var_string>] -C -F";
  12.     say "\t Where:";
  13.     say "\t\t<input_file>\tis the shell script you want to obfuscate";
  14.     say "\t\t<output_file>\tis where you want to save the obfuscated script";
  15.     say "\t\t<new_var_string>\tis an optional argument that defines what all variables will be changed to.";
  16.     say "\t\t\tThe default is 'a', which means all variables will be changed to a0,a1,a2,a3,...";
  17.     say "\t\t-C\tis an option to clean out full line comments and blank lines.";
  18.     say "\t\t-F\tis an option to flatten out the code (remove indentations)";
  19.     exit 0;
  20. }
  21.  
  22. sub parse_cmd_args {
  23.     my $input_file="";
  24.     my $output_file="";
  25.     my $delete_blanks="";
  26.     my $flatten="";
  27.     my $new_variable_prefix="a";
  28.     for my $argnum (0 .. $#ARGV) {
  29.         if ($ARGV[$argnum] eq "-i") {
  30.             $input_file=$ARGV[$argnum+1];
  31.             $argnum++;
  32.         } elsif ($ARGV[$argnum] eq "-o") {
  33.             $output_file=$ARGV[$argnum+1];
  34.             $argnum++;
  35.         } elsif ($ARGV[$argnum] eq "-h") {
  36.             &print_usage();
  37.         } elsif ($ARGV[$argnum] eq "-V") {
  38.             $new_variable_prefix=$ARGV[$argnum+1];
  39.             $argnum++;
  40.         } elsif ($ARGV[$argnum] eq "-C") {
  41.             $delete_blanks=1;
  42.         } elsif ($ARGV[$argnum] eq "-F") {
  43.             $flatten=1;
  44.         }
  45.     }
  46.     if ($input_file eq "" || $output_file eq "") {
  47.         say "Input or output file not specified!!";
  48.         &print_usage();
  49.     }
  50.     return ($input_file,$output_file,$new_variable_prefix,$delete_blanks,$flatten);
  51. }
  52.  
  53. sub parse_vars_from_file {
  54.     my $file_name=shift;
  55.     open(my $file_handle, "<", $file_name) || die "Couldn't open '".$file_name."' for reading because: ".$!;
  56.     my %vars=();
  57.     while(my $line=<$file_handle>) {
  58.         # First pull var names from declarations
  59.         if ($line =~ m/^[ \t]*([a-z]+[a-z0-9_]*)=/) {
  60.             $vars{$1}=1;
  61.         # Then, from read statements
  62.         } elsif (($line =~ m/^[ \t]*read -s ([a-z]+[a-z0-9_]*)/) || ($line =~ m/^[ \t]*read ([a-z]+[a-z0-9_]*)/)) {
  63.             $vars{$1}=1;
  64.         # Then, from for loops
  65.         } elsif ($line =~ m/^[ \t]*for ([a-z]+[a-z0-9_]*) /) {
  66.             $vars{$1}=1;
  67.         # Then, from array access
  68.         } elsif ($line =~ m/^[ \t]*([a-z]+[a-z0-9_]*)\[.+\]=/) {
  69.             $vars{$1}=1;
  70.         }
  71.     }
  72.     close $file_handle;
  73.     return keys %vars;
  74. }
  75.  
  76. sub obfuscate {
  77.     my $input_file=shift;
  78.     my $output_file=shift;
  79.     my $new_variable_prefix=shift;
  80.     my $delete_blanks=shift;
  81.     my $flatten=shift;
  82.     my @sorted_vars=@_;
  83.  
  84.     open(my $ifh, "<", $input_file) || die "Couldn't open '".$input_file."' for reading because: ".$!;
  85.     open(my $ofh, ">", $output_file) || die "Couldn't open '".$output_file."' for writing because: ".$!;
  86.     my %var_obfus=();
  87.     my $var_index=0;
  88.     for my $var (@sorted_vars) {
  89.         $var_obfus{$var}=$new_variable_prefix.$var_index;
  90.         $var_index++;
  91.     }
  92.     my %vars=();
  93.     while(my $line=<$ifh>) {
  94.         if ($delete_blanks && (($line =~ m/^[ \t]*#[^!].*/) || ($line =~ m/^[ \t]*$/))) {
  95.             next;
  96.         }
  97.         if ($flatten) {
  98.             $line =~ s/^[ \t]*//;
  99.         }
  100.         for my $var (@sorted_vars) {
  101.             # Substitute var names in declarations
  102.             $line =~ s/^([ \t]*)$var=/$1$var_obfus{$var}=/;
  103.             # Then, in read statements
  104.             $line =~ s/^([ \t]*read .*)$var/$1$var_obfus{$var}/;
  105.             # Then, in for loops
  106.             $line =~ s/^([ \t]*for )$var/$1$var_obfus{$var}/;
  107.             # Then, in array access
  108.             $line =~ s/^([ \t]*)$var(\[.+\]=)/$1$var_obfus{$var}$2/;
  109.             # General "$" usage while making sure we're not inside ''
  110.             while ($line =~ m/^(([^\']*('[^']*')*[^']*)*)\$$var/) {
  111.                 $line =~ s/^(([^\']*('[^']*')*[^']*)*)\$$var/$1\$$var_obfus{$var}/;
  112.             }
  113.             # Only allow a $var to be replaced between '' if they're already inside ""
  114.             while ($line =~ m/^([^']*(('[^']*')*("[^"]")*)*"[^"]*)\$$var/) {
  115.                 $line =~ s/^([^']*(('[^']*')*("[^"]")*)*"[^"]*)\$$var/$1\$$var_obfus{$var}/;
  116.             }
  117.             # Special case ${var} usage while making sure we're not inside ''
  118.             while ($line =~ m/^(([^']*('[^']*')*[^']*)*)\$\{$var/) {
  119.                 $line =~ s/^(([^']*('[^']*')*[^']*)*)\$\{$var/$1\$\{$var_obfus{$var}/;
  120.             }
  121.             # Likewise, allow ${var} between '' only if we're already between ""
  122.             while ($line =~ m/^([^']*(('[^']*')*("[^"]")*)*"[^"]*)\$\{$var/) {
  123.                 $line =~ s/^([^']*(('[^']*')*("[^"]")*)*"[^"]*)\$\{$var/$1\$\{$var_obfus{$var}/;
  124.             }
  125.         }
  126.         # Print whatever got through the filters
  127.         print $ofh $line
  128.     }
  129.     close $ifh;
  130.     close $ofh;
  131. }
  132.  
  133. my ($input_file,$output_file,$new_variable_prefix,$delete_blanks,$flatten)=&parse_cmd_args();
  134. my @parsed_vars=&parse_vars_from_file($input_file);
  135. my @sorted_vars = sort { length($b) <=> length($a) } @parsed_vars;
  136. &obfuscate($input_file,$output_file,$new_variable_prefix,$delete_blanks,$flatten,@sorted_vars);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement