ZJL BLOG

On The Road ZJL

我的博客列表

2009年1月5日星期一

Alipay UED » Blog Archive » 也来谈谈”完美”跨域

Alipay UED » Blog Archive » 也来谈谈”完美”跨域: "适用面更广一些"

也来谈谈”完美”跨域

oldfish 发表于2008-12-17,12:04 1,271 Views

关于跨域这个话题,很早就答应过要分享,但是因为懒,一直拖着,直到D2上有人谈起了“完美跨域”。“跨域”应该已经算不上什么难题了,只是提起“完美”这两个字,突然觉得有了新意,那就写点什么吧,至少对自己有个交代嘛!跨域方案有很多,接下来一一枚举,会给出demo,demo的宗旨是尽可能简单的让新手明白,各方案中跨域的原理,实际应用请酌情修改。
方案一、剪贴板

原理:IE本身依附于windows平台的特性为我们提供了一种基于iframe,利用内存来“绕行”的方案,在这里我称之为,本地存储原理。

缺点:不支持非IE浏览器,并且影响到用户对剪贴板的操作,用户体验非常不好,特别是在IE7下,受安全等级影响,会弹出提示框。

演示:[ 点此阅览 ]

子页面在子域:demo.ioldfish.cn下,在页面中加入如下代码获取页面高度并存入剪贴板。

1.

主页面在主域:www.ioldfish.cn下,在页面中加入如下代码,获取剪贴板的值并赋值为子页面所在的iframe的高度。

1.

方案二、document.domain

原理:设置了document.domain,欺骗浏览器

缺点:无法实现不同主域之间的通讯。并且当在一个页面中还包含有其它的iframe时,会产生安全性异常,拒绝访问。

演示:[ 点此阅览 ]

主页面在主域:www.ioldfish.cn下,子页面在子域:demo.ioldfish.cn下,在两个页面的头部都加入如下代码:

1.

方案三、通过JS获取hash值实现通讯

原理:hash可以实现跨域传值实现跨域通讯。

缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。并且IE之外的浏览器遇到hash的改变会记录历史,影响浏览器的前进后退功能,体验不佳。

演示:[ 点此阅览 ]

子页面在主域:www.lzdaily.com下,在页面中添加如下代码,因为hash是不受跨域限制的,所以可以将本页面的高度顺利的传送给主页面的hash。

1.

主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,首先取得子页面传递过来的hash值,然后将hash值赋到子页面所在的iframe的高度上。

1.

方案四、传hash值实现通讯改良版

原理:该方案通过“前端代理”的方式,实现hash的传值,体验上比之方案三有了很大的提升。

缺点:对于父窗口URL参数动态生成的,处理过程比较复杂一些。

演示:[ 点此阅览 ]

子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先在页面里添加一个和主页面同域的iframe[也可动态生成],他的作用就像是个跳板。C页面中不需任何代码,只要确保有个页面就防止404错误就可以了!该方法通过修改iframe的name值同样可以跨域传值,只是比较”猥琐“而已。

1.

然后在页面中加上如下代码,利用页面C的URL接收hash值,并负责把hash值传给同域下的主页面。

1.

主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,获取从C页面中传递过来的hash值。这里应用到一个技巧,就是直接从A页面用frames["iId"].frames["iframeC"].location.hash,可以直接访问并获取C页面的hash值。这样一来,通过代理页面传递hash值,比起方案三,大大提高了用户体验。

1.

方案五、JSONP

原理:有点脚本注入的味道

缺点:服务器端程序运行比脚本早,跨域交互时无法捕获前端页面元素的相关数据,比如自适应高度。

演示:[ 点此阅览 ]

主页面在主域:www.ioldfish.cn下,在页面中添加如下代码,动态创建一个script,然后指定到子域的动态文件,在动态文件后面可以添加参数,在这里我加了一个回调函数,当请求返回后,会运行这个回调函数。

1.

子页面在主域:www.lzdaily.com下,在页面中添加如下代码,首先先取得主页面传过来的回调函数名,然后生成一段 javascript代码,以回调函数带参数的形式返回主页面,这样就完成了跨域之间的通讯。由于服务器端程序执行总是优先于javascript代码,所以基本上没办法获取到子页面中DOM的相关数据,所以小白同学,我可以很负责人的告诉你,想通过这种方法实现跨域自适应高度是不可能的!

1.

方案六、window.name

原理:window.name本身并不能实现跨域,只是中间做了代理。

缺点:获取异域的前端页面元素值有一定局限性,比如取自适应高度的值。但是此方法在前端页面元素的数据交互上明显比JSONP强。

演示:[ 点此阅览 ]

这个方案,YAHOO的同事已经给出了详细的demo,我就不重复了,演示demo出自YAHOO克军之手。详细的说明可以参看“怿飞的BLOG”,个人觉得方案四比window.name适用面更广一些。
方案七、window.navigator

原理:window.navigator这个对象是在所有的Iframe中均可以访问的对象。应该是IE的一个漏洞!

缺点:不支持IE外的浏览器下的跨域。严格的dtd申明后,该方法失效!

演示:[ 点此阅览 ]

主页面在主域:www.ioldfish.cn下,首先先申明一个Json用来保存所有页面的高度window.navigator.PagesHeight={”":0};,然后根据name的属性找到页面的数据window.navigator.getData,最后将页面的数据注册到window.navigator.PagesHeight中。这里还定义了一个函数resetIframeData,在页面加载的时候调用它,完成跨域的数据交互。注释中详细说明了参数的作用。

1.

子页面在主域:www.lzdaily.com下,获取到页面高度后,将高度存到主页定义的Json中,Json标识为”PortalData”,这里可以自定义。

1.

其实通过css也可以实现跨域,数据获取的实质其实就是动态载入一段CSS,然后解析其中的字段提取数据,这个方法比较“猥琐”,再这里就不多介绍了,当然flash也可以实现跨域,只是还没去实践,实践完了再补充。啥时候能补完呢?恩……

以上这么多方案,有可以“完美跨域”的吗?单一的看,我想没有吧,都有缺陷,但是只要不同情况下使用合适的方法,我想这才是最完美的!原来绕了一圈,我只是再说废话,哎!不论怎么样,还是希望这些废话对还在苦苦追求“完美”的同学们有所启发!

Tags: jsonp, window.name, window.navigator, 跨域

星期三, 12月 17th, 2008 前端技术.

1. uidesigner
12月 17th, 2008 at 20:48

沙发,好多选择哦,哪个方案好呢?
2. 老鱼
12月 18th, 2008 at 10:37

最适合你的,才是最好的阿,哈哈,看你是什么应用场景了!
3. 刘镇维
12月 23rd, 2008 at 12:54

从方案4得到启发,如果可以修改页面4的内容的话,做如下修改就可以实时向父页面传递参数了。

function test(){
var str=location.hash;
parent.parent.test(str);
}
4. 刘镇维
12月 23rd, 2008 at 12:56

window.onload=test;

刚才漏了一句

跨域的iframe操作 - ①兲的耐情 - JavaEye技术网站

跨域的iframe操作 - ①兲的耐情 - JavaEye技术网站

下面直接帖上网上找到的那篇文章(怕这个链接失效)
来自:http://hily.me/blog/2006/11/special-domain-data-fetch/。

引用
浏览器跨域获取特定域的数据的办法
以前看了几篇这方面的文章,但是都未能找到一个合适的解决方法。
获取同一个域的数据,可以通过XMLHTTP组件或IFRAME来实现,不存在跨域访问的权限问题,因此比较简单。
但如果要访问不同域的数据时,由于浏览器的安全设置,XMLHTTP没有权限获取数据,而IFRAME没有权限将获取的数据传递给父窗口,似乎没有其它解决办法。
在网上提到的方法,不外乎这两种:
1. 如果要获取的数据位于同一个根域但是不同子域时,可以在脚本中指定document.domain为父域。
2. 如果要获取的数据位于不同的根域时,则可以在服务器上写一个脚本作为代理,由服务器上的脚本获取不同域的数据,然后传递给在同一个域中的网页。
以上两种方法很容易便能想到,现在的问题是,如果要获取一个不同根域的数据时,该如何实现?

一般我们不会漫无目的地去网上获取数据,往往是从指定的服务器上获取数据,就像Google Maps、Google Adsense和referer这样的网页插件,一般都是以脚本的形式提供给用户使用的。这时,如果要求用户在自己的服务器上写个代理的话,易用性就要大打折扣。获取你会考虑为用户写好各种脚本的代理,PHP、ASP、Python、Perl……,但是,如果这台服务器不支持动态脚本,又该怎么办呢?
想了两天都没想通这个问题(除去上班时间其实不到两个小时),曾考虑过用浏览器的漏洞来实现,但是这样做不能长久,因此放弃。随后发现Google本地搜索的地图数据来自于mapabc.com,好家伙,他们是怎么办到的?
用FireFox的DOM查看器可以看到,地图区是一个IFRAME,难道是用IFRAME实现的?但是拖动地图时如何知道要下载哪些图片的?这些数据是一定要从服务器上获取的,难道放这些数据的服务器也是google.com域内的?应该不会这么麻烦。
随即找来Google Maps的API进行开刀,官网给的范例网页如下:


Java代码 复制代码

1. 2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3.
4.
5.
6. Google Maps JavaScript API Example
7.
9.
19.
20.
21.

22.
23.
24.
25.
26.
27. 把http://maps.google.com/maps?file=api&v=2&key=abcdefg下载下来看了一下,里面有一句:
28.
29.
30. GScript("http://maps.google.com/mapfiles/maps2.67.api.js");
31.
32. 这句就是用来加载地图操作库的,GScript函数定义为:
33.
34. function GScript(src) {document.write('');}

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">



Google Maps JavaScript API Example










把http://maps.google.com/maps?file=api&v=2&key=abcdefg下载下来看了一下,里面有一句:


GScript("http://maps.google.com/mapfiles/maps2.67.api.js");

这句就是用来加载地图操作库的,GScript函数定义为:

function GScript(src) {document.write('');}


顿悟……
网页内引用不同域的脚本并不会提示权限不足,对了,就是它没错!
这个方法其实我早应该想到的,可能是太久没玩javascript的缘故吧。不论是referer还是Google Analytics,要统计页面访问信息,都要用脚本来向服务器提交信息,只是它们只提交一次(Google Analytics有统计逗留时间,应该有好几次)。习惯性地,我把提交和下载数据分开了,所以不容易想到这个方法。
但是用document.write始终不是好办法,它会清除页面上原有的内容。改进的方法估计你已经想到了,可以参考一下我很早以前乱写的这篇文章《有效地组织页面中复杂的JavaScript脚本》里的思想。
继续分析Google Maps的代码,打开http://maps.google.com/mapfiles/maps2.67.api.js,里面有这样的代码:

Java代码 复制代码

1. ta.prototype.Hk=function(a,b){var c=this.ql(a);if(c){window.setTimeout(function(){b(c)},
2. 0)}else{var d="__cg"+Zf++ +(new Date).getTime();
3. try{if(this.qe==null){this.qe=document.getElementsByTagName("head")[0]}
4. var e=window.setTimeout(sd(d,b,a,403),15000);
5. if(!window.__geoStore){window.__geoStore={}}window.__geoStore[d]=Jf(this,d,b,e);
6. var f=document.createElement("script");f.type="text/javascript";
7. f.id=d;f.charset="UTF-8";
8. f.src=this.vl+"?q="+window.encodeURIComponent(a)+"&output=json&callback=__geoStore."+d+"&key="+this.Lh;
9. this.qe.appendChild(f)}catch(g){if(e){window.clearTimeout(e)}window.setTimeout(sd(d,
10. b,a,500),0)}}};

ta.prototype.Hk=function(a,b){var c=this.ql(a);if(c){window.setTimeout(function(){b(c)},
0)}else{var d="__cg"+Zf++ +(new Date).getTime();
try{if(this.qe==null){this.qe=document.getElementsByTagName("head")[0]}
var e=window.setTimeout(sd(d,b,a,403),15000);
if(!window.__geoStore){window.__geoStore={}}window.__geoStore[d]=Jf(this,d,b,e);
var f=document.createElement("script");f.type="text/javascript";
f.id=d;f.charset="UTF-8";
f.src=this.vl+"?q="+window.encodeURIComponent(a)+"&output=json&callback=__geoStore."+d+"&key="+this.Lh;
this.qe.appendChild(f)}catch(g){if(e){window.clearTimeout(e)}window.setTimeout(sd(d,
b,a,500),0)}}};



script节点也是动态创建的,这样就可以避免document.write产生的问题。


解决方法找到了,现在来简单测试一下:
1. 在本地服务器上新建一页面。
test.html:


Java代码 复制代码

1.
2.
3. Over-Domain Data Fetching Test Page
4.
19.
20.
21.

22.

23. My Name:

24. My Blog:
25.
26.



Over-Domain Data Fetching Test Page







My Name:

My Blog:




解释两个关键点:
1. lastScript用于存放上次建立的script节点的ID,在下次要再新建script节点时,要删除上次建立的节点,以免加载的脚本越来越多,占用过多的内存。
2. url后面加了一个数值d是为了防止浏览器缓存脚本数据,在本例中可以不加,但是如果脚本是由服务器动态生成的,那最好加上。
然后再建立两个javascript脚本用于测试:
alert.js:

Java代码 复制代码

1. alert('You can see me!');

alert('You can see me!');


info.js:

Java代码 复制代码

1. g('myname').value='Hily Jiang';
2. g('myblog').value='http://hily.iyi.cn/';

g('myname').value='Hily Jiang';
g('myblog').value='http://hily.iyi.cn/';


好了,把它们放在本地服务器的根目录下,敲入http://127.0.0.1/test.html,这样它和localhost就不在同一个域内了。
点击“Test Alert”,应该会弹出对话框显示You can see me!。
点击“Get My Info”,应该会在文本框中显示我的信息。
(以上测试页在IE 6.0和FireFox1 .5.0下测试通过。)

跨域问题解决方案 - 朱燚 - 博客园

跨域问题解决方案 - 朱燚 - 博客园

转自:http://blog.csdn.net/lenel

关于跨域名问题还是问题么,这方面的解决实践非常多,今天我就旧话重提把我所知道的通过几个应用场景来分别总结一下(转帖请注明出处:http://blog.csdn.net/lenel)

先说明一点:我说的某某域名在您的控制下的意思是这个域名下的网页由您来负责开发内部的JavaScript
场景一:将bbs.xxx.com的页面用iframe嵌入到www.xxx.com的中,如何在iframe内外使用js通信(转帖请注明出处:http://blog.csdn.net/lenel)
一级域名都是xxx.com 这个域名一定是在您的控制下,所以你只要在两个页面中同时升级域名即可
在父窗口和iframe内部分别加上js语句:document.domain="xxx.com";
之后2个页面就等于在同一域名下,通过window.parent oIframe.contentDocument就可以相互访问,进行无障碍的JS通信
在新浪、淘宝等很多页面都能找到这样的语句。不过document.domain不可以随便指定,只能向上升级,从bbs.xxx.com升级到yyy.com肯定会出错

场景二:将www.yyy.com的页面用iframe嵌入到www.xxx.com的中,两个域名都在您的控制下,如何在iframe内外进行一定的数据交流(转帖请注明出处:http://blog.csdn.net/lenel)
你可以通过相互改变hash值的方式来进行一些数据的通信

这里的实现基于如下技术要点:
1、父窗口通过改变子窗口的src中的hash值把一部分信息传入,如果src只有hash部分改变,那么子窗口是不会重新载入的。
2、子窗口可以重写父窗口的location.href,但是注意这里子窗口无法读取而只能重写location.href所以要求前提是您控制两个域名,知道当前父窗口的location.href是什么并写在子窗口内,这样通过parent.location.href = "已知的父窗口的href"+"#"+hash。这样父窗口只有hash改变也不会重载。
3、上面两步分别做到了两个窗口之间的无刷新数据通知,那么下面的来说如何感知数据变化。标准中没有相关规定,所以当前的任意浏览器遇到 location.hash变化都不会触发任何javaScript事件,也就是说您要自己写监听函数来监视loaction.hash的值的变化。做法是通过setTimeout或者setInterval来写一个监听函数每20-100ms查看一下hash是否变化,如果变化了驱动js根据新的数据做想做的事情。

这种实现的一些分析:
1、信息通道是双向的,当然会兼容单向,如果只是父窗口向子窗口通知数据,只需要子窗口写hash监听,反之亦然。
2、局限性也是颇大,因为这种通信的前提是双方知道对方的location.href。如果父窗口带有动态的location.search也就是查询参数,那么子窗口的处理上就比较困难,需要把父窗口的location.search作为传递信息的一部分告知子窗口。
3、另外的困扰会有浏览器带给你,IE之外的浏览器遇到hash的改变会记录历史,这样你在处理前进后退的时候会非常头疼


场景三:将www.yyy.com的页面用iframe嵌入到www.xxx.com的中,只有被嵌入的yyy.com在您的控制下,如何在iframe内外进行一定的交流
真实场景:google adsence的一个需求,你希望google发现您的页面不能匹配出相关性非常好的按点击付费广告时,你希望google的广告iframe能够隐藏。
google的广告iframe在google域下显然不能把自己隐藏掉,那么怎么办呢?
1、google会提供给你一个html页面
2、您将这个页面放置在您的域名下,并告诉google它的位置
3、当google发现没有很好的广告时,会将子窗口的loaction重定向到您的那个页面下,这样您的页面因为同域名就可以访问父页面来隐藏自己了
是不是很巧的方法?

场景四:您是内容发布商,如何改造接口,让其他域名下的页面可以从浏览器端出发获得您的数据
我们知道ajax的xmlHttpRequest()说到底是一个无刷新请求服务器数据的辅助工具,但是xmlHttpRequest并不能跨域名请求数据,在某些情况下成了极大的限制。
但是我们如果通过其他方式完成无刷新请求数据不也可以么,我们用Dom方法操作动态JS脚本请求来做这件事。
//创建一个脚本节点
var oScript = document.createElement('script');
//指定脚本src src可以指向任意域名
//注意src不再指向静态js,而是带着查询参数指向一个动态脚本广播服务。
oScript.src = "http://yyy.com/query.php?"+yourQueryString;
//如果指定了charset 同时还可以解决xmlHttpRequest另一大困扰 乱码问题
//oScript.charset = "utf-8";
//通过Dom操作把这个新的节点加入到文档当中
document.getElementsByTagName("head")[0].appendChild(oScript);

这样只要query.php的输出是可执行的javaScript脚本,比如:djsCallBack({jsondata});
当他从服务器返回后就会自动执行,你可以方便的用json方式来做数据传递了。
要注意,您的脚本请求最好带上时间戳,避免浏览器缓存造成取回数据实时性下降。

如果您是数据提供者,您可以要求数据索取者在查询参数中提供回调函数名,比如query.php?callback=myDataHandler&key=...?
这样您就可以根据参数来提供给他myDataHandler({jsondata}),这样不同的数据索取者都会得到自定义的正确的异步回调。

进一步发展,可以做一个统一的从xml到动态json的数据转化服务器,脱离数据的实际意义,针对任何xml接口都可以作为转化后提供给客户端直接访问。
这样就不用针对单独xml数据服务,为了跨域名而做各自的后台数据抓取转化服务。

用动态脚本传数据功能非常强大,去年我最先在YAHOO的站点上看到这样的应用,让人眼前一亮。

总结总结:
第一种场景,相应的处理办法有这非常好的效果,可以说完全解决了问题。
第二种场景,相应的处理办法具有一定的跨域数据交流功效,具有相当大的局限,并不适合在复杂业务流程中应用,实际上我也确实也没看到过基于此的大规模应用。
第三种场景,相应的处理办法比较巧妙,虽然redirect之后就不干你什么事了,但如果你是google一样面向众多域名的内容提供商,也是个不错的解决思路。
第四种场景,相应的处理办法非常强大,对比Ajax可以看到,跨域名没问题,无刷新没问题,本身又是异步的,JSON比xml快的多,同时解决乱码问题,只是请求都是Get方式的,不能做Post方式的请求。多一种武器自然可以从容选择了。(转帖请注明出处:http://blog.csdn.net/lenel)

剪贴板实现跨域iframe高度自适应 @ 阅微堂

剪贴板实现跨域iframe高度自适应 @ 阅微堂
剪贴板实现跨域iframe高度自适应
zhiqiang10月 9, 2006 IT技术

这两天玩xiaonei用到的一个技术,虽说是跨域iframe,但要求对外部网页和内部网页都有编辑权限,所以只能用在一些特殊场合。

如果是域内的iframe,高度自适应非常简单,给iframe加入onload属性即可:



这样的方法,baidu一下有很多,一些复杂的方式考虑了浏览器差异等,某些情况下更有效更稳定。不过为安全因素,所有游览器都禁止了不同顶级域名的iframe与其父窗口之间的通信,上面的方法也全失效了。

在http://www.ikown.com/html/show-id-106.html提到另一种实现的技巧,不过需要完全征用用户的剪贴板,后来在code的提示下,可以在基本不影响用户剪贴板使用的情况下,做同样的事情。完整代码如下:



下面是http://othersite/a.html的代码


i love it.

2009年1月4日星期日

ActiveX 控件漏洞挖掘入门_悦来客栈-baidu分栈

【原创】ActiveX 控件漏洞挖掘入门
http://hi.baidu.com/bybabbitt/blog/item/ee5aedbfb73ff90d19d81fac.html
标 题: ActiveX控件漏洞挖掘入门
作 者: k7zj
时 间: 2008-03-27,14:52

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

【文章标题】: ActiveX控件漏洞挖掘入门
【文章作者】: k7zj
【作者邮箱】: k7zjmost@21cn.com
【编写语言】: html etc.
【使用工具】: COMRaider
【操作平台】: WINXP SP2
【作者声明】: 其实是看了一篇文章《ActiveX-ActiveExploitation》以及一些常见的ActiveX漏洞挖掘过程,想对这方面的东西做点小小的总结,权当作入门的东西,勉强算是原创吧。。。

【基础介绍】
ActiveX是微软在1996年引入,是基于COM组件和OLE的。COM组件开发的目的是为了简化代码的重用,通过建立带有接口的对象,它们能被其他 COM足见以及程序调用,IE里面经常用到这样的技术。因此COM组件被广泛用于开发浏览器的第三方应用程序,其实也就是插件。但由于现在有的第三方开发人员编程方面的原因,控件出现越来越多的漏洞能被恶意的网站来利用,通过溢出或者是功能代码的注入来侵害个人电脑。
ActiveX控件被利用多出现在2个方面:第一就是其导出函数可能具有的隐蔽的功能,比如操作注册表,读写文件等等,还有就是控件本身一些函数在处理参数的时候出现了参数长度未检查造成溢出的情况。恶意的网站如果在网站上安装了有漏洞的COM组件,而用户毫不知情的情况下访问很容易被入侵。
ActiveX控件被浏览器调用实例化的条件是:它是被标记了可安全执行脚本(as safe for scripting)。要判断其是否为可安全执行脚本,只需在注册表中对应的CLSID项下查看是否有Implemented Categories此项即可。

【FUZZ工具介绍】
目前FUZZ ActiveX控件比较好的工具是COMRaider.

【如何跟踪COM组件的接口】
首先来讲些基础知识:
IDispatch接口如下:
interface IDispatch:IUnknow
{
virtual HRESULT GetTypeInfoCount(UINT *pctinfo) = 0;
virtual HRESULT GetTypeInfo(UINT itinfo,LCID lcid,ITypeInfo **pptinfo) = 0;
virtual HRESULT GetIDsOfNames (
REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid) = 0;
virtual HRESULT Invoke(
DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr) = 0;
}
1.GetTypeInfoConut(): 用于获取自动化组件支持的ITypeInfo接口的数目。
2.GetTypeInfo(): 用于获取指针ITypeInfo接口的指针,通过该指针将能够判断自动化服务程序所提供的自动化支持。
3.GetIdsofNames(): 读取一个函数的名称并返回其调度ID(DISPID).
DISPID *rgdispid是一个long类型的数据,对于IDispatch的一个特定实现,此DISPID值应该是唯一的。REFIID riid:为保留参数,不许设置为IID_NULL,在rgszNames中指定了成员函数名及其参数,由cNames标识了名字的个数,lcid参数用于指定本地化标识,得到的DISPID将保存到rgdispid中。
4.Invoke(): 提供了访问自动化对象暴露出来的方法和属性的方法。
将DISPID作为函数指针数组的索引传入dispidMember参数,Invoke()将实现一组按此索引来访问的函数。riid和lcid的含义与在GetIDsOfNames()中的定义相同,分别为保留参数和本地化标识。
WORD wFlags: 指定了要访问的是接口的属性还是方法
DISPPARMS* pdispparams:包括了方法和属性调用的参数数组、DISPID数组以及数组中参数个数等信息。
VARIANT* pvarResult: 保存返回值信息。
EXCEPINFO* pexcepinfo: 指向一个有效的异常信息结构。
UINT * PuArgErr: 包含了第一个产生错误的参数指针。

综合以上,可以了解到:通过GetIDsOfNames()和Invoke()的结合使用,将可以根据函数名称对方法和属性进行调用。这样,函数地址、AddRef()、Release()以及接口指针等细节问题将无需考虑。
基于以上的分析,对于COM里面某个函数的定位思路是:由于在调用COM里面某个函数时,会去分发,然后再调用COM里面的函数,那么,我们就在它分发的时候先把它拦截下来,之后再单步跟入某个函数。
关键函数:DispCallFunc,位于OLEAUT32.dll。在DispCallFunc函数一直“步过”,直到见到Call ecx时,我们就来到了进入COM里面某个函数的边缘了!就差一步“步进”,就来到了COM里面的某个函数的入口点了。

【如何跟踪COM组件的接口--示例】
使用工具: COMRaider
目标: COMRaider里含有的vuln.dll

1. 首先注册vuln.dll
如图(点击放大):

2.运行COMRaider,选择开始并直接fuzz vuln.dll
如图(点击放大):

3.选择Method3开始“Fuzz member”
如图(点击放大):

4.点击Next后出现了很多文件,随便选择一个点右键“Launch in Olly”
如图(点击放大):

5.被ollydbg加载后出现在入口点。首先查看可执行模块,因为前面说过DispCallFunc位于OLEAUT32.dll,所以直接查看 OLEAUT32.dll,双击OLEAUT32那条,然后ctrl+n,在DispCallFun下断点即可。
如图(点击放大):



6.下好断点以后F9运行,会停在DispCallFunc这里,然后单步走。
如图(点击放大):

7.F8单步,直到看见Call ecx的时候单步步入,就到了被分发函数的入口了。
如图(点击放大):


这样就找了调试那个函数的入口,就可以自己调试了。

【再一个示例】
这次使用method1的函数,可以观察由COMRaider生成的fuzz文件(我的是在跟com-dll一个目录下)。

注意红色部分,表示填充的参数为3092个,该脚本通过调用mehod1来弹出一个显示3092个A的对话框,但是由于参数太多,导致溢出。双击文件可见结果如下:


可见是被A字符串所溢出。

【该部分小结】
COMRaider的目的就可以根据接口所提供的参数类型构造不同的FUZZ脚本,比如说method1的参数是string,则COMRaider就构造超长字符串的参数的脚本来fuzz,并且还能通过调试器来调试。

【其他类型的漏洞】
ActiveX控件提供了丰富的接口来操作,但是有的接口可能会被不法的人来利用干坏事。下面就举一个例子来演示ActiveX在这方面的破坏性。
这是一个2007年9月报出的漏洞。
QRcode ActiveX中的SaveAsBMW () 和 SaveAsWMF()可以储存任何文件类型的文件。那意味着它可以修改系统的配置文件以及做很多坏事。
还是先用COMRaider来看看。
选择MW6QRCode.dll,查看
这2个函数存在。
其实如何找到这2个函数有漏洞存在还是需要尝试去调用。这里过程是艰巨的,我还是直接给出EXP,是在www.milW0rm.org上找的。
是个网页形式的,上面有说明,点击以后会在系统目录下生成system_.ini文件,如果别有用意的人可能会写点可执行程序等等,病毒啊,木马啊甚至rootkit....那到时候就不堪设想了。

【总结】
可见挖掘软件漏洞是个非常困难的工程,要求掌握很多的知识,对于挖掘ActiveX的漏洞我之前并没有太多的认识。这篇算勉强算是ActiveX漏洞发掘的入门篇吧,说白了就是一些总结,因为好多东西都是在网上找的,所以有什么不对的地方,还希望能够多多指出。希望大家一起交流。

参考文献: 《 ActiveX-ActiveExploitation》
Milw0rm: http://www.milw0rm.com/exploits/4420

2008年11月24日星期一

優化XP設定

優化XP設定: "在〔控制台〕→〔電話和數據機選項〕→〔數據機〕→〔進階〕"
優化 Windows XP 設定
優先使用實際記憶加快系統速度 善用 CPU 的 L2 Cache 加快整體效能
關機時自動關閉停止回應程式 加快預讀能力改善開機速度
加快開機及關機速度 自動關閉停止回應程式
清除記憶體內被不用的DLL文件 加快寬頻連接速度
加快菜單顯示速度 加快自動更新率
使用微軟 Bootvis.exe 優化啟動速 移除啟動時載入不需要的程式
停用不需要的服務 關閉 XP 內設的燒碟功能
在啟動電腦時執行 Defrag 程式 減少多重啟動時等待時間
減少寬頻網卡在開機時等待的時間 加快撥號上網的撥號速度

優先使用實際記憶加快系統速度
如果你的系統具備 256MB 或以上的記憶體可按下列辦法調整
可加快系統的運行速度
在〔開始〕→〔執行〕→〔Regedit〕→〔HKKEY_LOCAL_MACHINE〕
→〔SYSTEM〕→〔CurrentControlSet〕→〔Control〕→〔Session Manager〕
→在〔Memory Management〕的右手邊視窗
將〔DisablePagingExecutive〕的〔Dword〕值由預設的〔0〕改為〔1〕
重新開機後生效
如由預設值設定為〔0〕則代表停用此功能
Registry Editor Example
DisablePagingExecutive REG_DWORD 0x00000001(1)
...HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

加快開機及關機速度
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_CURRENT_USER〕→〔Control Panel〕→〔Desktop〕
→將字串值〔HungAppTimeout〕的數值資料更改為〔200〕
→將字串值〔WaitToKillAppTimeout〕的數值資料更改為〔1000〕
Registry Editor Example
HungAppTimeout REG_SZ 200
WaitToKillAppTimeout REG_SZ 1000
我的電腦\HKEY_CURRENT_USER\Control Panel\Desktop

另在〔HKEY_LOCAL_MACHINE〕→〔System〕→〔CurrentControlSet〕→〔Control〕
→將字串值〔HungAppTimeout〕的數值資料更改為〔200〕
→將字串值〔WaitToKillServiceTimeout〕的數值資料更改為〔1000〕

Registry Editor Example
HungAppTimeout REG_SZ 200
WaitToKillServiceTimeout REG_SZ 1000
我的電腦\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control

自動關閉停止回應程式
在〔開始〕→〔執行〕→鍵入〔Regedit〕
→〔HKEY_CURRENT_USER〕→〔Control Panel〕→〔Desktop〕
→將字串值〔AutoEndTasks〕的數值資料更改為〔1〕
→重新開機便生效
Registry Editor Example
(預設值) REG_SZ (數值未設定)
AutoEndTasks REG_SZ 1
我的電腦\HKEY_CURRENT_USER\Control Panel\Desktop

清除記憶體內被不用的DLL文件
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKKEY_LOCAL_MACHINE〕
→〔SOFTWARE〕→〔Microsoft〕→〔Windows〕→〔CurrentVersion〕→〔Explorer〕
增加一個機碼〔AlwaysUnloadDLL〕預設值為〔1〕
如由預設值設定為〔0〕則代表停用此功能
Registry Editor Example
(預設值) REG_SZ 1
...\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\AlwaysUnloadDLL

加快寬頻連接速度
在〔開始〕→〔執行〕→鍵入〔gpedit.msc〕打開〔本機管理原則〕→〔電腦設定〕
→〔系統管理範本〕→〔Network〕→在右邊窗口打開〔QoS Packet Scheduler〕
→〔limit reservable bandwidth〕→選〔已啟用〕
→將〔Bandwidth limit %" 〕的數據改為〔0〕→重新開機便生效
* 僅適用用 Windows XP 商業版版本

家用版可按下執行
在〔開始〕→〔執行〕→鍵入〔regedit〕→在〔HKEY_LOCAL_MACHINE〕
→〔SOFTWARE〕→〔Policies〕→〔Microsoft〕 →〔Windows〕
增加一個名為〔Psched〕的機碼
在〔Psched〕右面窗口增加一個 Dword 值〔NonBestEffortLimit〕數值資料為〔0〕

Registry Editor Example
(預設值) REG_SZ (數值未設定)
NonBestEffortLimit REG_DWORD 0x00000000(0)
我的電腦\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Psched

加快菜單顯示速度
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_CURRENT_USER〕→〔Control Panel〕
→〔Desktop〕→將字串值〔MenuShowDelay〕的數值資料更改為〔0〕
調整後如覺得菜單顯示速度太快而不適應者可將〔MenuShowDelay〕的數值資料更改為〔200〕
→重新開機便生效
Registry Editor Example
(預設值) REG_SZ (數值未設定)
MenuShowDelay REG_SZ 200
我的電腦\HKEY_CURRENT_USER\Control Panel\Desktop

加快自動更新率
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_LOCAL_MACHINE〕→〔System〕
→〔CurrentControlSet〕→〔Control〕→〔Update〕
→將 Dword〔UpdateMode〕的數值資料更改為〔0〕
→重新開機便生效
Registry Editor Example
(預設值) REG_SZ (數值未設定)
UpdateMode REG_DWORD 0x00000000(0)
我的電腦\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Update

使用微軟 Bootvis.exe 優化啟動速度
下載 bootVis.exe檔案,然後解壓後執行 〔bootvis.exe〕
→ 之後在〔Trace〕選〔next boot + driver delays〕或其他選擇項目後XP會重新啟動,
並將記錄啟動資料產生成 BIN 的文件。再在〔Bootvis.exe〕→〔file〕
→〔open〕中打開這個文件→在〔Trace〕→選〔Optimize system〕
此優化需時頗長,請奈心等待

移除啟動時載入不需要的程式
如開機時太多程序要執行時會影響開機的速度,先檢查那些檔案會在開機時執行
在〔開始〕→〔執行〕→鍵入〔msconfig〕→選〔啟動〕
在啟動內的程式是代表開機時要執行的程式,如須暫時停止執行某須些程式
便取消在〔□〕的〔X〕符號便可,如想恢復開機時執行此程式在〔□〕內加回〔X〕符號便可
如希望徹底移除者在〔msconfig〕→〔啟動〕的左邊欄〔位置〕上便顯示引導程式執行的位置
其中
1. HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
其中的〔HKLM〕代表登錄檔上的〔HKEY_LOCAL_MACHINE〕
在〔Run〕的右邊視窗不需要的項目刪除
2. HKCU\Software\Microsoft\Windows\CurrentVersion\Run
其中的〔HKCU〕代表登錄檔上的〔HKEY_CURRENT_USER〕
在〔Run〕的右邊視窗不需要的項目刪除
3. SOFTWARE\Microsoft\Windows\CurrentVersion\Run
則代表登錄檔的路徑如下
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\MSConfig\startupreg
檢查在〔startupreg〕下的路徑,將不需要的項目刪除
4. Common Startup
代表在〔開始〕→〔所有程式〕→〔啟動〕的程式
只要在取消在〔msconfig〕→〔啟動〕內〔□〕不選〔X〕符號便會代為將程式移離〔啟動〕

停用不需要的服務
在〔開始〕→〔執行〕→鍵入〔services.msc〕→
檢查右邊窗口將不需要的服務在〔啟動類型〕內選〔停用〕
→再在〔服務狀態〕中選〔停止〕

加快預讀能力改善開機速度
Windows XP 預讀設定可提高系統速度,加快開機速度。
按下修改可進一步善用 CPU 的效率
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_LOCAL_MACHINE〕
→〔SYSTEM〕→〔CurrentControlSet〕→〔Control〕→〔SessionManager〕
→〔MemoryManagement〕→在〔PrefetchParameters〕右邊視窗
將〔EnablePrefetcher〕的數值資料如下更改
如使用 PIII 800MHz 以上的可嘗試將數值資料更改為〔4〕或〔5〕
否則建議保留數值資料為預設值即〔3〕
更新 SP-1 後如運行不暢順者請將數值資料改回〔3〕
Registry Editor Example
(預設值) REG_SZ (數值未設定)
EnablePrefetcher REG_DWORD 0x00000005(5)
....\HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters

善用 CPU 的 L2 Cache 加快整體效能
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_LOCAL_MACHINE〕
→〔SYSTEM〕→〔CurrentControlSet〕→〔Control〕→〔SessionManager〕
→在〔MemoryManagement〕的右邊視窗
將〔SecondLevelDataCache〕的數值資料更改為與 CPU L2 Cache 相同的十進制數值
例:P4 1.6G 的 L2 Cache 為 256Kb,數值資料更改為十進制數值 256
有關 L2 Cache 的數值並非如某些不負責任的網頁亂抄過來
例如 P4 1.6G 的 L2 Cache 為 256Kb,但 P4 1.6GA 的 L2 Cache 為 512Kb
如須取得有關 CPU 的 L2 Cache 的資料,可到此一看
Registry Editor Example
(預設值) REG_SZ (數值未設定)
SecondLevelDataCache REG_DWORD 0x00000100(256)
....HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management

在啟動電腦時執行 Defrag 程式
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_LOCAL_MACHINE〕
→〔SOFTWARE〕→〔Microsoft〕→〔Dfrg〕→〔BootOptimizeFunction 〕
將字串值〔Enable〕設定為〔Y〕等於開啟而設定為〔N〕等於關閉
Registry Editor Example
(預設值) REG_SZ (數值未設定)
Enable REG_SZ Y
我的電腦\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Dfrg\BootOptimizeFunction

減少多重啟動時等待時間
用 Notepad 打開在 C:\ 目錄下的 boot.ini 檔案,將內容〔timeout〕
的設定值由預設的 30 (秒) 改為要求等待的秒數數字,存檔

關閉 XP 內設的燒碟功能
如果不打算使用此功能可將其關閉,可加快使用 Nero 燒錄軟件的速度
因 Windows XP 的燒錄系統由 Roxio 公司提供 (即與 Easy Cd Creator 同公司)
在〔控制台〕→〔系統管理工具〕→〔服務〕→在右變窗口選
〔IMAPI CD-Burning COM Service〕→〔啟動類型〕→選〔已停用〕

加快撥號上網的撥號速度
在〔控制台〕→〔電話和數據機選項〕→〔數據機〕→〔進階〕
在〔外加初始化命令〕上填上〔s11=50〕

關機時自動關閉停止回應程式
在〔開始〕→〔執行〕→鍵入〔Regedit〕→〔HKEY_USERS〕→〔.DEFAULT〕→〔Control Panel〕
→在〔Desktop〕右面窗口將〔AutoEndTasks〕的數值資料改為〔1〕
登出或重新啟動
Registry Editor Example
(預設值) REG_SZ (數值未設定)
AutoEndTasks REG_SZ 1
我的電腦\HKEY_USERS\.DEFAULT\Control Panel\Desktop

減少寬頻網卡在開機時等待的時間
如果是使用 ADSL 寬頻上網者可作下列調整
在〔開始〕→〔連線到〕→〔顯示所有連線〕
鼠標右點〔Local Area Connections〕→〔內容〕
→點選〔Internet Protocol TCP/IP〕→按〔內容〕按鈕
→在〔IP位址〕輸入〔192.168.0.1〕及
→〔子網路遮罩〕輸入〔255.255.255.0〕

AL8 Forum 貴賓論壇之家 Alexa Certified Site Stats for www.alan888.com 千禧科技城-電腦新知、軟件情 報、網上學堂、聊天室、留言及校外論壇等等 PHPwind 討論區 - 演示用