分类:
2008-10-13 14:41:02
/* Jackal - Stealth/FireWall scanner. With the use of halfopen ports
and sending SYNC (sometimes additional flags like FIN) one can
scan behind a firewall. And it shouldnt let the site feel we're scanning
by not doing a 3-way-handshake we hope to avoid any tcp-logging.
Credits: Halflife, Jeff (Phiji) Fay, Abdullah Marafie.
Alpha Tester: Walter Kopecky.
Results:
Some firewalls did allow SYN | FIN to pass through. No Site has
been able to log the connections though.. during alpha testing.
ShadowS [email]shadows@kuwait.net[/email]
Copyleft (hack it i realy dont care).
*/
#include "stdio.h"
#include "stdlib.h"
#include "signal.h"
#include "string.h"
#include "unistd.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "arpa/inet.h"
#include "linux/ip.h"
#include "linux/tcp.h"
int timeout = 0;
int counter = 0;
void usage(char *name)
{
printf("usage:%s [-h target_ip] [-i your_ip] [-t timeout] [-s start-port] [-e end-port] [-f FIN] [-a ACK]\n",name);
exit(-1);
}
void handler(int whateva)
{
alarm(0);
timeout = 1;
}
/* Checksum Gen */
unsigned short in_cksum(unsigned short *ptr, int nbytes)
{
register long sum; /* assumes long == 32 bits */
u_short oddbyte;
register u_short answer; /* assumes u_short == 16 bits */
/*
* Our algorithm is simple, using a 32-bit accumulator (sum),
* we add sequential 16-bit words to it, and at the end, fold back
* all the carry bits from the top 16 bits into the lower 16 bits.
*/
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
/* mop up an odd byte, if necessary */
if (nbytes == 1) {
oddbyte = 0; /* make sure top half is zero */
*((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
sum += oddbyte;
}
/*
* Add back carry outs from top 16 bits to low 16 bits.
*/
sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* ones-complement, then truncate to 16 bits */
return(answer);
}
/* Generates the tcp header and packet */
struct tcphdr packetgen(int fin,int ack,unsigned int src_addr,unsigned int dst_addr, int port)
{
/* we create both a tcpheader and a ipheader to calculate checksum */
struct tcphdr packet;
struct ipheader
{
unsigned int source_address;
unsigned int dest_address;
unsigned char placeholder;
unsigned char protocol;
unsigned short tcp_length;
struct tcphdr tcp;
}
pseudo_header;
counter++;
/* Fill the headers with the options and data */
packet.source = getpid() + counter;
packet.dest = htons(port);
packet.seq = getpid() + counter;
packet.ack_seq = 0;
packet.res1 = 0;
packet.doff = 5;
packet.res2 = 0;
packet.fin = fin;
packet.syn = 1;
packet.rst = 0;
packet.psh = 0;
packet.ack = ack;
packet.urg = 0;
packet.window = htons(512);
packet.check = 0;
packet.urg_ptr = 0;
/* We need this for the checksum */
pseudo_header.source_address = src_addr;
pseudo_header.dest_address = dst_addr;
pseudo_header.placeholder = 0;
pseudo_header.protocol = IPPROTO_TCP;
pseudo_header.tcp_length = htons(20);
bcopy(&packet, &pseudo_header.tcp, 20);
/* Get the checksum and viowlla tcphdr is done :) */
packet.check = in_cksum((unsigned short *)&pseudo_header, 32);
return packet;
}
int scan(struct tcphdr packet,int port,unsigned int dst_addr)
{
struct sockaddr_in remote;
int len;
/* The header we'll receive the info in */
struct rect
{
struct iphdr ip;
struct tcphdr tcp;
unsigned char blah[65535];
}
recv_tcp;
int sockd;
/* Now we fill the sock struct */
remote.sin_family = AF_INET;
remote.sin_port = htons(port);
remote.sin_addr.s_addr = dst_addr;
len=sizeof(remote);
signal(SIGALRM, handler);
sockd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if(sockd < 0)
{
perror("Socket");
exit(1);
}
/* Blast the packet into ablivion! */
sendto(sockd, &packet, 20, 0, (struct sockaddr *)&remote, len);
timeout = 0;
alarm(10);
while(1)
{
/* Now we sit and read */
read(sockd, (struct recv_tcp *)&recv_tcp, 65535);
if(timeout == 1)
{
close(sockd);
timeout=0;
return -1;
}
if(recv_tcp.tcp.dest == (getpid() + counter))
{
alarm(0);
close(sockd);
/* It shouldnt be 1 */
if(recv_tcp.tcp.rst == 1)
return 0;
else
return 1;
}
}
}
main(int argc, char **argv)
{
int c;
int start = 0;
int end = 0;
int fin = 0;
int ack = 0;
int port = 0;
int retval;
struct tcphdr packet;
int host = 0;
int target = 0;
char source[100];
char destination[100];
if(getuid() != 0)
{
printf("Need root to run this I'm afraid .\n");
exit(-2);
}
if(argc < 2)
usage(argv[0]);
while ((c = getopt (argc, argv, "s:e:h:i:af")) != EOF)
{
switch (c)
{
case 's':
start = atoi(optarg);
break;
case 'e':
end = atoi(optarg);
break;
case 'a':
ack = 1;
break;
case 'f':
fin = 1;
break;
case 'h':
strcpy(destination,optarg);
target = 1;
break;
case 'i':
strcpy(source,optarg);
host = 1;
break;
case 't':
timeout = atoi(optarg);
break;
default:
usage(argv[0]);
}
}
if((host == 0) || (target == 0))
usage(argv[0]);
if(start == 0)
port = start;
if(end == 0)
end = 1024;
for(;port < (end + 1);port++)
{
packet = packetgen(fin,ack,inet_addr(source),inet_addr(destination),port);
if( (retval = scan(packet,port,inet_addr(source))) == 1)
printf("Port:%i is open.\n",port);
}
exit(0);
}
/**********************************************************************
** This is a real simple half opened connection scanner I
** put together. It scans ports 0 to 1024 for listening
** processes, and writes to stdout the ports that are
** listening.
**
** [email]halflife@saturn.net[/email]
**
** NOTE: You have to define MY_IP as your ip. If you have
** a dynamic ip, this is gonna bite :-).
*********************************************************************/
/* define the following as your ip address */
#define MY_IP "193.62.1.250"
#include "stdio.h"
#include "stdlib.h"
#include "signal.h"
#include "string.h"
#include "unistd.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "arpa/inet.h"
#include "linux/ip.h"
#include "linux/tcp.h"
int syn_timeout = 0;
unsigned short in_cksum(unsigned short *, int);
int scan_port(unsigned short, unsigned int, unsigned int);
void alarm_handler(int);
void alarm_handler(int s)
{
alarm(0);
syn_timeout = 1;
}
int scan_port(unsigned short port, unsigned int src_addr, unsigned int dst_addr)
{
struct tcphdr send_tcp;
struct recv_tcp
{
struct iphdr ip;
struct tcphdr tcp;
unsigned char blah[65535];
}recv_tcp;
struct pseudo_header
{
unsigned int source_address;
unsigned int dest_address;
unsigned char placeholder;
unsigned char protocol;
unsigned short tcp_length;
struct tcphdr tcp;
}pseudo_header;
int tcp_socket;
struct sockaddr_in sin;
int sinlen;
static int blah = 0;
blah++;
send_tcp.source = getpid() + blah;
send_tcp.dest = htons(port);
send_tcp.seq = getpid() + blah;
send_tcp.ack_seq = 0;
send_tcp.res1 = 0;
send_tcp.doff = 5;
send_tcp.res2 = 0;
send_tcp.fin = 0;
send_tcp.syn = 1;
send_tcp.rst = 0;
send_tcp.psh = 0;
send_tcp.ack = 0;
send_tcp.urg = 0;
send_tcp.window = htons(512);
send_tcp.check = 0;
send_tcp.urg_ptr = 0;
pseudo_header.source_address = src_addr;
pseudo_header.dest_address = dst_addr;
pseudo_header.placeholder = 0;
pseudo_header.protocol = IPPROTO_TCP;
pseudo_header.tcp_length = htons(20);
bcopy(&send_tcp, &pseudo_header.tcp, 20);
send_tcp.check = in_cksum((unsigned short *)&pseudo_header, 32);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = dst_addr;
sinlen=sizeof(sin);
signal(SIGALRM, alarm_handler);
tcp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
if(tcp_socket < 0)
{
fprintf(stderr, "couldnt open raw socket\n");
exit(1);
}
sendto(tcp_socket, &send_tcp, 20, 0, (struct sockaddr *)&sin, sinlen);
syn_timeout = 0;
alarm(10);
while(1)
{
read(tcp_socket, (struct recv_tcp *)&recv_tcp, 65535);
if(syn_timeout == 1) {close(tcp_socket);syn_timeout=0;return -1;}
if(recv_tcp.tcp.dest == (getpid() + blah))
{
alarm(0);
close(tcp_socket);
if(recv_tcp.tcp.rst == 1) return 0;
else return 1;
}
}
}
unsigned short in_cksum(unsigned short *ptr, int nbytes)
{
register long sum; /* assumes long == 32 bits */
u_short oddbyte;
register u_short answer; /* assumes u_short == 16 bits */
/*
* Our algorithm is simple, using a 32-bit accumulator (sum),
* we add sequential 16-bit words to it, and at the end, fold back
* all the carry bits from the top 16 bits into the lower 16 bits.
*/
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
/* mop up an odd byte, if necessary */
if (nbytes == 1) {
oddbyte = 0; /* make sure top half is zero */
*((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
sum += oddbyte;
}
/*
* Add back carry outs from top 16 bits to low 16 bits.
*/
sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* ones-complement, then truncate to 16 bits */
return(answer);
}
main(int argc, char **argv)
{
unsigned short i;
if(argc < 2)
{
fprintf(stderr, "%s target_ip\n", argv[0]);
exit(0);
}
if(geteuid() != 0)
{
fprintf(stderr, "this program requires root\n");
exit(0);
}
printf("Scanning %s\n", argv[1]);
for(i=0;i < 1025;i++)
{
if(scan_port(i, inet_addr(MY_IP), inet_addr(argv[1]))==1)
printf("Port %d active\n", i);
}
}