Home > System Administration > Using PTYs to fool getpass()

Using PTYs to fool getpass()

This is an article that I had posted in my livejournal on 4th-May-2006 03:08 pm. I’m trying to migrate the most valuable stuff to wordpress.

Today we’ll discuss the getpass() library function and the hurdles it presents for a system administrator for system automation. The usual bash pipe (‘|’) wont help us in providing password for tools like ssh, ftp, su, etc. The main reason is the way in which getpass works to get the password from the terminal. Unlike other library routines like getchar() or scanf() which read from stdin, this one opens the /dev/tty to read the user input.

The only solution been provided to overcome this is to create pseudo terminals(pty) and run your application in that. One of the most useful of the various functions used for this is forkpty(). Yes, here I’m talking about writing your own program to create a new pty, fork and run its child in that pty, and exec the application(like ssh, ftp,…) in the child. You will get a file descriptor which can be used to read or write data to the pty(ie, the application i/o). Below is given a program that tries to make a connection between you and your application.

// ptymagic.c
#include <pty.h>
#include <utmp.h>

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <pthread.h>

int readtunnel(int pty) // thread for reading from appl
{

char ch;
while(read(pty,&ch,1) != -1)
write(1,&ch,1);

}

int writetunnel(int pty) // thread for writing to appl
{

char ch;
while(read(0,&ch,1))
write(pty,&ch,1);

}

main(int argc, char **argv)
{

int pty,child;
int ret;
pthread_t pread,pwrite;

if(argc < 2)
{

exit(-1);

}

child = forkpty(&pty,0,0,0);

if(!child)
{

struct termios tios;tcgetattr(0, &tios);
tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
tios.c_oflag &= ~(ONLCR);
tcsetattr(0, TCSANOW, &tios);

execv(argv[1],&argv[1]);

exit(-1);

}

if(child == -1)

exit(-1);

read(pty,&ret,1); // wait till the child has outputted atleast one character
write(1,&ret,1);

pthread_create(&pread,0,readtunnel,pty);
pthread_create(&pwrite,0, writetunnel,pty);

pthread_join(pread,0);

wait(&ret);

if(ret >= 0 && ret <= 255)

exit(ret);

exit(-1);

}

Compile the program as:

gcc -l pthread -l util -o ptymagic ptymagic.c

And try to run as:

echo “Your_Root_Password” | ./ptymagic su -c “cat /etc/shadow”

and see the magic.

Here, the defect is that we have to write a c program for every different kind of application which is going to be a tedious task. A better alternative is also there about which I’ll explain later.

Till then,

BYE.

Categories: System Administration
  1. Ulrich-Xander
    24 May, 2007 at 8:28 am | #1

    Thank you very much for this tutorial..
    After spending more than two days non-stop
    on trying to get scp to work “scripted”
    with a pass phrase…

  2. Emil Stanchev
    26 August, 2010 at 9:20 am | #2

    Thanks, a really useful example.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.