HUA
级别:一般站友 威望:0 经验:0 货币:6 体力: 来源:海南 总发帖数:27 注册日期:2002-01-29 |
|
查看 邮件 主页 QQ 消息 引用 复制 下载
/* grabbb - elite
banner scanner * by scut of teso (http://teso.scene.at/) *
* nearly all of this code wouldn't have been possible without w.
richard stevens * excellent network coding book. if you are
interested in network coding, * there is no way around it.
wherever you are now, you showed me how to aquire one * of my
best skills, and my programs are the result of your teaching
abilities. * * oh yeah, special greetz for this one go to
random, who will once be a great * socket warrior, promised.
* * compilation: gcc -o grabbb grabbb.c -Wall */
#include <sys/types.h> #include
<sys/ioctl.h> #include <sys/socket.h> #include
<sys/time.h> #include <arpa/inet.h> #include
<netdb.h> #include <netinet/in.h> #include
<errno.h> #include <fcntl.h> #include
<stdarg.h> #include <stdio.h> #include
<stdlib.h> #include <string.h> #include
<unistd.h>
#define VERSION "0.0.1" #define AUTHORS
"scut of teso"
#define NET_CONNTIMEOUT 30 #define
NET_IDENTTIMEOUT 30
int net_conntimeout = NET_CONNTIMEOUT;
int net_identtimeout = NET_IDENTTIMEOUT; int sb_timeout =
30;
typedef struct { struct timeval tv; /* first
time the socket was used */ struct in_addr ip; /* ip we're
connecting to */ unsigned short int port; /* remote port */
int socket; /* phear */ int state; #define ST_CONNECTING
1 #define ST_CONNECTED 2
} sock_buck;
/* for
accessibility we go for a struct array, instead of a pointer array
or a * linked list. if we want to be even faster, we'd have to
do fd_set * multiplexing, which can be done with threads and
jields in unportable code, * sorry. */ #define OPEN_MAX
250 /* hehe, don't mess with the mighty fdset's limits */ int
open_max = OPEN_MAX; int sock_free = OPEN_MAX; sock_buck
sockets[OPEN_MAX];
/* in_addr structures needed for scanning
*/ struct in_addr ip_src, ip_dst_s, ip_dst_e,
ip_dst_cur;
unsigned short int port = 21; unsigned
long int stat_hosts = 0; unsigned long int stat_conn = 0;
void usage (char *prg_name); void sb_mainloop
(void); void sb_check (sock_buck *sb_r, int sb_count, fd_set
*readset, fd_set *writeset); void sb_timecheck (sock_buck
*sb); void sb_print (sock_buck *sb, char *buf); void sb_free
(sock_buck *sb); int sb_assign (void); sock_buck *sb_ip_new
(struct in_addr *ip, unsigned short int port); sock_buck
*sb_fd_findactive (sock_buck *sb_r, int sb_count, fd_set *fds);
sock_buck *sb_getnew (sock_buck *sb_r, int sb_count); fd_set
*sb_trigger (sock_buck *sb_r, int sb_count, int *max_fd, int wr);
fd_set *sb_prepare (fd_set *fds, sock_buck *sb, int *max_fd, int
wr); void sb_init (sock_buck *sb); char *net_getlocalip
(void); char *net_peername (int socket); unsigned long int
net_resolve (char *host); int net_printip (struct in_addr *ia,
char *str, size_t len); void *xcalloc (int factor, size_t size);
int main (int argc, char **argv) { int
summary = 0; char chr;
if (argc < 4) usage
(argv[0]);
while ((chr = getopt (argc - 3, argv, "x:t ")) !=
EOF) { switch (chr) { case 'x': open_max = atoi (optarg);
sock_free = open_max; break; case 't': sb_timeout = atoi
(optarg); break; case 's': summary = 1; break;
default: break; } }
port = atoi (argv[optind]);
ip_dst_s.s_addr = net_resolve (argv[optind + 1]);
ip_dst_e.s_addr = net_resolve (argv[optind + 2]);
ip_dst_cur.s_addr = ip_dst_s.s_addr;
sb_mainloop ();
if (summary) { printf ("finished scanning %lu hosts.\n"
"got response from %lu hosts.\n", stat_hosts, stat_conn); }
exit (EXIT_SUCCESS); }
void usage (char
*prg_name) { printf ("grabbb "VERSION" by "AUTHORS"\n\n"
"usage: %s [options] <port> <startip>
<endip>\n\n" "__options\n" "\t-x <maxsock>
maximum number of sockets to use (default 250)\n" "\t-t
<seconds> connection timeout\n" "\t-s print summary
information after scan\n\n", prg_name);
exit (EXIT_SUCCESS);
}
void sb_mainloop (void) { int n;
fd_set *fds_r, *fds_w; int max_fd; struct timeval tv = {
2, 0 }; /* 2 seconds timeout */ int eoscan;
while (1) {
eoscan = sb_assign (); #ifdef DEBUG printf ("eoscan = %d
-- sock_free = %d -- open_max = %d\n", eoscan, sock_free, open_max);
#endif if (eoscan == -1 && sock_free == open_max) {
return; }
fds_r = fds_w = NULL; fds_r =
sb_trigger (sockets, open_max, &max_fd, 0); fds_w =
sb_trigger (sockets, open_max, &max_fd, 1);
#ifdef DEBUG
printf ("fds_r = %08x -- fds_w = %08x -- eoscan = %d\n", fds_r,
fds_w, eoscan); #endif if (fds_r == NULL && fds_w ==
NULL && eoscan == -1) return; n = select (max_fd,
fds_r, fds_w, NULL, &tv); #ifdef DEBUG printf ("select()
= %d\n", n); #endif if (n == -1) { perror ("select
failed"); exit (EXIT_FAILURE); }
sb_check (sockets,
open_max, fds_r, fds_w);
free (fds_r); free (fds_w);
}
}
/* please ignore the bad style exposed
here */
void sb_check (sock_buck *sb_r, int
sb_count, fd_set *readset, fd_set *writeset) { int i,
error, len = sizeof (error); sock_buck *sb;
for
(i = 0 ; i < sb_count ; ++i) { sb = &(sb_r[i]); if
(sb->socket != 0 && sb->state == ST_CONNECTING) {
if (FD_ISSET (sb->socket, readset) || FD_ISSET
(sb->socket, writeset)) { if (FD_ISSET (sb->socket,
readset) && FD_ISSET (sb->socket, writeset)) { if
(getsockopt (sb->socket, SOL_SOCKET, SO_ERROR, &error,
&len) < 0) { sb_free (sb); } else if (error == 0) {
/* we experienced a successful connection */
sb->state = ST_CONNECTED; } else { sb_free (sb);
} } } } else if (sb->socket != 0 &&
sb->state == ST_CONNECTED && FD_ISSET (sb->socket,
readset)) { int n; unsigned char buf[256];
memset
(buf, '\0', sizeof (buf)); n = read (sb->socket, buf, sizeof
(buf) - 1); if (n <= 0) { sb_free (sb); } else {
sb_print (sb, buf); } }
if (sb->socket != 0)
{ sb_timecheck (sb); } }
return; }
void sb_timecheck (sock_buck *sb) { unsigned
long seconds, microseconds; struct timeval tv_cur;
gettimeofday (&tv_cur, NULL);
seconds =
tv_cur.tv_sec - sb->tv.tv_sec; if (tv_cur.tv_usec >=
sb->tv.tv_usec) { microseconds = tv_cur.tv_usec -
sb->tv.tv_usec; } else { microseconds = sb->tv.tv_usec
+ tv_cur.tv_usec; seconds--; /* seconds must be at least one,
sapienta sat */ }
if (microseconds >= 500000)
seconds++;
if (seconds >= sb_timeout &&
sb->state == ST_CONNECTED) { sb_print (sb, ""); } else if
(seconds >= sb_timeout) { sb_free (sb); }
return;
}
void sb_print (sock_buck *sb, char *buf) {
char ip[32];
net_printip (&sb->ip, ip, sizeof
(ip));
while (buf[strlen (buf) - 1] == '\r' || buf[strlen
(buf) - 1] == '\n') buf[strlen (buf) - 1] = '\0';
printf
("%s:%hu: %s\n", ip, sb->port, buf);
stat_conn++;
sb_free (sb);
return; }
void
sb_free (sock_buck *sb) { if (sb->socket != 0)
close (sb->socket);
sb_init (sb);
sock_free++;
return; }
int
sb_assign (void) { int cnx = 0; /* number of connects
issued */
if (sock_free == 0) return (0);
while
(sock_free > 0) { sock_buck *sb;
if (ntohl
(ip_dst_cur.s_addr) > ntohl (ip_dst_e.s_addr)) { return (-1);
}
sb = sb_ip_new (&ip_dst_cur, port);
stat_hosts++;
ip_dst_cur.s_addr = ntohl (ntohl
(ip_dst_cur.s_addr) + 1);
cnx++; --sock_free; }
return (cnx); }
sock_buck * sb_ip_new
(struct in_addr *ip, unsigned short int port) {
int n;
sock_buck *new; struct sockaddr_in sa;
new =
sb_getnew (sockets, open_max); if (new == NULL) return
(NULL);
sb_init (new);
memcpy (&new->ip, ip,
sizeof (struct in_addr)); memset (&sa, '\0', sizeof (struct
sockaddr_in)); sa.sin_family = AF_INET; sa.sin_port = htons
(port);
new->socket = socket (sa.sin_family, SOCK_STREAM,
0); new->port = port;
sa.sin_addr.s_addr =
ip->s_addr;
/* fear this lame socket coding style =)
(didn't learned this from stevens * though */ fcntl
(new->socket, F_SETFL, (fcntl (new->socket, F_GETFL, 0) |
O_NONBLOCK));
n = connect (new->socket, (struct sockaddr
*) &sa, sizeof (struct sockaddr_in)); gettimeofday
(&new->tv, NULL); if (n < 0 && errno !=
EINPROGRESS) { close (new->socket); new->socket = 0;
return (new);
} else if (n == 0) {
new->state = ST_CONNECTED;
return (new); }
new->state = ST_CONNECTING;
return (new); }
sock_buck * sb_fd_findactive (sock_buck *sb_r, int
sb_count, fd_set *fds) { int i;
for (i = 0 ; i <
sb_count ; ++i) { int socket = sb_r[i].socket;
if
(socket != 0 && FD_ISSET (socket, fds) != 0) return
(&sb_r[i]); }
return (NULL); }
sock_buck * sb_getnew (sock_buck *sb_r, int
sb_count) { int i;
for (i = 0 ; i < sb_count ;
++i) { if (sb_r[i].socket == 0) return (&sb_r[i]); }
return (NULL); }
fd_set * sb_trigger
(sock_buck *sb_r, int sb_count, int *max_fd, int wr) { int
i; fd_set *fds = NULL;
for (i = 0 ; i < sb_count ;
++i) { fds = sb_prepare (fds, &sb_r[i], max_fd, wr); }
*max_fd = *max_fd + 1;
return (fds); }
fd_set * sb_prepare (fd_set *fds, sock_buck *sb, int
*max_fd, int wr) { /* if socket is empty or socket is
already part of fd_set, * which means we fucked the structs
somehow, then skip */ if (sb->socket == 0) return
(fds);
if (sb->state == ST_CONNECTED && wr == 1)
return (fds);
if (fds == NULL) { fds = xcalloc (1,
sizeof (fd_set)); FD_ZERO (fds); *max_fd = 0; }
if (FD_ISSET (sb->socket, fds) != 0) return (fds);
FD_SET (sb->socket, fds); if (sb->socket >
*max_fd) *max_fd = sb->socket;
return (fds); }
void sb_init (sock_buck *sb) { memset
(&sb->ip, '\0', sizeof (struct in_addr)); sb->port =
htons (0); /* wasting jiffies */ sb->socket = 0;
sb->state = 0;
return; }
char *
net_getlocalip (void) { struct sockaddr_in pf; char
name[255];
memset (name, '\0', sizeof (name));
if
(gethostname (name, sizeof (name) - 1) == -1) { return (NULL);
}
pf.sin_addr.s_addr = net_resolve (name);
return (strdup (inet_ntoa (pf.sin_addr)));; }
char * net_peername (int socket) { struct
sockaddr_in peeraddr; struct hostent he, *hep; size_t size =
sizeof (struct sockaddr_in); int n, h_errno; unsigned char
h_buf[8192];
if (getpeername (socket, (struct sockaddr *)
&peeraddr, &size) == -1) return (NULL);
/*
digital unix / hp-ux freaks mod here =) */ n =
gethostbyaddr_r ((char *) &peeraddr.sin_addr, sizeof (struct
in_addr), AF_INET, &he, h_buf, sizeof (h_buf), &hep,
&h_errno);
if (hep == NULL) { char *ip_str = xcalloc
(1, 32);
net_printip (&peeraddr.sin_addr, ip_str, 31);
return (ip_str); }
return (strdup (he.h_name));
}
unsigned long int net_resolve (char *host)
{ long i; struct hostent *he;
i = inet_addr
(host); if (i == -1) { he = gethostbyname (host); if (he
== NULL) { return (0); } else { return (*(unsigned long
*) he->h_addr); } } return (i); }
int
net_printip (struct in_addr *ia, char *str, size_t len) {
unsigned char *ipp;
ipp = (unsigned char *)
&ia->s_addr; snprintf (str, len - 1, "%d.%d.%d.%d",
ipp[0], ipp[1], ipp[2], ipp[3]);
return (0); }
void * xcalloc (int factor, size_t size) { void
*bla;
bla = calloc (factor, size);
if (bla == NULL)
{ fprintf (stderr, "no memory left\n"); exit (EXIT_FAILURE);
}
return (bla); }
/*TMD,有个家伙仗着别人给的点EXPLOIT,写了两篇破文章就不知道天高地厚了我呸*/
|