[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NetScape's dependence upon RSA down for the count!



In article <[email protected]> you write:
> 
> The "messenger attack" as described in my earlier posts regarding
> public key encryption and key management seems to apply to NetScape's SSL.
> I have a Fifty dollar bill for the first person to submit to the mail box
> [email protected] a working Unix server (with cleartext session logs) which
> accepts all connections on a unix based host to the www port and redirects
> them to netscape.com leaving a clear text log of each session's SSL packets
> in /tmp by session.  All entries become the property of DMS Design. The winner
> and I will submit a claim for one of Community COnneXion's "I HACKED NETSCAPE"
> tee shirts as a server hack. (Have Fun!!)
> 

This is a trivial program!  I can't believe anyone considers this
technically difficult.  But hey, who am I to question, if you'll
pay $50!

Ok, let me back that up with real code.  Here's a proxy I've been
using for experimenting, in lieu of root access & tcpdump.

Usage: proxy localport remotehost remoteport > capturefile

Try:

$ ./proxy 2999 www.netscape.com 80 > capturefile &
$ netscape http://localhost:2999/home/welcome.html &

or

$ ./proxy 3999 alpha.mkn.co.uk 443 > capturefile &
$ netscape https://localhost:3999/ &

Here's the source.  It's a bit unstable, and could be a improved
a little, but was fine for a quick kludge.  So feel free send the
$50 to the following address at your convenience!! :-)

David Wagner
UC Berkeley
330 Soda Hall
Berkeley, CA  94720


#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <ctype.h>

/* dump bytes, sorta similar to tcpdump's style */
dump(char *p, int len)
{
	int	i, j;

	while (len > 0) {
		for (i=0; i<16 && i < len; i++) {
			printf("%2.2x", (unsigned char) p[i]);
			if (i & 1)
				printf(" ");
		}
		j = i;
		for (; i<16; i++) {
			printf("  ");
			if (i & 1)
				printf(" ");
		}
		printf("    # ");
		for (i=0; i<j; i++)
			printf("%c", (isprint(p[i])) ? p[i] : '.');
		printf("\n");

		len -= j; p += j;
	}
	printf("\n");
}

/* copy one message; guaranteed not to block */
int fromto(int from, int to)
{
	static char	buf[2048];
	int	len;

	len = read(from, buf, sizeof(buf));
	switch(len) {
		case 0:		return(0); /* EOF */
		case -1:	perror("read"); exit(1);
	}
	dump(buf, len);
	return(write(to, buf, len));
}

/* kludge to deal with select fd_set * parameters weirdness */
/* #define	FSC(x)	((fd_set *) x) */
#define	FSC(x)	((int *) x)

/* repeatedly copy both ways */
proxy(int xfd, int yfd)
{
	fd_set	fs;
	char	buffer[2048];
	int	done = 0;

	while (!done) {
		FD_ZERO(&fs);
		FD_SET(xfd, &fs); FD_SET(yfd, &fs);
		if (select(64, FSC(&fs), FSC(0), FSC(0), (struct timeval *) 0)
							== -1) {
			perror("select"); exit(1);
		}
		if (FD_ISSET(xfd, &fs))
			if (fromto(xfd, yfd) <= 0)
				done = 1;
		if (FD_ISSET(yfd, &fs))
			if (fromto(yfd, xfd) <= 0)
				done = 1;
	}
}

int remoteinit(char *addr, int port)
{
	struct sockaddr_in si;
	int fd;
	struct hostent *hp;
	char    hostname[MAXHOSTNAMELEN];

	memset(&si, 0, sizeof(struct sockaddr_in));
	si.sin_family = AF_INET;
	si.sin_addr.s_addr = inet_addr(addr);
	si.sin_port = port;
	if (si.sin_addr.s_addr == -1)
		hp = gethostbyname(addr);
	else
		hp = gethostbyaddr((char *)&si.sin_addr.s_addr,
					sizeof(struct sockaddr_in), AF_INET);
	if (hp == NULL) {
		fprintf(stderr, "unknown host %s\n", addr); exit(1);
	}
	si.sin_family = hp->h_addrtype;
	memcpy(&(si.sin_addr), hp->h_addr, hp->h_length);
	strncpy(hostname, hp->h_name, MAXHOSTNAMELEN-1);
 	if (si.sin_family == AF_INET)
		printf("Connecting to %s (%s)\n", hostname,
			inet_ntoa(*(struct in_addr *)&si.sin_addr.s_addr));
	else
		printf("Connecting to %s\n", hostname);

	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket"); exit(1);
	}
	if (connect(fd, &si, sizeof(si)) < 0) {
		perror("connect"); exit(1);
	}
	return(fd);
}

int localinit(int port)
{
	struct sockaddr_in thissock;
	int	s, i;

	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("socket"); exit(1);
	}

	memset((char *)&thissock, 0, sizeof(struct sockaddr_in));
	thissock.sin_family = AF_INET;
	thissock.sin_port = port;
	thissock.sin_addr.s_addr = htonl(INADDR_ANY);
 
	i = 1;
	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(int));

	if (bind(s, (struct sockaddr *)&thissock, sizeof(struct sockaddr_in)) < 0) {
		perror("bind"); exit(1);
	}
	if (listen(s, 5) < 0) {
		perror("listen"); exit(1);
	}

	return(s);
}

usage()
{
		fprintf(stderr, "Usage: proxy localport remotehost remoteport\n");
		exit(1);
}


int main(int argc, char **argv)
{
	int	partialxfd, xfd, yfd, i, localport, remoteport;
	struct sockaddr_in thatsock;
	char *remotehost;

	if (argc != 4)
		usage();
	localport = atoi(argv[1]);
	remotehost = argv[2];
	remoteport = atoi(argv[3]);
	if (localport < 1024 || remoteport <= 0)
		usage();

	partialxfd = localinit(localport);

	for (;;) {
		i = sizeof(struct sockaddr_in);
		if ((xfd = accept(partialxfd, (struct sockaddr *)&thatsock, &i)) < 0) {
			perror("accept"); exit(1);
		}
  
		yfd = remoteinit(remotehost, remoteport);
		proxy(xfd, yfd);
	}
}