我试图手动为收到的确认数据包创建 TCP 同步确认。然而,欺骗的 synack 正在被源丢弃。从wireshark 观察时,同步确认校验和显示为错误。下面是我在一些在线资源的帮助下用于构建数据包的代码。
/*
* spoof.h
*
* Created on: Dec 19, 2017
* Author: root
*/
#ifndef SPOOF_H_
#define SPOOF_H_
#endif /* SPOOF_H_ */
#ifndef _NETINET_TCP_H_
#include <netinet/tcp.h>
#endif
#ifndef _NETINET_IP_H_
#include <netinet/ip.h>
#endif
#ifndef _LINUX_IF_ETHER_H
#include <linux/if_ether.h>
#endif
struct in_addr dest_ip;
char *target;
unsigned short csum(unsigned short* ,int);
unsigned short compute_tcp_checksum(struct iphdr *, unsigned short *);
void compute_ip_checksum(struct iphdr* );
static unsigned short compute_checksum(unsigned short *, unsigned int );
char * syn_ack(char * pkbuff){
char* datagram=(char*)malloc(1518);
struct ethhdr *ethr = (struct ethhdr *)pkbuff;
struct ethhdr *eths = (struct ethhdr *)datagram;
struct iphdr *iphr = (struct iphdr *)(pkbuff+sizeof(struct ethhdr )); //ip header of incoming packet
struct iphdr *iphs = (struct iphdr *) (datagram + sizeof(struct ethhdr )); // ip header of the spoofed packet
struct tcphdr *tcphr = (struct tcphdr *)(pkbuff+sizeof(struct ethhdr )+sizeof(struct iphdr )); // TCP header of incomming packet
struct tcphdr *tcphs = (struct tcphdr *)(datagram + sizeof(struct iphdr)+sizeof(struct ethhdr )); // ip header of spoofed packet
memset(datagram,0,1518); /*zero out the buffer */
// Fill in the IP header
iphs->ihl =5;
iphs->version = 4;
iphs->tos = 0;
iphs->tot_len = sizeof(struct iphdr )+sizeof(struct tcphdr );
iphs->id = iphr->id;
iphs->frag_off= 0x00;//htons(16384);
iphs->ttl = 64;
iphs->protocol = IPPROTO_TCP;
iphs->check = 0; //set to 0 before calculating checksum
iphs->saddr = iphr->daddr;
iphs->daddr = iphr->saddr;
compute_ip_checksum(iphs);
//TCP header
tcphs->source = tcphr->dest;
tcphs->dest = tcphr->source;
tcphs->seq = htonl(1000000 + rand () % 90000);
tcphs->ack_seq = htonl(ntohl(tcphr->seq) +1);
tcphs->doff=sizeof(struct tcphdr)/4;
tcphs->res1 = 0;
tcphs->res2 = 0;
tcphs->fin = 0;
tcphs->syn = 1;
tcphs->rst = 0;
tcphs->psh = 0;
tcphs->ack = 1;
tcphs->urg =0;
tcphs->window = htons(29200); // maximum allowed window size;
tcphs->check =0 ;
tcphs->urg_ptr =0 ;
tcphs->check = compute_tcp_checksum(iphs,(unsigned short*)tcphs);
eths->h_dest[0] = ethr->h_source[0];
eths->h_dest[1] = ethr->h_source[1];
eths->h_dest[2] = ethr->h_source[2];
eths->h_dest[3] = ethr->h_source[3];
eths->h_dest[4] = ethr->h_source[4];
eths->h_dest[5] = ethr->h_source[5];
eths->h_source[0] = ethr->h_dest[0];
eths->h_source[1] = ethr->h_dest[1];
eths->h_source[2] = ethr->h_dest[2];
eths->h_source[3] = ethr->h_dest[3];
eths->h_source[4] = ethr->h_dest[4];
eths->h_source[5] = ethr->h_dest[5];
eths->h_proto = 8;
return datagram;
}
//*************************CHECKSUM IMPLEMENTATION ************************************************
/* set tcp checksum: given IP header and tcp segment */
unsigned short compute_tcp_checksum(struct iphdr *pIph, unsigned short *ipPayload) {
register unsigned long sum = 0;
unsigned short tcpLen = ntohs(pIph->tot_len) - (pIph->ihl<<2);
struct tcphdr *tcphdrp = (struct tcphdr*)(ipPayload);
//add the pseudo header
//the source ip
sum += (pIph->saddr>>16)&0xFFFF;
sum += (pIph->saddr)&0xFFFF;
//the dest ip
sum += (pIph->daddr>>16)&0xFFFF;
sum += (pIph->daddr)&0xFFFF;
//protocol and reserved: 6
sum += htons(IPPROTO_TCP);
//the length
sum += htons(tcpLen);
//add the IP payload
//initialize checksum to 0
tcphdrp->check = 0;
while (tcpLen > 1) {
sum += * ipPayload++;
tcpLen -= 2;
}
//if any bytes left, pad the bytes and add
if(tcpLen > 0) {
//printf("+++++++++++padding, %dn", tcpLen);
sum += ((*ipPayload)&htons(0xFF00));
}
//Fold 32-bit sum to 16 bits: add carrier to result
while (sum>>16) {
sum = (sum & 0xffff) + (sum >> 16);
}
sum = ~sum;
//set computation result
//tcphdrp->check = (unsigned short)sum;
return (unsigned short)sum;
}
//##############################IP CHECKSUM CALCULATION #####################################
/* set ip checksum of a given ip header*/
void compute_ip_checksum(struct iphdr* iphdrp){
iphdrp->check = 0;
iphdrp->check = compute_checksum((unsigned short*)iphdrp, iphdrp->ihl<<2);
}
/* Compute checksum for count bytes starting at addr, using one's complement of one's complement sum*/
static unsigned short compute_checksum(unsigned short *addr, unsigned int count) {
register unsigned long sum = 0;
while (count > 1) {
sum += * addr++;
count -= 2;
}
//if any bytes left, pad the bytes and add
if(count > 0) {
sum += ((*addr)&htons(0xFF00));
}
//Fold sum to 16 bits: add carrier to result
while (sum>>16) {
sum = (sum & 0xffff) + (sum >> 16);
}
//one's complement
sum = ~sum;
return ((unsigned short)sum);
}
这里似乎有什么问题?