1. 项目概述:Sorcino,一个专为暴露的LLM代理设计的“安全探照灯”
在当今这个大型语言模型(LLM)应用遍地开花的时代,像OpenClaw、LiteLLM、Ollama这类代理和网关工具,正以前所未有的速度被部署到各种环境中,从企业内部研发到公开的云服务。然而,一个普遍被忽视的问题是:这些强大的工具,一旦配置不当,就可能从“智能助手”变成“安全黑洞”。想象一下,一个无需认证就能访问的OpenClaw WebSocket端点,或者一个在HTTP响应里明文返回了OpenAI API密钥的LiteLLM服务,它们暴露在公网上,就像把自家保险箱的钥匙插在门上一样危险。Sorcino这个工具,就是为解决这个问题而生。它不是一个泛泛的端口扫描器,而是一个高度特化的“安全探照灯”,专门用来在茫茫IP地址海洋中,精准定位那些配置存在疏漏、暴露在互联网上的LLM代理服务,并详细诊断其安全风险。
简单来说,Sorcino能帮你回答几个关键问题:我的网络里有没有我不小心暴露出去的LLM服务?别人部署的公开服务是否存在我可以验证的配置错误?作为一个安全研究员或渗透测试人员,如何系统性地评估这类新兴基础设施的风险面?它通过主动扫描IP范围、CIDR地址块甚至整个自治系统(ASN),结合对OpenClaw、LiteLLM、Ollama、MCP Server等特定服务指纹的识别,以及一系列深入的安全检查(如认证绕过、敏感信息泄露、调试模式开启等),来生成一份清晰的风险报告。无论你是负责企业安全的工程师,想要排查内部资产;还是进行授权安全评估的研究员,需要一款精准的工具;亦或是好奇的学习者,希望了解这类应用的安全现状,Sorcino都提供了一个从发现到验证的完整闭环方案。
2. 核心设计思路:精准识别与深度检测的结合
Sorcino的设计哲学非常明确:在保证一定扫描效率的前提下,实现针对LLM代理服务的“高精度”与“深检测”。这区别于传统的漏洞扫描器,后者往往追求漏洞库的广度,而对特定服务链的深度挖掘不足。Sorcino则反其道而行之,聚焦于一个快速发展的垂直领域,其核心思路可以拆解为三个层次:发现、识别、诊断。
2.1 目标发现:多源输入与智能寻址
首先,工具需要知道“扫哪里”。Sorcino提供了极其灵活的输入方式,这背后是对不同扫描场景的考量。直接指定单个IP或CIDR(如192.168.1.0/24)是最常见的,适合针对已知或怀疑的网络段进行排查。而IP范围(如10.0.0.1-254)则提供了更精细的控制。从文件读取目标(@targets.txt)便于集成到自动化工作流或处理预定义的目标列表。
更具威胁情报色彩的是ASN扫描功能(sorcino asn AS12345)。自治系统号(ASN)代表了一个实体(如某云服务商、某大学、某公司)管理的一片IP地址空间。通过扫描整个ASN,安全研究员可以宏观评估某个组织在LLM代理服务暴露面上的整体风险,这对于外部攻击面管理(EASM)非常有价值。--list-only参数则允许只获取该ASN下的IP列表而不立即扫描,方便进行目标筛选或与其他工具联动。
与Shodan的集成(sorcino shodan-import)是另一个亮点。Shodan作为互联网设备搜索引擎,已经积累了海量的服务指纹数据。Sorcino可以直接利用Shodan的查询语法(如port:18789 country:IT)来获取一批“可能相关”的初始目标,然后导入进行深度验证。这相当于用Shodan做“粗筛”,再用Sorcino做“精检”,极大地提升了在广域网中寻找目标的效率。--scan参数更是实现了“查询即扫描”的一站式操作。
最后,对于本地网络,mdns-scan功能利用mDNS(多播DNS)协议来发现局域网内广播自身服务的设备。许多本地部署的LLM工具(尤其是开发版)会使用mDNS来方便本地发现,这无意中也可能泄露信息(如工具路径、SSH端口等)。Sorcino能捕获这些广播信息,将其转化为扫描目标。
注意:ASN扫描和Shodan导入功能会生成大量目标,务必确保你拥有扫描这些IP地址的合法授权。未经授权的扫描可能违反法律和服务条款,甚至被视为攻击行为。
2.2 服务识别:指纹比对与协议探针
发现目标IP和端口后,下一步是识别其上运行的服务是否为Sorcino关心的LLM代理。这里没有依赖简单的端口匹配(虽然预设了常见端口如OpenClaw的18789),因为服务可能运行在任何端口上。Sorcino的核心识别逻辑是基于HTTP/HTTPS和WebSocket协议的主动探针。
它会向目标发送特定的HTTP请求,例如访问根路径/、/v1/models(OpenAI兼容API)、/api/tags(Ollama)等。通过分析响应的状态码、头部字段(如Server、X-Powered-By)以及响应体内容(是否包含“OpenClaw”、“LiteLLM”、“Ollama”等关键字),来判定服务类型。对于WebSocket服务,它会尝试建立连接并发送一个简单的握手或探测帧,观察其响应行为。
这种基于行为特征的识别,比单纯看端口更可靠。例如,一个Nginx反向代理后面可能运行着OpenClaw,端口是常见的80或443,但通过访问特定路径的响应特征,Sorcino仍然有可能将其识别出来。工具内置的SPA(单页应用)误报过滤机制在这里也起了作用:有些Web服务器会对所有未知路径返回同一个HTML页面(通常是前端应用的主页)。Sorcino会检测这种模式,避免将这类“全能响应”错误地归类为LLM代理的配置文件泄露。
2.3 安全诊断:多层级的漏洞检测策略
识别出服务后,最关键的“深度检测”环节开始。Sorcino按照安全风险的严重程度,构建了一个分层的检测体系:
认证绕过(Auth Bypass):这是最高危的风险之一。检测器会尝试访问那些本应需要API Key、Token或密码才能访问的端点。例如,直接尝试连接OpenClaw的WebSocket网关(
/ws),或向LiteLLM的聊天补全接口(/v1/chat/completions)发送一个不含认证头的请求。如果请求成功并返回了看似正常的LLM响应,则说明存在认证缺失。敏感信息泄露(Information Disclosure):
- API密钥暴露:在HTTP响应体、错误消息甚至默认页面的HTML源码中,正则搜索
sk-ant-*(Anthropic Claude)、sk-*(OpenAI)等模式的字符串。许多开发者在调试时会将密钥硬编码在配置中或打印到日志,这些信息可能通过未受保护的调试接口泄露。 - 配置文件与环境变量:尝试访问常见的敏感文件路径,如
/.env、/config.json、/manifest.yml。结合SPA过滤,确保只保存真正返回了配置文件内容(而非HTML页面)的结果。 - 调试信息与堆栈跟踪:检查响应中是否包含“debug”、“traceback”、“exception”等关键词,这通常意味着服务运行在调试模式,可能暴露内部逻辑、代码路径甚至数据库连接信息。
- 版本信息泄露:从响应头或正文中提取具体的软件版本号,这有助于攻击者寻找对应的公开漏洞。
- API密钥暴露:在HTTP响应体、错误消息甚至默认页面的HTML源码中,正则搜索
mDNS信息泄露:对于通过
mdns-scan发现的目标,解析其广播的TXT记录。某些服务的mDNS实现可能会泄露cliPath(暴露服务器上的用户名路径)、sshPort(暴露SSH服务端口)等额外信息,扩大了攻击面。策略配置错误:例如,检测到某些代理服务(如OpenClaw)的域管理(DM)策略是否为完全开放的“allow all”模式,而未设置任何允许列表(allowlist),这可能导致服务被滥用。
每一类检测结果都会被赋予一个严重等级(如CRITICAL, HIGH, MEDIUM, LOW),用户可以通过--min-severity参数来过滤报告,只关注符合自己需求的风险级别。
3. 实战部署与扫描策略详解
了解了Sorcino能做什么,接下来我们看看怎么把它用起来,以及如何根据不同的场景调整扫描策略,在效率、深度和隐蔽性之间找到最佳平衡。
3.1 环境搭建与初步运行
部署Sorcino非常简单,它基于Python 3.9+,使用Poetry或pip进行依赖管理。推荐在虚拟环境中安装,以避免污染系统Python环境。
# 1. 克隆仓库 git clone https://github.com/renat0z3r0/sorcino.git cd sorcino # 2. 创建并激活虚拟环境(以venv为例) python -m venv .venv source .venv/bin/activate # Linux/macOS # .venv\Scripts\activate # Windows # 3. 安装依赖(使用pip直接安装) pip install -e . # 或者使用项目提供的requirements.txt(如果存在) # pip install -r requirements.txt安装完成后,直接在命令行输入sorcino即可看到主帮助信息。我们来运行一个最简单的扫描,针对本地回环地址上的一个假设服务进行测试:
sorcino scan 127.0.0.1 --ports 8080,18789 --verbose这个命令会扫描127.0.0.1的8080和18789端口,并启用详细模式。--verbose参数对于初次使用和理解工具工作流程非常有用,它会打印出每个探针发送的请求和接收到的原始响应(节选),让你清楚地看到Sorcino是如何与目标交互的。如果本地没有运行相关服务,你可能会看到连接超时或拒绝连接的提示,这属于正常现象。
3.2 扫描模式深度解析:快、准、隐
Sorcino预设了三种扫描模式:fast、thorough(默认)和stealth。它们本质上是三组预设参数的组合,包括超时时间、并发数和请求延迟。理解这些参数的含义,是灵活运用工具的关键。
- 超时时间(
--timeout):等待目标响应的最长时间。对于网络延迟高或服务响应慢的目标,需要设置更长的超时。fast模式设为3秒,可能错过一些响应慢但实际存在的服务;stealth模式设为15秒,则容错性更高。 - 并发数(
--concurrency):同时执行扫描任务的最大数量。并发数越高,扫描速度越快,但对本地网络和计算资源消耗越大,也更容易触发目标的防护机制(如速率限制、IP封禁)。fast模式使用50个并发,追求速度;stealth模式仅用5个,极为温和。 - 延迟(
--delay):在发送一批请求后,暂停的时间(毫秒)。这是“隐身”扫描的关键。fast和thorough模式延迟为0,全力冲刺;stealth模式每批请求后延迟500毫秒,模拟人类操作节奏,极大降低被WAF或IDS检测到的概率。 - 反向DNS解析(
--rdns/--no-rdns):是否对目标IP进行PTR记录查询,以获取其域名。这能帮助你将一个冰冷的IP地址关联到更有意义的域名(如server-1.prod.llm-cluster.example.com),在报告中提供更多上下文。但反向DNS查询会增加扫描总耗时。
模式选择指南:
- 内部资产清查(
fast模式):当你拥有对目标网络(如公司内网、VPC)的完全控制权和扫描许可时,追求速度是第一位的。使用--mode fast,甚至可以搭配--concurrency 100或更高来进一步加速。由于是内部环境,通常无需考虑隐蔽性。 - 授权的渗透测试(
thorough或stealth模式):在对客户外部资产进行授权测试时,需要平衡全面性和隐蔽性。初期可以使用thorough模式进行较全面的发现。在对关键业务系统或已知有敏感防护的系统进行深度检测时,则应切换到stealth模式,并可能手动增加--delay到1000ms以上,以避免触发告警。 - 互联网广谱研究(
fast+--rdns):如果你在进行合法的安全研究,希望了解某类服务在互联网上的暴露情况,可以先用fast模式快速扫描大量IP(例如从Shodan导入的列表),并开启--rdns以便对结果进行归类分析(例如,发现大量暴露服务属于某家云厂商的特定产品)。
你完全可以打破预设,手动组合参数。例如:
# 高并发快速扫描,但保留反向DNS查询以便分析 sorcino scan 10.0.0.0/24 --concurrency 80 --timeout 5 --rdns # 极致的隐蔽扫描,用于敏感目标 sorcino scan 203.0.113.10 --concurrency 2 --timeout 20 --delay 2000 --no-rdns3.3 证据收集与报告生成:从发现到取证
单纯的“有漏洞”结论是不够的,我们需要证据。Sorcino的--dump-evidence参数就是为此而生。当启用此选项后,工具会为每一个发现问题的目标创建一个独立的目录,保存原始的、未经修饰的证据文件。
sorcino scan 192.168.1.100 --dump-evidence --verbose执行后,你会在当前目录下看到一个以时间戳和IP命名的文件夹,例如evidence/20250203_143052_192.168.1.100/。里面可能包含:
.env:如果探测到并成功下载了该文件,这里保存的就是其真实内容,可能包含数据库密码、API密钥等。config.json:服务的配置文件。websocket_responses.txt:WebSocket连接的完整握手过程和消息交互记录,这是证明认证绕过最直接的证据。manifest.json:一个索引文件,列出了所有收集到的证据及其对应的检测项。
这些原始证据对于编写渗透测试报告、进行深入分析或与系统所有者沟通确认漏洞至关重要。务必妥善保管这些证据,因为它们包含真实的敏感信息。
报告输出是另一个核心功能。Sorcino支持三种格式:
- JSON(
-f json):默认格式,结构化程度最高,适合被其他程序(如SIEM系统、自动化工单平台)解析和导入。 - Markdown(
-f markdown):可读性很好,可以直接粘贴到Wiki、GitHub Issue或报告中,支持表格和代码块格式化。 - 纯文本(
-f txt):最简洁的格式,适合快速在终端查看或通过命令行工具处理。
如果不使用-o指定输出文件名,Sorcino会自动生成带时间戳的文件名,如sorcino_scan_20250203_143052.md,这能很好地避免报告被覆盖。在自动化扫描中,你可以将输出重定向到指定目录,并结合日期变量来归档报告。
# 生成Markdown报告并归档 OUTPUT_DIR="./reports" mkdir -p $OUTPUT_DIR sorcino scan @target_list.txt -f markdown -o $OUTPUT_DIR/scan_$(date +%Y%m%d_%H%M%S).md4. 典型应用场景与避坑指南
在实际使用中,Sorcino能应用于多种场景,但每个场景都有需要注意的“坑”。这里结合我自己的使用经验,分享几个典型案例和对应的技巧。
4.1 场景一:企业内部LLM服务资产梳理与风险排查
场景描述:一家公司内部多个团队各自部署了OpenClaw或LiteLLM用于项目开发,但缺乏统一管控。安全团队需要摸清家底,找出所有暴露在内部网络(甚至可能因配置错误暴露到公网)的实例,并评估其安全状态。
操作流程:
- 目标收集:首先,从公司CMDB、云平台API、子域名枚举结果中,收集所有可能运行服务的IP段和域名列表,保存到
targets.txt。 - 初步扫描:使用快速模式进行第一轮存活探测和端口识别。由于是内网,可以放宽并发限制。
sorcino scan @targets.txt --ports 18789,4000,11434,8080,8000 --mode fast --concurrency 100 -o initial_scan.json - 深度检测:针对初步扫描发现的疑似目标,进行第二轮深度安全检测。此时应使用
thorough模式,并开启证据收集。# 从initial_scan.json中提取出有响应的IP列表 (假设用jq工具) jq -r '.results[] | select(.status == "open") | .ip' initial_scan.json > live_targets.txt sorcino scan @live_targets.txt --mode thorough --dump-evidence -o detailed_report.md - 分析与报告:分析Markdown报告,按照严重等级排序。将CRITICAL和HIGH级别的发现(如认证绕过、API密钥泄露)立即通知相关团队整改。MEDIUM和LOW级别(如版本信息泄露)纳入定期安全加固计划。
避坑指南:
- 避开生产高峰期:即使在内网,高并发扫描也可能对性能较差的服务造成压力,甚至导致服务短暂不可用。务必在变更窗口或业务低峰期进行。
- 注意非标端口:团队可能将服务运行在任意端口上。除了常用端口,可以结合内部流量日志分析,找出非常规的HTTP/WebSocket流量端口,加入扫描列表。
- 误报处理:某些内部管理系统或API网关的响应可能与LLM代理的指纹相似。务必人工复核
--dump-evidence收集到的原始响应,确认是否为真正的目标服务。
4.2 场景二:授权渗透测试中的外部攻击面发现
场景描述:对客户授权的外部IP范围进行渗透测试,需要发现暴露的、易受攻击的LLM代理端点。
操作流程:
- 范围确认:明确获得授权的IP范围或域名列表。这是法律和合规的底线。
- 隐蔽信息收集:优先使用被动信息收集。尝试使用
sorcino shodan-import,查询与客户相关的域名、IP段或ASN,看是否有历史记录暴露了相关服务。这不会对目标产生主动流量。 - 温和扫描:对授权目标进行扫描时,首选
stealth模式。如果目标范围很大,可以先对一小部分IP进行stealth扫描,测试对方的防护设备是否敏感。根据响应情况,再谨慎调整--delay和--concurrency。sorcino scan 203.0.113.0/28 --mode stealth --min-severity high -o pentest_initial.md - 针对性深度探测:对于发现的每一个开放服务,手动运行一次带有
--verbose和--dump-evidence的深度扫描,确保不漏过任何细节。WebSocket认证绕过测试尤其需要完整的交互证据。
避坑指南:
- 严格遵守授权范围:绝对不要扫描授权书指定范围之外的任何IP或域名。一个常见的错误是,当目标域名指向CDN时,其背后的真实IP可能不在授权范围内。
- 警惕WAF/IPS:
stealth模式并非万能。一些高级的WAF或入侵防御系统(IPS)能识别出扫描工具的特征流量。如果发现连接被频繁重置或IP被短暂封禁,应立即停止扫描,并与客户沟通。 - 证据链完整性:渗透测试报告需要无可辩驳的证据。
--dump-evidence保存的原始流量、--verbose输出的日志,以及扫描命令本身的历史记录,都应妥善保存,作为测试工作的证明。
4.3 场景三:安全研究与互联网暴露面测绘
场景描述:安全研究员希望了解OpenClaw等LLM代理在全球互联网上的暴露情况和普遍的安全状况。
操作流程:
- 获取目标列表:利用Shodan、Censys等网络空间搜索引擎的API,大规模获取运行在特定端口(如18789, 4000)的服务IP列表。Sorcino的Shodan导入功能可以直接对接。
# 假设已设置SHODAN_API_KEY环境变量 sorcino shodan-import "port:18789" --api-key $SHODAN_KEY --list-only > openclaw_ips.txt # 可以对列表进行去重、随机采样等处理 shuf openclaw_ips.txt | head -1000 > sample_targets.txt - 抽样扫描:由于是研究性质,且目标数量可能巨大,通常采用抽样扫描。使用
fast模式快速获取一批样本数据。sorcino scan @sample_targets.txt --mode fast --rdns -f json -o research_data.json - 数据分析:使用脚本(如Python的pandas、jq)对输出的JSON数据进行分析。计算暴露服务的比例、各服务类型的分布、存在高风险漏洞(认证绕过、密钥泄露)的比例等。反向DNS信息(
--rdns)可以帮助分析这些服务主要分布在哪些云服务商、大学或组织中。
避坑指南:
- 法律与伦理:这是最需要谨慎的领域。即使是为了研究,大规模扫描互联网也可能违反计算机滥用相关法律,并可能对目标系统造成影响。务必:
- 将扫描速率控制在极低水平(高延迟、低并发)。
- 优先扫描那些明确标识为“测试”、“沙箱”或属于云厂商公开实验项目的IP段。
- 考虑与Shodan等平台合作,利用其已有的扫描数据进行分析,而非自己发起大量新扫描。
- 在公开发布研究成果时,对数据进行充分的匿名化和聚合处理,不暴露具体的IP和可识别信息。
- 资源消耗:大规模扫描会消耗大量本地网络带宽和系统资源。确保在拥有足够资源的机器上运行,并监控系统状态。
5. 常见问题排查与进阶技巧
即使工具设计得再完善,在实际操作中总会遇到各种问题。下面整理了一些我遇到过的典型问题及其解决方法,以及一些能提升效率的进阶技巧。
5.1 扫描结果为空或漏报
问题:明明感觉目标应该存在服务,但Sorcino报告没有发现任何东西。
排查步骤:
- 确认网络连通性:首先用
curl或telnet手动测试目标IP和端口是否能连通。curl -v http://target:port。 - 启用详细模式:使用
--verbose参数。这会输出每个探针的详细请求和响应信息。观察是连接超时、连接被拒绝,还是收到了响应但未被识别。- 连接超时:增加
--timeout值(例如从10秒增加到30秒)。 - 连接被拒绝:端口未开放,或者有防火墙拦截。
- 收到响应但未识别:查看响应的原始内容。可能服务指纹不在Sorcino的当前识别库中,或者服务返回了非标准错误页面。这是一个向工具反馈或自行研究新指纹的机会。
- 连接超时:增加
- 检查端口列表:Sorcino默认扫描的端口是有限的(如OpenClaw的18789)。确保你通过
--ports参数指定了正确的端口。如果服务运行在80或443端口,需要显式指定--ports 80,443。 - 尝试不同扫描模式:
fast模式可能因为超时时间短而漏掉响应慢的服务。换用thorough或stealth模式再试一次。
5.2 误报问题
问题:Sorcino报告发现了漏洞(如配置文件泄露),但实际访问发现只是一个普通的404页面或应用首页。
原因与解决:这通常是SPA(单页应用)误报过滤未能完全生效的情况。虽然Sorcino内置了过滤机制,但某些Web框架或自定义错误页面的行为可能比较特殊。
- 复核证据:使用
--dump-evidence功能,直接查看工具保存的所谓“配置文件”内容。如果里面是HTML代码,那就是误报。 - 调整过滤逻辑:目前Sorcino的过滤逻辑是内置的。如果某种误报模式反复出现,且你懂Python,可以尝试阅读源码中关于响应过滤的部分(通常涉及检查Content-Type和内容是否为HTML),并向项目提交Issue或PR来改进指纹库。
- 人工研判:在自动化工具报告的基础上,人工复核中高风险发现是安全工作的必要环节。不要完全依赖工具的输出。
5.3 性能优化与大规模扫描
当需要扫描成千上万个IP时,性能和时间成为关键因素。
技巧:
- 合理设置并发数:并发数 (
--concurrency) 并非越高越好。过高的并发会导致本地网络拥堵、大量Socket占用,甚至被目标网络设备识别为洪水攻击。一般建议从20-50开始,根据本地带宽和CPU情况调整。监控top或htop命令,如果CPU或网络I/O持续饱和,应降低并发。 - 分而治之:将巨大的目标列表(例如
/16网段,6万多个IP)分割成多个小文件,并行运行多个Sorcino实例,每个实例处理一个子集。注意要错开扫描的起始时间,并使用不同的输出文件。# 假设 targets_all.txt 包含大量IP split -l 1000 targets_all.txt target_chunk_ # 在后台并行运行多个扫描任务 for chunk in target_chunk_*; do sorcino scan @$chunk --mode fast --quiet -o result_${chunk}.json & done wait # 等待所有后台任务结束 - 利用
--quiet模式:在脚本化或后台运行时,使用--quiet参数可以关闭进度条和所有非关键信息输出,只打印错误和最终结果摘要,减少输出开销,也便于日志解析。 - 结果合并:扫描完成后,你可能需要将多个JSON结果文件合并分析。可以使用
jq工具:jq -s '.[].results[]' result_*.json | jq -s 'add' > final_combined.json
5.4 与其他工具集成
Sorcino可以很好地融入现有的安全工具链。
- 与Nmap联动:先用Nmap进行快速的端口发现和基础服务识别,然后将开放了相关端口(如18789, 4000, 11434)的IP导出,交给Sorcino进行深度检测。
nmap -p 18789,4000,11434 --open -oG open_ports.gnmap 10.0.0.0/24 grep -E "^(Host:|Ports:.*open)" open_ports.gnmap | awk '/^Host:/ {ip=$2} /^Ports:/ {if (ip) print ip}' > sorcino_targets.txt sorcino scan @sorcino_targets.txt --mode thorough - 将结果导入SIEM或工单系统:Sorcino的JSON输出是结构化的,可以编写脚本,提取出CRITICAL和HIGH级别的发现,自动创建Jira工单或发送告警到Slack/Teams频道,甚至推送到SIEM(如Splunk、Elasticsearch)进行关联分析。
最后,再分享一个我个人非常受用的习惯:为每一次重要的扫描任务创建一个独立的日志目录。里面不仅存放Sorcino的报告和证据,还保存你当时使用的完整命令、目标列表、以及任何手动测试的笔记(用curl测试的命令历史等)。这就像飞行器的黑匣子,当几周或几个月后需要回溯或澄清某个发现时,这些记录是无价之宝。安全工作的价值不仅在于发现漏洞,更在于清晰、可追溯、可复现的过程。