Fast httpd scanner that scans a block of IPs using a half open scan.
2defbdb4ab4e646551e3f5483833a3029ed3bac341a8d20e07d7d3da00941bc1
/*
quick (lame ?) httpd sweeper.
takes input on stdin.
#./sweep < ipfile 2>output
(requires root to run it)
- starch (starch at starch dot tk)
greetz to #ihc, #india
*/
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <signal.h>
struct pseudo_hdr {
struct in_addr source;
struct in_addr dest;
u_int8_t place_holder;
u_int8_t protocol;
u_int16_t length;
} pseudo_hdr;
extern int errno;
struct tcp
{
u_int16_t th_sport; /* source port */
u_int16_t th_dport; /* destination port */
u_int32_t th_seq; /* sequence number */
u_int32_t th_ack; /* acknowledgement number */
u_int8_t th_x2:4; /* (unused) */
u_int8_t th_off:4; /* data offset */
u_int8_t th_flags;
# define TH_FIN 0x01
# define TH_SYN 0x02
# define TH_RST 0x04
# define TH_PUSH 0x08
# define TH_ACK 0x10
# define TH_URG 0x20
u_int16_t th_win; /* window */
u_int16_t th_sum; /* checksum */
u_int16_t th_urp; /* urgent pointer */
};
/* from libmix (mixter.warrior2k.com) */
int
isip(char *ip)
{
int a, b, c, d;
if (!sscanf(ip, "%d.%d.%d.%d", &a, &b, &c, &d))
return 0;
if (a < 1)
return 0;
if (a > 255)
return 0;
if (b < 0)
return 0;
if (b > 255)
return 0;
if (c < 0)
return 0;
if (c > 255)
return 0;
if (d < 0)
return 0;
if (d > 255)
return 0;
return 1;
}
unsigned short in_cksum (unsigned short *addr, int len) {
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -=2;
}
if (nleft == 1) {
*(unsigned char *)&answer = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum &0xffff);
sum += sum >> 16;
answer = ~sum;
return (answer);
}
int
main (int argc, char **argv)
{
pid_t child;
if (argc!=2) {
printf ("%s <srcip>\n", argv[0]);
exit(0);
}
if (getuid()!=0) {
printf ("lamer\n");
exit(0);
}
child = fork();
if (child == 0) { /* child */
int sock = socket (PF_INET, SOCK_RAW, 6), n, size; /* 1 = icmp , 6 = TCP*/
char buf[1024];
struct tcp *tcp;
struct sockaddr_in sockst;
tcp = (struct tcp *) (buf+sizeof(struct iphdr));
while (1) {
size = sizeof(sockst);
n = recvfrom (sock, buf, sizeof(buf), 0, (struct sockaddr *)&sockst, &size);
/* do the checks */
if ((tcp->th_flags&TH_SYN) && (ntohs(tcp->th_sport)==80) && (tcp->th_flags&TH_ACK)) /* self evident */
fprintf (stderr, "httpd open on %s\n", inet_ntoa(sockst.sin_addr));
}
} /* end of child */
else { /* parent */
int sock = socket(AF_INET, SOCK_RAW, 6), n;
u_int16_t tempsum;
char buf[512], *ptr, cmd[1024];
struct tcp *tcp = (struct tcp *)buf;
struct sockaddr_in sockst;
while (1) {
if (fgets (cmd, sizeof(cmd), stdin) == NULL ) break;
cmd[strlen(cmd)-1] = '\0';
if (!isip(cmd)) { fprintf (stderr, "not a valid IP: %s\n", cmd); continue; }
bzero (buf, 512);
/* fill da data now */
tcp->th_sport = htons(31337);
tcp->th_dport = htons (80);
tcp->th_seq = htonl (2342344);
tcp->th_ack = htonl (3232);
tcp->th_flags = TH_SYN;
tcp->th_win = htons (512);
tcp->th_off = 5;
/* compute cksum */
pseudo_hdr.protocol = 6;
pseudo_hdr.length = htons (40);
pseudo_hdr.place_holder = 0;
pseudo_hdr.source.s_addr = inet_addr (argv[1]);
ptr = (char *)malloc (sizeof(pseudo_hdr) +40);
bzero (&sockst, sizeof(sockst));
sockst.sin_port = htons (80);
sockst.sin_family = AF_INET;
pseudo_hdr.dest.s_addr = inet_addr (cmd);
sockst.sin_addr.s_addr = inet_addr (cmd);
memcpy (ptr, &pseudo_hdr, sizeof(pseudo_hdr));
memcpy (ptr+sizeof(pseudo_hdr), buf, 40);
tcp->th_sum = in_cksum ((u_short *)ptr, 40+sizeof(pseudo_hdr));
n = sendto (sock, buf, 40, 0, (struct sockaddr *)&sockst, sizeof(sockst));
}
if (feof (stdin))
printf ("finished scanning\n");
else
printf ("something fuked up\n");
printf ("Waiting for 5 secs for child to finish off\n");
sleep (5);
kill (child, SIGKILL);
waitpid (child, NULL, 0);
}
}