C写的端口打描程序

Home / Article MrLee 2015-12-31 3230

端口扫描是指某些别有用心的人发送一组端口扫描消息,试图以此侵入某台计算机,并了解其提供的计算机网络服务类型(这些网络服务均与端口号相关)。端口扫描是计算机解密高手喜欢的一种方式。攻击者可以通过它了解到从哪里可探寻到攻击弱点。实质上,端口扫描包括向每个端口发送消息,一次只发送一个消息。接收到的回应类型表示是否在使用该端口并且可由此探寻弱点。 扫描器是一种自动检测远程或本地主机安全性弱点的程序,通过使用扫描器你可以不留痕迹的发现远程服务器的各种TCP端口的分配及提供的服务和它们的软件版本!这就能让我们间接的或直观的了解到远程主机所存在的安全问题。
下面是基于TCP扫描,UDP我就不发上来了,下载工程:端口扫描C版
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
/*
  * tcp_scan - determine available tcp services, optionally collect banners
  * and detect telnet options
  *
  * Author: Wietse Venema.
  */
#include <sys types.h="">
#include <sys param.h="">
#include <sys time.h="">
#include <sys socket.h="">
#include <netinet in.h="">
#include <netinet in_systm.h="">
#include <netinet ip.h="">
#include <netinet ip_icmp.h="">
#include <netinet tcp.h="">
#include <arpa telnet.h="">
#include <stdio.h>
#include <signal.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
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 <sys select.h="">
#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);
}
</sys></errno.h></string.h></netdb.h></signal.h></stdio.h></arpa></netinet></netinet></netinet></netinet></netinet></sys></sys></sys></sys>

 

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

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