我有一个本地服务器和客户端。没关系。我的目标是感染捕获的数据包 例如: 服务器发送:“ hello world”客户端接收:“ hello word”
而不是
服务器发送:“ hello world”,我想更改数据包数据或像这样修改数据>>>
客户recv:“另一个句子”
我用C写了一个嗅探器(这根本不是这个世界的新面孔。) 代码:
#include<stdio.h>
#include<string.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<errno.h> /
#include<netinet/tcp.h>
#include<netinet/ip.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/filter.h>
void PrintData (unsigned char* , int);
FILE *logfile;
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof((arr)[0]))
/*
96 bit (12 bytes) pseudo header needed for tcp 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 tcp_length;
};
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)
{
struct sock_filter code[] = {
{ 0x30, 0, 0, 0x00000009 },
{ 0x15, 0, 7, 0x00000006 },
{ 0x28, 0, 0, 0x00000014 },
{ 0x45, 4, 0, 0x00001fff },
{ 0xb1, 0, 0, 0x0000000e },
{ 0x50, 0, 0, 0x00000013 },
{ 0x15, 0, 2, 0x00000050 },
{ 0x06, 0, 0, 0xffffffff },
{ 0x06, 0, 0, 0xffffffff },
{ 0x06, 0, 0, 0000000000 },
};
char datagram[4096] , *data , *pseudogram;
struct iphdr *iph = (struct iphdr *) datagram;
//TCP header
struct tcphdr *tcph = (struct tcphdr *) (datagram + sizeof (struct ip));
struct sockaddr_in sin,sender;
struct pseudo_header psh;
int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
if(s == -1)
{
//socket creation failed, may be because of non-root privileges
perror("Failed to create socket");
exit(1);
}
char messg[500],source_ip[32];
//some address resolution
strcpy(source_ip , "127.0.0.1");
sin.sin_family = AF_INET;
sin.sin_port = 13;
sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
sender.sin_family = AF_INET;
sender.sin_port = ;
sender.sin_addr.s_addr = inet_addr ("127.0.0.1");
struct sock_fprog bpf;
// bpf.len = ARRAY_SIZE(code);
bpf.len = 10;
bpf.filter = code;
logfile=fopen("log.txt","w");
if(logfile==NULL) printf("Unable to create file.");
//Create a raw socke
setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));
perror("setsockopt");
//Datagram to represent the packet
//zero out the packet buffer
memset (datagram, 0, 4096);
//
//Data part
data = datagram + sizeof(struct iphdr) + sizeof(struct tcphdr);
strcpy(data , messg);
bind(s, (struct sockaddr *)&sin, sizeof(sin));
perror("bind");
//Fill in the IP Header
iph->ihl = 5;
iph->version = 4;
iph->tos = 0;
iph->tot_len = sizeof (struct iphdr) + sizeof (struct tcphdr) + strlen(data);
iph->id = htonl (54321); //Id of this packet
iph->frag_off = 0;
iph->ttl = 255;
iph->protocol = IPPROTO_TCP;
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);
unsigned short iphdrlen;
iphdrlen =iph->ihl*4;
//TCP Header
tcph->source = htons (1234);
tcph->dest = htons (80);
tcph->seq = 0;
tcph->ack_seq = 0;
tcph->doff = 5; //tcp header size
tcph->fin=0;
tcph->syn=1;
tcph->rst=0;
tcph->psh=0;
tcph->ack=0;
tcph->urg=0;
tcph->window = htons (5840); /* maximum allowed window size */
tcph->check = 0; //leave checksum 0 now, filled later by pseudo header
tcph->urg_ptr = 0;
//Now the TCP checksum
psh.source_address = inet_addr( source_ip );
psh.dest_address = sin.sin_addr.s_addr;
psh.placeholder = 0;
psh.protocol = IPPROTO_TCP;
psh.tcp_length = htons(sizeof(struct tcphdr) + strlen(data) );
int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + strlen(data);
pseudogram = malloc(psize);
memcpy(pseudogram , (char*) &psh , sizeof (struct pseudo_header));
memcpy(pseudogram + sizeof(struct pseudo_header) , tcph , sizeof(struct tcphdr) + strlen(data));
tcph->check = csum( (unsigned short*) pseudogram , psize);
//IP_HDRINCL to tell the kernel that headers are included in the packet
int one = 1;
const int *val = &one;
if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)
{
perror("Error setting IP_HDRINCL");
exit(0);
}
//loop if you want to flood :)
while (1)
{ sleep(1);
//Send the packet
if (sendto (s, datagram, iph->tot_len , 0, (struct sockaddr *) &sender, sizeof (sender)) < 0)
{
perror("sendto failed");
}
//Data send successfully
else
{
char bbuf[500]={0};
int re = 0;
printf ("Packet Send. Length : %d \n" , iph->tot_len);
if ( recvfrom(s, bbuf, 500, 0, (struct sockaddr *) &sender, &re)< 0)
printf("Recv failed\n");
else
{
printf("%x %x %x %x %x \n", bbuf[0], bbuf[1], bbuf[2], bbuf[3], bbuf[4] );
int numbytes;
printf("Received in pid=%d, text=: %s \n",getpid(), bbuf);
sleep(1);
fprintf(logfile,"TCP Header\n");
PrintData(bbuf + iphdrlen,tcph->doff*4);
fprintf(logfile,"Data Payload\n");
PrintData(bbuf + iphdrlen + tcph->doff*4 , (500 - tcph->doff*4-iph->ihl*4) );
}
if (recvfrom(s, bbuf, 500, 0, (struct sockaddr *) &sin, &re) < 0)
printf("Recv failed\n");
else
{
int i;
for(i=0;i<500;i++)
{
printf("%x ",bbuf[i]);
}
}
}
}
return 0;
}
void PrintData (unsigned char* data , int Size)
{
int i,j;
for(i=0 ; i < Size ; i++)
{
if( i!=0 && i%16==0) //if one line of hex printing is complete...
{
fprintf(logfile," ");
for(j=i-16 ; j<i ; j++)
{
if(data[j]>=32 && data[j]<=128)
fprintf(logfile,"%c",(unsigned char)data[j]); //if its a number or alphabet
else fprintf(logfile,"."); //otherwise print a dot
}
fprintf(logfile,"\n");
}
if(i%16==0) fprintf(logfile," ");
fprintf(logfile," %02X",(unsigned int)data[i]);
if( i==Size-1) //print the last spaces
{
for(j=0;j<15-i%16;j++) fprintf(logfile," "); //extra spaces
fprintf(logfile," ");
for(j=i-i%16 ; j<=i ; j++)
{
if(data[j]>=32 && data[j]<=128) fprintf(logfile,"%c",(unsigned char)data[j]);
else fprintf(logfile,".");
}
fprintf(logfile,"\n");
}
}
}
我知道某个地方丢失或弄错了,但是现在不重要了(我正在尝试这段代码中的其他事情,但是可以正常工作..)。 我想做一个过滤器,也许是基本的bsf,我想掉到客户端连接。在更改数据包后停止服务器与客户端之间的连接,然后恢复连接。我不知道该怎么做。 或。当客户端-服务器连接继续进行时。我的代码正在嗅探并修改为数据包。我该怎么办。谢谢,对不起我的英语不好:)