漏洞分析 | 漏洞调试的捷径:精简代码加速分析与利用

news2024/11/30 14:29:17

0x01前言

近期,Microsoft威胁情报团队曝光了DEV-0950(Lace Tempest)组织利用SysAid的事件。随后,SysAid安全团队迅速启动了应急响应,以应对该组织的攻击手法。然而,在对漏洞的分析和复现过程中,并未提供详细说明。由于该产品在安装时需要许可证,增加了动态调试漏洞的难度。为了便于调试能够快速复现该漏洞,我们尝试通过只使用部分的单元代码来模拟漏洞的主要逻辑流程进行动态调试分析。最终,我们成功利用 Goby 工具完美地实现了该漏洞的利用。
在这里插入图片描述

0x02 补丁分析

在 SysAid 中发布的公告中说明在 23.3.36 修复了该漏洞,通过 Diff 补丁发现该修复方式主要为限制 com.ilient.server.UserEntry#doPost函数中的 ..来完成的。
在这里插入图片描述

0x03 单元调试

由于安装包在安装时对许可证进行了限制,因此无法有效地进行安装和调试。为了能够高效地进行动态调试,我们采取了以下优化策略:创建一个独立的空项目,将存在漏洞的 Servlet 进行重写,用于单元模拟。通过这种方法,我们可以在没有任何依赖的情况下最小化地运行漏洞点,并顺利完成研究和分析的工作。
通过修复的方式来推断,该漏洞通过目录穿越的方式来指定上传的路径(accountId 参数)以及上传内容来完成利用。
在这里插入图片描述

再收到 accountId 参数值后会通过 a 函数来完成对该路径的拼接,由于该拼接方式存在一定的问题就导致了目录穿越,然后将传入的数据流写入到 accountId 可控的路径。
在这里插入图片描述

在写入完毕之后通过调用 a(var31, var46, var7);完成对传入数据的解压到指定的目录中。
在这里插入图片描述

根据漏洞分析得出漏洞的核心利用点主要取决于 accountId 和 POST 请求传入的字节数据,所以我们可以将存在可能利用的代码进行抽象。

package com.example.sysaid;

import com.ilient.server.IlientConf;

import java.io.*;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.zip.InflaterInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
    private String message;

    public void init() {
    }

    public void doGet(HttpServletRequest var1, HttpServletResponse var2) throws IOException {
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse var2) throws ServletException, IOException {
        String accountId = request.getParameter("accountId");
        InflaterInputStream inputStream = new InflaterInputStream(request.getInputStream());
        byte[] bytes = InputStreamUtils.InputStreamToBytes(inputStream);
        String var46  = a(accountId);
        String var7 = request.getParameter("symbolName");
        File var31 = new File(var46 + File.separator + Long.toString(Calendar.getInstance().getTimeInMillis()) + ".zip");
        FileOutputStream var38;
        (var38 = new FileOutputStream(var31)).write(bytes);
        var38.flush();
        var38.close();
        // var46
        a(var31, var46, var7);
        if (!var31.delete()) {
            var31.setWritable(true);
            var31.delete();
        }
    }

    private static void a(File var0, String var1) {
        File var2;
        if ((var2 = new File(var1)).exists() && var2.isDirectory()) {
            File[] var6 = var2.listFiles();
            String var3 = Long.toString(Calendar.getInstance().getTimeInMillis()) + ".bad";
            File var5 = new File(var1, var3);
            if (var0.renameTo(var5)) {
                System.out.println("UserEntry.renameAndMoveFile: File renamed and moved successfully.");
            } else {
                System.out.println("UserEntry.renameAndMoveFile: Failed to rename and move the file.");
            }
            if (var6.length >= 10) {
                Arrays.sort(var6, Comparator.comparingLong(File::lastModified));
                for(int var4 = 0; var4 < var6.length - 9; ++var4) {
                    if (var6[var4].isFile() && !var6[var4].delete()) {
                        System.out.println("UserEntry.renameAndMoveFile: Failed to delete file: " + var6[var4].getName());
                    }
                }
            }
        } else {
            System.out.println("UserEntry.renameAndMoveFile: Invalid output folder specified.");
        }
    }

    private static void a(File var0, String var1, String var2) {
        if (!var2.startsWith("LDAP_REFRESH_")) {
            IlientConf.logger.error(String.format("Error on UserEntry: symboleName %s not validated.", var2));
            a(var0, var1);
        } else {
            byte[] var8 = new byte[1024];
            try {
                ZipInputStream var3;
                for(ZipEntry var4 = (var3 = new ZipInputStream(new FileInputStream(var0))).getNextEntry(); var4 != null; var4 = var3.getNextEntry()) {
                    String var9;
                    if ((var9 = var4.getName()) != null && var9.indexOf("..") >= 0) {
                        System.out.println("Error in UserEntry.unZipIt - Found path manipulation!");
                        a(var0, var1);
                        return;
                    }
                    File var10 = new File(var1 + File.separator + var9);
                    String var5 = (new File(var1)).getCanonicalPath();
                    System.out.println(var10.getCanonicalPath());
                    System.out.println(var5 + File.separator);
                    if (!var10.getCanonicalPath().startsWith(var5 + File.separator)) {
                        System.out.println("Error in UserEntry.unZipIt - File is outside of the output directory!");
                        a(var0, var1);
                        return;
                    }
                    System.out.println("File unzip : " + var10.getAbsoluteFile());
                    FileOutputStream var11 = new FileOutputStream(var10);
                    int var12;
                    while((var12 = var3.read(var8)) > 0) {
                        var11.write(var8, 0, var12);
                    }
                    var11.close();
                }
                var3.closeEntry();
                var3.close();
                System.out.println("Finish unziping: " + var0.getAbsolutePath());
            } catch (Exception var7) {
                var7.printStackTrace();
                System.err.println("UserEntry: Error in unZipIt method:"+ var7);
            }
        }
    }

    public static String a(String var0) {
//        String var1 = IlientConf.getInstance().getNonAccountSharedFilesDir("ldapfiles");
        String var1 = "/1111/SysAidServer/root/WEB-INF/ldapfiles";
        File var2;
        if (!(var2 = new File(var1 + File.separator + var0)).exists()) {
            var2.mkdirs();
        }
        return var1 + File.separator + var0;
    }

    public void destroy() {
    }
}

构建新的 war 工程部署该 Servlet 即可完成对漏洞点单元模拟,用于漏洞的动态调试。
在这里插入图片描述

0x04 总结

在特殊情况下漏洞调试以及武器化利用时无法能够满足最佳的调试环境,我们尝试通过将有漏洞的部分代码进行单元模拟完成漏洞的动态调试。

0x05 参考

https://www.sysaid.com/blog/service-desk/on-premise-software-security-vulnerability-notification
https://www.huntress.com/blog/critical-vulnerability-sysaid-cve-2023-47246

Goby 欢迎表哥/表姐们加入我们的社区大家庭,一起交流技术、生活趣事、奇闻八卦,结交无数白帽好友。

也欢迎投稿到 Goby(Goby 介绍/扫描/口令爆破/漏洞利用/插件开发/ PoC 编写/ IP 库使用场景/ Webshell /漏洞分析 等文章均可),审核通过后可奖励 Goby 红队版,快来加入微信群体验吧~~~

文章来自Goby社区成员:Gryffinbit@白帽汇安全研究院,转载请注明出处。
微信群:公众号发暗号“加群”,参与积分商城、抽奖等众多有趣的活动
获取版本:https://gobysec.net/sale

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1215489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rabbitmq 集群搭建

RabbitMQ集群介绍 RabbitMQ集群是一组RabbitMQ节点&#xff08;broker&#xff09;的集合&#xff0c;它们一起工作以提供高可用性和可伸缩性服务。 RabbitMQ集群中的节点可以在同一物理服务器或不同的物理服务器上运行。 RabbitMQ集群的工作原理是&#xff0c;每个节点在一个…

语音识别芯片NRK3301在智能茶吧机的应用

传统的饮水机传大多只能提供热水和冷水&#xff0c;而智能茶吧机则是一款集合了热饮水机、煮茶器、泡茶壶等多种功能于一体的多功能生活电器。它不仅具备了传统饮水机的所有功能&#xff0c;还可以根据不同的需求&#xff0c;提供多种水温的饮水方式&#xff1b;还具备了煮茶和…

打开IE浏览器

原文地址&#xff1a;https://www.xiaoheiwoo.com/windows-11-internet-explorer/#:~:text%E5%A6%82%E4%BD%95%E5%9C%A8%20Windows11%20%E4%B8%AD%E5%90%AF%E7%94%A8%20IE%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%843%E7%A7%8D%E6%96%B9%E6%B3%95%201%20%E6%96%B9%E6%B3%95%E4%B8%80…

系列九、对象的生命周期和GC

一、堆细分 Java堆从GC的角度还可以细分为&#xff1a;新生代&#xff08;eden【伊甸园区】、from【幸存者0区】、to【幸存者1区】&#xff09;和老年代。 二、MinorGC的过程 复制>清空》交换 1、eden、from区中的对象复制到to区&#xff0c;年龄1 首先&#xff0c;当eden区…

C#开发的OpenRA游戏之世界存在的属性RenderDebugState(5)

C#开发的OpenRA游戏之世界存在的属性RenderDebugState(5) 前面分析过一个调试的属性,在这里分析另外一个属性,这个属性就是RenderDebugState,它就是用来显示渲染的信息。 跟前面的分析规则可知,属性都是有一个信息类和操作类组成。 在这里信息类叫RenderDebugStateInfo…

指针数组和数组指针的理解(个人理解版)

指针数组和数组指针的形式 int *p[3] // 指针数组 int (*p)[3] // 数组指针指针数组和数组指针的理解 1.指针数组 int *p[3] 首先找到变量p&#xff0c; &#xff08;1&#xff09;先与[]结合看&#xff08;因为[]优先级比*高&#xff09;&#xff0c;也就是p[3]&#…

2023亚太杯数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 算法介绍FP树表示法构建FP树实现代码 建模资料 ## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c…

抖音小程序开发:疫苗预约系统的技术实现

在疫苗接种的背景下&#xff0c;借助抖音小程序&#xff0c;可以更好地整合用户社交信息和提供便捷的疫苗预约服务。 一、疫苗预约系统的需求分析 在开发抖音小程序疫苗预约系统之前&#xff0c;首先需要进行详细的需求分析。系统应该具备用户注册、疫苗信息展示、预约功能、…

前端安全策略保障

文章目录 前言后台管理系统网络安全XSSCSRFSQL注入 后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端系列文章 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出…

Nerf相关、公式

在3D重建领域&#xff0c;这幅图怎么理解 这张图展示的是“体素剪枝&#xff08;Voxel Pruning&#xff09;”在3D重建中的应用&#xff0c;这是一种利用稀疏性&#xff08;Sparsity&#xff09;来优化3D数据存储和处理的技术。体素剪枝的目的是为了降低存储需求和提高计算效率…

前端界面网页截图(干货)

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; 看了一些谷歌插件&#xff0c;可以对网页进行局部截图或者是整个网页截图&#xff0c;于是想着弄个demo,关于前端的截图。最后选择了 html2canvas 1.下载安装包 Install NPM npm install --save html2canvas或者…

隐私协议 Secret Network 宣布使用 Octopus Network 构建的 NEAR-IBC 连接 NEAR 生态

2023年11月 NearCon2023 活动期间&#xff0c;基于 Cosmos SDK 构建的隐私协议 Secret Network&#xff0c;宣布使用 Octopus Network 开发的 NEAR-IBC&#xff0c;于2024年第一季度实现 Secret Network 与 NEAR Protocol 之间的跨链交互。 这将会是Cosmos 生态与 NEAR 之间的首…

大模型幻觉成应用落地难题 最新评测文心一言解决幻觉能力最好文心一言解决幻觉能力最好 或成产业应用首选

“林黛玉倒拔垂杨柳”、“月球上面有桂树”、“宋江字武松”……相信经常使用大语言模型都会遇到这样“一本正经胡说八道”的情况。这其实是大模型的“幻觉”问题&#xff0c;是大模型行业落地的核心挑战之一。例如幻觉会影响生成内容的可靠性&#xff0c;对于法律、金融、医疗…

通用人工智能:迈向智能革命的下一步

原创 | 文 BFT机器人 AGI&#xff0c;全称为Artificial General Intelligence&#xff0c;中文翻译为“通用人工智能”&#xff0c;亦被称作强AI&#xff0c;是人工智能研究领域长期探讨的重要议题。此概念指的是在人类可能涉及的所有专业领域内&#xff0c;具备与人类智慧相当…

搜维尔科技:业内普遍选择Varjo头显作为医疗VR/AR/XR解决方案

Varjo 的人眼分辨率混合现实和虚拟现实头显将医疗专业人员的注意力和情感投入提升到更高水平。借助逼真的 XR/VR&#xff0c;医疗和保健人员可以为最具挑战性的现实场景做好准备&#xff01; 在虚拟、增强和混合现实中进行最高水平的训练和表现 以逼真的 3D 方式可视化医疗数据…

如何将本地Portainer管理界面结合cpolar内网穿透工具实现远程浏览器访问

文章目录 前言1. 部署Portainer2. 本地访问Portainer3. Linux 安装cpolar4. 配置Portainer 公网访问地址5. 公网远程访问Portainer6. 固定Portainer公网地址 前言 Portainer 是一个轻量级的容器管理工具&#xff0c;可以通过 Web 界面对 Docker 容器进行管理和监控。它提供了可…

时间同步时钟小课堂——常用的对时方式有哪些?

目前常用的对时信号有NTP 网口、B码、串口、脉冲等授时方式&#xff0c;分别介绍如下 1、NTP授时&#xff1a; 是基于NTP 协议实现网络授时的。NTP网络时钟同步协议是目前国际互联网通用的时间服务协议。NTP 协议采用 client/Server架构&#xff0c;基于 UDP/IP&#xff0c;使用…

js构造函数之工厂模式(学习笔记1)

目录 一、简单工厂 1、存储一个用户信息 2、存储N个用户信息 3、存储N个用户信息不同年龄用户有不同美食的搭配方案【简单工厂模式】 二、抽象工厂模式 1、抽象工厂(AbstractFactory) 2、具体工厂&#xff08;ConcreteFactory&#xff09; 3、生产新款手机 4、总结 本…

No matching version found for zr-map-ol@1.1.19.

问题描述&#xff1a; 通常情况下直接安装可能还会报错&#xff0c;因为有的依赖包是在私库里的 解决方法&#xff1a; 1.查看模块的注册信息 2. 安装 如果上面这种方式安装之后npm i还是报错&#xff0c;试试下面这种方式(我没有试下面的方式 上面的已经解决掉了) 具体可以参…

医疗器械展示预约小程序的效果如何

医疗器械行业涵盖的内容非常广&#xff0c;市场中大小从业的品牌/门店也很多&#xff0c;比如我们常见的轮椅、康复器械、拐杖、血压仪等产品市场需求都非常高&#xff0c;当然还有医院里用的器械等。 医疗器械市场呈现多品牌、多门店的发展趋势&#xff0c;虽然这些东西不是必…