QQ,就是OICQ,TENCENT公司研发的即时信息软件,是中国市场上国产IM软件绝对的老大。中国网民几乎人手至少一个QQ号码。大家都比我清楚,不多介绍。 
    本文谈谈QQ的安全问题。 
    QQ具有如此惊人的人气,却有着与之不相称的安全问题。基本上可以说,使用QQ,基本没有任何隐私可言!另外它也为你的电脑带来了诸多附送的安全隐患。有识之士如我都早已不用QQ啦。

QQ的安全问题
作者:doublelee

QQ,就是OICQ,TENCENT公司研发的即时信息软件,是中国市场上国产IM软件绝对的老大。中国网民几乎人手至少一个QQ号码。大家都比我清楚,不多介绍。
   
   本文谈谈QQ的安全问题。
   
   QQ具有如此惊人的人气,却有着与之不相称的安全问题。基本上可以说,使用QQ,基本没有任何隐私可言!另外它也为你的电脑带来了诸多附送的安全隐患。有识之士如我都早已不用QQ啦。
   
   一,本地密码保存方式
   
   QQ的客户端会不经用户同意,把用户的密码经过数万次的MD5运算后存在本地。每次登陆在发送网络数据包之前进行本地验证,相信熟悉QQ的朋友对这一点都不陌生。这样事实上给了攻击者暴力破解QQ密码的机会,只要攻击者得到本地保存的这个数据即可。这个文件曾经叫ewh.db或者user.db,不知道现在是否又变了。说明一点,由于MD5作了数万次,这样的破解效率不高,但再低的效率也有弱智密码中招,当年在线尝试登陆都可以,还有什么不可能呢?
   如果选择了自动登陆,那么密码的一次MD5保存在oicq2000.cfg中,破解速度大大提高。
   
   二,本地聊天记录查看漏洞
   
   典型的攻击场景是:已经拿到全部本地记录,就是一个以QQ号为名的文件夹,不知道密码(或者俗称忘记了密码,求助者多数号称是mm)如何查看其聊天记录?
   QQ登陆的流程是这样的:1.输入用户名密码->2.本地验证通过->3.得到用户界面(企鹅开始闪动)->4.发送登陆包->5.收到登陆包成功响应->6.登陆成功。
   其中在步骤3的时候,我们就可以查看聊天记录了。
   如果2失败,则要求重新输入密码;如果5失败,则退出步骤3中得到的用户界面。对于没有正确密码的攻击者来说,要保持3的状态以查看本地聊天记录,需要首先骗过2,并防止4发生。由于QQ没有软件加密(加壳),所以2十分容易,修改一个跳转就OK。4就更容易了,拔了网线或设置防火墙就可以了。现在网上有很多这样的修改教程和修改好的客户端。所以不再赘述。
   
   三,本地聊天记录的加密方法
   
   事实上以上第二条所说是一个利用已有客户端简单规避本地检查的办法。如果你愿意,可以自己写一个查看聊天记录的工具,因为它的加密方式是如此的脆弱。
   首先普及一点常识:TEA算法(Tiny Encryption Algorithm,即微型加密算法)是一个正规的密码学意义上的加密算法,你可以在http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html找到原作者对其的介绍。QQ的加密,包括本地文件加密和远程数据包加密,主要使用的就是这个算法。值得注意的是原作者使用的是32轮运算(即使是32轮,这个算法也被证明是可以已知明文攻击的),然而TENCENT将其降为了16轮。时间上省了一半,但安全性却严重下降。算法常识以后再讲,我们只要知道该算法是公开的就可以了。(废话,不公开哪来的那么多开源QQ,比如lumaQQ)。
   QQ本地历史数据,包括聊天记录和一些日志,用一个key加密后存在本地Msg.db或者MsgEx.db中,但是这个key呢,用QQ号码的MD5加密存在本地同一个文件中,换句话说,知道QQ号码就可以解密这些文件,QQ号码是什么呢?就是所在目录名!
   当然,如果你启用了本地消息加密,情况会稍微好那么一点点,要看你的本地加密密码强度了。但是有多少人会去设置呢?
   
   四,木马泛滥,Windows的HOOK
   
   关于QQ密码的安全性我想是大家最关心的问题。网络上充斥着各种各样的偷QQ密码的文章或者工具,其实绝大多数越来越不好用,有些所谓偷密码的工具甚至本身就是木马,是来偷你自己的密码的。这些工具主要原理是挂钩子,判断当前窗口名,截键盘,某种方式发回。实际上,能种下木马本身已经是可遇而不可求的了。加上对方稍有安全意识,有个象样点的防火墙,这些工具就很难成功。
   另外臭名昭著的QQ病毒之一类,俗称QQ尾巴的,也多是利用这种原理,查找窗口,发送消息。
   针对这些问题,TENCENT公司自己也做了不少工作,比如窗口名是空的,实际看到的窗口名是画上去的。比如软键盘,比如其他的密码保护措施,可惜效果不太好啊。
   
   五,登陆数据包如果遭窃听,密码可能被离线暴力破解
   
   这是一个十分严重的问题,也会导致密码丢失。而且比前一条所说更严重。实际上,攻击者不再需要装木马,他只要会用Sniffer就可以了。
   随便分析一下QQ的程序,或者看看开源的QQ程序,我们就知道,虽然普通数据包是协商的密钥,但QQ的登陆请求数据包中,由于还没有协商密钥,临时密钥是写在数据段之前的,也就是说这个数据包是可以轻松解密的。那么这个数据包里包含什么呢?它包含了用QQ密码的MD5或2次MD5加密空字符串得到的一段16字节数据!加密算法是TEA,最要命的是,经过TENCENT公司对算法模式的一个包装,如果用一个不相干的密钥去尝试解密这段二进制数据,解密函数会返回错误!而不是解密出一段无用的数据并返回正确!这种傻瓜逻辑为穷举攻击创造了极大的便利条件。实际攻击者不需要去穷举128位的密钥,他只要猜测可能的密码,做MD5运算一到二次后尝用来尝试解密那16字节数据就可以了。
   简而言之,如果你的密码够简单,或者进了字典,那么恶意攻击者只要用一个sniffer,或者开个QQ代理,就能知道你的密码,这个穷举只要本地运算即可,而且速度非常之快。大约10^6~10^8次/秒。这个速度意味着,所有8位以下数字,6位以下字母,简单数字字母组合的密码都是形同虚设。作为对策,建议普通用户使用足够强壮的密码并且不要使用任何QQ代理。
   
   六,得到工作密钥,实时解密QQ数据
   
   QQ聊天数据加密用了协商密钥作工作密钥,这不错。可是,它竟然用对称算法传递协商的密钥!?
   QQ的工作密钥是服务器随机生成并发回的(也许不是随机?可以预测?不过我没搞到QQ服务器源码,不知道),如果QQ在线,这个密钥会是一直不变的,如果不在线一段时间,这个工作密钥就被更新。所以每两次登陆,如果间隔了一定时间,大约十几分钟,这个密钥就不同。从而一劳永逸地破解工作密钥是不现实的。但是如果有了QQ密码的MD5,那么攻击者可以解密QQ登陆确认数据包,解密后竟然就可以看到工作密钥,是16个字节的大小写字母加数字组合。此后所有客户端到服务器的数据将全部用此工作密钥解密。如果需要点对点聊天,那么所需密钥用同样算法和工作密钥加密送来。总之,此后所有QQ数据都可以认为是明文了。
   如果你的密码被偷或被破解,攻击者很可能不通知你,也不修改你的密码,因为他知道你有密码保护,但是不要以为你的QQ号没有丢,可能攻击者正在看着你的聊天信息偷着乐呢。他也随时可以上线踢你下去,帮你聊天。
   
   七,太多而繁杂的发行版本
   
   QQ的客户端有太多的版本了,各种语言发行版不论,各种年号版、XP版、beta版、正式发行版,冠以各色名字,令人眼花缭乱,关键是他们还都好用。实际上,一个成功的C/S结构的网络产品不应当同时有太多的客户端版本,不仅难以维护,增大服务器开销,而且给冒名版本提供了可乘之机。现在流行有许多非官方发布的QQ客户端版本,什么珊瑚虫版,免广告版,显IP版……都大行其道,傻瓜也会想得到,其中必然有偷密码版,恶作剧版,留后门版在其中鱼目混珠。QQ对自己的客户端不加壳也就算了,它还不作进程检查和文件完整性校验,也没有守护进程。这么大大咧咧,怎么对得起这么多信之爱之的忠实用户啊?
   
   八,多处不作任何加密处理的模块
   
   也许由于数据量太大,语音和视频聊天就都没有加密,是明文传播,任何人可以直接在线收听收看。如果你想用WEB方式登陆www.qq.com,那么密码也就按照明文发出去了。
   
   九,乱添插件,乱加功能
   
   直接调用控件编写的内置IE浏览器,完全继承了IE的各种功能,以及漏洞。大家知道IE的漏洞研究的人十分之多,那么QQ也就随之非常危险了。
   QQ秀,Q币,手机绑定等等在线服务,常常是每推出一个,就捎带出一堆漏洞。研究的人不少,这个需要在线研究,有风险,所以我没怎么干过。谁有经验告诉我啊。
   自定义头像漏洞:据说QQ自定义头像的功能传出过一个漏洞,导致任意代码执行,我虽然没有实践过,但想来可能不假。
   可以想见,功能越多,潜在的危险也就越大!这其实是安全软件开发中一条很有名的原则。所以建议各位,尽量少去玩试用版新功能,使用稳定而功能少的旧版本其实有时利大于弊。
   
   十,相同认证方式的其他网络服务和产品
   
   HTTP服务,《凯旋》游戏,QQ游戏大厅,等等,都可以用QQ号加同样的密码登陆。也许方便了用户,但在安全性上来讲这是大忌。整体安全性降到了其中的最小值。凯旋和游戏大厅是有客户端的,用户名密码的加密方式与QQ相同。但是HTTP可是明文的啊。
   
   以下讲几个场景。
   
   例如:
   首先,滑稽的很,我竟然可以在http://service.qq.com查询到任意QQ号是否申请了密码保护,那么查查隔壁mm的吧。
   然后,晓之以情动之以理,mm你去申请密码保护吧。同时打开sniffer。
   哎,申请密码保护竟然要WEB方式输入密码!你知道么?申请密码保护的过程可能就是丢失密码的过程哦,顺便还捎带了提示问题及其答案呢!
   
   再例如:
   我是网管,已经得到了你的密码,我修改了你的密码,你没有密码保护,那么你可以去申诉,向一个CGI叫做http://service.qq.com/cgi-bin/TellError的申诉。
   然后,我就知道了你的曾经密码,真实信息,另一个QQ号……真是大丰收啊。什么,你打电话申诉?好吧去打吧,很艰辛的,社会工程学攻击已经超出本篇的范围了。
   
   再例如,你有密码保护,好吧那么你的找回过程还是要WEB登陆。再说,现在有多少电子邮箱又能抵挡住sniffer这样的简单工具呢?我就不多说了。

下面我们来欣赏一下QQ的解密代码。
   
void decrypt_qword(unsigned long *in, unsigned long *key, unsigned long *out)
{

unsigned long code[4];
       register unsigned long i=16, j=0xe3779B90, m, n;
 
       m = swapu32(in[0]);
       n = swapu32(in[1]);
 
       code[0] = swapu32(key[0]); code[1] = swapu32(key[1]);
       code[2] = swapu32(key[2]); code[3] = swapu32(key[3]);
 
       while(i-- >0)
       {
               n -= ((m>>5)+code[3])^((m<<4)+code[2])^(j+m);
               m -= ((n>>5)+code[1])^((n<<4)+code[0])^(j+n);
               j += 0x61C88647;
       }
       out[0] = swapu32(m);
       out[1] = swapu32(n);
}

int decrypt_msg(unsigned char *in, int inlen, unsigned long *key,
unsigned char *out, unsigned long *outlen)
{
       unsigned char q[8], mkey[8], *q1, *q2, *outp;
       register int count, i, j, p;
 
       if (inlen%8 || inlen<16) return 0;
       decrypt_qword((unsigned long *)in, key, (unsigned long *)q);
       j = q[0]&0x7;
       count = inlen - j - 10;
    //   if (*outlen < count || count < 0) return 0; //?????*outlen
       if (count < 0) return 0;
       *outlen = count;
 
       memset(mkey, 0, 8);
       q2 = mkey;
       i = 8; p = 1;
       q1 = in+8;
       j ++;
       while (p <= 2) {     
               if (j < 8) {
                       j ++;
                       p ++;
               } else if (j == 8) {
                       q2 = in;
                       for (j = 0; j < 8; j ++ ) {
                               if (i + j >= inlen) return 0;
                               q[j] ^= q1[j];
                       }
                       decrypt_qword((unsigned long *)q, key, (unsigned long *)
q);
                       i += 8;
                       q1 += 8;
                       j = 0;
               }
       }
       outp = out;
       while(count !=0) {
               if (j < 8) {
                       outp[0] = q2[j] ^ q[j];
                       outp ++;
                       count --;
                       j ++;
               } else if (j == 8) {
                       q2 = q1-8;
                       for (j = 0; j < 8; j ++ ) {
                               if (i + j >= inlen) return 0;
                               q[j] ^= q1[j];
                       }
                       decrypt_qword((unsigned long *)q, key, (unsigned long *)
q);
                       i += 8;
                       q1 += 8;
                       j = 0;
               }
       }
       for (p = 1; p < 8; p ++) {
               if (j < 8) {
                       if (q2[j]^q[j])
                               return 0;
                       j ++;
               } else if (j == 8 ) {
                       q2 = q1;
                       for (j = 0; j < 8; j ++ ) {
                               if (i + j >= inlen) return 0;
                               q[j] ^= q1[j];
                       }
                       decrypt_qword((unsigned long *)q, key, (unsigned long *)
q);
                       i += 8;
                       q1 += 8;
                       j = 0;
               }
       }
       return 1;
}

算法模式简要概括如下:
   F(i) = P(i) + C(i-1)
   C(i) = E(Fi) + F(i-1)
   P是明文,C是密文,E是TEA算法,作用于8字节单元上。每次i增加1,就作用于一个8字节分组。

我们看到QQ的加密在算法模式上作了两个设计,其一引入随机字符作头部padding,这样基本保证同样的明文和密钥可以导致完全不同的加密结果。模式设计使得解密函数解密后可以准确抛弃掉这部分随机字。这个设计的确很好。但其模式在另一点上做的太差了,就是用返回值明确指出了解密的成功与否。

实际上至少两年前,水木清华的Crack版上,pure(青衣~ shadow in silence) 的文章就揭示了这一段代码,早已不是什么秘密了。我自己也跟踪得到了这样的东西,不过还是参考过Shufeng Tan的Net-OICQ-0.8,以及Puzzlebird为Gaim写的QQ插件OpenQ-0.3.1,至于lumaQQ就没看了,想来也就差不多了吧。
   
   事实上我还有一个猜想,32轮的TEA降低到16轮,肯定是出奇地危险,如果对算法破解有兴趣,那么可以看看下面这些参考书。
   1)John Kelsey,Bruce Schneier, David Wagner, “Related Cryptanalysis of 3-Way, Biham-DES, CAST, DES-X, NewDES, RC2, and TEA”
   2)Fauzan Mirza, “Block Ciphers And Cryptanalysis”
   3)VIKRAM REDDY ANDEM, “A CRYPTANALYSIS OF THE TINY ENCRYPTION ALGORITHM”

也许由于时间原因,技术能力所限,以上描述难免有偏颇不足或谬误之处,或者过时了。欢迎不吝赐教。doublelee[at.]etang.com 
全问题

QQ的安全问题 (www.team509.com)相关推荐

  1. 只有失去的时候,才知道它的珍贵,QQ成为不明真相的群众发泄怒火的最大牺牲品...

    360这款流氓软件,主动攻击,篡改QQ,以致于造成QQ无法正常登录,给无数的用户造成了巨大的麻烦.想想中国几亿用户,每天已经习惯开机上网,登录QQ,和好友,同学,同事,家人沟通.可以在群里交流,可以和 ...

  2. QQ聊天记录如何加密

    原文链接:http://www.baiyikeji.com/rjgc/265.htm QQ,就是OICQ,TENCENT公司研发的即时信息软件,是中国市场上国产IM软件绝对的老大.中国网民几乎人手至少 ...

  3. 360 PK QQ 始末

    题前 腾讯QQ 不知何时起,一只可爱的企鹅已经成为众多网民每日不可或缺的小宠物,根据官方数据,腾讯即时通讯服务的活跃账户数达6.125亿. 凭借庞大的用户规模和天然的客户端资源,腾讯也逐步将业务延伸到 ...

  4. 360 VS QQ:一场精心策划的西安事变(上)

    本文来自CSDN特约评论员:徐三清 我一向将公司比喻成国家,公司之间的竞争也很类似战争,国外网站曾经有一幅描述微软帝国的作战形势图就是例证.这次360和QQ之争,在中国软件互联网史上,是一场不折不扣的 ...

  5. 【CSDN 特稿】360 VS QQ:一场精心策划的西安事变

    [CSDN 特稿]360 VS QQ:一场精心策划的西安事变(上) 本文来自CSDN特约评论员:徐三清 我一向将公司比喻成国家,公司之间的竞争也很类似战争,国外网站曾经有一幅描述微软帝国的作战形势图就 ...

  6. 华夏时报:腾讯QQ如何监视你的?

    华夏时报:腾讯QQ如何监视你的? srw发布于2010-7-18 21:14:12 来源:华夏时报 阅读:1339 支持:31 反对:2 大 中 小 杭州的徐小姐是腾讯QQ的老用户了,不过,最近发生的 ...

  7. OAuth1.0介绍

    背景 为什么需要OAuth授权呢? 最典型的应用场景就是第三方登录了, 我们开发了一个网站希望用户可以QQ登录, 但是怎么能拿到用户的 QQ 信息呢? 用户将 账号密码告诉我们当然可以, 但是这样有如 ...

  8. Entity FrameWork中常用的数据修改方式

    http://buluo.qq.com/p/detail.html?bid=392683&pid=1192374-1505239292&2017.09.13/o936=dl http: ...

  9. 初探QQ空间本地安全问题!

    QQ用了好多年,但昨天才开通QQ空间,我一直感觉QQ空间太幼稚,太花,本身的博客系统也不成熟, 以前QQ空间是可以复制代码进行控制页面的,同时腾讯也开放了一些端口,但现在呢? 其实这正是腾讯对QQ空间 ...

最新文章

  1. WPF查找子控件和父控件方法
  2. 程序员们的时间管理法则
  3. 怎么做圆一圈圈扩散效果_推广为什么没有效果,网络推广怎么做才有效果?
  4. Cocoa如何应用设计模式
  5. Android NDK 编译选项设置[zhuan]
  6. 第一行代码:以太坊(1)-创建自己的私有区块链
  7. php 加密cer_php 生成RSA非对称加密用的证书-cer-pfx文件
  8. 5-5 用TSNE进行数据降维并展示聚类结果
  9. 数学推导题,NTT,快速数论变换,Wannafly-乒乓球
  10. 前端学习(578):chrome devtools
  11. php elements,wd elements se和wd elements的区别是什么
  12. 硬件基础知识---(17)如何设计一个三极管放大电路
  13. from mysql partition select_通过分区(Partition)提升MySQL性能[原创翻译]
  14. wps如何使用ppt美化大师_WPS的ppt一键美化软件怎么用
  15. 手游和平精英透视教学
  16. Video Caption(跨模态视频摘要/字幕生成)
  17. PHP设计聊天室步步通
  18. word根据标题自动生成目录
  19. 二等水准数据平差_二等水准测量方法与步骤
  20. java 三维数组 魔方_三维数组的横向/纵向输出

热门文章

  1. 支付宝和微信支付合作伙伴RiverPay加速全球化战略布局
  2. 星巴克——starbuck
  3. MSI_MSI-X中断之体验与使用
  4. 【看表情包学Linux】软件包管理器 yum | Vim 编辑器介绍 | Vim 文本批量化操作 | 配置 Vim
  5. 跟老杜手撕Spring6教程(三)Spring的入门程序
  6. JKS 密钥库使用专用格式。建议使用 “xxx“ 迁移到行业标准格式 PKCS12
  7. app上线——“游手乐”懂你的手游平台
  8. 通达信指标公式编写答疑汇总(二)
  9. 【求职】小米 2018 秋招测试开发工程师笔试题
  10. 曾仕强《领导的沟通艺术》