skills/tool/browser-xterm-interaction/SKILL.md
Playwright Browser MCP 与 xterm.js 终端交互方法论。当需要通过浏览器操作网页内嵌终端、CTF 靶场伪终端、Cloud Shell、在线 IDE 中的终端时使用。覆盖终端内容读取(5 种方法)、命令执行、输出捕获、screenshot 降级策略。只要目标页面中有任何形式的 Web 终端(xterm.js/hterm/jQuery Terminal),就应使用此技能
npx skillsauth add wgpsec/AboutSecurity browser-xterm-interactionInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Web 终端(xterm.js、hterm 等)在浏览器中渲染终端界面,但其输出通常用 canvas 或自定义 DOM 渲染,标准的 browser_snapshot() 只能看到 accessibility tree 中的最后一行 prompt。这是与 Web 终端交互时最大的痛点——需要用特定的 JS 方法才能可靠地读取终端输出。
echo "===START==="; cmd; echo "===END===" 包裹命令输出,方便精确提取先用一次 browser_snapshot() 或 browser_evaluate 探测终端类型:
// 探测终端类型
() => {
const xterm = document.querySelector('.xterm');
const jquery_term = window.jQuery && window.jQuery.fn.terminal;
const hterm = document.querySelector('[id*="hterm"]');
return {
xterm: !!xterm,
jquery_terminal: !!jquery_term,
hterm: !!hterm,
terminal_classes: xterm ? xterm.className : 'not found'
};
}
browser_type(ref='<terminal_input_ref>', text='your command', submit=True)
browser_click(element='terminal area', ref='<terminal_ref>')
browser_press_key(key='your command text') // 逐字符
browser_press_key(key='Enter')
() => {
const textarea = document.querySelector('.xterm-helper-textarea');
if (textarea) {
textarea.focus();
// 通过 InputEvent 模拟输入
}
}
⚠️ 重要:执行命令后,必须等待足够时间让输出完成:
browser_wait_for(time=2)browser_wait_for(time=5)browser_wait_for(time=15-30)读取终端输出后,必须检查输出是否完整:
发现输出可能不完整时,立即用重定向法重试:
command > /tmp/verify.txt 2>&1 && cat /tmp/verify.txt
不要继续基于不完整输出做决策。
() => {
const rows = document.querySelectorAll('.xterm-rows > div');
let lines = [];
for (let row of rows) {
const text = row.innerText || row.textContent || '';
if (text.trim()) lines.push(text);
}
return lines.join('\n');
}
() => {
const screen = document.querySelector('.xterm-screen');
return screen ? screen.innerText : 'not found';
}
() => {
// 尝试通过 xterm.js Terminal 实例的 buffer 读取
const term = document.querySelector('.xterm');
if (term && term._core) {
const buffer = term._core.buffer.active;
let lines = [];
for (let i = 0; i < buffer.length; i++) {
const line = buffer.getLine(i);
if (line) lines.push(line.translateToString(true));
}
return lines.join('\n');
}
return 'Terminal API not accessible';
}
执行命令时用 marker 包裹,便于精确提取:
echo "===START==="; your_command_here; echo "===END==="
然后在 JS 中提取 ===START=== 和 ===END=== 之间的内容。
your_command > /tmp/out.txt 2>&1; cat /tmp/out.txt
适用于输出很长或滚动导致内容丢失的情况。
当 JS 方法都无法可靠读取终端输出时:
browser_take_screenshot(type='png', filename='term_output.png')
Read(file_path='<output_dir>/term_output.png')
然后通过图片内容视觉分析终端输出。
⚠️ 禁止使用 fullPage=True — 全页截图体积极大(>1MB),会导致 SDK JSON buffer 溢出崩溃。只用默认的 viewport 截图。
优点:100% 可靠,不依赖 DOM 结构 缺点:消耗更多 tokens、只能看到可视区域
技巧:
fullPage=True 尝试全页截图browser_snapshot() 只返回最后一行 promptxterm.js 用 canvas 或 DOM renderer 渲染,snapshot 只能看到 accessibility tree。
解决: 用 browser_evaluate + Phase 3 的 JS 方法。
browser_evaluate 返回空字符串可能终端用了 canvas renderer,DOM 中没有文本节点。 解决: 用 screenshot 兜底。
xterm.js 有 scrollback buffer 限制(默认 1000 行)。 解决: 用重定向到文件法,或分段查看。
可能等待时间不够,或终端没有刷新。
解决: 增加 browser_wait_for 时间,或按 Enter 触发刷新。
开始
↓
识别终端类型 (Phase 1)
↓
执行命令 (Phase 2, 方法 A 优先)
↓
等待输出 (browser_wait_for)
↓
尝试 JS 读取 (Phase 3, 方法 1)
├── 成功 → 锁定此方法,后续复用
├── 失败 → 尝试方法 2
│ ├── 成功 → 锁定
│ ├── 失败 → 尝试方法 3
│ │ ├── 成功 → 锁定
│ │ └── 失败 → Screenshot 兜底 (Phase 4)
└── 3 次后仍不稳定 → Screenshot 兜底
⚠️ 禁止: 在 JS 读取方法之间反复来回切换超过 3 次。确定一种方法后坚持使用。
Web 终端的输入框通常是单行的,直接粘贴多行 Python/Bash 脚本会导致格式错误。
方法 A: heredoc 写文件(推荐)
// 逐行写入脚本文件
browser_type(ref, "cat > /tmp/exploit.py << 'PYEOF'", submit=True)
browser_wait_for(time=1)
browser_type(ref, "import boto3, json", submit=True)
browser_type(ref, "s3 = boto3.client('s3')", submit=True)
browser_type(ref, "print(s3.list_buckets())", submit=True)
browser_type(ref, "PYEOF", submit=True)
browser_wait_for(time=1)
browser_type(ref, "python3 /tmp/exploit.py", submit=True)
方法 B: base64 编码(最可靠)
// 先在本地构造脚本,base64 编码后一行写入
// 本地 bash:
echo 'import boto3; print(boto3.client("s3").list_buckets())' | base64
// → aW1wb3J0IGJvdG8z...
// 在 Web 终端:
browser_type(ref, "echo 'aW1wb3J0IGJvdG8z...' | base64 -d > /tmp/s.py && python3 /tmp/s.py", submit=True)
方法 C: echo 追加(简单脚本)
browser_type(ref, "echo 'import boto3' > /tmp/s.py", submit=True)
browser_type(ref, "echo 's3=boto3.client(\"s3\")' >> /tmp/s.py", submit=True)
browser_type(ref, "echo 'print(s3.list_buckets())' >> /tmp/s.py", submit=True)
browser_type(ref, "python3 /tmp/s.py", submit=True)
⚠️ 禁止: 在 browser_type 的 text 参数中包含 \n 换行符 — Web 终端输入框不支持多行输入。
Web 终端可能限制写入 ~/.aws/credentials(Permission denied):
// 方法 A: export 在同一行(仅当前命令有效)
browser_type(ref, "AWS_ACCESS_KEY_ID=AKIAXXXX AWS_SECRET_ACCESS_KEY=YYYY aws s3 ls", submit=True)
// 方法 B: 在 Python 脚本内设置
browser_type(ref, "cat > /tmp/s.py << 'EOF'", submit=True)
browser_type(ref, "import os, boto3", submit=True)
browser_type(ref, "os.environ['AWS_ACCESS_KEY_ID']='AKIAXXXX'", submit=True)
browser_type(ref, "os.environ['AWS_SECRET_ACCESS_KEY']='YYYY'", submit=True)
browser_type(ref, "s3=boto3.client('s3',region_name='us-east-1')", submit=True)
browser_type(ref, "print(s3.list_buckets())", submit=True)
browser_type(ref, "EOF", submit=True)
browser_type(ref, "python3 /tmp/s.py", submit=True)
Web 终端输出缓冲区有限,长输出会丢失开头部分:
// 使用 marker 包裹 + tail 截取
browser_type(ref, "echo '===START==='; aws s3 ls 2>&1 | tail -50; echo '===END==='", submit=True)
// 输出写文件再分段读取
browser_type(ref, "python3 /tmp/exploit.py > /tmp/out.txt 2>&1", submit=True)
browser_type(ref, "head -20 /tmp/out.txt", submit=True)
browser_type(ref, "tail -20 /tmp/out.txt", submit=True)
testing
Azure 云环境渗透测试总体方法论。当目标使用 Azure/Microsoft 365/Entra ID、发现 Azure 相关资产(Blob Storage/App Service/Azure VM/Azure Functions)、获取 Azure 凭据(Service Principal/Managed Identity/Access Token)、或需要对 Azure 环境进行安全评估时使用。提供从未授权枚举到 Entra ID 攻击、服务提权、Cloud-to-OnPrem 横向移动的全流程决策树。覆盖 35+ Azure 服务攻击面
tools
Mythic C2 操作方法论。当需要部署 Mythic、选择 Mythic Agent、安装 C2 Profile、配置 HTTP/DNS/WebSocket/SMB/TCP 通信、生成 payload、管理回连任务,或把 Mythic 作为跨平台 C2 框架用于授权红队演练时使用。覆盖 mythic-cli 安装、Agent/Profile 选择、SSL 证书配置、payload 构建和基础 OPSEC 判断
development
Docker 安全测试与容器渗透方法论。当需要评估 Docker 容器、Docker Daemon、Docker Registry、镜像层、构建产物或容器逃逸风险时使用。覆盖容器环境识别、特权容器逃逸、docker.sock/Remote API 利用、procfs/cgroup/capabilities 滥用、Docker 用户组提权、运行时/内核 CVE、Registry 枚举、镜像层 Secret 分析和构建上下文泄露。发现 Docker 容器环境、Registry 暴露、镜像凭据或容器配置错误时应使用此技能
development
使用 PadBuster 进行 Padding Oracle 攻击。当发现 Web 应用使用 CBC 模式加密且存在 Padding Oracle 漏洞时使用。PadBuster 可自动解密密文和伪造任意明文对应的合法密文,适用于加密 Cookie/Token/URL 参数。任何涉及 Padding Oracle 攻击、CBC 密文解密、Cookie 伪造的场景都应使用此技能