铁人下载系统代码审计

搞搞java代码审计,发现和php还是有很多不一样的地方。php真是一门神奇的语言,很多有趣的漏洞在java这里没有出现。

1.安装问题

没有删除安装页面,老生常谈的重复安装

2.注入问题

先测试下基本的功能,试试搜索

找到so.jsp ,跟踪发现被带入 发编译找到Ruanjianguanli,找到so函数, ruanjianDao其实是个接口,说明ruanjianDao向上转型了。继续找到实现接口的类RuanjianMySQL,然后找到其so函数 很遗憾的看到了prepareStatement,prepareStatement基本不能注入,Statement可以注入 全局搜索用Statement的地方

全局搜索一下 RuanjianMysql.java中 Chaxun函数 Zuixin函数 Tuijian函数 Paixing函数 Chuang函数 只有一处调用了 看样子是管理后台,这个后台的就不用管了,你都能进后台了还要啥注入,除非root权限写 shell Zuixin倒是不需要后台操作,但是却是写死了,每处都写死了。 找到Tuition的时候找到一处 白白激动了,一个写成12,一个int化了

<%
    int pageNo = 1;
    int pageSize = 12;
    String strpageNo = request.getParameter("pageNo");
    if(strpageNo != null && !strpageNo.equals("")) {
        pageNo = Integer.parseInt(strpageNo);
    }
    pageModel pagemodel = Ruanjianguanli.getInstance().Tuijian(pageNo,pageSize);
%>

试了几个常见的函数还是不行 登录注册都藏试过了,注册会员之后,功能也是少的出奇,会员的功能都是用的是防止注入的 看了那几个函数,调用的时候都是在管理员后台。所以基本注入无望。

3.测试后台未授权

访问的后台的时候直接,跳转到 翻看到过滤器

if(bl && (session == null || session.getAttribute("admin") == null))
            {
                response.sendRedirect((new StringBuilder(String.valueOf(request.getContextPath()))).append("/buzai.htm").toString());
                return;
            }

无果。

4.xss测试

由于功能实在是简单,只有一处须改用户资料的地方,也就修改邮箱是有XSS的

5.CSRF漏洞

随处可见,这个就不演示了

上传getshell

上传处的代码

res.setContentType("text/html; charset=GB2312");
        PrintWriter out = res.getWriter();
        DiskFileItemFactory factory = new DiskFileItemFactory();
        factory.setSizeThreshold(4096);
        File tempPath = new File((new StringBuilder(String.valueOf(getServletContext().getRealPath("/")))).append("temp/").toString());
        factory.setRepository(tempPath);
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setSizeMax(0xf4240L);
        String date = "";
        try
        {
            List fileItems = upload.parseRequest(req);
            Iterator iter = fileItems.iterator();
            String regExp = ".+\\\\(.+)$";
            String errorType[] = {
                ".exe", ".com", ".cgi", ".asp"
            };
            Pattern p = Pattern.compile(regExp);
            while(iter.hasNext())
            {
                FileItem item = (FileItem)iter.next();
                if(item.isFormField() && item.getFieldName().equals("date"))
                    date = item.getString();
                if(!item.isFormField())
                {
                    String name = item.getName();
                    long size = item.getSize();
                    if(name != null && !name.equals("") || size != 0L)
                    {
                        Matcher m = p.matcher(name);
                        boolean result = m.find();
                        if(result)
                        {
                            for(int temp = 0; temp < errorType.length; temp++)
                                if(m.group(1).endsWith(errorType[temp]))
                                    throw new IOException((new StringBuilder(String.valueOf(name))).append(": wrong type").toString());

                            try
                            {
                                item.write(new File((new StringBuilder(String.valueOf(getServletContext().getRealPath("/")))).append("images/youqing/").append(date).append(".gif").toString()));
                                res.sendRedirect((new StringBuilder("../admin/left7/chenggong3.jsp?")).append(date).append(".gif").toString());
                            }
                            catch(Exception e)
                            {
                                out.println(e);
                            }
                        } else
                        {
                            throw new IOException("fail to upload");
                        }
                    }
                }
            }
        }
        catch(IOException e)
        {
            out.println(e);
        }
        catch(FileUploadException e)
        {
            out.println(e);
        }

简单解释下这段代码逻辑 List fileItems = upload.parseRequest(req);

解析所有请求参数并放到一个list里面,同时对上传的文件名有个正则判断

String regExp = ".+\\\\(.+)$";

文件名必须是xxx\xxx的形式,这个可以抓包然后改

if(m.group(1).endsWith(errorType[temp]))
                                    throw new IOException((new StringBuilder(String.valueOf(name))).append(": wrong type").toString());

文件名不能以errorType数组里面的字符结尾,最后上传生成的文件以gif结尾。 shell躺在那

看看过滤器,发现根本没有任何权限限制,于是就可以直接上传getshell了。 ps:转载请标明作者b5mali4和出处


为您推荐了相关的技术文章:

  1. 利用 Python 特性在 Jinja2 模板中执行任意代码
  2. PHP代码审计学习 | 零の杂货铺
  3. CVE-2017-6920:Drupal远程代码执行漏洞分析及POC构造
  4. CI框架下column注入 – Wupco's Blog
  5. Python Waf黑名单过滤下的一些Bypass思路 - Mosuan's Blog

原文链接: www.codersec.net