网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > 数据库 > Oracle教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
数据库:数据库教程,数据库技巧,Oracle教程,MySQL教程,Sybase教程,Access教程,DB2教程,数据库安全,数据库文摘
本月文章推荐
.Oracle并行服务器(OPS)12问.
.个人经验总结:在Oracle中恢复被.
.Oracle9i重建与切换临时表空间.
.简单提高ORACLE数据库的查询统计.
.主外键约束信息.
.[Oracle]减少临时表使用空间的几.
.PL/SQL Packages and Types Refe.
.全面解读 startx.
.转载:如何有效的利用数据字典.
.数据表性能优化实例.
.如何使用oracle的decode函数进行.
.ORA-01034错误的解决办法.
.Oracle sql 语句分析.
.Oracle 10g RAC与SLES9.
.改变非归档模式的Oracle数据库.
.如何返回指定行数之间的查询结果.
.一句T-SQL语句引发的思考 转帖.
.PL/SQL的SELECT FOR UPDATE游标.
.Oracle 10g R2ORA-3136 错误解决.
.如何给表、列加注释.

raw_socket server设计文档(1)

发表日期:2008-2-9



  socket( PF_INET, SOCK_RAW, IPPROTO_TCP );
  
  在RedHat 6.1下这两种socket都可以正常建立,内核支持了的。但是对于Solaris 2.6,假如以root身份truss跟踪这两个函数,发现第二个socket建立的时候 内核不支持这种情况下指定IPPROTO_TCP,库函数本身做了处理:
  
  so_socket(2, 4, 6, "", 1) Err#98 EPROTOTYPE
  stat("/dev/rawip", 0xEFFFFAC4) = 0
  so_socket(2, 4, 6, "/dev/rawip", 1) = 4
  setsockopt(4, 65535, 4105, 0xEFFFFBB4, 4) = 0
  
  从执行效果看,这样的处理和Linux下的意义不同了。
  
  假如考虑广泛兼容性,应该扔弃第二种socket,全部以IPPROTO_RAW方式出现。这样的话,理论上可以考虑不用TCP/UDP协议,但是涉及client/server模式,显然应该继
  续使用TCP/UDP。从突破防火墙角度看,还是以鬼子的ACK方式为好。UDP通信被很多防火墙屏蔽,TCP也好不到哪里去。而且按照目前的设想,等于仅仅使用TCP的头部概 念,并没有使用TCP协议的超时、重传等机制,更没有有限状态机介入,为什么不使用UDP呢?还是应该从防火墙角度考虑这个设计选择,具体问题具体分析吧。现在的难点是完全使用IPPROTO_RAW,写没多大问题,读有了麻烦,又需要重翻UNP;此外, 丢包是毫无疑问的,因此必须尽量设计成无状态方式(NFS Server就是一个例子),这 个也仅仅是说说,技术问题尚未可知。
  
  关于内核传递IP报文到一个raw_socket,有几点需要注重,我们分别探讨之:
  
  1) TCP/UDP报文(IP报文负载为TCP/UDP)"永远"不会传递给raw_socket。Stevens介绍
  的时候以BSD家族为例。
  
  对于Linux显然已经不适用这个结论,socket( PF_INET, SOCK_RAW, IPPROTO_TCP )
  就可以接收到TCP报文,Linux内核是给了这个机会的,此时正常的TCP协议层也会收到TCP报文(后面我们会写测试代码验证它)。于是造成潜在的安全隐患,在无需
  数据链路层和网卡混杂模式介入的情况下,利用raw_socket监视发往本机的TCP报文。尽管只有root才可以创建raw_socket,但获得创建raw_socket的机会和获得完整root权限相比要大得多。对于Solaris系统,内核应该是没有支持
  socket( PF_INET, SOCK_RAW, IPPROTO_TCP )方式,尽管以root身份执行库函数并没有报错(此时库函数自己做了其他处理)。
  
  对于Windows 2K,从backend拖回来的程序执行效果以及袁哥分析代码的结论看,2K可能支持socket( PF_INET, SOCK_RAW, IPPROTO_TCP )这种方式。抓包分析
  backdoor的client/server通信,发现除了预料中的ACK,还夹带有RST,只能说明2K内核传递IP报文到raw_socket的同时传递给了正常的TCP协议层,RST是由正常
  TCP协议层发出的。NT/9x估计没戏。
  
  考虑我们要达到的目的,假如内核不给这个机会(传递TCP报文到raw_socket),意味着ACK方式破产。UDP自然也不用想了。虽然Linux可以,但我们希望得到一个更广泛兼容的backdoor。可以从数据链路层考虑这个问题,牵扯的问题更多,没有太大必要。
  
  2) 对于伯克利实现而言,内核一般处理了几种常见ICMP报文(3种,回应请求、时间戳请求、地址掩码请求),其余未处理ICMP报文交给raw_socket。注重内核并没有
  处理上面三种请求报文的应答报文,想想ping.c的实现,假如内核处理icmp echo reply,即使指定IPPROTO_ICMP,处于应用层的ping也没有机会得到应答报文。这里所说内核处理,都是指处理入IP报文,对于发送IP报文,基本上任
  由应用程序处理的,所以ping可以发送自己的icmp echo request。
  
  Linux/Solaris的实现有差别,提供给应用层更多机会。内核处理了icmp echo request,同时会交给socket( PF_INET, SOCK_RAW, IPPROTO_ICMP ),不同于BSD
  实现。内核未处理的icmp报文依旧交给raw_socket。这给我们一个机会,编写自己的icmp daemon,利用被内核传递到raw_socket的icmp报文进行交互式通信。从突破防火墙角度考虑,比较现实,一般治理员会答应icmp echo request进入。治理员要是在防火墙上过滤了icmp echo request,估计我们也没有机会在这种敌人内部安装icmp daemon,走先。
  
  3) 所有的IGMP报文交给raw_socket。
  
  同上,可以利用。现在的操作系统好象已经开始在内核里处理igmp,那样的话,机会不大。而且防火墙对IGMP报文比较敏感。
  
  socket( AF_INET, SOCK_RAW, IPPROTO_IGMP ),Linux上可以接收到IGMP报文, Solaris上不行。

  
  4) 假如内核无法理解IP报文头中高层协议类型,传递该报文给raw_socket。
  
  内核无法理解的,对于防火墙也是无法理解的,除非不考虑突破防火墙的网络拓扑,否则暂时别想。此外从前面的测试中看到,Linux/Solaris下必须精确指定第
  三个参数可以接收匹配IP报文,假如要利用内核无法理解之协议类型,必须确保该类型可以指定在第三个参数中。
  
  5) IP分片一定是在内核中重组完成了才会传递给raw_socket。
  
  换句话说,raw_socket无法分析IP分片,数据链路层可以。这里隐含着一个意思,IP分片重组永远在内核完成,一旦这部分的处理代码出了问题,就是内核的麻烦,所以死得快。
  
  6) 假如内核决定传递一个IP报文到raw_socket,则系统中所有进程创建的所有raw_socket都会收到这个IP报文,这是一个潜在的安全问题。
  
  我们在测试程序中创建socket( PF_INET, SOCK_RAW,
  IPPROTO_ICMP ),启动了两
  个实例,然后从其他主机ping本机,两个实例都收到了icmp echo request。
  
  7) 创建socket( PF_INET, SOCK_RAW, 0 ),并且不调用bind、connect,这样的
  raw_socket接收所有内核传递上来的IP报文。第三个参数是指定匹配的,假如非
  零,不匹配的IP报文不会被传递给该raw_socket。对于这种系统,企图监视本机
  所有入IP报文,不需要数据链路层介入,也不要求网卡混杂模式,简单创建一个
  raw_socket,指定第三个参数为0即可。
  
  遗憾的是,我们在Linux下测试,根本就不支持第三个参数指定为0,指定成
  255(IPPROTO_RAW)也无法达到Stevens描述的效果,255主要用于发送,Stevens介
  绍的可能仅仅是BSD实现吧。
  
  关于这个,觉得看看Linux关于raw_socket的实现部分比较好,瞎猜也不是办法。
  
  8) 有些代码使用了raw_socket,并未指定IP_HDRINCL选项。1988年为了解决
  traceroute问题引入了一个patch,创建SOCK_RAW时,指定第三个参数为
  IPPROTO_RAW(值255),效果和指定IP_HDRINCL选项一样,还更方便些。
  
  --------------------------------------------------------------------------
  /*
  * For Solaris
  * gcc -O3 -o raw raw.c -lsocket -lnsl
  *
  * For Linux
  * gcc -O3 -o raw raw.c
  */
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  #include
  
  #define SUCCESS 0
  #define FAILURE -1
  
  int recvSocket;
  u_char packet[ 1500 ];
  
  void Close ( int fd )
  {
  if ( close( fd ) == -1 )
  {
  perror( "close" );
  exit( FAILURE );
  }
  return;
  } /* end of Close */
  
  void outputBinary ( const unsigned char * byteArray, const size_t byteArrayLen )
  {
  u_long offset;
  int i, j, k;
  fprintf( stderr, "byteArray [ %lu bytes ] ----> \n", byteArrayLen );
  if ( byteArrayLen <= 0 )
  {
  return;
  }
  i = 0;
  offset = 0;
  for ( k = byteArrayLen / 16; k > 0; k--, offset += 16 )
  {
  fprintf( stderr, "%08X ", offset );
  for ( j = 0; j < 16; j++, i++ )
  {
  if ( j == 8 )
  {
  fprintf( stderr, "-%02X", byteArray[i] );
  }
  else
  {
  fprintf( stderr, " %02X", byteArray[i] );
  }
  }
  fprintf( stderr, " " );
  i -= 16;
  for ( j = 0; j < 16; j++, i++ )
  {
  /* if ( isprint( (int)byteArray[i] ) ) */
  if ( ( byteArray[i] >= ' ' ) && ( byteArray[i] <= 255 ) )
  {
  fprintf( stderr, "%c", byteArray[i] );

  }
  else
  {
  fprintf( stderr, "." );
  }
  }
  fprintf( stderr, "\n" );
  } /* end of for */
  k = byteArrayLen - i;
  if ( k <= 0 )
  {
  return;
  }
  fprintf( stderr, "%08X ", offset );
  for ( j = 0 ; j < k; j++, i++ )
  {
  if ( j == 8 )
  {
  fprintf( stderr, "-%02X", byteArray[i] );
  }
  else
  {
  fprintf( stderr, " %02X", byteArray[i] );
  }
  }
  i -= k;
  for ( j = 16 - k; j > 0; j-- )
  {
  fprintf( stderr, " " );
  }
  fprintf( stderr, " " );
  for ( j = 0; j < k; j++, i++ )
  {
  if ( ( byteArray[i] >= ' ' ) && ( byteArray[i] <= 255
上一篇:使用LogMiner分析Oracle8i/9i的重做日志和归档日志 人气:809
下一篇:如何给Linux补洞 人气:554
浏览全部Oracle教程的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐