使用sendto()函数发送数据包,使用TCP Dump分析数据包,我得到:
IP0 bad-hlen 0
此程序使用libpcap和raw socket来避免SYN Stealth,每个开放端口发送一个SYN / ACK数据包,以欺骗攻击者。
这是我的代码:
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
#include <time.h>
#include <netinet/ether.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
#include <malloc.h>
#define MAX_EXISTING_PORTS 30
void caught_packet(u_char *,const struct pcap_pkthdr *,const u_char *);
int set_packet_filter(pcap_t *,struct in_addr *,u_short *);
unsigned short csum(unsigned short *ptr,int nbytes);
int random_number(int);
void fatal(char *);
void print_ip_hdr(struct iphdr *);
void print_eth_hdr(struct ethhdr *);
void print_tcp_hdr(struct tcphdr *);
int main(int argc,char *argv[]){
//Pcap header
struct pcap_pkthdr cap_header;
//Packet Char pointer
const u_char *packet;
//Pcap Handle
pcap_t *pcap_handle;
//Pcap error Buffer
char errbuf[PCAP_ERRBUF_SIZE];
//Sniffing Device
char *device;
//Socket Descriptor
int sockfd;
int i,yes=1;
//sockaddr_in to check validity of IP
struct sockaddr_in sa;
//Array of available ports
u_short existing_ports[MAX_EXISTING_PORTS];
if((argc < 2) || ( argc > MAX_EXISTING_PORTS+2)){
if(argc >2)
printf("Limited to tracking %d existing ports.\n",MAX_EXISTING_PORTS);
else
printf("Usage: %s <IP to shroud> [existing ports...]\n",argv[0]);
exit(0);
}
if(geteuid()!=0)
fatal("you must run this program as root ");
//Check target ip
if(inet_pton(AF_INET,argv[1],&(sa.sin_addr)) == 0)
fatal("Invalid target address");
if((sockfd = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1)
fatal("Making socket");
if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &yes, sizeof(yes)) < 0)
fatal("Setting IP_HDRINCL");
//Iterate command line arguments saving them to existing_ports[]
for(i=2;i< argc;i++)
existing_ports[i-2] = (u_short) atoi(argv[i]);
existing_ports[argc-2] = 0;
//Initialize Pcap Device
device = pcap_lookupdev(errbuf);
if(device == NULL)
fatal(errbuf);
printf("Sniffing on device %s \n",device);
//Initialize Pcap Handle in promiscous mode
pcap_handle = pcap_open_live(device,128,1,0,errbuf);
if(pcap_handle == NULL)
fatal(errbuf);
//Call set_packet_filter() function
set_packet_filter(pcap_handle,(struct in_addr *)&sa.sin_addr,existing_ports);
//Call pcap_loop() function and use callback function caught_packet
pcap_loop(pcap_handle,-1,caught_packet,(u_char *)&sockfd);
//Close pcap handler
pcap_close(pcap_handle);
//Close socket descriptor
close(sockfd);
return(0);
}
void fatal(char *msg){
printf("%s",msg);
exit(1);
}
int random_number(int nt){
struct timeval tv;
gettimeofday(&tv,NULL);
unsigned int seed = (unsigned int)tv.tv_usec;
srand(seed);
switch(nt){
//1 <--> Unsigned 8-Bit
case 1:
return(rand()%UCHAR_MAX);
break;
//2 <--> Signed 8-Bit
case 2:
return(rand()%SCHAR_MAX);
break;
//3 <--> Unsigned Short
case 3:
return(rand()%USHRT_MAX);
break;
//4 <--> Signed Short
case 4:
return(rand()%SHRT_MAX);
break;
//5 <--> Unsigned Int
case 5:
return(rand()%UINT_MAX);
break;
//6 <--> Signed Int
case 6:
return(rand()%INT_MAX);
break;
//7 <--> Unsigned Long
case 7:
return(rand()%ULONG_MAX);
break;
//8 <--> Signed Long
case 8:
return(rand()%LONG_MAX);
break;
// Default value
default:
return(0);
break;
}
}
int set_packet_filter(pcap_t *pcap_hdl,struct in_addr *target_ip,u_short *ports){
//Bpf Filter
struct bpf_program filter;
char *str_ptr,filter_string[90+(25 * MAX_EXISTING_PORTS)];
int i=0;
//Set dst host rule
sprintf(filter_string,"dst host %s and ",inet_ntoa(*target_ip));
//Set flag rule
strcat(filter_string,"tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack = 0");
//Set ports rules
if(ports[0] != 0){
str_ptr = filter_string + strlen(filter_string);
if(ports[1] == 0)
sprintf(str_ptr," and not dst port %hu",ports[i]);
else{
sprintf(str_ptr," and not (dst port %hu",ports[i++]);
while(ports[i] != 0){
str_ptr= filter_string + strlen(filter_string);
sprintf(str_ptr," or dst port %hu",ports[i++]);
}
strcat(filter_string,")");
}
}
//Print final filter string
printf("DEBUG: filter string is \' %s \' \n ",filter_string);
//Try to compile filter string into bpf filter
if(pcap_compile(pcap_hdl,&filter,filter_string,0,0) == -1)
fatal("pcap_compile failed");
//Assign bpf filter to pcap handler
if(pcap_setfilter(pcap_hdl,&filter) == -1)
fatal("pcap_setfilter failed");
}
unsigned short csum(unsigned short *buf, int nwords)
{ //
unsigned long sum;
for(sum=0; nwords>0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum &0xffff);
sum += (sum >> 16);
return (unsigned short)(~sum);
}
void print_ip_hdr(struct iphdr *iphdr){
//Print IP Header IN HOST BYTE ORDER AND NETWORK BYTE ORDER
printf("IP HEADER \n\n ");
printf(" NORD HORD \n");
printf("IP VERSION | %d | %d |\n",iphdr->version,ntohs(iphdr->version));
printf("IP HDL | %d | %d |\n",iphdr->ihl,ntohs(iphdr->ihl));
printf("IP TOS | %d | %d |\n",iphdr->tos,ntohs(iphdr->tos));
printf("IP TOT LEN | %d | %d |\n",iphdr->tot_len,ntohs(iphdr->tot_len));
printf("IP ID | %d | %d |\n",iphdr->id,ntohs(iphdr->id));
printf("IP FRAG OFF | %d | %d |\n",iphdr->frag_off,ntohs(iphdr->frag_off));
printf("IP TTL | %d | %d |\n",iphdr->ttl,ntohs(iphdr->ttl));
printf("IP PROTOCOL | %d | %d |\n",iphdr->protocol,ntohs(iphdr->protocol));
printf("IP CHECKSUM | %d | %d |\n",iphdr->check,ntohs(iphdr->check));
printf("SOURCE ADDRESS | %s | \n",inet_ntoa(*((struct in_addr *)&iphdr->saddr)));
printf("DEST ADDRESS | %s | \n\n",inet_ntoa(*((struct in_addr *)&iphdr->daddr)));
}
void print_eth_hdr(struct ethhdr *ethhdr){
int i;
//Print ETHERNET Header
printf("ETHERNET HEADER \n\n");
printf("DEST MAC | ");
for(i=0;i<ETH_ALEN;i++)
printf("%x",ethhdr->h_dest[i]);
printf(" |\n");
printf("SOURCE MAC | ");
for(i=0;i<ETH_ALEN;i++)
printf("%x",ethhdr->h_source[i]);
printf(" |\n\n");
}
void print_tcp_hdr(struct tcphdr *tcphdr){
//Print TCP Header IN HOST BYTE ORDER AND NETWORK BYTE ORDER
printf("TCP HEADER \n\n");
printf(" NORD HORD \n");
printf("SOURCE PORT | %d | %d |\n",tcphdr->source,ntohs(tcphdr->source));
printf("DEST PORT | %d | %d |\n",tcphdr->dest,ntohs(tcphdr->dest));
printf("SEQ | %d | %d |\n",tcphdr->seq,ntohl(tcphdr->seq));
printf("ACK | %d | %d |\n",tcphdr->ack_seq,ntohl(tcphdr->ack_seq));
printf("Flags |FIN|SYN|RST|PSH|ACK|URG| \n");
printf(" |%d |%d |%d |%d |%d |%d | \n",tcphdr->fin,tcphdr->syn,tcphdr->rst,tcphdr->psh,tcphdr->ack
,tcphdr->urg);
printf("WINDOW | %d | %d |\n",tcphdr->window,ntohs(tcphdr->window));
printf("TCP CHECKSUM| %d | %d |\n",tcphdr->check,ntohs(tcphdr->check));
printf("URG PTR | %d | %d |\n\n",tcphdr->urg_ptr,ntohs(tcphdr->urg_ptr));
}
void caught_packet(u_char *user_args,const struct pcap_pkthdr *cap_header,const u_char *packet){
//Bytes written and Socket Descriptor
int bcount,sockfd;
//IP Header
struct iphdr *iphdr_old,*iphdr;
//TCP Header
struct tcphdr *tcphdr_old,*tcphdr;
//Retrieve sockfd
sockfd = *((int *)user_args);
//Packet Buffer
char pkt_buffer[sizeof(struct iphdr) + sizeof(struct tcphdr)];
//Structuring old packet
iphdr_old = (struct iphdr *)(packet + sizeof(struct ethhdr));
tcphdr_old = (struct tcphdr *)(packet + sizeof(struct ethhdr) + sizeof(struct iphdr));
//Structuring new headers
iphdr = (struct iphdr *)(packet);
tcphdr = (struct tcphdr *)(packet + sizeof(struct iphdr));
//Sin address to send packet
struct sockaddr_in sin;
//initialize buffer
memset(pkt_buffer,0,(sizeof(struct iphdr) + sizeof(struct tcphdr)));
//initialize sin addr
sin.sin_family = AF_INET;
sin.sin_port = tcphdr_old->source;
sin.sin_addr = *((struct in_addr *)&iphdr_old->saddr);
print_ip_hdr(iphdr_old);
print_tcp_hdr(tcphdr_old);
//Create Packet
//Ip Header
iphdr->ihl = 5;
iphdr->version = 4;
iphdr->tos = IPTOS_LOWDELAY;
iphdr->tot_len = htons(sizeof(struct ip) + sizeof(struct tcphdr));
iphdr->id = htons(random_number(3));;
iphdr->frag_off = 0;
iphdr->ttl = MAXTTL;
iphdr->protocol = IPPROTO_TCP;
iphdr->check = 0;
//Reverse IPs
iphdr->saddr = iphdr_old->daddr;
iphdr->daddr = iphdr_old->saddr;
//Tcp Header
//Reverse Ports
tcphdr->source = tcphdr_old->dest;
tcphdr->dest = tcphdr_old->source;
tcphdr->seq = htonl(random_number(5));
tcphdr->ack_seq= (tcphdr_old->seq+1);
tcphdr->doff = 5;
tcphdr->syn = 1;
tcphdr->ack = 1;
tcphdr->fin = 0;
tcphdr->rst = 0;
tcphdr->psh = 0;
tcphdr->urg = 0;
tcphdr->window = htons(random_number(3));
tcphdr->check = 0;
tcphdr->urg_ptr= 0;
//IP Checksum
iphdr->check = csum((unsigned short *) pkt_buffer,(sizeof(struct iphdr) + sizeof(struct tcphdr)));
//DEBUG
print_ip_hdr(iphdr);
print_tcp_hdr(tcphdr);
//Send packet
bcount = sendto(sockfd,pkt_buffer,ntohs(iphdr->tot_len),0,(struct sockaddr *)&sin,(socklen_t)sizeof(sin));
if(bcount < 0 )
printf("Couldn't send packet: %s \n",strerror(errno));
else
printf("(%d) bytes sent ! \n",bcount);
}
我该如何解决这个问题?