程序员

铁人下载CMS代码审计

2019-05-08  本文已影响0人  Wudi1

简介

初学java代码审计,跟着大佬的审计方案,走一遍审计流程,这个系统没有使用java框架,作为入门不错。主要作为熟悉代码审计流程,寻找漏洞思路,学习记录。

环境准备

环境搭建使用了本地搭建环境,查看代码使用IDEA,配合tomcat8.0,因为IDEA会自动反编译,比较方便。我使用的是安装必看中的第二种方法,手动安装,修改数据库连接,然后手动将sql文件导入数据库,接着打开后台管理地址,安装完成。使用默认的管理员账号密码。

发现漏洞

非框架的代码审计,按照前台--后台,紧急--低危,非交互--交互,跟随代码流程尽量发现高危和易利用的漏洞类型为主。

重安装漏洞

因为我使用手动安装的方法进行安装,sql文件也是手工导入,直接导入sql文件,然后后台打开安装发现无法安装,需要将db_an设置为no,才能安装成功。使用系统自带的安装功能安装完成后,db_an会被设为no,虽然/install目录的重新安装页面没删除,但确实使用系统自带的安装功能不存在重新安装的漏洞。
跟随/install/index.html页面,找到了install.jsp文件,再根据form action,找到install_setup.jsp页面

安装页面
然后再根据install_setup.jsp上的import语句
import="liuxing.util.Install,java.util.*"
找到安装的主要逻辑代码,在WEB-INF/class/liuxing/util/Install.class中,安装时会判断db_an的值,yes可以安装,no不安装;安装完成后会把值设置为no,虽然install页面没有被删除,但是已经不能再次安装了。
image.png
   所以当使用系统自带的install方法安装时不存在重安装漏洞;如果使用手动导入sql文件,并且没有将db_an设置未no的话,且没删除install目录,就会存在重安装漏洞。

SQL注入

先尝试下搜索功能,随便输入关键字,点击搜索,跳转到so.jsp.查看so.jap

image.png
发现将搜索的值传入了Ruanjianguanli的so方法中,找到Ruanjianguanli的so方法
image.png
是调用了ruanjianDao.so()函数,我们接着来看看
image.png
同一个构造函数中可以发现ruanjianDao其实RuanjianMySQL的一个实例,接着再往下跟。打开WEB-INF/class/liuxing/dao/RuanjianMySQL.class文件 搜索so方法,最终使用预编译的方法来执行sql,所以这个地方不存在sql注入。
image.png
有一处使用了预编译方式,说明很多地方采用预编译的方式来执行sql语句,基本没有sql注入漏洞。所以换个思路,通过全局搜索createStatement关键字,看看有没有用拼接的SQL语句的。
image.png
如上图所示也有很多可以注入的地方,但是需要后台登陆,在delete语句中存在时间盲注,比如
delete from user where id in('222') or if(ascii(substr(database(),1,1))>107,0,sleep(3));
image.png
利用:
GET /admin/left6/Delete.jsp?pageNo=1&id=000')+or+if(ascii(substr(database(),1,1))>108,0,sleep(3))--+ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/admin/left6/guanliyouhu.jsp
Connection: close
Cookie: Phpstorm-da0128c6=8686f169-5769-401c-a557-13b58accd387; JSESSIONID=29976F22C3B4A37F8BFEDEA123CB35C7
Upgrade-Insecure-Requests: 1

但是后台都已经登陆了,也没必要去纠结这种sql了,应该有更容易利用的漏洞,我们继续往下找。

存储型XSS

系统比较简单,所以前台能产生XSS的地方比较少。会员注册后修改个人资料,邮箱处
可以使用payload
""><script>alert(0)</script>

image.png
成功处罚XSS漏洞。我们来看denlu1.jsp代码
image.png
我们来找到Userguanli的Xiugaiyonghu2的方法。最终定位到WEB-INF/classliuxing/dao/UserDaoMySQL.class文件中的Xiugaiyonghu2方法中,直接将前端传过来的 youxiang值写入数据库中,导致存储型XSS。
image.png

后台任意文件上传漏洞

   在"其它管理"—"添加友情链接"处、"软件管理"—"软件发布"页面,都可以上传文件,在web.xml中或者顺着jsp页面调用寻找,都能够找到具体的逻辑代码。
内部代码看起来都是一样的,以WEB-INF/class/liuxing/util/shangchuan2.class文件为例,关键代码如下:

            List e = upload.parseRequest(req);
            Iterator iter = e.iterator();
            String regExp = ".+\\\\(.+)$";
            String[] errorType = new String[]{".exe", ".com", ".cgi", ".asp"};
            Pattern p = Pattern.compile(regExp);

            while(true) {
                FileItem item;
                String name;
                long size;
                do {
                    do {
                        if(!iter.hasNext()) {
                            return;
                        }

                        item = (FileItem)iter.next();
                        if(item.isFormField() && item.getFieldName().equals("date")) {
                            date = item.getString();
                        }
                    } while(item.isFormField());

                    name = item.getName();
                    size = item.getSize();
                } while((name == null || name.equals("")) && size == 0L);

                Matcher m = p.matcher(name);
                boolean result = m.find();
                if(!result) {
                    throw new IOException("无法上传");
                }

                for(int e1 = 0; e1 < errorType.length; ++e1) {
                    if(m.group(1).endsWith(errorType[e1])) {
                        throw new IOException(name + ": wrong type");
                    }
                }

                try {
                    String var24 = m.group(1);
                    String men = this.getExt(var24);
                    item.write(new File(this.getServletContext().getRealPath("/") + "wen/" + date + men));
                    res.sendRedirect("../admin/left3/chenggong2.jsp?" + date + men);
                } catch (Exception var21) {
                    out.println(var21);
                }
            }
        } catch (IOException var22) {
            out.println(var22);
        } catch (FileUploadException var23) {
            out.println(var23);
            out.println("文件大小超出限制");
        }

    }

其中会判断上传的文件名,要符合正则表达式 ".+\(.+)$",才能够正常上传。即形似xxx\xx的文件名,估计是为了 匹配Windows路径中的\,比如C:\a.jpg。定义了内部禁止的后缀名".exe", ".com", ".cgi", ".asp",这就是唯一的过滤方式了。
继续往下看,写文件时,关键的一句代码:

item.write(new File((new StringBuilder(String.valueOf(getServletContext().getRealPath("/")))).append("wen/").append(date) .append(men).toString()));

即将文件存放在/wen目录下,保存为date+men形式的文件名,两者都是可以控制的,直接修改写shell了。


image.png image.png
image.png

其他漏洞

未完待续

参考文章

源码下载
铁人下载系统代码审计
JAVA代码审计的一些Tips

上一篇下一篇

猜你喜欢

热点阅读