Upload code to a remote machine & tunnel back out
# This tool runs a program remotely on a server that will need to make a
# network connection back out. It does this under two heavy
# 1. the target machine is prevented from doing so by for example an
# external firewall.
# 2. The required program to execute on the target machine doesn't
# exist. The only route into the machine is through ssh, and we
# assume it can execute a shell with basic unix tool once it's there.
# The first is quite a common situation and the second is a typical
# situation that is in effect with a heavily change controlled
# environment where "foreign" programs aren't allowed to be installed,
# or where the change management is hindering Getting Real Work
# Done(TM). So in effect this is designed to take advantage of what is
# essentially a flaw in the original security model and use it in a way
# that wasn't intended.
# How it works is essentially this: the program is sent down an SSH
# connection, written to a temporary file and then executed. As part of
# the SSH connection, a listener process is created on the target
# machine at a particular port the program is expecting to communicate
# over which is tunneled through the SSH session to another host:port
# target_host: an ssh address of the machine to run the program remotely on.
# target_port: where ssh will create a listener process on the target host.
# remote_host: the full name of the machine to be connected to from the
# target machine. It doesn't necessarily have to the machine executing
# the ssh session, simply that the machine executing the ssh session can
# connect to it.
# program: the code to run on the target machine.
# Normally program would point to a real program compiled for the target
# host's architecture.
# target_bin is the directory the program will reside on the target machine.
# /tmp is world-writeable so we have a guaranteed dropzone.
# This cat is just to create a test program; it requires lynx to test
# the outgoing connection and leave evidence of success.
cat > $program <<PROGRAM
lynx -source http://localhost:$target_port/ > /tmp/localhost.html
# . Make a target bin directory; copy the program there; set
# executable flag.
# . Set up target port forwarding so that a port on the target machine is
# forwarded over the ssh connection to a port on another (possibly local)
# machine. So, from the target machine's point of view,
# localhost:target_port -> remote_host:remote_port
# . Run the program that's been left in the target bin directory.
# It so happens this is all possible with a single ssh invocation.
ssh -R $target_port:$remote_host:$remote_port $target_host "\
mkdir $target_bin 2>/dev/null;\
cd $target_bin ;\
cat > $program_name ;\
chmod +x $program_name ;\
$target_bin/$program_name" < $program &