Platon Technologies
neprihlásený Prihlásiť Registrácia
SlovakEnglish
open source software development oslavujeme 10 rokov vývoja otvoreného softvéru! Sobota, 21. apríl 2018
O nás
Magazín
Otvorený softvér
CVS
Služby
Index  »  Administrácia  »  Rýchla oprava lokálnej vmsplice() zraniteľnosti

Rýchla oprava lokálnej vmsplice() zraniteľnosti

Autor: Ondrej Jombík | Sekcia: Administrácia | Dátum: 2008-02-12

Základné info

Dňa 8. februára 2008 bola publikovaná lokálna zraniteľnosť Linuxového systému pre jadrá od 2.6.1 až po jadro 2.6.24. Chyba v systémovom volaní vmsplice() umožňuje lokálnemu používateľovi (potenciálnemu útočníkovi) prostredníctvom dostupného exploitu získať administrátorské práva na systéme.

Naša skupina Platon Group pre vás pripravila rýchlu opravu tejto vážnej zraniteľnosti. Oprava spočíva v úplnom vypnutí systémového volania vmsplice() prostredníctvom modulu, ktorý je možné vykompilovať voči aktuálnemu jadru. Nie je teda nutná rekompilácia jadra ani reštart systému!

Modul, okrem blokovania volania vmsplice(), loguje každé volanie do kernel logu. Z toho je možné zistiť, či niektorá aplikácia toto volanie používa, alebo či sa niektorí z lokálnych používateľov pokúsil o spustenie exploitu a získanie administrátorských práv.

Takto vyzerá príklad nainštalovania modulu a logovania aktivity vmsplice():

vmsplice-EPERM.c Linux Kernel 2.6 module by Ondrej Jombik <nepto@platon.sk>
vmsplice-EPERM.c disables vmsplice() syscall for preventing local root vulnearbility
vmsplice-EPERM.c: searching for syscall table
vmsplice-EPERM.c: syscall table found at c03fc540
vmsplice-EPERM.c module installed
vmsplice-EPERM.c call attempt: fd=4, iov=bff720b8, nr_segs=1, flags=0; forcing -EPERM

Stiahnutie a inštalácia

Zdrojové kódy modulu do jadra sú dostupné na tejto adrese:

http://platon.sk/projects/release_view_page.php?release_id=68

Po rozbalení stačí spustiť kompiláciu cez príkaz make. Ak kompilácia dopadla úspešne, vložíme modul do jadra príkazom:

insmod vmsplice-EPERM.ko

V logoch, ktoré si pozrieme cez príkaz dmesg by sme mali vidieť, či sme boli v našom snažení úspešní, alebo nie.

Poznámky

  • Táto oprava je vhodná len pre systémy, ktorých komponenty a aplikácie pri svojej plnohodnotnej prevádzke nepoužívajú volanie vmsplice().

  • Pokiaľ zlyhá autodetekcia sys_call_table, je možné zistiť túto adresu priamo príkazom:

    grep sys_call_table /boot/System.map

    Zistenú adresu potom napíšte do súboru vmsplice-EPERM.c na riadok 62 namiesto hodnoty NULL.

  • Toto riešenie nie je plnohodnotná oprava. Doporučovaná je aktualizácia systému na poslednú stabilnú verziu Linuxového jadra.

Zdrojový kód

Nasleduje kompletný výpis zdrojového kódu modulu:

/*
 * vmsplice-EPERM.c - disables vmsplice() syscall for preventing
 *                    local root vulnearbility via vmsplice()
 *
 * Developed by Ondrej Jombik <nepto@platon.sk>
 * Copyright (c) 2008 Platon Group, http://platon.sk/
 * Licensed under terms of GNU General Public License.
 * All rights reserved.
 *
 * Changelog:
 * 2008-02-11 - created
 * 2008-02-12 - released
 *
 */

/* $Platon$ */

#include <linux/init.h>
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/time.h>

#include <asm/unistd.h>

#define BUFSIZE 100 /* we'll read first 100 bytes of int $0x80*/

struct {
    unsigned short limit;
    unsigned int base;
} __attribute__ ((packed)) idtr;

struct {
    unsigned short off1;
    unsigned short sel;
    unsigned char none,flags;
    unsigned short off2;
} __attribute__ ((packed)) idt;

long (*real_sys_vmsplice)(
    int fd,
    const struct iovec *iov,
    unsigned long nr_segs,
    unsigned int flags
);
asmlinkage long new_sys_vmsplice(
    int fd,
    const struct iovec *iov,
    unsigned long nr_segs,
    unsigned int flags
);

/* This is the place, where you can write fixed address of sys_call_table.
 * You can get this address from:
 *   $ grep sys_call_table /boot/System.map
 * Leave this NULL for autodetect.
 */
unsigned long **sys_call_table = NULL;

/* Stolen from scprint.c
 * http://downloads.securityfocus.com/downloads/scprint.tar.gz
 */
unsigned long **find_sys_call_table_old(void) /* {{{ */
{
    unsigned long **sctable;
    unsigned long ptr;
    extern unsigned long loops_per_jiffy;
    sctable = NULL;
    for (ptr = (unsigned long) &loops_per_jiffy;
            ptr < (unsigned long) &boot_cpu_data;
            ptr += sizeof(void *))
    {
        unsigned long *p;
        p = (unsigned long *)ptr;
        if (p[__NR_close] == (unsigned long) sys_close){
            sctable = (unsigned long **)p;
            return &sctable[0];
        }
    }
    return NULL;
} /* }}} */

static void *memmem(const void* haystack, size_t hl, /* {{{ */
        const void* needle, size_t nl)
{
    register int i;
    if (nl > hl) {
        return 0;
    }
    for (i = hl - nl + 1; i; --i) {
        if (! memcmp(haystack, needle, nl)) {
            return (char*) haystack;
        }
        ++haystack;
    }
    return 0;
} /* }}} */

/* Function will return address of the syscall table.
 * Based on
 * http://www.epanastasi.com/docs/syscall_talk/example1-sct/example1.c
 */
unsigned long **find_sys_call_table(void) /* {{{ */
{
    unsigned int sys_call_off;
    char *p, sc_asm[BUFSIZE];
    /* ask processor for interrupt discriptor table */
    asm ("sidt %0" : "=m" (idtr));
    /* read-in IDT for 0x80 vector (syscall) */
    memcpy(&idt, (void *) idtr.base+8*0x80,sizeof(idt));
    sys_call_off = (idt.off2 << 16) | idt.off1;
    memcpy(sc_asm, (void *) sys_call_off, BUFSIZE);
    /* we have syscall routine address now, look for syscall table
       dispatch (indirect call) */
    p = (char*) memmem(sc_asm, BUFSIZE, "\xff\x14\x85", 3);
    if (p != NULL) {
        return (void *)*(unsigned*)(p+3);
    }
    return NULL;
} /* }}} */

static int __init vmsplice_EPERM_init(void) /* {{{ */
{
    printk(KERN_INFO "vmsplice-EPERM.c Linux Kernel 2.6 module"
            " by Ondrej Jombik <nepto@platon.sk>\n");
    printk(KERN_INFO "vmsplice-EPERM.c disables vmsplice() syscall"
            " for preventing local root vulnearbility via vmsplice()\n");

    if (sys_call_table == NULL) {
        printk(KERN_INFO "vmsplice-EPERM.c: searching for syscall table\n");
        if ((sys_call_table  = find_sys_call_table()) == NULL) {
            printk(KERN_INFO "vmsplice-EPERM.c: syscall table NOT found");
            printk(KERN_INFO "vmsplice-EPERM.c module NOT installed\n");
            return -1;
        } else {
            printk(KERN_INFO "vmsplice-EPERM.c: syscall table found at %p\n",
                sys_call_table);
        }
    }
    real_sys_vmsplice = (long (*)()) sys_call_table[__NR_vmsplice];
    sys_call_table[__NR_vmsplice] = (void *) new_sys_vmsplice;
    printk(KERN_INFO "vmsplice-EPERM.c module installed\n");
    return 0;
} /* }}} */

static void __exit vmsplice_EPERM_exit(void) /* {{{ */
{
    sys_call_table[__NR_vmsplice] = (void *) real_sys_vmsplice;
    printk(KERN_INFO "vmsplice-EPERM.c module removed\n");
} /* }}} */

asmlinkage long new_sys_vmsplice( /* {{{ */
        int fd,
        const struct iovec *iov,
        unsigned long nr_segs,
        unsigned int flags
        )
{
    printk(KERN_INFO "vmsplice-EPERM.c call attempt:"
            " fd=%d, iov=%p, nr_segs=%lu, flags=%u;"
            " forcing -EPERM\n",
            fd, iov, nr_segs, flags);
    return -EPERM; /* always return -EPERM */
} /* }}} */

module_init(vmsplice_EPERM_init);
module_exit(vmsplice_EPERM_exit);

MODULE_AUTHOR("Ondrej Jombik");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Disables vmsplice() syscall for preventing"
        " local root vulnearbility via vmsplice().");

/* Modeline for ViM {{{
 * vim: set ts=4:
 * vim600: fdm=marker fdl=0 fdc=3:
 * }}} */

Credits: rajo, jojo, ivan, hlava, roleta

Čo je Platón?
Platón bol veľmi doležitý filozof starovekého Grécka, študent Sokratesa a učiteľ Aristotela. viac info...

Platon Group zastrešuje slovenskú skupinu vývojárov otvoreného softvéru. Vyvíja, spravuje, dokumentuje niekoľko úspešných open-source projektov.

Platon Technologies, s.r.o. je mladá a dynamicky rozvíjajúca sa spoločnosť, ktorá má za cieľ prinášať otvorené technológie do komerčnej a verejnej sféry.

Podporte nás

Výkonný webhosting
a multihosting

Platon Webhosting

Super rýchle servery
a profesionálna administrácia

Virtuálne, dedikované a manažované servery

Vývoj
Diskusia k článku
David 2008-02-13 07:48
wire     2008-03-12 02:12

   

 
Copyright © 2002-2006 Platon Group
Stránka používa redakčný systém Metafox
Na začiatok · Odkazový formulár · Prihláška
Upozorniť na chybu na PLATON.SK webstránke · Podmienky použitia · Ochrana osobných údajov