国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

raw_socket server設(shè)計文檔(1)

2024-07-21 02:35:52
字體:
供稿:網(wǎng)友

  socket( PF_INET, SOCK_RAW, ipPROTO_TCP );
  
  在RedHat 6.1下這兩種socket都可以正常建立,內(nèi)核支持了的。但是對于Solaris 2.6,假如以root身份truss跟蹤這兩個函數(shù),發(fā)現(xiàn)第二個socket建立的時候 內(nèi)核不支持這種情況下指定IPPROTO_TCP,庫函數(shù)本身做了處理:
  
  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
  
  從執(zhí)行效果看,這樣的處理和linux下的意義不同了。
  
  假如考慮廣泛兼容性,應(yīng)該扔棄第二種socket,全部以IPPROTO_RAW方式出現(xiàn)。這樣的話,理論上可以考慮不用TCP/UDP協(xié)議,但是涉及client/server模式,顯然應(yīng)該繼
  續(xù)使用TCP/UDP。從突破防火墻角度看,還是以鬼子的ACK方式為好。UDP通信被很多防火墻屏蔽,TCP也好不到哪里去。而且按照目前的設(shè)想,等于僅僅使用TCP的頭部概 念,并沒有使用TCP協(xié)議的超時、重傳等機(jī)制,更沒有有限狀態(tài)機(jī)介入,為什么不使用UDP呢?還是應(yīng)該從防火墻角度考慮這個設(shè)計選擇,具體問題具體分析吧。現(xiàn)在的難點(diǎn)是完全使用IPPROTO_RAW,寫沒多大問題,讀有了麻煩,又需要重翻UNP;此外, 丟包是毫無疑問的,因此必須盡量設(shè)計成無狀態(tài)方式(NFS Server就是一個例子),這 個也僅僅是說說,技術(shù)問題尚未可知。
  
  關(guān)于內(nèi)核傳遞IP報文到一個raw_socket,有幾點(diǎn)需要注重,我們分別探討之:
  
  1) TCP/UDP報文(IP報文負(fù)載為TCP/UDP)"永遠(yuǎn)"不會傳遞給raw_socket。Stevens介紹
  的時候以BSD家族為例。
  
  對于Linux顯然已經(jīng)不適用這個結(jié)論,socket( PF_INET, SOCK_RAW, IPPROTO_TCP )
  就可以接收到TCP報文,Linux內(nèi)核是給了這個機(jī)會的,此時正常的TCP協(xié)議層也會收到TCP報文(后面我們會寫測試代碼驗(yàn)證它)。于是造成潛在的安全隱患,在無需
  數(shù)據(jù)鏈路層和網(wǎng)卡混雜模式介入的情況下,利用raw_socket監(jiān)視發(fā)往本機(jī)的TCP報文。盡管只有root才可以創(chuàng)建raw_socket,但獲得創(chuàng)建raw_socket的機(jī)會和獲得完整root權(quán)限相比要大得多。對于Solaris系統(tǒng),內(nèi)核應(yīng)該是沒有支持
  socket( PF_INET, SOCK_RAW, IPPROTO_TCP )方式,盡管以root身份執(zhí)行庫函數(shù)并沒有報錯(此時庫函數(shù)自己做了其他處理)。
  
  對于Windows 2K,從backend拖回來的程序執(zhí)行效果以及袁哥分析代碼的結(jié)論看,2K可能支持socket( PF_INET, SOCK_RAW, IPPROTO_TCP )這種方式。抓包分析
  backdoor的client/server通信,發(fā)現(xiàn)除了預(yù)料中的ACK,還夾帶有RST,只能說明2K內(nèi)核傳遞IP報文到raw_socket的同時傳遞給了正常的TCP協(xié)議層,RST是由正常
  TCP協(xié)議層發(fā)出的。NT/9x估計沒戲。
  
  考慮我們要達(dá)到的目的,假如內(nèi)核不給這個機(jī)會(傳遞TCP報文到raw_socket),意味著ACK方式破產(chǎn)。UDP自然也不用想了。雖然Linux可以,但我們希望得到一個更廣泛兼容的backdoor。可以從數(shù)據(jù)鏈路層考慮這個問題,牽扯的問題更多,沒有太大必要。
  
  2) 對于伯克利實(shí)現(xiàn)而言,內(nèi)核一般處理了幾種常見ICMP報文(3種,回應(yīng)請求、時間戳請求、地址掩碼請求),其余未處理ICMP報文交給raw_socket。注重內(nèi)核并沒有
  處理上面三種請求報文的應(yīng)答報文,想想ping.c的實(shí)現(xiàn),假如內(nèi)核處理icmp echo reply,即使指定IPPROTO_ICMP,處于應(yīng)用層的ping也沒有機(jī)會得到應(yīng)答報文。這里所說內(nèi)核處理,都是指處理入IP報文,對于發(fā)送IP報文,基本上任
  由應(yīng)用程序處理的,所以ping可以發(fā)送自己的icmp echo request。
  
  Linux/Solaris的實(shí)現(xiàn)有差別,提供給應(yīng)用層更多機(jī)會。內(nèi)核處理了icmp echo request,同時會交給socket( PF_INET, SOCK_RAW, IPPROTO_ICMP ),不同于BSD
  實(shí)現(xiàn)。內(nèi)核未處理的icmp報文依舊交給raw_socket。這給我們一個機(jī)會,編寫自己的icmp daemon,利用被內(nèi)核傳遞到raw_socket的icmp報文進(jìn)行交互式通信。從突破防火墻角度考慮,比較現(xiàn)實(shí),一般治理員會答應(yīng)icmp echo request進(jìn)入。治理員要是在防火墻上過濾了icmp echo request,估計我們也沒有機(jī)會在這種敵人內(nèi)部安裝icmp daemon,走先。
  
  3) 所有的IGMP報文交給raw_socket。
  
  同上,可以利用。現(xiàn)在的操作系統(tǒng)好象已經(jīng)開始在內(nèi)核里處理igmp,那樣的話,機(jī)會不大。而且防火墻對IGMP報文比較敏感。
  
  socket( AF_INET, SOCK_RAW, IPPROTO_IGMP ),Linux上可以接收到IGMP報文, Solaris上不行。

  
  4) 假如內(nèi)核無法理解IP報文頭中高層協(xié)議類型,傳遞該報文給raw_socket。
  
  內(nèi)核無法理解的,對于防火墻也是無法理解的,除非不考慮突破防火墻的網(wǎng)絡(luò)拓?fù)洌駝t暫時別想。此外從前面的測試中看到,Linux/Solaris下必須精確指定第
  三個參數(shù)可以接收匹配IP報文,假如要利用內(nèi)核無法理解之協(xié)議類型,必須確保該類型可以指定在第三個參數(shù)中。
  
  5) IP分片一定是在內(nèi)核中重組完成了才會傳遞給raw_socket。
  
  換句話說,raw_socket無法分析IP分片,數(shù)據(jù)鏈路層可以。這里隱含著一個意思,IP分片重組永遠(yuǎn)在內(nèi)核完成,一旦這部分的處理代碼出了問題,就是內(nèi)核的麻煩,所以死得快。
  
  6) 假如內(nèi)核決定傳遞一個IP報文到raw_socket,則系統(tǒng)中所有進(jìn)程創(chuàng)建的所有raw_socket都會收到這個IP報文,這是一個潛在的安全問題。
  
  我們在測試程序中創(chuàng)建socket( PF_INET, SOCK_RAW,
  IPPROTO_ICMP ),啟動了兩
  個實(shí)例,然后從其他主機(jī)ping本機(jī),兩個實(shí)例都收到了icmp echo request。
  
  7) 創(chuàng)建socket( PF_INET, SOCK_RAW, 0 ),并且不調(diào)用bind、connect,這樣的
  raw_socket接收所有內(nèi)核傳遞上來的IP報文。第三個參數(shù)是指定匹配的,假如非
  零,不匹配的IP報文不會被傳遞給該raw_socket。對于這種系統(tǒng),企圖監(jiān)視本機(jī)
  所有入IP報文,不需要數(shù)據(jù)鏈路層介入,也不要求網(wǎng)卡混雜模式,簡單創(chuàng)建一個
  raw_socket,指定第三個參數(shù)為0即可。
  
  遺憾的是,我們在Linux下測試,根本就不支持第三個參數(shù)指定為0,指定成
  255(IPPROTO_RAW)也無法達(dá)到Stevens描述的效果,255主要用于發(fā)送,Stevens介
  紹的可能僅僅是BSD實(shí)現(xiàn)吧。
  
  關(guān)于這個,覺得看看Linux關(guān)于raw_socket的實(shí)現(xiàn)部分比較好,瞎猜也不是辦法。
  
  8) 有些代碼使用了raw_socket,并未指定IP_HDRINCL選項。1988年為了解決
  traceroute問題引入了一個patch,創(chuàng)建SOCK_RAW時,指定第三個參數(shù)為
  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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 泸水县| 永昌县| 合肥市| 本溪市| 凌海市| 乳源| 皮山县| 敦化市| 师宗县| 克拉玛依市| 宁海县| 庆云县| 罗田县| 思茅市| 保定市| 绍兴县| 长泰县| 东阳市| 个旧市| 鄂托克旗| 怀远县| 宿松县| 鱼台县| 闸北区| 娱乐| 衡水市| 临清市| 华阴市| 南丰县| 海兴县| 江山市| 东兰县| 汝城县| 察隅县| 侯马市| 南郑县| 淅川县| 福安市| 聂拉木县| 长阳| 富源县|