C写的端口打描程序

Home / Hackintosh MrLee 2015-12-31 2718

端口扫描是指某些别有用心的人发送一组端口扫描消息,试图以此侵入某台计算机,并了解其提供的计算机网络服务类型(这些网络服务均与端口号相关)。端口扫描是计算机解密高手喜欢的一种方式。攻击者可以通过它了解到从哪里可探寻到攻击弱点。实质上,端口扫描包括向每个端口发送消息,一次只发送一个消息。接收到的回应类型表示是否在使用该端口并且可由此探寻弱点。 扫描器是一种自动检测远程或本地主机安全性弱点的程序,通过使用扫描器你可以不留痕迹的发现远程服务器的各种TCP端口的分配及提供的服务和它们的软件版本!这就能让我们间接的或直观的了解到远程主机所存在的安全问题。
下面是基于TCP扫描,UDP我就不发上来了,下载工程:端口扫描C版
 /*
  * tcp_scan - determine available tcp services, optionally collect banners
  * and detect telnet options
  * 
  * Author: Wietse Venema.
  */
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
extern int errno;
extern char *optarg;
extern int optind;
#ifndef __STDC__
extern char *strerror();
#endif
#define offsetof(t,m)	(size_t)(&(((t *)0)->m))
#ifndef IPPORT_TELNET
#define IPPORT_TELNET	23
#endif
#ifndef FD_SET
#include 
#endif
#ifndef INADDR_ANY
#define INADDR_ANY 0xffffffff
#endif
#include "lib.h"
#define BANNER_LENGTH	2048		/* upper bound on banner info */
#define BANNER_TIME	10		/* time for host to send banner */
#define BANNER_IDLE	1		/* delay after last banner info */
#define YES     1
#define NO      0
#define WAIT	1
#define NOWAIT	0
int     verbose;			/* default silent mode */
int     banner_time = BANNER_TIME;	/* banner timeout */
int     open_file_limit;		/* max nr of open files */
int     load_limit;			/* max nr of open sockets */
struct timeval now;			/* banner_info last update time */
fd_set  write_socket_mask;		/* sockets with connect() in progress */
fd_set  read_socket_mask;		/* sockets with connect() finished */
int     ports_busy;			/* number of open sockets */
int     ports_done;			/* number of finished sockets */
int     max_sock;			/* max socket file descriptor */
int     want_err;			/* want good/bad news */
int     show_all;			/* report all ports */
char   *src_port = 0;			/* port to send from */
int    *socket_to_port;			/* socket to port number */
typedef struct {
    unsigned char *buf;			/* banner information or null */
    int     count;			/* amount of banner received sofar */
    int     flags;			/* see below */
    struct timeval connect_time;	/* when connect() finished */
    struct timeval read_time;		/* time of last banner update */
} BANNER_INFO;
BANNER_INFO *banner_info = 0;
#define F_TELNET	(1<<0)		/* telnet options seen */
int     icmp_sock;			/* for unreachable reports */
static struct sockaddr_in dst;		/* remote endpoint info */
static struct sockaddr_in src;		/* local endpoint info */
static char *send_string;		/* string to send */
int     response_time;			/* need some response */
#define NEW(type, count) (type *) mymalloc((count) * sizeof(type))
#define time_since(t) (now.tv_sec - t.tv_sec + 1e-6 * (now.tv_usec - t.tv_usec))
/* main - command-line interface */
main(argc, argv)
int     argc;
char   *argv[];
{
    int     c;
    struct protoent *pe;
    char  **ports;
    progname = argv[0];
    if (geteuid())
	error("This program needs root privileges");
    open_file_limit = open_limit();
    load_limit = open_file_limit - 10;
    while ((c = getopt(argc, argv, "abl:s:t:S:uUvw:")) != EOF) {
	switch (c) {
	case 'a':
	    show_all = 1;
	    break;
	case 'b':
	    if (banner_info == 0)
		banner_info = NEW(BANNER_INFO, open_file_limit);
	    break;
	case 'l':
	    if ((load_limit = atoi(optarg)) <= 0)
		usage("invalid load limit");
	    if (load_limit > open_file_limit - 10)
		load_limit = open_file_limit - 10;
	    break;
	case 's':
	    send_string = optarg;
	    signal(SIGPIPE, SIG_IGN);
	    break;
	case 'S':
	    src_port = optarg;
	    break;
	case 't':
	    if ((response_time = atoi(optarg)) <= 0)
		usage("invalid timeout");
	    break;
	case 'u':
	    want_err = EHOSTUNREACH;
	    break;
	case 'U':
	    want_err = ~EHOSTUNREACH;
	    break;
	case 'v':
	    verbose = 1;
	    break;
	case 'w':
	    if ((banner_time = atoi(optarg)) <= 0)
		usage("invalid timeout");
	    break;
	default:
	    usage((char *) 0);
	    break;
	}
    }
    argc -= (optind - 1);
    argv += (optind - 1);
    if (argc < 3)
	usage("missing host or service argument");
    socket_to_port = NEW(int, open_file_limit);
    FD_ZERO(&write_socket_mask);
    FD_ZERO(&read_socket_mask);
    ports_busy = 0;
    /*
     * Allocate the socket to read ICMP replies.
     */
    if ((pe = getprotobyname("icmp")) == 0)
	error("icmp: unknown protocol");
    if ((icmp_sock = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
	error("icmp socket: %m");
    FD_SET(icmp_sock, &read_socket_mask);
    /*
     * Scan the ports.
     */
    memset((char *) &dst, 0, sizeof(dst));
    dst.sin_addr = find_addr(argv[1]);
    dst.sin_family = AF_INET;
    if (src_port) {
	memset((char *) &src, 0, sizeof(src));
	src.sin_addr.s_addr = INADDR_ANY;
	src.sin_port = find_port(src_port, "tcp");
	src.sin_family = AF_INET;
    }
    if (response_time > 0)
	alarm(response_time);
    for (ports = argv + 2; *ports; ports++)
	scan_ports(*ports);
    while (ports_busy > 0)
	monitor_ports(WAIT);
    return (0);
}
/* usage - explain command syntax */
usage(why)
char   *why;
{
    if (why)
	remark(why);
    error("usage: %s [-abuU] [-l load] [-s string] [-S src_port] [-w time] host ports...",
	  progname);
}
/* scan_ports - scan ranges of ports */
scan_ports(service)
char   *service;
{
    char   *cp;
    int     min_port;
    int     max_port;
    int     port;
    int     sock;
    /*
     * Translate service argument to range of port numbers.
     */
    if ((cp = strchr(service, '-')) != 0) {
	*cp++ = 0;
	min_port = (service[0] ? ntohs(find_port(service, "tcp")) : 1);
	max_port = (cp[0] ? ntohs(find_port(cp, "tcp")) : 65535);
    } else {
	min_port = max_port = ntohs(find_port(service, "tcp"));
    }
    /*
     * Iterate over each port in the given range. Try to keep as many sockets
     * open at the same time as possible. Gradually increase the number of
     * probes so that they will be spread in time.
     */
    for (port = min_port; port <= max_port; port++) {
	if (verbose)
	    remark("connecting to port %d", port);
	dst.sin_port = htons(port);
	while ((sock = socket(dst.sin_family, SOCK_STREAM, 0)) < 0) {
	    remark("socket: %m");
	    monitor_ports(WAIT);
	}
	if (src_port && bind(sock, (struct sockaddr *) & src, sizeof(src)) < 0)
	    error("bind port %s: %m", src_port);
	add_socket(sock, port);
	non_blocking(sock, YES);
	if (connect(sock, (struct sockaddr *) & dst, sizeof(dst)) < 0
	    && errno != EINPROGRESS) {
	    if (errno == EADDRINUSE)
		error("connect: %m");
	    report_and_drop_socket(sock, errno);
	    continue;
	}
	if (ports_busy < load_limit && ports_busy < ports_done) {
	    monitor_ports(NOWAIT);
	} else {
	    while (ports_busy >= load_limit || ports_busy >= ports_done)
		monitor_ports(WAIT);
	}
    }
}
/* monitor_ports - watch for socket activity */
monitor_ports(wait)
int     wait;
{
    fd_set  read_mask;
    fd_set  write_mask;
    static struct timeval waitsome = {1, 1,};
    static struct timeval waitnot = {0, 0,};
    int     sock;
    char    ch;
    if (banner_info == 0) {
	/*
	 * When a connect() completes, report the socket and get rid of it.
	 */
	write_mask = write_socket_mask;
	read_mask = read_socket_mask;
	if (select(max_sock + 1, &read_mask, &write_mask, (fd_set *) 0,
		   wait ? (struct timeval *) 0 : &waitnot) < 0)
	    error("select: %m");
	if (FD_ISSET(icmp_sock, &read_mask))
	    receive_icmp(icmp_sock);
	for (sock = 0; ports_busy > 0 && sock <= max_sock; sock++) {
	    if (FD_ISSET(sock, &write_mask)) {
		if (read(sock, &ch, 1) < 0 && errno != EWOULDBLOCK && errno != EAGAIN) {
		    if (errno == EADDRINUSE)
			error("connect: %m");
		    report_and_drop_socket(sock, errno);
		} else {
		    report_and_drop_socket(sock, 0);
		}
	    }
	}
    } else {
	/*
	 * When a connect() completes, try to receive some data within
	 * banner_time seconds. Assume we have received all banner data when
	 * a socket stops sending for BANNER_IDLE seconds.
	 */
	write_mask = write_socket_mask;
	read_mask = read_socket_mask;
	if (select(max_sock + 1, &read_mask, &write_mask, (fd_set *) 0,
		   wait ? &waitsome : &waitnot) < 0)
	    error("select: %m");
	if (FD_ISSET(icmp_sock, &read_mask))
	    receive_icmp(icmp_sock);
	gettimeofday(&now, (struct timezone *) 0);
	for (sock = 0; ports_busy > 0 && sock <= max_sock; sock++) {
	    if (sock == icmp_sock)
		continue;
	    if (FD_ISSET(sock, &write_mask)) {
		FD_CLR(sock, &write_socket_mask);
		FD_SET(sock, &read_socket_mask);
		banner_info[sock].connect_time = now;
		if (send_string)
		    do_send_string(sock);
	    } else if (FD_ISSET(sock, &read_mask)) {
		switch (read_socket(sock)) {
		case -1:
		    if (errno != EWOULDBLOCK && errno != EAGAIN)
			report_and_drop_socket(sock, errno);
		    break;
		case 0:
		    report_and_drop_socket(sock, 0);
		    break;
		}
	    } else if (FD_ISSET(sock, &read_socket_mask)) {
		if (time_since_connect(sock) > banner_time
		    || time_since_read(sock) > BANNER_IDLE)
		    report_and_drop_socket(sock, 0);
	    }
	}
    }
}
/* read_socket - read data from server */
read_socket(sock)
int     sock;
{
    BANNER_INFO *bp = banner_info + sock;
    unsigned char *cp;
    int     len;
    int     count;
    if (bp->buf == 0)
	bp->buf = (unsigned char *) mymalloc(BANNER_LENGTH);
    cp = bp->buf + bp->count;
    len = BANNER_LENGTH - bp->count;
    if (len == 0)
	return (0);
    bp->read_time = now;
    /*
     * Process banners with one-character reads so that we can detect telnet
     * options.
     */
    if ((count = read(sock, cp, 1)) == 1) {
	if (cp[0] == IAC) {
	    if ((count = read(sock, cp + 1, 2)) == 2) {
		if (cp[1] == WILL || cp[1] == WONT) {
		    cp[1] = DONT;
		    bp->flags |= F_TELNET;
		    write(sock, cp, 3);
		} else if (cp[1] == DO || cp[1] == DONT) {
		    cp[1] = WONT;
		    bp->flags |= F_TELNET;
		    write(sock, cp, 3);
		}
	    }
	} else {				/* cp[0] != IAC */
	    bp->count++;
	}
    }
    return (count);
}
/* report_and_drop_socket - report what we know about this service */
report_and_drop_socket(sock, err)
int     sock;
int     err;
{
    alarm(0);
    if (show_all || want_err == err || (want_err < 0 && want_err != ~err)) {
	struct servent *sp;
	int     port = socket_to_port[sock];
	printf("%d:%s:", port, (sp = getservbyport(htons(port), "tcp")) != 0 ?
	       sp->s_name : "UNKNOWN");
	if (banner_info) {
	    BANNER_INFO *bp = banner_info + sock;
	    if (bp->flags & F_TELNET)
		putchar('t');
	    putchar(':');
	    if (bp->count > 0)
		print_data(stdout, bp->buf, bp->count);
	}
	if (err && show_all)
	    printf("%s", strerror(err));
	printf("\n");
	fflush(stdout);
    }
    drop_socket(sock);
}
/* add_socket - say this socket is being connected */
add_socket(sock, port)
int     sock;
int     port;
{
    BANNER_INFO *bp;
    socket_to_port[sock] = port;
    if (banner_info) {
	bp = banner_info + sock;
	bp->count = 0;
	bp->buf = 0;
	bp->flags = 0;
    }
    FD_SET(sock, &write_socket_mask);
    if (sock > max_sock)
	max_sock = sock;
    ports_busy++;
}
/* drop_socket - release socket resources */
drop_socket(sock)
int     sock;
{
    BANNER_INFO *bp;
    if (banner_info && (bp = banner_info + sock)->buf)
	free((char *) bp->buf);
    close(sock);
    FD_CLR(sock, &read_socket_mask);
    FD_CLR(sock, &write_socket_mask);
    ports_busy--;
    ports_done++;
}
/* time_since_read - how long since read() completed? */
time_since_read(sock)
int     sock;
{
    BANNER_INFO *bp = banner_info + sock;
    return (bp->count == 0 ? 0 : time_since(bp->read_time));
}
/* time_since_connect - how long since connect() completed? */
time_since_connect(sock)
int     sock;
{
    BANNER_INFO *bp = banner_info + sock;
    return (time_since(bp->connect_time));
}
/* receive_icmp - receive and decode ICMP message */
receive_icmp(sock)
int     sock;
{
    union {
	char    chars[BUFSIZ];
	struct ip ip;
    }       buf;
    int     data_len;
    int     hdr_len;
    struct ip *ip;
    struct icmp *icmp;
    struct tcphdr *tcp;
    int     port;
    if ((data_len = recv(sock, (char *) &buf, sizeof(buf), 0)) < 0) {
	error("error: recv: %m");
	return;
    }
    /*
     * Extract the IP header.
     */
    ip = &buf.ip;
    if (ip->ip_p != IPPROTO_ICMP) {
	error("error: not ICMP proto (%d)", ip->ip_p);
	return;
    }
    /*
     * Extract the IP payload.
     */
    hdr_len = ip->ip_hl << 2;
    if (data_len - hdr_len < ICMP_MINLEN) {
	remark("short ICMP packet (%d bytes)", data_len);
	return;
    }
    icmp = (struct icmp *) ((char *) ip + hdr_len);
    data_len -= hdr_len;
    if (icmp->icmp_type != ICMP_UNREACH)
	return;
    /*
     * Extract the offending IP packet header.
     */
    if (data_len < offsetof(struct icmp, icmp_ip) + sizeof(icmp->icmp_ip)) {
	remark("short IP header in ICMP");
	return;
    }
    ip = &(icmp->icmp_ip);
    if (ip->ip_p != IPPROTO_TCP)
	return;
    if (ip->ip_dst.s_addr != dst.sin_addr.s_addr)
	return;
    /*
     * Extract the offending TCP packet header.
     */
    hdr_len = ip->ip_hl << 2;
    tcp = (struct tcphdr *) ((char *) ip + hdr_len);
    data_len -= hdr_len;
    if (data_len < offsetof(struct tcphdr, th_dport) + sizeof(tcp->th_dport)) {
	remark("short TCP header in ICMP");
	return;
    }
    /*
     * Process ICMP subcodes.
     */
    switch (icmp->icmp_code) {
    case ICMP_UNREACH_NET:
    case ICMP_UNREACH_PROTOCOL:
	/* error("error: network or protocol unreachable"); */
	/* NOTREACHED */
    case ICMP_UNREACH_PORT:
    case ICMP_UNREACH_HOST:
	port = ntohs(tcp->th_dport);
	for (sock = 0; sock < open_file_limit; sock++)
	    if (socket_to_port[sock] == port) {
		report_and_drop_socket(sock, EHOSTUNREACH);
		return;
	    }
	break;
    }
}
/* do_send_string - send the send string */
do_send_string(sock)
int     sock;
{
    char    buf[BUFSIZ];
    char   *cp = buf;
    char    ch;
    int     c;
    int     i;
    char   *s = send_string;
    while (*s && cp < buf + sizeof(buf) - 1) {	/* don't overflow the buffer */
	if (*s != '\\') {			/* ordinary character */
	    *cp++ = *s++;
	} else if (isdigit(*++s) && *s < '8') {	/* \nnn octal code */
	    sscanf(s, "%3o", &c);
	    *cp++ = c;
	    for (i = 0; i < 3 && isdigit(*s) && *s < '8'; i++)
		s++;
	} else if ((ch = *s++) == 0) {		/* at string terminator */
	    break;
	} else if (ch == 'b') {			/* \b becomes backspace */
	    *cp++ = '\b';
	} else if (ch == 'f') {			/* \f becomes formfeed */
	    *cp++ = '\f';
	} else if (ch == 'n') {			/* \n becomes newline */
	    *cp++ = '\n';
	} else if (ch == 'r') {			/* \r becomes carriage ret */
	    *cp++ = '\r';
	} else if (ch == 's') {			/* \s becomes blank */
	    *cp++ = ' ';
	} else if (ch == 't') {			/* \t becomes tab */
	    *cp++ = '\t';
	} else {				/* \any becomes any */
	    *cp++ = ch;
	}
    }
    write(sock, buf, cp - buf);
}

 

本文链接:https://www.it72.com/7432.htm

推荐阅读
最新回复 (0)
返回