Commit message: Buddy-ng: Fixed segmentation fault (Closes #15 on GitHub).

git-svn-id: http://svn.aircrack-ng.org/trunk@2418 28c6078b-6c39-48e3-add9-af49d547ecab
CVE: CVE-2014-8321
CWE: CWE-20
Vulnerability description: Stack-based buffer overflow in the gps_tracker function in airodump-ng.c in Aircrack-ng before 1.2 RC 1 allows local users to execute arbitrary code or gain privileges via unspecified vectors.

Project: aircrack-ng
File: buddy-ng.c

void drop_privs()
{
	if (chroot(".") == -1)
		err(1, "chroot()");

	if (setgroups(0, NULL) == -1)
		err(1, "setgroups()");

	if (setgid(69) == -1)
		err(1, "setgid()");

	if (setuid(69) == -1)
		err(1, "setuid()");
}

Project: aircrack-ng
File: buddy-ng.c

void handle_dude(int dude, int udp)
{
	unsigned char buf[2048];
	int rc;
	fd_set rfds;
	int maxfd;
	struct sockaddr_in s_in;
	socklen_t len;

	/* handshake */
	rc = recv(dude, buf, 5, 0);
	if (rc != 5) {
		close(dude);
		return;
	}

	if (memcmp(buf, "sorbo", 5) != 0) {
		close(dude);
		return;
	}

	if (send(dude, "sorbox", 6, 0) != 6) {
		close(dude);
		return;
	}

	printf("Handshake complete\n");
	memset(ids, 0, sizeof(ids));
	last_id = 0;
	wrap = 0;

	while (1) {
		FD_ZERO(&rfds);
		FD_SET(udp, &rfds);
		FD_SET(dude, &rfds);

		if (dude > udp)
			maxfd = dude;
		else
			maxfd = udp;

		if (select(maxfd+1, &rfds, NULL, NULL, NULL) == -1)
			err(1, "select()");

		if (FD_ISSET(dude, &rfds))
			break;

		if (!FD_ISSET(udp, &rfds))
			continue;

		len = sizeof(s_in);
		rc = recvfrom(udp, buf, sizeof(buf), 0,
			      (struct sockaddr*) &s_in, &len);
		if (rc == -1)
			err(1, "read()");

		if (handle(dude, buf, rc, &s_in))
			break;
	}
	close(dude);
}

Project: aircrack-ng
File: buddy-ng.c

int is_dup(unsigned short id)
{
	int idx = id/8;
	int bit = id % 8;
	unsigned char mask = (1 << bit);

	if (ids[idx] & mask)
		return 1;

	ids[idx] |= mask;
	return 0;
}

Project: aircrack-ng

int main(int argc, char *argv[])
{
	struct utsname utsName;
	struct sockaddr_in s_in;
	struct sockaddr_in dude_sin;
	int len, udp, ch, dude, s;
	int port = S_DEFAULT_PORT;
	int drop;

	while ((ch = getopt(argc, argv, "ph")) != -1) {
		switch (ch) {
		case 'p':
			drop = 0;
			break;

		default:
		case 'h':
			usage();
			break;

		}
	}

	memset(&s_in, 0, sizeof(s_in));
	s_in.sin_family = PF_INET;
	s_in.sin_addr.s_addr = INADDR_ANY;
	s_in.sin_port = htons(S_DEFAULT_UDP_PORT);

	udp = socket(s_in.sin_family, SOCK_DGRAM, IPPROTO_UDP);
	if (udp == -1)
		err(1, "socket(UDP)");
	if (bind(udp, (struct sockaddr*) &s_in, sizeof(s_in)) == -1)
		err(1, "bind()");

	s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == -1)
		err(1, "socket(TCP)");

	drop = 1;

	if (uname(&utsName) == 0)
	{
		drop = strncasecmp(utsName.sysname, "cygwin", 6);
	}

	if (drop)
		drop_privs();

	memset(&s_in, 0, sizeof(s_in));
	s_in.sin_family = PF_INET;
	s_in.sin_port = htons(port);
	s_in.sin_addr.s_addr = INADDR_ANY;

	len = 1;
	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &len, sizeof(len)) == -1)
		err(1, "setsockopt(SO_REUSEADDR)");

	if (bind(s, (struct sockaddr*) &s_in, sizeof(s_in)) == -1)
		err(1, "bind()");

	if (listen(s, 5) == -1)
		err(1, "listen()");


	while (1) {
		len = sizeof(dude_sin);
		printf("Waiting for connexion\n");
		dude = accept(s, (struct sockaddr*) &dude_sin,
			      (socklen_t*) &len);
		if (dude == -1)
			err(1, "accept()");

		printf("Got connection from %s\n",
		       inet_ntoa(dude_sin.sin_addr));
		handle_dude(dude, udp);
		printf("That was it\n");
	}
	exit(0);
}

Project: aircrack-ng
File: buddy-ng.c

void usage()
{
	printf("\n"
		"  %s - (C) 2007,2008 Andrea Bittau\n"
		"  http://www.aircrack-ng.org\n"
		"\n"
		"  Usage: buddy-ng <options>\n"
		"\n"
		"  Options:\n"
		"\n"
		"       -h        : This help screen\n"
		"       -p        : Don't drop privileges\n"
		"\n",
		getVersion("Buddy-ng", _MAJ, _MIN, _SUB_MIN, _REVISION, _BETA, _RC));

	exit(1);
}