0x00 前言
简介
JFinalCMS,极速开发,动态添加字段,自定义标签,动态创建数据库表并crud数据,数据库备份、还原,动态添加站点(多站点功能),一键生成模板代码,让您轻松打造自己的独立网站,同时也方便二次开发,让您快速搭建个性化独立网站,为您节约更多时间,去陪恋人、家人和朋友。
本篇只做sql注入部分。
0x01 Sql注入
1 接口分析:"/admin/div_data"
1.1 漏洞分析
分析delete方法代码,知传入参数divId与ids均被转为int类型,if中的ids拼接不含注入点,把目光放到div.getTableName ⽅法,该⽅法是从获取 div 对象的表名,div 对象则是通过 divId 从数据库查询得到。如果这⾥表名可控,则可通过传⼊ divId 来控制div.getTableName 的值,从⽽实现⼆阶注⼊。⽽DivController#save ⽅法正好没有做任何的过滤,可以原封不动的将表名传递进去,存放在 value 变量中。
追踪div.getTableName()函数,判断传入的tableName不为null,则返回为它的值;而div则为:根据给定的主键值数组和指定的列,从数据库中查询并返回符合条件的模型对象。它首先验证主键值的正确性,然后构建查询语句,并通过执行查询获取结果,最后返回查询到的模型对象或者 null
,也就是数据库中查询tableName这个参数,返回它。
//BaseDiv#getTableName()
public String getTableName() {
return getStr("tableName");
}
//public abstract class Model<M extends Model>#getStr(String attr)
public String getStr(String attr) {
Object s = this.attrs.get(attr);
return s != null ? s.toString() : null;
}
//DivController#save
public void save() {
Div div = getModel(Div.class,"",true);
div.setCreateDate(new Date());
div.setUpdateDate(new Date());
div.save();
//创建数据库表
TableUtils.create(div.getTableName());
redirect(getListQuery("/admin/div"));
}
1.2 漏洞利用
div//save保存tableName的为sql恶意字符串。
然后删除⾃定数据的时候选择带有注⼊的表 id,⽽数据库表名称中的 id 需要为⾃定义数据中存在的 id,否则会出错。
此处自己没试成功,借用一下别人的图。
可以看到恶意语句成功拼接到正常的SQL语句中,成功造成SQL注⼊。
2 接口分析:"/admin/admin"
2.1 漏洞分析
AdminController#index方法中name,username传入参数是String字符串类型,同时findPage方法中存在拼接sql未过滤语句,造成sql注入。
//AdminController#index
public void index(){
setListQuery();
String name = getPara("name");
String username = getPara("username");
Integer pageNumber = getParaToInt("pageNumber");
if(pageNumber==null){
pageNumber = 1;
}
setAttr("page", new Admin().dao().findPage(name,username,pageNumber,PAGE_SIZE));
setAttr("name", name);
setAttr("username", username);
render(getView("admin/index"));
}
//admin#findPage
public Page<Admin> findPage(String name,String username,Integer pageNumber,Integer pageSize){
String filterSql = "";
if(StringUtils.isNotBlank(name)){
filterSql+= " and name like '%"+name+"%'";
//如果name不为空,则filtersql为拼接sql语句,且未经过滤,存在注入点。
}
if(StringUtils.isNotBlank(username)){
filterSql+= " and username like '%"+username+"%'";
//同上
}
String orderBySql = DbUtils.getOrderBySql("createDate desc");
return paginate(pageNumber, pageSize, "select *", "from cms_admin where 1=1 "+filterSql+orderBySql);
}
//返回的sql语句查询也未对字符串参数进行过滤,典型的拼接型sql注入点。
2.2 漏洞利用
抓包,将数据包copy下来放到sqlmap目录下的r.txt文件中。
利用sqlmap输入命令:python sqlmap.py -r r.txt --dbs
3 接口分析:"/admin/content"
3.1 漏洞分析
ContentController#data方法中tiltle传入参数是String字符串类型,同时findPage方法中存在拼接sql未过滤语句,造成sql注入,跟2相同原因。
//ContentController#data
public void data() {
setListQuery();
String title = getPara("title");//传入字符串
Integer categoryId = getParaToInt("categoryId");
Integer pageNumber = getParaToInt("pageNumber");
if(pageNumber==null){
pageNumber = 1;
}
setAttr("categoryId",categoryId);
setAttr("page", new Content().dao().findPage(categoryId,title,pageNumber,PAGE_SIZE,getCurrentSite().getId()));//title这里
setAttr("title", title);
render(getView("content/data"));
}
//content#findPage
public Page<Content> findPage(Integer categoryId,String title,Integer pageNumber,Integer pageSize,Integer siteId){
String filterSql = " and siteId="+siteId;
if(categoryId!=null){
filterSql+=" and (categoryId="+categoryId+" or categoryId in ( select id from cms_category where treePath like '%"+Category.TREE_PATH_SEPARATOR+categoryId+Category.TREE_PATH_SEPARATOR+"%'))";
}
if(StringUtils.isNotBlank(title)){
filterSql+= " and title like '%"+title+"%'";//未过滤的拼接
}
String orderBySql = DbUtils.getOrderBySql("sort desc,createDate desc");
return paginate(pageNumber, pageSize, "select *", "from cms_content where 1=1 "+filterSql+orderBySql);
}
3.2 漏洞利用
抓包,将数据包copy下来放到sqlmap目录下的r.txt文件中
利用sqlmap输入命令:python sqlmap.py -r r.txt
4 接口分析:"/search"
之前全是admin接口,后台需要登陆以后才能利用,审计一下前台代码,看是否存在漏洞。找到/searchController.java文件,看到keyword参数可能有问题。追踪,追追追没找到sql调用。
//searchController#index()
public void index() {
String keyword = getPara("keyword");
Integer pageNumber = getParaToInt("pageNumber");
if(pageNumber==null){
pageNumber = 1;
}
setAttr("pageNumber", pageNumber);
setAttr("keyword", keyword); //直觉可能有问题
render("/templates/"+getCurrentTemplate()+"/search.html");
}
搜索一下吧
验证一下,啊居然真的有漏洞,太菜了,追不出来,只知道有漏洞,具体原因不详。 sqlmap抛下数据库验证一下,完活。