0x00 360Quake牛刀小试
在对某厂商进行授权安全测试时,苦于寻找资产,于是利用360quake的title搜索语法进行搜索边缘资产。
搜到疑似该厂商的一个边缘站点。根据经验,像这种界面的系统一般多多少少都有漏洞。
因为站点只有一个后台界面,所以我们的漏洞利用点一般先是寻找爆破弱口令账户,或者是找到一处全局越权。最好是弱口令账户。经过一些列的账户爆破处理,并没有一个有效用户可利用。于是乎只能寄托于能不能搞到这套系统的相似源码或者框架。
这时候,我注意到之前quake搜索出来的结果。在360quake当中,对存在ico的站点会在搜索栏下告知站点ico的md5值。根据favicon的图标,我猜测这不是一套原生框架。
删除对应的title关键词,可以根据favicon来搜索使用同套相似框架的站点。
当然假如quake没有给出这个站点的icon值,你也可以根据 curl http://xxxx.com/favicon.ico|md5sum
的方式,得到站点ico的md5,然后利用quake语法,favicon:"{MD5}"
搜索。
运气较好,在quake的第一页就发现了和厂商使用同样cms,并且明示用了什么框架的站点:jeecg-boot。
0x01 如何利用360quake搜索相似站点,并获得源码
这里一般我们搜索相似源码的站点有以下几种方式:
- 1、
根据favicon搜索
- 2、
根据首页页面里的一些特征,利用body:"{特征}"来搜索
- 3、
根据response里的header头特征来搜索,一般是在cookie里有设置特定的cookie。比如shiro的rememberMe=xxx,或者apache的ofbiz。
搜索到相似站点后,有几种方式搞到源码:
- 1、
对相似站点进行入侵,getshell后获得源码(动静较大)
- 2、
对相似站点批量扫备份文件
- 3、
得知cms的名称去凌风云网盘搜索该cms源码是否有人分享
- 4、
闲鱼搜有没有对应源码有人在买卖
- 5、
去github,gitee搜有没有相似的源码,是否是根据别人的源码二次开发的成品
0x02 步入正题,如何搞定这个cms。
这里我们搜索到jeecg-boot是github上开源的成熟项目,项目成熟,不代表没有漏洞。成熟项目有成熟项目的好,就是有人会去发现漏洞,然后告知到github的issue上,你只要祈祷你遇到的站点不是最新版本就行。项目不成熟,只能你自己审计代码,好处就是用的人少,相对有漏洞的概率就大。
根据 https://github.com/zhangdaiscott/jeecg-boot 项⽬可知,该项⽬是由java基于 springboot开发的。所以我第⼀时间阅读了这个项⽬的README。
舒服,有fastjson和shiro,还有我熟悉的springboot的。
首先,登录抓个包。
符合站点描述缩写的,确实是可能使用了fastjson,整个response和request里的url都有springboot的气息。
因为知道有shiro,但是shiro版本⼤于是1.4.0。所以有那个paddingoracle的漏洞,也有⼏个
shiro配合springboot的url绕过漏洞。整理下⼏个漏洞的利⽤条件。
paddingoracle的漏洞利⽤条件:
- 1、需要登录后的rememberMe的值,也就是说需要账号密码。
shiro的url验证绕过:
- 1、不需要利⽤条件,但是前提是作者那样⼦配置认证⽅式,其次就是
你有对应的后台漏洞的url。
第⼀个paddingoracle暂时利⽤不了,只能从第⼆个shiro绕过找办法。
因为是1.4.0所以那个
反序列化还是存在的。因为只是key随机化了⽽已,查看项⽬,并没有设置固定的key,所以
⽤⼯具没跑出来key。
于是乎,根据前面提到的,我们在issue上找到⼀个最近的sql注⼊漏洞。 https://github.com/ zhangdaiscott/jeecg-boot/issues/1887
先看看这个url在未登陆下是啥情况。
提示重新失效。然后根据shiro的最近⼏个未授权漏洞进⾏fuzz。当发现下图情况时候,返回码不
⼀样了。说明已经绕过了shiro认证。
根据issues⾥的图⽚请求,进⾏填写剩余的get参数。成功获取到数据。
注⼊点在code=处。mysql数据库。
注入点很明显,直接可以用sqlmap。 --is-dba
然后下载源代码,看看有没有upload的漏洞。找到⼀处新版被注释掉的上传代码(大概率可能有洞才被在新版注释掉)。
// @PostMapping(value = "/upload2")
// public Result<?> upload2(HttpServletRequest request, HttpServletResponse response) {
// Result<?> result = new Result<>();
// try {
// String ctxPath = uploadpath;
// String fileName = null;
// String bizPath = "files";
// String tempBizPath = request.getParameter("biz");
// if(oConvertUtils.isNotEmpty(tempBizPath)){
// bizPath = tempBizPath;
// }
// String nowday = new SimpleDateFormat("yyyyMMdd").format(new Date());
// File file = new File(ctxPath + File.separator + bizPath + File.separator + nowday);
// if (!file.exists()) {
// file.mkdirs();// 创建文件根目录
// }
// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// MultipartFile mf = multipartRequest.getFile("file");// 获取上传文件对象
// String orgName = mf.getOriginalFilename();// 获取文件名
// fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf("."));
// String savePath = file.getPath() + File.separator + fileName;
// File savefile = new File(savePath);
// FileCopyUtils.copy(mf.getBytes(), savefile);
// String dbpath = bizPath + File.separator + nowday + File.separator + fileName;
// if (dbpath.contains("\")) {
// dbpath = dbpath.replace("\", "/");
// }
// result.setMessage(dbpath);
// result.setSuccess(true);
// } catch (IOException e) {
// result.setSuccess(false);
// result.setMessage(e.getMessage());
// log.error(e.getMessage(), e);
// }
// return result;
// }
构造请求包:
根据代码,看下上传到哪⾥去了。
${jeecg.path.upload}
可惜,这个站点的biz不可控,文件只能上传到和webapp同⽬录下的upload⽬录,那在web的URL下是访问不到我们的上传文件。如果是上传到webapp下⾯,那就可以访问到。
0x03 后续渗透思路
- 1、利用注入点,新增or修改后台某个账户为弱口令。
- 2、利用弱口令账户登入系统,获取到rememberMe的正确值,使用shiro的paddingoracle的JRMP的gadget进行攻击。
- 3、看了下项目,作者提供了便捷的docker方案。So后续渗透getshell后有大概率是在docker里。
0x04 总结
- 1、在日益艰难的web项目渗透下,利用现有的资产搜索引擎可以更好的帮我们掌握目标站点的情报。
- 2、现在的入侵都不是一步水到渠成,往往需要迂回而上,越了解目标的环境,越有机会拿下目标站点。