package Net::FullAuto::ISets::Amazon::KaliLinux_is;

### OPEN SOURCE LICENSE - GNU AFFERO PUBLIC LICENSE Version 3.0 #######
#
#    Net::FullAuto - Powerful Network Process Automation Software
#    Copyright © 2000-2015  Brian M. Kelly
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but **WITHOUT ANY WARRANTY**; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public
#    License along with this program.  If not, see:
#    <http://www.gnu.org/licenses/agpl.html>.
#
#######################################################################


our $VERSION='0.01';
our $DISPLAY='Kali Linux™';
our $CONNECT='ssh';
our $defaultInstanceType='t2.micro';

use 5.005;


use strict;
use warnings;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw($select_kali_setup);

use Net::FullAuto::Cloud::fa_amazon;

my $install_dashboard_on_kalilinux=sub {

   my $server_type=$_[0];
   my $cnt=$_[1];
   my $server_host_block=$_[2]||'';
   my $handle=$main::aws->{$server_type}->[$cnt]->[1];
   my ($stdout,$stderr,$hash,$error,$output)=('','','','',''); 
   ($stdout,$stderr)=$handle->cmd("apt-get update",3600,'__display__');
   ($stdout,$stderr)=$handle->cmd(
       "apt-get -o Dpkg::Progress=true -y install apache2",3600,
       '__display__');
   ($stdout,$stderr)=$handle->cmd("sed -e 's/index.php //' ".
        "/etc/apache2/mods-enabled/dir.conf");
   ($stdout,$stderr)=$handle->cmd("sed -e 's/Index/Index index.php/' ".
        "/etc/apache2/mods-enabled/dir.conf");
   ($stdout,$stderr)=$handle->cmd("service apache2 restart");
   ($stdout,$stderr)=$handle->cmd(
      "apt-get -o Dpkg::Progress=true -y install git",3600,'__display__');
   if ($stderr) {
      print "Kali Linux Instruction Set aws cmd ERROR!: $stderr at Line",
         __LINE__,"\n";
      Net::FullAuto::FA_Core::cleanup();
   }
   ($stdout,$stderr)=$handle->cwd("/var/www");
   ($stdout,$stderr)=$handle->cmd("git clone ".
       "https://github.com/afaqurk/linux-dash.git 2>&1",
       '__display__');
   ($stdout,$stderr)=$handle->cmd(
       "apt-get -o Dpkg::Progress=true -y install php5 ".
       "libapache2-mod-php5 php5-mcrypt",3600,
       '__display__');
   ($stdout,$stderr)=$handle->cmd("/usr/sbin/apache2ctl start",
      '__allow_no_output__');
   my $master=$main::aws->{$server_type}->[$cnt]->[0]->{InstanceId};
   my $c="aws ec2 describe-instances --instance-ids $master 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   my $mdns=$hash->{Reservations}->[0]->{Instances}->[0]->{PublicDnsName};
   print "\n   ACCESS KALI LINUX DASHBOARD AT:\n\n",
         " http://$mdns/linux-dash\n";
   my $thanks=<<'END';

     ______                  _    ,
       / /              /   ' )  /        /
    --/ /_  __.  ____  /_    /  / __ . . /
   (_/ / /_(_/|_/ / <_/ <_  (__/_(_)(_/_'   For Trying
                             //

           _   _      _         _____      _ _    _         _
          | \ | | ___| |_      |  ___|   _| | |  / \  _   _| |_  |
          |  \| |/ _ \ __| o o | |_ | | | | | | / _ \| | | | __/ | \
          | |\  |  __/ |_  o o |  _|| |_| | | |/ ___ \ |_| | ||     |
          |_| \_|\___|\__|     |_|   \__,_|_|_/_/   \_\__,_|\__\___/ ©


   Copyright © 2000-2015  Brian M. Kelly  Brian.Kelly@FullAuto.com

END
   eval {
      local $SIG{ALRM} = sub { die "alarm\n" }; # \n required
      alarm 15;
      print $thanks;
      print "   \n   Press Any Key to EXIT ... ";
      <STDIN>;
   };alarm(0);
   print "\n\n\n   Please wait at least a minute for the Default Browser\n",
         "   to start with your new Kali Linux™ installation!\n\n\n";
   &Net::FullAuto::FA_Core::cleanup;

};

my $configure_kalilinux=sub {

   my $server_type=$_[0];
   my $cnt=$_[1];
   my $selection=$_[2]||'';
   my $server_host_block=$_[3]||'';
   my $handle=$main::aws->{$server_type}->[$cnt]->[1];
   my ($stdout,$stderr)=('','');
   ($stdout,$stderr)=$handle->cmd("sudo apt update",'__display__');
   ($stdout,$stderr)=$handle->cmd(
       "sudo apt-get -o Dpkg::Progress=true -y install git debootstrap",
       3600,'__display__');
   if ($stderr) {
      print "Kali Linux Instruction Set cmd ERROR!: $stderr at Line".
         __LINE__."\n";
      Net::FullAuto::FA_Core::cleanup();
   }
   ($stdout,$stderr)=$handle->cmd("sudo ln -sf ".
       "/usr/share/debootstrap/scripts/{wheezy,kali}");
   # BUILDING uses Jazmine Figlet Font
   my $install_kali=<<'END';

                oooo.  o    o o o     ooo.   o o    o .oPYo.
                8   `8 8    8 8 8     8  `8. 8 8b   8 8    8
                8YooP' 8    8 8 8     8   `8 8 8`b  8 8
                8   `b 8    8 8 8     8    8 8 8 `b 8 8   oo
                8    8 8    8 8 8     8   .P 8 8  `b8 8    8
                8oooP' `YooP' 8 8oooo 8ooo'  8 8   `8 `YooP8
          ........................................................
          ::::::::::::::::::::::::::::::::::::::::::::::::::::::::


        ##  ##   ##   ##     ##     ##     ## ##   ## ##   ## ##  ## TM
        ##  ##  ####  ##     ##     ##     ## ###  ## ##   ## ##  ##
        ## ##  ##  ## ##     ##     ##     ## #### ## ##   ##  ####
        ####   ##  ## ##     ##     ##     ## ## #### ##   ##   ##
        ## ##  ###### ##     ##     ##     ## ##  ### ##   ##  ####
        ##  ## ##  ## ##     ##     ##     ## ##   ## ##   ## ##  ##
        ##  ## ##  ## ###### ##     ###### ## ##   ##  #####  ##  ##


   http://www.kali.org

   (The Kali Linux™ Project is **NOT** a sponsor of the FullAuto© Project.)
END
   print $install_kali;sleep 10;
   ($stdout,$stderr)=$handle->cmd('git clone '.
      "https://github.com/offensive-security/kali-cloud-build.git 2>&1",
      3600,'__display__');
   if ($stderr) {
      print "Kali Linux Instruction Set cmd ERROR!: $stderr at Line".
         __LINE__."\n";
      Net::FullAuto::FA_Core::cleanup();
   }
   ($stdout,$stderr)=$handle->cwd("kali-cloud-build");
   my $sk='';my $ak='';
   unless (exists $main::aws->{access_id}) {
      open(CF,"$ENV{HOME}/.aws/credentials");
      while (my $line=<CF>) {
         if ($line=~/^aws_access_key_id *= *(.*)\s*/) {
            $ak=$1;
         } elsif ($line=~/^aws_secret_access_key *= *(.*)\s*/) {
            $sk=$1;
         }
      }
      close CF;
   } else {
      $ak=$main::aws->{access_id};
      $sk=$main::aws->{secret_key};
   }
   my $getownerid='aws ec2 describe-security-groups --filters '.
                  'Name="description",Values="default VPC security group"';
   my ($hash,$output,$error)=('','','');
   ($hash,$output,$error)=run_aws_cmd($getownerid);
   if ($error) {
      print "Kali Linux Instruction Set aws cmd ERROR!: $error at Line".
         __LINE__."\n";
      Net::FullAuto::FA_Core::cleanup();
   }
   my $getkaliimages='aws ec2 describe-images --filters Name=owner-id,Values='
                    .$hash->{SecurityGroups}->[0]->{OwnerId};
   ($hash,$output,$error)=run_aws_cmd($getkaliimages);
   if (-1<$#{$hash->{Images}}) {
      foreach my $image (@{$hash->{Images}}) {
         next if -1==index $image->{Name},'kali-kali-amd';
         ($hash,$output,$error)=run_aws_cmd(
            "aws ec2 deregister-image --image-id ".$image->{ImageId});
         if ($error) {
            print "Kali Linux Instruction Set aws cmd ERROR!: $error at Line".
               __LINE__."\n";
            Net::FullAuto::FA_Core::cleanup();
         }
         ($hash,$output,$error)=run_aws_cmd(
            "aws ec2 delete-snapshot --snapshot-id ".
            $image->{BlockDeviceMappings}->[0]->{Ebs}->{SnapshotId});
         if ($error) {
            print "Kali Linux Instruction Set aws cmd ERROR!: $error at Line".
               __LINE__."\n";
            Net::FullAuto::FA_Core::cleanup();
         }
      }
   }
   ($stdout,$stderr)=$handle->cmd(
      "sudo ./kali-cloud-build ec2 --secret-key $sk --access-key $ak",
      3600,'__display__');
   my @lastfew=();
   foreach my $line (reverse split "\n", $stderr) {
      chomp($line=~tr/\0-\11\13-\37\177-\377//d);
      $line=~s/^......(.*)...$/$1/;
      unshift @lastfew, $line;
      last if $line=~/Unable to register an AMI/;
   }
   my $lastfew=join "\n",@lastfew;
   my ($nm,$arch,$kern,$snap,$sz,$del,$typ)=('','','','','','','');
   my $r=qr/['](.*?)[']/;
   $lastfew=~
      /^.*?$r.*cture $r.*rnel $r.*shot ['](.*?)[:](.*?):(.*?):(.*?)['].*$/s;
   $nm=$1;$arch=$2;$kern=$3;$snap=$4;$sz=$5;$del=$6;$typ=$7;
   print "NM=$nm and ARCH=$arch and TYP=$typ\n";
   my $rd=$main::aws->{$server_type}->[0]->[0]->{RootDeviceName};
   my $reg_cmd="aws ec2 register-image --name '".$nm."' --description '' ".
         "--architecture '".$arch."' --kernel-id '".$kern."' --root-device".
         "-name '".$rd."' --block-device-mappings \"[{\\\"DeviceName\\\":".
         "\\\"".$rd."\\\",\\\"Ebs\\\":{\\\"SnapshotId\\\":\\\"".$snap.
         "\\\",\\\"VolumeSize\\\":$sz,\\\"DeleteOnTermination\\\":$del".
         ",\\\"VolumeType\\\":\\\"$typ\\\"}}]\"";
   ($hash,$output,$error)=run_aws_cmd($reg_cmd);
   if ($error) {
      print "Kali Linux Instruction Set aws cmd ERROR!: $error at Line".
         __LINE__."\n";
      Net::FullAuto::FA_Core::cleanup();
   }
   my $i=$hash->{ImageId};
   my $pemfile=$pem_file;
   $pemfile=~s/\.pem\s*$//s;
   my $type=$main::aws->{kali}->{type};
   $type=~s/^t2/t1/;
   $type=~s/^m2/m1/;
   $type=~s/^m3/m1/;
   my $kali=$main::aws->{kali}->{kali};
   my $s=$main::aws->{fullauto}->
      {NetworkInterfaces}->[0]->{SubnetId}||'';
   my $g=get_aws_security_id('KaliLinuxSecurityGroup');
   my $c="aws ec2 run-instances --image-id $i --count 1 ".
      "--instance-type $type --key-name $pemfile ".
      "--security-group-ids $g --subnet-id $s";
   launch_server('Kali.org',1,$kali,'root',$c,
                   $install_dashboard_on_kalilinux);

};

my $standup_kali_linux=sub {

   my $type="]T[{select_type}";
   $type=~s/^"//;
   $type=~s/"$//;
   $type=substr($type,0,(index $type,' ->')-3);
   $main::aws->{kali}->{type}=$type;
   my $os='Ubuntu';
   my $kali="]T[{select_kali_setup}";
   $main::aws->{kali}->{kali}=$kali;
   my $i=$main::aws->{fullauto}->{ImageId}||'';
   $i='ami-29ebb519' if $os eq 'Ubuntu';
   my $s=$main::aws->{fullauto}->
         {NetworkInterfaces}->[0]->{SubnetId}||'';
   my $g=$main::aws->{fullauto}->
         {SecurityGroups}->[0]->{GroupId}||'';
   my $n=$main::aws->{fullauto}->
         {SecurityGroups}->[0]->{GroupName}||'';
   my $c='aws ec2 describe-security-groups '.
         "--group-names $n";
   my $u=($os eq 'Ubuntu')?'ubuntu':'';
   my ($hash,$output,$error)=('','','');
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error;
   my $cidr=$hash->{SecurityGroups}->[0]->{IpPermissions}
            ->[0]->{IpRanges}->[0]->{CidrIp};
   $c='aws ec2 create-security-group --group-name '.
      'KaliLinuxSecurityGroup --description '.
      '"Kali.org Security Group" 2>&1';
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name KaliLinuxSecurityGroup --protocol '.
      'tcp --port 22 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name KaliLinuxSecurityGroup --protocol '.
      'tcp --port 0-65535 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   $c='aws ec2 authorize-security-group-ingress '.
      '--group-name KaliLinuxSecurityGroup --protocol '.
      'icmp --port -1 --cidr '.$cidr." 2>&1";
   ($hash,$output,$error)=run_aws_cmd($c);
   Net::FullAuto::FA_Core::handle_error($error) if $error
      && $error!~/already exists/;
   my $cnt=0;
   my $pemfile=$pem_file;
   $pemfile=~s/\.pem\s*$//s;
   if (exists $main::aws->{'Kali.org'}) {
      my $g=get_aws_security_id('KaliLinuxSecurityGroup');
      my $c="aws ec2 run-instances --image-id $i --count 1 ".
         "--instance-type $type --key-name $pemfile ".
         "--security-group-ids $g --subnet-id $s";
      if ($#{$main::aws->{'Kali.org'}}==0) {
         launch_server('Kali.org',$cnt,$kali,$u,$c,$configure_kalilinux);
      } else {
         my $num=$#{$main::aws->{'Kali.org'}}-1;
         my @tags=('Name Node','Secondary Name Node','Slave 1','Slave 2');
         foreach my $num (0..$num) {
            launch_server('Kali.org',$cnt++,$kali,$u,$c,
                          $configure_kalilinux,$tags[$num]);
         }
      }
   }

   return '{choose_demo_setup}<';

};

my $kali_setup_summary=sub {

   package kali_setup_summary;
   use JSON::XS;
   my $region="]T[{awsregions}";
   $region=~s/^"//;
   $region=~s/"$//;
   my $type="]T[{select_type}";
   $type=~s/^"//;
   $type=~s/"$//;
   my $money=$type;
   $money=~s/^.*-> \$(.*?) +(?:[(].+[)] )*\s*per hour$/$1/;
   $type=substr($type,0,(index $type,' ->')-3);
   my $kali="]T[{select_kali_setup}";
   $kali=~s/^"//;
   $kali=~s/"$//;
   print "REGION=$region and TYPE=$type\n";
   print "KALI=$kali\n";
   my $num_of_servers=0;
   my $hp=$kali;
   $hp=~s/^.*(\d+)\sServer.*$/$1/;
   if ($hp==1) {
      $main::aws->{'Kali.org'}->[0]=[];
   } elsif ($hp=~/^\d+$/ && $hp) {
      foreach my $n (0..$hp) {
         $main::aws->{'Kali.org'}=[] unless exists
            $main::aws->{'Kali.org'};
         $main::aws->{'Kali.org'}->[$n]=[];
      }
   }
   $num_of_servers=$hp;
   my $cost=int($num_of_servers)*$money;
   my $cents='';
   if ($cost=~/^0\./) {
      $cents=$cost;
      $cents=~s/^0\.//;
      if (length $cents>2) {
         $cents=~s/^(..)(.*)$/$1.$2/;
         $cents=~s/^0//;
         $cents=' ('.$cents.' cents)';
      } else {
         $cents=' ('.$cents.' cents)';
      }
   }
   my $show_cost_banner=<<'END';

      _                  _       ___        _  ___
     /_\  __ __ ___ _ __| |_    / __|___ __| ||__ \
    / _ \/ _/ _/ -_) '_ \  _|  | (__/ _ (_-<  _|/_/
   /_/ \_\__\__\___| .__/\__|   \___\___/__/\__(_)
                   |_|

END
   $show_cost_banner.=<<END;
   Note: There is a \$$cost per hour cost$cents to launch $num_of_servers
         AWS EC2 $type servers for the FullAuto Demo:

         $kali


END
   my %show_cost=(

      Name => 'show_cost',
      Item_1 => {

         Text => "I accept the \$$cost$cents per hour cost",
         Result => $standup_kali_linux,

      },
      Item_2 => {

         Text => "Return to Choose Demo Menu",
         Result => sub { return '{choose_demo_setup}<' },

      },
      Item_3 => {

         Text => "Exit FullAuto",
         Result => sub { Net::FullAuto::FA_Core::cleanup() },

      },
      Scroll => 1,
      Banner => $show_cost_banner,

   );
   return \%show_cost;

};

our $select_kalilinux_setup=sub {

   my @options=('Kali Linux™ on 1 Server');
   my $kali_setup_banner=<<'END';


   ##  ##   ##   ##     ##     ##     ## ##   ## ##   ## ##  ## TM
   ##  ##  ####  ##     ##     ##     ## ###  ## ##   ## ##  ##
   ## ##  ##  ## ##     ##     ##     ## #### ## ##   ##  ####
   ####   ##  ## ##     ##     ##     ## ## #### ##   ##   ##
   ## ##  ###### ##     ##     ##     ## ##  ### ##   ##  ####
   ##  ## ##  ## ##     ##     ##     ## ##   ## ##   ## ##  ##
   ##  ## ##  ## ###### ##     ###### ## ##   ##  #####  ##  ##

   http://www.kali.org

   (The Kali Linux™ Project is **NOT** a sponsor of the FullAuto© Project.)

   Choose the Kali Linux™ setup you wish to demo. Note that more servers
   means more expense, and more JVMs means less permformance on a
   small instance type. Consider a medium or large instance type (previous
   screens) if you wish to test more than 1 JVM on a server. You can
   navigate backwards and make new selections with the [<] LEFTARROW key.

END
   my %select_kali_setup=(

      Name => 'select_kali_setup',
      Item_1 => {

         Text => ']C[',
         Convey => \@options,
         Result => $kali_setup_summary,

      },
      Scroll => 1,
      Banner => $kali_setup_banner,
   );
   return \%select_kali_setup,

};

1
