/isrcore/shellz.pm
Perl | 547 lines | 426 code | 35 blank | 86 comment | 19 complexity | c7d0543067d17d0e7c5f29a14a3de7ff MD5 | raw file
Possible License(s): GPL-2.0
- ###############
- # shellz.pm
- #
- # Copyright 2010 Francisco Amato
- #
- # This file is part of isr-evilgrade, www.infobytesec.com .
- #
- # isr-evilgrade is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation version 2 of the License.
- #
- # isr-evilgrade 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 General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with isr-evilgrade; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- #
- # '''
- ##
- package isrcore::shellz;
- use strict;
- #internal modules
- use base qw(isrcore::Shell);
- use isrcore::webserver;
- use isrcore::main;
- use isrcore::ASCIITable;
- use isrcore::dnsserver;
- #external modules
- use Data::Dump qw(dump);
- #ignore child's process to avoid zombie
- $SIG{CHLD} = 'IGNORE';
- ##########################################################################
- # FUNCTION init
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES class initialize
- my $ppid=0;
- sub init {
- my $self = shift;
- my $webserver = isrcore::webserver->new();
- my $dnsserver = isrcore::dnsserver->new();
- my $isrmain = isrcore::main->new();
- if( $shellz::ppid == 0 )
- {
- $shellz::ppid= getppid();
- }
- #Loadmodules
- my $ret = $isrmain->loadmodules();
- if ($ret != 1){ # loadmodules error
- $isrmain->println($ret);
- exit;
- }
- $self->{'dnsserver'}=$dnsserver;
- $self->{'webserver'}=$webserver;
- $self->{'isrmain'}=$isrmain;
- $self->{'VERSION'}="2.0.1";
- $self->{'path'}="";
- $self->{'prompt'}="evilgrade";
- $self->{'change'}=0;
- }
- ##########################################################################
- # FUNCTION prompt_str
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES return shell's prompt
- sub prompt_str {
- my $self =shift;
- my $prompt = $self->{'prompt'};
- if ($self->{'path'}){
- $prompt .= "($self->{'path'})";
- }
- $prompt .= ">";
- "$prompt"
- } #()
- ##########################################################################
- # SHELLS COMMANDS
- ##########################################################################
- ##########################################################################
- # FUNCTION run_show
- # RECEIVES cmd
- # RETURNS
- # EXPECTS
- # DOES show [object]'s information
- sub run_show {
- my $self = shift;
- my ($cmd) = @_;
- my $mods=0;
- if ($cmd eq "modules"){
- $self->{'isrmain'}->ptitle("List of modules");
- foreach my $module (sort(keys %{$self->{'isrmain'}->{'modules'}})){
- $self->{'isrmain'}->println("$module\n");
- $mods++;
- }
- $self->{'isrmain'}->println("- $mods modules available.\n\n");;
- $self->{'isrmain'}->println("\n");
- }elsif ($cmd eq "status"){
- $self->run_status($self);
- }elsif ($cmd eq "version"){
- $self->run_version($self);
- }elsif ($cmd eq "vhosts"){
- $self->run_vhosts($self);
- }elsif ($cmd eq "active"){
- $self->{'isrmain'}->ptitle("List of actived modules");
- foreach my $module (@{$self->{'webserver'}->{'current'}}){
- $self->{'isrmain'}->println("$module\n");
- $mods++;
- }
- $self->{'isrmain'}->println("- $mods modules loaded.\n\n");;
- $self->{'isrmain'}->println("\n");
- }elsif ($cmd eq "options"){
- $self->{'isrmain'}->ptitle("Display options");
- my $object;
- if ($self->{'path'}){
- $object = $self->{'isrmain'}->{'modules'}->{$self->{'path'}}->{'Base'};
- $self->{'isrmain'}->println("Name = $object->{'name'}\n");
- $self->{'isrmain'}->println("Version = $object->{'version'}\n");
- $self->{'isrmain'}->println("Author = ".dump($object->{'author'})."\n");
- $self->{'isrmain'}->println("Description = ".dump($object->{'description'})."\n");
- $self->{'isrmain'}->println("VirtualHost = ".dump($object->{'vh'})."\n\n");
- }else{
- $object = $self->{'isrmain'}->{'Base'};
- }
- my $t = new isrcore::ASCIITable;
- $t->setCols(['Name','Default','Description']);
- foreach my $module (keys %{$object->{'options'}}){
- if (!$object->{'options'}->{$module}->{'hidden'}){ #Verify if it's a hidden option
- $t->addRow($module,$object->{'options'}->{$module}->{'val'},$object->{'options'}->{$module}->{'desc'});
- }
- }
- $self->{'isrmain'}->println($t->draw()."\n");
-
- }
- }
- ##########################################################################
- # FUNCTION run_set
- # RECEIVES cmd,value
- # RETURNS
- # EXPECTS
- # DOES configure option
- sub run_set {
- my $self = shift;
- my ($cmd,$value) = @_;
- $self->{'isrmain'}->println("set $cmd, $value\n");
- my $object;
- if ($self->{'path'}){
- $object = \$self->{'isrmain'}->{'modules'}->{$self->{'path'}}->{'Base'}->{'options'};
- }else{
- $object = \$self->{'isrmain'}->{'Base'}->{'options'};
- }
- if (!$cmd){
- $self->{'isrmain'}->println("(*) Please specify option name\n");
- return
- }else{
- if (!exists($$object->{$cmd})){
- $self->{'isrmain'}->println("(*) Option name ($cmd) did not exists\n");
- return
- }else {
- $self->{'change'}=1;
- $$object->{$cmd}->{'val'} =$value; #TODO: check exists val
- #TODO: Message required webserver restart
- }
- }
-
- }
- ##########################################################################
- # FUNCTION run_configure
- # RECEIVES cmd
- # RETURNS
- # EXPECTS
- # DOES configure modules
- sub run_configure {
- my $self = shift;
- my ($cmd) = @_;
- if ($cmd){
- if (!exists($self->{'isrmain'}->{'modules'}->{$cmd})){
- $self->{'isrmain'}->println("(*) Module name ($cmd) did not exists\n");
- return
- }
- $self->{'path'}=$cmd
- }else {
- $self->{'path'}="";
- }
- }
- ##########################################################################
- # FUNCTION run_vhosts
- # RECEIVES cmd
- # RETURNS
- # EXPECTS
- # DOES display vhosts available
- sub run_vhosts{
- my $self = shift;
- my ($cmd) = @_;
- $self->{'isrmain'}->ptitle("Virtual hosts");
- print $self->{'isrmain'}->println(dump($self->{'dnsserver'}->{'Base'}->{'domains'}));
- }
- ##########################################################################
- # FUNCTION run_version
- # RECEIVES cmd
- # RETURNS
- # EXPECTS
- # DOES display console version
- sub run_version{
- my $self = shift;
- my ($cmd) = @_;
- $self->{'isrmain'}->println("version " . $self->{'VERSION'}."\n");
- }
- ##########################################################################
- # FUNCTION run_reload
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES reload modules
- sub run_reload {
- my $self = shift;
- $self->{'isrmain'}->println("reload\n");
- $self->{'isrmain'}->loadmodules();
- }
- ##########################################################################
- # FUNCTION run_start
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES start servers
- sub run_start {
- my $self = shift;
- my ($cmd) = @_;
-
- start_server( $self, "webserver",$cmd);
- start_server( $self, "dnsserver",$cmd) unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
- }
-
- sub start_server {
- my $self = shift;
- my $server_type = shift;
- my ($cmd) = @_;
- if ($self->{$server_type}->status() ){
- $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : (pid $self->{$server_type}->{'Base'}->{'child'}) already running\n");
- return;
- }
- my $response = $self->{$server_type}->loadconfig($self->{'isrmain'});
- if ($response != 1){ #error loadconfig
- $self->{'isrmain'}->println($response);
- return;
- }
- if( $server_type == "webserver" ){
- #solo para webserver esto
- $self->{'comm'}->{'parent'} = $self->{'parent'};
- $self->{'comm'}->{'child'} = $self->{'child'};
- }
- my $child;
- my $line;
- # crear el fork para salir
- die "Can't fork: $!" unless defined ($child = fork());
- if ($child==0) {
- my $line;
- $self->{$server_type}->start($self);
- if ($self->{$server_type}->{'Base'}->{'error'}){
- $self->{'isrmain'}->println("\n\nError: $self->{$server_type}->{'Base'}->{'error'}\n");
- }
- exit 0;
- }
-
- $self->{$server_type}->{'Base'}->{'child'} = $child;
- }
- ##########################################################################
- # FUNCTION run_status
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES display servers status
- sub get_status {
- my $self = shift;
- my $server_type = shift;
- if ($self->{$server_type}->status()){
- $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : (pid $self->{$server_type}->{'Base'}->{'child'}) already running\n");
- }
- else{
- $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : stopped.\n");
- }
- }
- sub run_status{
- my $self = shift;
- get_status($self,"webserver");
- get_status($self,"dnsserver") unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
- my $j=0;
- $self->{'isrmain'}->ptitle("Users status");
- my $t = new isrcore::ASCIITable;
- $t->setCols(['Client','Module','Status','Md5,SHA256,Cmd,File']);
- foreach my $ip (keys %{$self->{'webserver'}->{'users'}}){
- foreach my $module (keys %{$self->{'webserver'}->{'users'}->{$ip}}){
- my ($obj,$file) = $self->{'webserver'}->{'users'}->{$ip}->{$module};
- $file = $obj->{'file'} if ($obj->{'file'});
- $t->addRow($ip,$module,$obj->{'status'},$file);
- }
- $j++;
- }
- if ($j){ #object found
- $self->{'isrmain'}->println($t->draw()."\n");
- }else{
- $self->{'isrmain'}->println("[*] Waiting users..\n")
- }
- }
- ##########################################################################
- # FUNCTION run_stop
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES stop servers
- sub stop_server {
- my $self = shift;
- my $server_type = shift;
-
- if ($self->{$server_type}->status()){
- $self->{$server_type}->stop();
- $self->{'isrmain'}->println("Stopping $self->{$server_type}->{'Base'}->{'whoami'} [OK]\n");
-
- }
- else{
- $self->{'isrmain'}->println("$self->{$server_type}->{'Base'}->{'whoami'} : stopped\n");
- }
- }
- sub run_stop {
- my $self = shift;
- stop_server($self,"webserver");
- stop_server($self,"dnsserver") unless ( $self->{'isrmain'}->{'Base'}->{'options'}->{'DNSEnable'}->{'val'} == 0 );
-
- }
-
- ##########################################################################
- # FUNCTION run_restart
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES restart servers
- sub run_restart {
- my $self = shift;
- $self->run_stop();
- $self->run_start();
- }
- ##########################################################################
- # FUNCTION run_exit
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES exit console
- sub run_exit {
-
- my $self = shift;
- if( getppid() == $shellz::ppid ){
- $self->run_stop();
- kill KILL => $self->{pid};
- $self->{on_signal}=1;
- $self->stoploop();
- $self->SUPER::DESTROY;
- system("reset");
- }
- # $self->SUPER::DESTROY;
- # require Term::Screen;
- # my $terminal = new Term::Screen;
- # $terminal->clrscr();
- # $terminal::DESTROY;
- # sleep 2;
- exit 0;
- }
- ##########################################################################
- # FUNCTION console_cmd
- # RECEIVES xml cmd command
- # RETURNS
- # EXPECTS
- # DOES communication commands between thread and parent (called from Shell)
- sub console_cmd {
- my $self = shift;
- my ($cmd) = @_;
- my ($action,$module,$ip,$file);
- #TODO: Move to object
- my $action =$1 if $cmd =~ /\<action\>([\w]+)\<\/action\>/;
- my $module =$1 if $cmd =~ /\<module\>([\w\:\_\-]+)\<\/module\>/;
- my $ip =$1 if $cmd =~ /\<ip\>([\d\.]+)\<\/ip\>/;
- my $file =$1 if $cmd =~ /<file\>([\w\W]+)\<\/file\>/;
- my $md5 =$1 if $cmd =~ /<md5\>([\w\W]+)\<\/md5\>/;
- my $sha256 =$1 if $cmd =~ /<sha256\>([\w\W]+)\<\/sha256\>/;
- my $cwd =$1 if $cmd =~ /<cmd\>([\w\W]+)\<\/cmd\>/;
- my $tfile=$self->{'webserver'}->{'users'}->{$ip}->{$module}->{'file'};
- $self->{'webserver'}->{'users'}->{$ip}->{$module}->{'status'}=$action if ($action);
- if ($file) {
- $self->{'webserver'}->{'users'}->{$ip}->{$module}->{'file'}=($tfile) ? "$tfile\n$md5,$sha256,'$cwd',$file" :"$md5,$sha256,'$cwd',$file";
- }
-
- }
- ##########################################################################
- ## HELP
- ##########################################################################
- sub smry_show {"Display information of <object>."}
- sub smry_version {"Display framework version."}
- sub smry_set {"Configure variables"}
- sub smry_configure {"Configure <module-name>"}
- sub smry_reload {"Reload to update all the modules"}
- sub smry_start {"Start webserver"}
- sub smry_status {"Get webserver status"}
- sub smry_stop {"Stop webserver"}
- sub smry_restart {"Restart webserver"}
- sub smry_vhosts {"Show vhosts enable"}
- sub help_show {
- my ($o,$cmd) = @_;
- <<'END';
- Display information of <object>
- END
- }
- ##########################################################################
- ## AUTOCOMPLETE
- ##########################################################################
- ##########################################################################
- # FUNCTION comp_show
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES autocomplete command show
- sub comp_show{
- my ($o, $word, $line, $start) = @_;
- my @comp = ('modules','active','options','status','version','vhosts');
- @comp = sort @comp;
- @comp;
- }
- ##########################################################################
- # FUNCTION comp_configure
- # RECEIVES
- # RETURNS
- # EXPECTS
- # DOES autocomplete command configure
- sub comp_configure {
- my ($o, $word, $line, $start) = @_;
- my @comp = keys %{$o->{'isrmain'}->{'modules'}};
- @comp = sort @comp;
- @comp;
- }
- ##########################################################################
- # FUNCTION gtime
- # RECEIVES
- # RETURNS parsed time string
- # EXPECTS
- # DOES get parsed localtime
- sub gtime{
- my @t = localtime(time);
- return "[".$t[3]."/".(int($t[4])+1)."/".(int($t[5])+1900).":".$t[2].":".$t[1].":".$t[0]."] - ";
- }
-
- ##########################################################################
- ## PUBLIC FUNCTIONS
- ##########################################################################
- ##########################################################################
- # FUNCTION printshell
- # RECEIVES msg
- # RETURNS
- # EXPECTS message,debug,time
- # DOES print information to the console thread
- sub printshell{
- my $self = shift;
- my ($msg,$debug,$time) = @_;
- #return if
- return if ($debug && $self->{'isrmain'}->{'Base'}->{'options'}->{'debug'}->{'val'} == 0);
- local *PARENT = $self->{'comm'}->{'parent'};
- my $data;
- $data=$self->gtime if (!$time);
- $data .= "[DEBUG] - " if ($debug);
- $data .=$msg;
- print PARENT $data;
- sleep 1;
- }
- ##########################################################################
- # FUNCTION sendcommand
- # RECEIVES msg
- # RETURNS
- # EXPECTS
- # DOES send internal command between child and parent
- sub sendcommand{
- my $self = shift;
- my ($msg) = @_;
- local *PARENT = $self->{'comm'}->{'parent'};
- print PARENT $msg;
- }
- 1;