📄 synscan.c
字号:
{ static char pkt[sizeof(struct tcphdr)]; struct tcphdr *tcp; struct in6_addr source; unsigned char buf[60]; bzero(pkt, sizeof(pkt)); bzero(buf, sizeof(buf)); tcp = (struct tcphdr *) (pkt); tcp->th_sport = htons(sport); tcp->th_dport = htons(dport); tcp->th_seq = th_seq; tcp->th_ack = th_ack; tcp->th_x2 = 0; tcp->th_off = 5; tcp->th_flags = flag; tcp->th_win = 4096; tcp->th_sum = 0; tcp->th_urp = 0; routethrough6(dst, &source); memcpy(&(buf[0]), &source, sizeof(source)); memcpy(&(buf[16]), &dst->sin6_addr, sizeof(dst->sin6_addr)); buf[34] = sizeof(struct tcphdr) / 256; buf[35] = sizeof(struct tcphdr) % 256; buf[39] = IPPROTO_TCP; memcpy(&(buf[40]), tcp, 20); tcp->th_sum = in_cksum(buf, 60); *len = 20; return pkt;}#elsechar * mktcp6(struct sockaddr_in6 * dst, int sport, int dport, unsigned long th_seq, unsigned long th_ack, unsigned char flag, int * len){ return NULL;}#endif/*--------------------------------------------------------------------*/int find_rtt(struct in_addr dst, struct sockaddr_in6 * sin6, unsigned long *rtt){ int soc; unsigned short ports[] = {21, 22, 34, 25, 53, 79, 80, 110, 113, 135, 139, 143, 264, 389, 443, 993, 1454, 1723, 3389, 8080, 0}; unsigned short use[3]; int num = 0; int n; int i; int bpf; int magic = 4441 + (rand() % 1200); struct sockaddr_in soca; int len; int skip; struct in_addr src; int j; unsigned long max, max_max; int err = 0; int noresend = 0; struct sockaddr * so; int so_sz; soc = rawsocket(); if (soc < 0) return -1; if ( is_ipv6 != 0 ) bpf = openbpf6(sin6, magic); else bpf = openbpf(dst, &src, magic); if (bpf < 0) { close(soc); return -1; } skip = get_datalink_size(bpf_datalink(bpf)); bzero(&soca, sizeof(soca)); if ( is_ipv6 == 0 ) { soca.sin_family = AF_INET; soca.sin_addr = dst; so = (struct sockaddr*)&soca; so_sz = sizeof(soca); } else { so = (struct sockaddr*)sin6; so_sz = sizeof(*sin6); } for (i = 0; ports[i] != 0; i++) { char *res; unsigned long ack = maketime(); int plen = 0; char *pkt = (is_ipv6 == 0) ? mktcp(src, magic, dst, ports[i], ack, 0, TH_SYN, &plen) : mktcp6(sin6, magic, ports[i], ack, 0, TH_SYN, &plen); int e; struct timeval tv = {1, 0}; int err = 0; unsigned short p = ports[i];#if DEBUG > 1 printf("send to port %d\n", ports[i]);#endif errno = 0; e = sendto(soc, pkt, plen, 0, so, so_sz); if (e < 0) { fprintf(stderr, "[%d] synscan->find_rtt->sendto failed: %s\n", getpid(), strerror(errno)); close(soc); bpf_close(bpf); return -1; } res = (char *) bpf_next_tv(bpf, &len, &tv); if (res != NULL) {#if DEBUG > 1 printf("Found port %d\n", p);#endif use[num++] = p; if (num >= 3) break; } } if (num == 0) {#if DEBUG > 1 printf("Found nothing\n");#endif bpf_close(bpf); close(soc); *rtt = htonl(1 << 28); /* One second */ return 0; } max = max_max = 0; for (j = 0, n = 0; j < 10; j++, n++) { char *res; unsigned long ack = maketime(); char *pkt; int plen; int e; struct timeval tv = {1, 0}; pkt = (is_ipv6 == 0) ? mktcp(src, magic, dst, use[n % num], ack, 0, TH_SYN, &plen) : mktcp6(sin6, magic, use[n%num], ack, 0, TH_SYN, &plen); e = sendto(soc, pkt, plen, 0, so, so_sz); if (e < 0) { fprintf(stderr, "[%d] synscan->find_rtt(2)->sendto failed: %s\n", getpid(), strerror(errno)); close(soc); bpf_close(bpf); return -1; } res = (char *) bpf_next_tv(bpf, &len, &tv); if (res != NULL) { unsigned long val = compute_rtt(extractack(res + skip, len)); noresend = 0; if (val && val > max_max) { if (max != 0) { if (val < max * 2) { max = max_max; max_max = val; } } else { max = max_max; max_max = val; } } } else {#if DEBUG > 1 printf("No reply ?!\n");#endif j--; err++; noresend++; if (noresend > 4) noresend = 0; if (err > 10) { *rtt = htonl(1 << 28); return 0; } } } close(soc); bpf_close(bpf); if(max == 0)max = htonl(1 << 28); *rtt = max; return 1;}struct list *sendpacket(int soc, int bpf, int skip, struct in_addr dst, struct in_addr src, struct sockaddr_in6 * sin6, int dport, int magic, struct list * packets, unsigned long * rtt, int sniff, struct arglist * env){ unsigned long ack = maketime(); int plen; char *pkt = (is_ipv6 == 0) ? mktcp(src, magic, dst, dport, ack, 0, TH_SYN, &plen):mktcp6(sin6, magic, dport, ack, 0, TH_SYN, &plen); int len; char *res; struct sockaddr_in soca; struct sockaddr * so; int so_sz = 0; struct timeval rtt_tv = timeval(*rtt); static int retry = 0; bzero(&soca, sizeof(soca)); if ( is_ipv6 == 0 ) { soca.sin_family = AF_INET; soca.sin_addr = dst; so = (struct sockaddr*)&(soca); so_sz = sizeof(soca); } else { so = (struct sockaddr*)sin6; so_sz = sizeof(*sin6); } rtt_tv.tv_sec *= 1000; rtt_tv.tv_sec /= 8; rtt_tv.tv_usec += (rtt_tv.tv_sec % 1000) * 1000; rtt_tv.tv_sec /= 1000; if ( rtt_tv.tv_sec >= 0 && rtt_tv.tv_usec > 10000 ) { rtt_tv.tv_sec = 0; rtt_tv.tv_usec = 10000; } if (dport != 0) { int e; ipci(); packets = add_packet(packets, dport, ack);send: errno = 0; e = sendto(soc, pkt, plen, 0, so, so_sz); if (e < 0) { if ( errno == ENOBUFS ) { retry ++; if ( retry < 60 ) { sleep(1); goto send; } } fprintf(stderr, "[%d] synscan->sendpacket->sendto failed: %s\n", getpid(), strerror(errno)); return SCAN_FATAL_ERR; } } if (sniff != 0) { struct timeval t, n;again: res = (char *) bpf_next_tv(bpf, &len, &rtt_tv); if (res != NULL) { unsigned short sport = extractsport(res + skip, len); int synack = issynack(res + skip, len); unsigned int rack = extractack(res + skip, len); unsigned int rseq = extractseq(res + skip, len); int ttl = extractttl(res + skip, len); if (synack) { char * rst; int len; char key[1024];#ifdef DEBUG printf("=> Port %d is open\n", sport);#endif scanner_add_port(env, sport, "tcp"); /* Send a RST to make sure the connection is closed on the remote side */ rst = (is_ipv6 == 0) ? mktcp(src, magic, dst, sport, htonl(ntohl(ack) + 1),htonl(ntohl(rseq) + 1 ), TH_RST, &plen): mktcp6(sin6, magic, sport, ack + 1, htonl(ntohl(rseq) + 1), TH_RST, &plen); sendto(soc, rst, sizeof(struct ip) + sizeof(struct tcphdr), 0, so, so_sz); /* Adjust the rtt */ *rtt = compute_rtt(rack); if ( ntohl(*rtt) >= ( 1 << 28 ) ) *rtt = htonl(1 << 28); snprintf(key, sizeof(key), "SynScan/TTL/%d", sport); plug_set_key(env, key, ARG_INT, (void*)ttl); } ipcd(); packets = rm_packet(packets, sport); rtt_tv.tv_sec = 0; rtt_tv.tv_usec = 0; goto again; } } return packets;}int scan(struct arglist * env, struct in_addr dst, struct sockaddr_in6 * sin6, unsigned long rtt){ int num; int soc = rawsocket(); int bpf; struct in_addr src; int magic = 4441 + (rand() % 1200); int skip; int i; struct list *packets = NULL; struct timeval rtt_tv = timeval(htonl(ntohl(rtt) / 2)); struct arglist *globals = arg_get_value(env, "globals"); struct arglist *hostinfos = arg_get_value(env, "HOSTNAME"); char *hname = arg_get_value(hostinfos, "NAME"); int retry; char *range = get_preference(env, "port_range"); unsigned short *ports;#ifdef DEBUG printf("===> port range = %s\n", range);#endif ports = (unsigned short *) getpts(range, &num); if (soc < 0) return -1;# if ( is_ipv6 != 0 ) bpf = openbpf6(sin6, magic); else bpf = openbpf(dst, &src, magic); skip = get_datalink_size(bpf_datalink(bpf)); for (i = 0; i < num ; i += 2) { int retry = 0; if (i % 100 == 0) comm_send_status(globals, hname, "portscan", i, num); if ( ipcc() != 0 ) packets = rm_dead_packets(packets, rtt, &retry); else { int err = 0; if ( sin6 == NULL && ! cct(dst, ports[i]) ) err = 1; if ( err == 0 ) packets = sendpacket(soc, bpf, skip, dst, src, sin6, ports[i], magic, packets, &rtt, 0, env); if ( packets == SCAN_FATAL_ERR ) break; if ( i + 1 < num ) { packets = sendpacket(soc, bpf, skip, dst, src, sin6, ports[i + 1], magic, packets, &rtt, 1, env); if ( packets == SCAN_FATAL_ERR ) break; } } }#ifdef DEBUG printf("Done with the sending\n");#endif while (packets != NULL && packets != SCAN_FATAL_ERR ) { i = 0; retry = 0; packets = rm_dead_packets(packets, rtt, &retry); while (retry != 0 && i < 2) { packets = sendpacket(soc, bpf, skip, dst, src, sin6, retry, magic, packets, &rtt, 0, env); if ( packets == SCAN_FATAL_ERR ) break; packets = rm_dead_packets(packets, rtt, &retry); i++; } packets = sendpacket(soc, bpf, skip, dst, src, sin6, retry, magic, packets, &rtt, 1, env); } comm_send_status(globals, hname, "portscan", num, num);#if 0 plug_set_key(env, "Host/num_ports_scanned", ARG_INT, (void*)num);#endif close(soc); bpf_close(bpf); if(ports != NULL)efree(&ports); if (num >= 65535) plug_set_key(env, "Host/full_scan", ARG_INT, (void*) 1); return 0;}#define EN_NAME "SYN Scan"#define EN_DESC "\n\This plugins performs a supposedly fast SYN port scan\n\It does so by computing the RTT (round trip time) of the packets\n\coming back and forth between the nessusd host and the target,\n\then it uses that to quicky send SYN packets to the remote host\n"#define COPYRIGHT "Copyright (C) Renaud Deraison <deraison@cvs.nessus.org>"#define EN_SUMMARY "Performs a TCP SYN scan"#define EN_FAMILY "Port scanners"PlugExport int plugin_init(struct arglist * desc){ plug_set_id(desc, 11219); plug_set_version(desc, "$Revision: 1.30 $"); plug_set_name(desc, EN_NAME, NULL); plug_set_summary(desc, EN_SUMMARY, NULL); plug_set_description(desc, EN_DESC, NULL); plug_set_copyright(desc, COPYRIGHT, NULL); plug_set_category(desc, ACT_SCANNER); plug_set_family(desc, EN_FAMILY, NULL); plug_set_dep(desc, "ping_host.nasl"); return (0);}PlugExport int plugin_run(struct arglist * env){ int ret = maketime(); unsigned long rtt; struct in_addr *dst = plug_get_host_ip(env); struct in_addr dest; struct timeval tv; int kb_rtt; int type;#ifdef IPV6_SUPPORT struct sockaddr_in6 * sin6 = plug_get_host_ip6(env); bzero(&dest, sizeof(dest)); if ( sin6 != NULL && dst == NULL ) is_ipv6 = 1; else is_ipv6 = 0; if ( is_ipv6 != 0 && islocalhost6(&sin6->sin6_addr) ) return 0;#else struct sockaddr_in * sin6 = NULL;#endif if ( dst ) dest = *dst; if ( (is_ipv6 == 0) && islocalhost(dst) ) return 0; /* Don't scan for ever -- emergency fix : abort after one hour */ signal(SIGALRM, _exit); alarm(3600); kb_rtt = (int)plug_get_key ( env, "/tmp/ping/RTT", &type ); if ( kb_rtt ) rtt = (kb_rtt / 1000000) << 28 | ( ( (kb_rtt % 1000000 ) & 0xFFFFFFF0 ) >> 4 ); else { if (find_rtt(dest, sin6, &rtt) < 0) { fprintf(stderr, "Something went wrong, bailing out\n"); return (1); } } if ( rtt >= ( 1 << 28 ) ) rtt = htonl(1 << 28);#ifdef DEBUG printf("RTT = 0x%.8x\n", ntohl(rtt));#endif tv = timeval(rtt);#ifdef DEBUG printf("That's %d seconds and %d usecs\n", tv.tv_sec, tv.tv_usec);#endif scan(env, dest, sin6, rtt); plug_set_key(env, "Host/scanned", ARG_INT, (void *) 1); plug_set_key(env, "Host/scanners/synscan", ARG_INT, (void*)1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -