Using SSH Without A TTY

I recently received a mail asking how to get SSH to work from within a reverse shell (see php-reverse-shell , php-findsock-shell and perl-reverse-shell ).  I thought I’d write a brief description of the problems I’ve seen and how to work round them.

I’d be very interested if anyone has any better solutions.  Drop me a mail (pentestmonkey at pentestmonkey dot net).

Update: Also see this follow-up post on a similar subject.

Problem 1: “Host key verification failed.”

When you connect to a host for the first time you normally (when you ave a TTY) get a message like:

$ ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is ...
Are you sure you want to continue connecting (yes/no)?

You can answer “yes” and the authentication proceeds.

However, if you don’t have a TTY (like when you’re using a reverse shell), authentication fails immediately with an error:

$ ssh localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Host key verification failed.

Workaround

Before attempting an SSH connection for the first time you need to grab the host keys for host you want to connect to and store them in the known_hosts file of the current user:

ssh-keyscan -t rsa1,rsa,dsa localhost >> ~/.ssh/known_hosts

Next time you try an SSH connection you won’t get the “Host key verification failed” error.

Problem 2: Can’t enter SSH password

If you don’t have a TTY (you typically don’t when using a reverse shell) you won’t be asked for a password, authentication will just fail:

sh-3.2$ ssh localhost
Pseudo-terminal will not be allocated because stdin is not a terminal.
Permission denied (publickey,keyboard-interactive).

Workaround

You can use an external program to provide the password you want to use. Check out:

$ cat /tmp/returnpassword.sh
#!/bin/sh
echo 'some password' </dev/null
$ export DISPLAY=:0
$ export SSH_ASKPASS=/tmp/returnpassword.sh
$ ssh user@host
id
uid=1000(user) gid=1000(user)
bash -i
user@host $

Other potential solutions

Modify your php-reverse-shell (or whatever) to use PTYs if the PHP installation supports them.  Of course your php code will also need to handle the case when PTYs aren’t supported.  PHP 5 can support PTYs, but it needs to be compiled with the right options (–enable-pty).  The code modification should be simple:

$descriptorspec = array(
   0 => array("pty"),  // stdin   
   1 => array("pty"),  // stdout
   2 => array("pty")   // stderr
);

The system I tested the above code on gave the following error because PHP5 didn’t have PTY support enabled:

Warning: proc_open() [function.proc-open]: pty pseudo terminal not supported on this system in ...htdocs/php-reverse-shell.php on line 109


Leave a Reply