[英]C: UDP packets source Ip faking - can't receive packet
在Google上工作幾個小時后,我仍然無法弄清楚。
我想做的是:我想通過C程序使用偽造的源IP發送UDP數據包(請參見下面的代碼)。
無法正常工作:當我從服務器1向服務器2發送數據包並嘗試接收它時,當該數據包的源IP沒有被偽造時,它只會出現在“ iftop”中。 當我在UDP報頭中放入偽造的ip時,仍然說我發送了數據包(我也看到在server-1的'iftop'上),但是在server-2上什么也收不到。 因此,例如,當我使用正確的發送者IP發送它時,我將接收到該數據包並在“ iftop”上看到它,但是當我以“ 1.2.3.4”作為源IP時,我將無法接收它(但是“ iftop”在server-1上仍然說它已經發送)。
我讀了很多東西,每個人都說偽造UDP數據包的源IP沒問題,所以我想知道我做錯了什么。 我也在python中嘗試過,但也沒有收到任何東西。
/*
Raw UDP sockets
*/
#include<stdio.h> //for printf
#include<string.h> //memset
#include<sys/socket.h> //for socket ofcourse
#include<stdlib.h> //for exit(0);
#include<errno.h> //For errno - the error number
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/ip.h> //Provides declarations for ip header
/*
96 bit (12 bytes) pseudo header needed for udp header checksum calculation
*/
struct pseudo_header
{
u_int32_t source_address;
u_int32_t dest_address;
u_int8_t placeholder;
u_int8_t protocol;
u_int16_t udp_length;
};
/*
Generic checksum calculation function
*/
unsigned short csum(unsigned short *ptr,int nbytes)
{
register long sum;
unsigned short oddbyte;
register short answer;
sum=0;
while(nbytes>1) {
sum+=*ptr++;
nbytes-=2;
}
if(nbytes==1) {
oddbyte=0;
*((u_char*)&oddbyte)=*(u_char*)ptr;
sum+=oddbyte;
}
sum = (sum>>16)+(sum & 0xffff);
sum = sum + (sum>>16);
answer=(short)~sum;
return(answer);
}
int main (void)
{
//Create a raw socket of type IPPROTO
int s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
if(s == -1)
{
//socket creation failed, may be because of non-root privileges
perror("Failed to create raw socket");
exit(1);
}
//Datagram to represent the packet
char datagram[4096] , source_ip[32] , *data , *pseudogram;
//zero out the packet buffer
memset (datagram, 0, 4096);
//IP header
struct iphdr *iph = (struct iphdr *) datagram;
//UDP header
struct udphdr *udph = (struct udphdr *) (datagram + sizeof (struct ip));
struct sockaddr_in sin;
struct pseudo_header psh;
//Data part
data = datagram + sizeof(struct iphdr) + sizeof(struct udphdr);
strcpy(data , "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
//some address resolution
strcpy(source_ip , "***.***.***.***"); // <- This is the (fake-)source IP
sin.sin_family = AF_INET;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = inet_addr ("***.***.***.***"); // <- Receiver IP
//Fill in the IP Header
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct iphdr) + sizeof (struct udphdr) + strlen(data);
iph->id = htonl (54321); //Id of this packet
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_UDP;
iph->check = 0; //Set to 0 before calculating checksum
iph->saddr = inet_addr ( source_ip ); //Spoof the source ip address
iph->daddr = sin.sin_addr.s_addr;
//Ip checksum
iph->check = csum ((unsigned short *) datagram, iph->tot_len);
//UDP header
udph->source = htons (45242);
udph->dest = htons (12345);
udph->len = htons(8 + strlen(data)); //tcp header size
udph->check = 0; //leave checksum 0 now, filled later by pseudo header
//Now the UDP checksum using the pseudo header
psh.source_address = inet_addr( source_ip );
psh.dest_address = sin.sin_addr.s_addr;
psh.placeholder = 0;
psh.protocol = IPPROTO_UDP;
psh.udp_length = htons(sizeof(struct udphdr) + strlen(data) );
int psize = sizeof(struct pseudo_header) + sizeof(struct udphdr) + strlen(data);
pseudogram = malloc(psize);
memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
memcpy(pseudogram + sizeof(struct pseudo_header) , udph , sizeof(struct udphdr) + strlen(data));
udph->check = csum( (unsigned short*) pseudogram , psize);
//loop if you want to flood :)
//while (1)
{
//Send the packet
if (sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &sin, sizeof (sin)) < 0)
{
perror("sendto failed");
}
//Data send successfully
else
{
printf ("Packet Send. Length : %d \n" , iph->tot_len);
}
}
return 0;
}
謝謝你的時間。
您放置了一個欺騙性的源ip-服務器將接收您的數據包,但會將答復(或嘗試將其發送)發送到欺騙性的源(1.2.3.4),我猜這沒有正確的反向路由。 因此,他們迷路了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.