漏洞复现:
新增用户test密码:111111,并登录test用户
看见为test用户,点击修改密码,抓包,将user_id修改为1,则成功修改管理员密码
代码分析:
根据数据包找接口system/user
定位到控制层,找到方法respwd进行分析:
该函数先用获取数据包请求参数,并用equals方法进行一致性对比,失败返回,一致则进入下一层。
创建一个 Record 对象,用于封装待更新的用户信息。再次检查输入密码是否为空,使用 SHA-256 哈希算法对旧密码进行加密,并将其转换为十六进制字符串表示。
并用record对象封装user_id值(此处user_id值由用户传入,为进行任何权限校验,直接用作修改对象的标识符)。
将fengzhuanghaoderecord对象传入,并调用 Db.update() 方法更新数据库表 AdminConst.TABLE_OF_SYS_USER 中用户的密码,由此造成越权修改任意用户密码。
SQL注入漏洞:
漏洞复现:
如下地点输入sql语句
成功爆出数据库名:
代码分析:
根据数据包找到路由:system/generate
定位到save代码块:看到通过getPara方法获取传入sql语句。
跟进getPara方法:
发现并未做任何过滤。
跟进Db.update(sql)的update方法:
继续跟进:
继续跟进:
在var4参数再次使用update函数,并传入用户输入参数sql,继续跟进该函数:
可以看到对sql进行了预编译,但因为是整个语句传入,也就是带入数据库的sql语句的语法结构完全由我们控制,所以预编译不起作用。
sql语句带入后由executeUpdate执行并将结果赋值给result。
文件上传漏洞:
漏洞复现:点击保存并抓包
在以上数据包处将dirs参数改为../../../static,file_name改为shell.jsp,将内容改为url编码的jsp马:
上传成功,蚁剑连接成功:
代码分析:
根据数据包定位路由:cms/template
由数据包save结构及传入参数得知处理数据包代码块如下:
定位第115行代码,通过getPara函数获取参数dirs并赋值给dirName参数,跟进函数,发现该函数无任何过滤:
并调用File类处理设置为NULL值的pathFile与dirName
跟进File函数:
可以看到在File类构造的函数中,进行是否为空判断后,便将parent与child进行拼接构成最终的路径,并在controller层赋值给pathFile。
以同样方式获取到fileName参数。
定位到123行代码,继续以File简单处理用户传入的dirs路径与file_name参数,进行简单拼接便由writeString写入。
模板注入
漏洞复现:在以下内容写入模板注入代码,保存,访问首页弹出计算机:
代码分析:
网站使用了freemarker作为模板语言,且看前端也有极其明显的模板注入特征。
XML注入:
漏洞复现:
仿照文件上传漏洞在static目录下传入一个xxe.jrxml文件:
文件内容为访问dnslog验证xxe漏洞:
访问url漏洞复现成功:http://localhost:8081/ofcms-admin/admin/reprot/expReport.html?j=../../static/xxe
代码分析:
根据数据包接口定位路由:/report
找到接口对应代码块:
可以看到从数据包中获取j参数,并未过滤直接进行拼接赋值给jrxmlFileName参数,如果传入j参数值为xxe则拼接结果为:/WEB-INF/jrxml/xxe.jrxml
如果拼接j参数值为../../static/xxe则拼接结果为/static/xxe.jrxml
由上图可见在39行根据路径创建好的File对象在48行传入了compileReport,继续跟进compileReport。
compileReport 方法内部读取 InputStream 中的字节流,将其解析成 JRXML 格式的报表定义,在该函数内部再次调用complie函数接受inputStream传参。
继续跟进:
接受inputStream参数后,以JRXmlLoader.load()方法来解析jrxml文件,由于并未进行过滤则会造成XXE漏洞,加载外部实体。
加下方wx,拉你一起进群学习
原文始发于微信公众号(红队蓝军):Ofcms1.1.3版本审计
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论