nextdoor 发表于 2014-8-8 16:57:45

对某bbs论坛的简单审计2(跨站和越权漏洞)

001x 跨站漏洞

首先我们说说一下跨站漏洞吧
       
//这两个类addBbs和answerBbs主要的作用是发帖和回帖的,当把数据插入数据库时进行了过滤,是Change下的HTMLChange函数
public ActionForward addBbs(ActionMapping mapping, ActionForm form, httpervletRequest request, httpervletResponse response){
                httpession session=request.getSession();               
                session.setAttribute("mainPage","/pages/add/bbsAdd.jsp");
               
                String validate=request.getParameter("validate");
                if(validate==null||validate.equals("")||!validate.equals("yes")){
                        return mapping.findForward("showAddJSP");
                }
                else{                       
                        BbsForm bbsForm=(BbsForm)form;
                       
                        String        boardId=(String)session.getAttribute("boardId");
                        String         bbsTitle=Change.HTMLChange(bbsForm.getBbsTitle()); //利用函数过滤
                        String         bbsContent=Change.HTMLChange(bbsForm.getBbsContent()); //利用函数过滤
                        String         bbsSender=((UserForm)session.getAttribute("logoner")).getUserName();
                        String         bbsSendTime=Change.dateTimeChange(new Date());
                        String         bbsFace=bbsForm.getBbsFace();
                        String         bbsOpTime=bbsSendTime;
                        String         bbsIsTop="0";
                        String         bbsToTopTime="";
                        String         bbsIsGood="0";
                        String         bbsToGoodTime="";
                       
                        String sql="insert into tb_bbs values(?,?,?,?,?,?,?,?,?,?,?)";
                        Object[] params={boardId,bbsTitle,bbsContent,bbsSender,bbsSendTime,bbsFace,bbsOpTime,bbsIsTop,bbsToTopTime,bbsIsGood,bbsToGoodTime};
                       
                        ActionMessages messages=new ActionMessages();                       
                        OpDB myOp=new OpDB();
                        int i=myOp.OpUpdate(sql,params);
                        if(i<=0){
                                System.out.println("发表帖子失败!");
                                messages.add("userOpR",new ActionMessage("luntan.bbs.add.E"));
                                saveErrors(request,messages);
                                return mapping.findForward("error");                               
                        }
                        else{
                                System.out.println("发表帖子成功!");
                                session.setAttribute("currentP","1");
                                messages.add("userOpR",new ActionMessage("luntan.bbs.add.S"));
                                bbsForm.clear();
                                saveErrors(request,messages);
                                return mapping.findForward("success");
                        }                       
                }       
        }
       
        /** 回复帖子 */
        public ActionForward answerBbs(ActionMapping mapping, ActionForm form, httpervletRequest request, httpervletResponse response){
                httpession session=request.getSession();               
                BbsAnswerForm bbsAnswerForm=(BbsAnswerForm)form;
               
                StringrootId=(String)session.getAttribute("bbsId");               
                String         bbsTitle=Change.HTMLChange(bbsAnswerForm.getBbsAnswerTitle());
                String         bbsContent=Change.HTMLChange(bbsAnswerForm.getBbsAnswerContent());
                String         bbsSender=((UserForm)session.getAttribute("logoner")).getUserName();
                String         bbsSendTime=Change.dateTimeChange(new Date());
                String         bbsFace=bbsAnswerForm.getBbsFace();               
               
                String sql="insert into tb_bbsAnswer values(?,?,?,?,?,?)";
                Object[] params=new Object;
               
                params=rootId;
                params=bbsTitle;
                params=bbsContent;
                params=bbsSender;
                params=bbsSendTime;
                params=bbsFace;
               
                ActionMessages messages=new ActionMessages();
                String forwardPath="";
               
                OpDB myOp=new OpDB();
                int i=myOp.OpUpdate(sql, params);
                if(i<=0){
                        System.out.println("回复帖子失败!");
                        forwardPath="error";
                        messages.add("userOpR",new ActionMessage("luntan.bbs.answerR.E"));
                }
                else{
                        System.out.println("回复帖子成功!");
                        forwardPath="success";
                        messages.add("userOpR",new ActionMessage("luntan.bbs.answerR.S"));                       
                        bbsAnswerForm.clear();                       
                }               
                saveErrors(request,messages);
                return mapping.findForward(forwardPath);
        }

下面我们看看Chang类的HTMLChange是怎样过滤的

//过滤了& < >和空格和换行,看到下面几句,又把[和]换成了<和>,我们有了尖括号就可以绕过了
public class Change {
        public static String HTMLChange(String source){
                String changeStr="";
                changeStr=source.replace("&","&amp;");
                changeStr=changeStr.replace(" ","&nbsp;");
                changeStr=changeStr.replace("<","&lt;");
                changeStr=changeStr.replace(">","&gt;");               
                changeStr=changeStr.replace("\r\n","<br>");
               
                changeStr=changeStr.replace("[F","<font ");
                changeStr=changeStr.replace("[","<");
                changeStr=changeStr.replace("]",">");
                return changeStr;
        }



由于作者有一个很重要的反斜杠没有过滤导致可以绕过
<svg/onload=alert(document.cookie)>改为就可以触发代码了,下面的两个就不演示了,都是一样的
<script>alert(888);</script>
<img/src/onerror=alert(19)>

测试过程


成功触发,代码插入


002x 越权漏洞

//有if的条件可知,当为管理员或帖子的发布者才可以提前帖子。由于发布者bbsSender可以有客户端伪造,当发布者和登陆名相同,从而提前任意帖子
        if(lognerAble.equals("2")||lognerName.equals(master)||lognerName.equals(bbsSender)){
                  //当登陆名和发送者相当时可以提前帖子,bbsSender可以伪造
                        if(bbsId!=null&&!bbsId.equals("")){
                                Object[] params={time,bbsId};
                                String sql="update tb_bbs set bbs_opTime=? where bbs_id=?";
                                OpDB myOp=new OpDB();
                                int i=myOp.OpUpdate(sql,params);
                                if(i<=0){
                                        System.out.println("提前帖子失败");
                                        forwardPath="error";
                                        messages.add("userOpR",new ActionMessage("luntan.bbs.first.E"));                                       
                                }
                                else{
                                        System.out.println("提前帖子成功!");
                                        forwardPath="success";
                                        messages.add("userOpR",new ActionMessage("luntan.bbs.first.S"));                                       
                                }                               
                        }
                        else{
                                forwardPath="error";
                        }
                }
                else{
                        System.out.println("您没有权限提前该帖子!");
                        forwardPath="error";
                        messages.add("userOpR",new ActionMessage("luntan.bbs.first.N"));
                }
                saveErrors(request,messages);
                return mapping.findForward(forwardPath);
        }

下面这个是任意帖子删除的漏洞,和上面的同源,不在过多的讲解
       
public ActionForward deleteRootBbs(ActionMapping mapping, ActionForm form, httpervletRequest request, httpervletResponse response) throws UnsupportedEncodingException{               
                httpession session=request.getSession();               
                UserForm logoner=(UserForm)session.getAttribute("logoner");
               
                String bbsId=request.getParameter("bbsId");                                                //获取要删除帖子的ID       
                String bbsSender=request.getParameter("bbsSender");                                //获取要删除帖子的发布者
                bbsSender=new String(bbsSender.getBytes("ISO-8859-1"));
                String lognerAble=logoner.getUserAble();                                                //获取当前登录用户的权限
                String lognerName=logoner.getUserName();                                                //获取当前登录用户的用户名
                String master=(String)session.getAttribute("boardMaster");                //获取当前斑竹
               
                if(bbsId==null)
                        bbsId="-1";
                if(bbsSender==null)
                        bbsSender="";               
               
                ActionMessages messages=new ActionMessages();
               
            //如果当前登录的用户是帖子的发表者、帖子所属版面的斑竹、管理员
                if(lognerAble.equals("2")||lognerName.equals(master)||lognerName.equals(bbsSender)){ //更改bbsSender的值和登陆者相同可以删除任意帖子
                        if(bbsId!=null&&!bbsId.equals("")){                                               
                                String sql="delete tb_bbs where bbs_id=?";                               
                                Object[] params={bbsId};
                               
                                OpDB myOp=new OpDB();
                                int i=myOp.OpUpdate(sql,params);
                                if(i<=0){
                                        System.out.println("删除出错!");
                                        messages.add("userOpR",new ActionMessage("luntan.bbs.deleteRoot.E"));
                                        saveErrors(request,messages);                                       
                                }
                                else{                                                        //删除成功后,要返回列表显示根帖的页面,该页面有:查看某版面下所有根帖的页面、查看我的帖子的页面、查看精华帖子的页面
                                        System.out.println("删除成功!");
                                        messages.add("userOpR",new ActionMessage("luntan.bbs.deleteRoot.S"));
                                        saveErrors(request,messages);
                                        ActionForward forward=new ActionForward("/"+session.getAttribute("servletPath")+"?method="+session.getAttribute("method"));                //因为返回的页面存在以上三种情况,所以返回的视图要在程序中动态指定
                                        return forward;
                                }                               
                        }
                        return mapping.findForward("error");
                }
                else{
                        System.out.println("您没有权限删除该帖子!");                       
                        messages.add("userOpR",new ActionMessage("luntan.bbs.deleteRoot.N"));
                        saveErrors(request,messages);
                        return mapping.findForward("error");
                }               
        }


下面是利用过程
修改bbsSender的值

帖子提前成功

nextdoor 发表于 2014-8-8 17:06:36

又要几天没网上了,明天就回家,再来一贴

phantomer 发表于 2014-8-8 17:52:48

好贴~。学习了。

lyrric 发表于 2014-8-8 17:57:38

本地搭建的么?

nextdoor 发表于 2014-8-8 18:02:00

lyrric 发表于 2014-8-8 17:57
本地搭建的么?

嗯 ,是的

ICBM 发表于 2014-8-8 21:17:58

XSS大牛给跪了

蓝色_ 发表于 2014-8-9 15:19:51

给审计牛跪了

lmf1009 发表于 2014-8-11 21:02:11

谢谢分享

csadsl 发表于 2014-8-12 15:43:59

会审计的就是好啊

S-Man 发表于 2014-8-15 11:06:58

跪拜代码审计大牛
页: [1]
查看完整版本: 对某bbs论坛的简单审计2(跨站和越权漏洞)