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

From: Aggelos P. Varvitsiotis (avarvitat_private)
Date: Tue Jul 14 1998 - 06:30:32 PDT

  • Next message: Alexander Kjeldaas: "Re: ncurses 4.1 security bug"

    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.varvitsiotisat_private                     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);
    }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:04:27 PDT