Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Building.Open.Source.Network.Security.Tools.Components.And.Techniques [Electronic resources] - نسخه متنی

Mike D. Schiffman

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Sample Code–Knock

The following two source files comprise the Knock codebase. To preserve readability, we richly comment the code but do not include any book-text inside the code. You can download the full source files from this book's companion Web site at http://www.wiley.com/compbooks/schiffman.


knock.h



/*
* $Id: knock.h,v 1.1.1.1 2002/03/13 21:01:12 route Exp $
*
* Building Open Source Network Security Tools
* knock.h - Port Scanning Technique example code
*
* Copyright (c) 2002 Mike D. Schiffman mike@infonexus.com>
* All rights reserved.
*
*/
#include <libnet.h>
#include <pcap.h>
#define SNAPLEN 94 /* Ethernet + IP + opt + TCP */
#define PROMISC 1
#define TIMEOUT 500
#define PORT_OPEN 0
#define PORT_CLOSED 1
#define PORT_OPEN_TIMEDOUT 2
#define PORT_CLOSED_TIMEDOUT 3
#define SOURCE_PORT 31337
struct knock_pacK
{
pcap_t *p; /* pcap descriptor */
struct pcap_pkthdr h; /* pcap packet header */
libnet_t *1; /* libnet descriptor */
libnet_ptag_t ip; /* IP header */
libnet_ptag_t tcpudp; /* TCP or UDP header */
libnet_plist_t *plist; /* libnet port list */
u_long src_ip; /* our IP address */
u_long dst_ip; /* host to scan */
u_char flags; /* control flags */
u_char to; /* packet read timeout */
#define NETWORK_TIMEOUT 2 /* 2 seconds and we're crying foul */
u_char scan_type; /* either TCP or UDP! */
#define SCAN_TCP 0 /* TCP */
#define SCAN_UDP 1 /* UDP */
u_char scan_subtype; /* TCP scan subtype */
#define SCAN_TCP_SYN 1 /* Half-open scan */
#define SCAN_TCP_FIN 2 /* Stealth FIN scan */
#define SCAN_TCP_XMAS 3 /* Stealth XMAS scan */
u_short port; /* current port we're scanning */
u_char *packet; /* everyone's favorite: packet! */
u_short ports_open; /* open ports */
char errbuf[LIBNET_ERRBUF_SIZE];
};
struct knock_pack *knock_init(char *, u_char, char *, u_char, u_char,
u_char, char *, char *);
void knock_destroy(struct knock_pack *);
void knock(struct knock_pack *);
int build_packet (struct knock_pack *);
int write_packet(struct knock_pack *);
int receive_packet(struct knock_pack *);
void cleanup(int);
int catch_sig(int, void (*)());
void usage(char *);
/* EOF */


knock.c



/*
* $Id: knock.c,v 1.1.1.1 2002/03/13 21:01:12 route Exp $
*
* Building Open Source Network Security Tools
* knock.c - Port Scanning Technique example code
*
* Copyright (c) 2002 Mike D. Schiffman <mike@infonexus.com>
* All rights reserved.
*
*/
#include "./knock.h"
int loop = 1;
int
main(int argc, char **argv)
{
int c;
u_char flags, to;
u_char scan_type, scan_subtype;
char *device;
struct knock_pack *kp;
char errbuf[LIBNET_ERRBUF_SIZE], host[512], p_list[100];
printf("Knock 1.0 [TCP / UDP port scanning tool]\n");
to = 0;
flags = 0;
device = NULL;
scan_type = SCAN_TCP;
scan_subtype = SCAN_TCP_SYN;
memset (&host, NULL, sizeof (host));
while ((c = getoptfargc, argv, "hi:T:t:u")) !=EOF)
{
switch (c)
{
case 'h':
usage(argv[0]);
exit(EXIT_SUCCESS);
break;
case 'i':
device = optarg;
break;
case 'T':
to = atoi(optarg);
break;
case 't':
scan_type = SCAN_TCP;
scan_subtype = atoi(optarg);
switch (scan_subtype)
{
case SCAN_TCP_SYN:
break;
case SCAN_TCP_FIN:
break;
case SCAN_TCP_XMAS:
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
break;
case 'u':
scan_type = SCAN_UDP;
break;
default:
usage(argv[0]);
exit(EXIT_FAILURE);
}
}
c = argc - optind;
if (c != 2)
{
usage(argv[0]);
exit(EXIT_FAILURE);
}
else
{
/* target host */
strncpy(host, argv[optind] , sizeof (host) - 1);
/* port list */
strncpy(p_list, argvfoptind + 1], sizeof (p_list) - 1);
}
/*
* Initialize knock. Here we'll bring up libpcap and libnet.
*/
kp = knock_init (device, flags, host, scan_type, scan_subtype, to,
p_list, errbuf);
if (kp == NULL)
{
fprintf(stderr, "knock_init() failed: %s n", errbuf); goto done;
}
/* print out the scan type~*/
switch (scan_type)
{
case SCAN_UDP:
printf("UDP");
break;
case SCAN_TCP:
switch (scan_subtype)
{
case SCAN_TCP_SYN:
printf("TCP Half-open");
break;
case SCAN_TCP_FIN:
printf("TCP Stealth FIN");
break;
case SCAN_TCP_XMAS:
printf("TCP Stealth XMAS");
break;
}
}
printf("-based port scan n");
printf("<ctrl-c> to quit n");
knock(kp);
done:
if (kp)
{
printf("%d %s open n", kp->ports_open, kp->ports_open == 1 ?
"port" : "ports");
}
knock_destroy(kp);
/* shut down knock */
return (EXIT_SUCCESS);
}
struct knock_pack *
knock_init(char *device, u_char flags, char *host, u_char scan_type,
u_char scan_subtype, u_char to, char *p_list, char *errbuf)
{
struct knock_pack *kp;
/*
* We want to catch the interrupt signal so we can inform the user
* how many packets we captured before we exit.
*/
if (catch_sig(SIGINT, cleanup) == -1)
{
sprintf(errbuf, "can't catch SIGINT signal. n");
return (NULL);
}
kp = malloc (sizeof (struct knock_pack));
if (kp == NULL)
{
snprintf(errbuf, PCAP_ERRBUF_SIZE, strerror(errno));
return (NULL);
}
kp->flags = flags;
kp->scan_type = scan_type;
kp->scan_subtype = scan_subtype;
kp->to = to == 0 ? NETWORK_TIMEOUT : to;
/*
* If device is NULL, that means the user did not specify one and
* is leaving it up libpcap / libnet to find one. We'll use
* libpcap's lookup routine, but they're both from the same
* codebase so it doesn't matter… ;)
*/
if (device == NULL)
{
device = pcap_lookupdev(errbuf);
if (device == NULL)
{
return (NULL);
}
}
/*
* Open the packet capturing device with the following values:
*
* SNAPLEN: We won't need more than 80 bytes
* PROMISC: on
* The interface needs to be in promiscuous mode to capture all
* network traffic on the localnet.
* TIMEOUT: 500ms
* A 500 ms timeout is probably fine for most networks. For
* architectures that support it, you might want to tune this value
* depending on how much traffic you're seeing on the network.
*/
kp->p = pcap_open_live(device, SNAPLEN, PROMISC, TIMEOUT, errbuf);
if (kp- p == NULL)
{
return (NULL);
}
/*
* We need to make sure this is Ethernet. The DLT_EN10MB specifies
* standard 10MB and higher Ethernet.
*/
if (pcap_datalink(kp->p) != DLT_EN10MB)
{
sprintf(errbuf, "Knock only works with ethernet.\n");
return (NULL);
}
kp->l = libnet_init(LIBNET_RAW4, device, errbuf);
if (kp->l == NULL)
{
return (NULL);
}
kp->src_ip = libnet_get_ipaddr4(kp->l);
if (!(kp->dst_ip = libnet_name2addr4(kp->l, host, LIBNET_RESOLVE)))
{
sprintf(errbuf, "libnet_name2addr4(): %s",
libnet_geterror(kp->l));
return (NULL);
}
if (libnet_plist_chain_new(kp->I, &kp->plist, p_list) == -1)
{
sprintf(errbuf, "libnet_plist_chain_new(): %s",
libnet_geterror(kp->l));
return (NULL);
}
return (kp);
}
void
knock_destroy(struct knock_pack *kp)
{
if (kp)
{
if (kp->p)
{
pcap_close(kp->p) ;
}
if (kp->l)
{
libnet_destroy(kp->l);
}
}
}
int
catch_sig(int signo, void (*handler)())
{
struct sigaction action;
action.sa_handler = handler;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(signo, fcaction, NULL) == -1)
{
return (-1);
}
else
{
return (1);
}
}
void
knock(struct knock_pack *kp)
{
u_short bport, eport;
/*
* Loop until user hits ctrl-c at the corrjriand prcir.pt or until we
* run out of ports to scan.
*/
for (; loop; )
{
/* set ports */
if (libnet_plist_chain_next_pair(kp->plist, &bport, &eport) < 1)
{
/* we're done */
loop = 0;
continue;
}
while (!(bport > eport) && bport != 0 && loop)
{
kp->port = bport++;

/* build a port scanning packet */
if (build_packet(kp) == -1)
{
fprintf(stderr, "build_packet: %s", kp->errbuf);
continue;
}
/* write it to the network */
if (write_packet(kp) == -1)
{
fprintf(stderr, "write_packet: %s", kp->errbuf);
continue;
}
fprintf(stderr, "port %d ", kp->port);
/* look for a response and report port status to user */
switch (receive_packet(kp))
{
case PORT_OPEN~
printf("open n");
kp->ports_open++;
break;
case PORT_OPEN_TIMEDOUT:
printf("open? (timeout)\n");
kp->ports_open++;
break;
case PORT_CLOSED:
printf("closed\n");
break;
case PORT_CLOSED_TIMEDOUT:
printf("closed? (timeout)\n");
break;
}
}
}
}
int
build_packet(struct knock_pack *kp)
{
u_char control = 0;
u_short protocol;
u_long packet_size;
/* determine total packet size and port scan type */
packet_size = LIBNET_IPV4_H + (kp->scan_type == SCANJTCP ?
LIBNET_TCP_H : LIBNET_UDP_H);
protocol = kp->scan_type == SCAN_TCP ? IPPROTO_TCP : IPPROTO_UDP;
switch (kp->scan_type)
{
case SCAN_TCP:
/* set the TCP scan type */
switch (kp->scan_subtype)
{
case SCAN_TCP_SYW:
control = TH_SYN;
break;
case SCAN_TCP_FIN:
control = TH_FIN;
break;
case SCAN_TCP_XMAS:
control = TH_FIN | TH_URG | TH_PUSH;
break;
}
/*
* Build a TCP header. If this is the first time we've hit
* this block of code, kp->tcpudp will be 0 and
* libnet_build_tcp() will create the state for the packet
* and we will save it to kp->tcpudp. Each subsequent time
* we hit this block of code libnet_build_tcp will update
* this packet template. This is the same for
* libnet_build_udp() and libnet_build_ip().
*/
kp->tcpudp = libnet_build_tcp(
SOURCE_PORT, /* source port */
kp->port, /* destination port */
0x00000bad, /* sequence number */
0x0000bad0, /* acknowledgement num */
control, /* control flags */
32767, /* window size */
0, /* checksum */
0, /* urgent pointer */
LIBNET_TCP_H, /* TCP packet size */
NULL, /* payload */
0, /* payload size */
kp->l, /* libnet handle */
kp->tcpudp); /* libnet id */
if (kp->tcpudp == -1)
{
sprintf(kp->errbuf, "Can't build TCP header: %s n",
libnet_geterror (kp->l));
return (-1);
}
break;
case SCAN_UDP:
kp->tcpudp = libnet_build_udp(
SOURCE_PORT, /* source port */
kp->port, /* destination port */
LIBNET_UDP_H, /* packet size */
0, /* checksum */
NULL, /* payload */
0, /* payload size */
kp->l, /* libnet handle */
kp->tcpudp); /* libnet id */
if (kp->tcpudp == -1)
{
sprintf(kp->errbuf, "Can't build UDP header: %s n",
libnet_geterror(kp->l));
return (-1);
}
break;
}
kp->ip = libnet_build_ipv4(
packet_size, /* total packet size */
0, /* type of service */
242, /* identification */
0, /* fragmentation */
64, /* time to live */
protocol, /* protocol */
0, /* checksum */
kp->src_ip, /* source */
kp->dst_ip, /* destination */
NULL, /* payload */
0, /* payload size */
kp->l, /* libnet handle */
kp->ip); /* ptag */
if (kp->ip == -1)
{
sprintf(kp->errbuf, "Can't build IP header: %s n",
libnet_geterror(kp->l));
return (-1);
}
return (1);
}
int
write_packet(struct knock_pack *kp)
{
int c;
c = libnet_write(kp->l);
if (c == -1)
{
sprintf(kp->errbuf, "libnet_write(): %s n",
libnet_geterror(kp->l));
}
return (c);
}
int
receive_packet(struct knock_pack *kp)
{
u_short ip_hl ;
time_t start;
struct libnet_ipv4_hdr *ip;
struct libnet_tcp_hdr *tcp;
struct libnet_icmpv4_hdr *icmp;
struct libnet_udp_hdr *udp;
for (start = time(NULL); (time(NULL) - start) < kp- to; )
{
kp->packet = (u_char *)pcap_next(kp->p, &kp->h);
if (kp->packet == NULL)
{
/*
* We have to be careful here as pcap_next() can return
* NULL if the timer expires with no data in the packet
* buffer or under some special circumstances under linux.
*/
continue;
}
/*
* By using libnet's natively defined protocol headers, we can
* cast our received IP packet and access all header fields
* directly. As you'll see, this is much easier than the
* bitwise stuff we had to do in the last chapter. Also you'll
* note the lack of endian concern when dealing with libnet.
* It handles all of this for us. How nice and thoughtful of
* libnet.
*/
ip = (struct libnet_ipv4_hdr *)(kp->packet + 14);
ip_hl = ip->ip_hl << 2;
switch (ip->ip_p)
{
case IPPROTO_TCP:
if (kp->scan_type != SCAN_TCP)
{
continue;
}
tcp = (struct libnet_tcp_hdr *)(kp->packet + 14 +
ip_hl);
if (ip->ip_src.s_addr == kp->dst_ip && ip->ip_dst.s_addr == kp->src_ip && ntohs(tcp->th_sport) == kp->port && ntohs(tcp->th_dport) == SOURCE_PORT)
{
if ((tcp->th_flags & TH_SYN) &&
(tcp->th_flags & TH_ACK))
{
/* we got a SYNJACK back, we know port is open */
return (PORT_OPEN);
}
if (tcp->th_flags & TH_RST)
{
/* we got an RST back, we know port is closed */
return (PORT_CLOSED);
}
}
continue;
case IPPROTO_ICMP:
if (kp->scan_type != SCAN_UDP)
{
continue;
}
icmp = (struct libnet_icmpv4_hdr *)
(kp->packet + 14 + ip_hl);
if (icmp- icmp_type != ICMP_NREACH &&
icmp->icmp_code != ICMP_UNREACH_PORT)
{
/* it's not a terminal response to our packet */
continue;
}
/* past IPv4 header, past ICMPv4 header */
ip = (struct libnet_ipv4_hdr *)(kp->packet + 14
+ ip_hl + LIBNET_ICMPV4_UNREACH_H);
/* past IPv4 header, past ICMPv4 header, past IPv4 */
udp = (struct libnet_udp_hdr *)(kp->packet + 14
+ ip_hl + LIBNET_ICMPV4_UNREACH_H +
LIBNET_IPV4_H);
if (ip->ip_src.s_addr == kp->src_ip && ip->ip_dst.s_addr
== kp->dst_ip && ntohs (udp->uh_dport) == kp-> &&
ntohs(udp->uh_sport) == SOURCE_PORT)
{
/* we got an ICMP port unreach; port is closed */
return (PORT_CLOSED);
}
default:
continue;
}
}
/*
* If we get down here, the scan has timed out, and depending on
* the scan protocol and type, the port may be open or it may be
* closed.
*/ if (kp->scan_type == SCAN_TCP)
{
switch (kp->scan_subtype)
{
case SCAN_TCP_SYN:
/* for half-open TCP scans assume the port is closed */
return (PORT_CLOSED_TIMEDOUT);
case SCAN_TCP_FIN:
case SCAN_TCP_XMAS:
/* for "stealth" TCP scans assume the port is open */
return (PORT_OPEN_TIMEDOUT);
}
}
else
{
/* for UDP scans assume the port is open */
return (PORT_OPEN_TIMEDOUT);
}
/* NOTREACHED (this silences compiler warnings) */
return (PORT_CLOSED);
}
void
cleanup(int signo)
{
loop = 0;
printf("Interrupt signal caught… n");
}
void
usage(char *name)
{
printf("usage %s [options] target_host port_list n"
"-h\t\tthis blurb you see right here\n"
"-i device\tspecify a device\n"
"-T timeout\tseconds to wait for a resonse\n"
"-t scantype\tscan TCP ports "
"(1 == TCP SYN, 2 == TCP FIN, 3 == TCP XMAS)\n"
"-u\t\tscan UDP ports\n", name);
}
/* EOF */

/ 135