- name
- jeecg-boot-deep-exploitation
- description
- JeecgBoot 深入利用(双防线SQLi盲注/PBE凭据破解/接管/RCE判定)时用。
# JeecgBoot 深度利用链(2.4.5 实战固化)
> 2026-08-12 科亿 KYKMS 官方演示站实战:fieldName 盲注过双防线 → admin PBE 凭据拖取破解(123456)→ L3 完全接管。
> 前置技能:java-web-framework-pentest(指纹/攻击面地图/初判路线)。本技能接管"确认是 JeecgBoot 之后怎么打穿"。
## 1. SQLi:双防线结构与唯一正解
### 防线识别(响应特征)
- **应用层 SqlInjectionUtil**:`"请注意,值可能存在SQL注入风险!---><你的payload>"`(payload 回显=黑名单型过滤器)
- **Druid WallFilter**:`"sql injection violation, comment not allow"` / `syntax error`(注释全禁、语法检查)
### ✅ 唯一稳定正解:合法 SQL 布尔 oracle(零注释/零黑名单词/零引号)
以 `/sys/duplicate/check`(tableName/fieldName 为 `${}` 直拼、fieldVal 参数化):
```
fieldName=if(1,0x78,0x79) → "该值不可用,系统中已存在!"(真)
fieldName=if(0,0x78,0x79) → "该值可用!"(假)
```
构造要点(全在 references 有推导):
- **hex 字面量替代字符串**:`'` 在黑名单 → 0x78='x';尾部 `= #{fieldVal}` 拼成合法等式
- **子查询无空格形态**:`select(password)from(sys_user)where(username)=0x61646d696e`——2.4.5 黑名单是"select␣"带尾随空格,`select(` 不命中
- **布尔假分支必须 if() 包裹**:裸 `id<0` 会被尾巴 `='x'` 变成永真(运算符优先级坑)
- **长度探测用逐位存在性**:`ascii(substr(f,N,1))>0`(越界→''→ascii=0→假);length() 可能被拦/异常,**多判据矛盾时以 substr 存在性链为准**(自洽性校验)
- 报错注入(extractvalue/updatexml)在新版词表被拦且 MyBatis 分页 COUNT 包装吞 XPATH 回显——优先布尔/时间形态
- 时间盲注注意:`ORDER BY sleep(N)` 对全表每行执行(行数×N 秒,远超客户端超时=连接池风险)——判定用双发对照+量级估算
### 拖数据工程化
- 二分 ascii(32-126),4s 间隔低频,断点落盘(state.json),token 失效自动重登
- 16hex 密文 ≈ 16×7 发 ≈ 18 分钟
## 2. 认证体系解剖(2.4.5 实测)
- `JwtUtil.sign(username, syspassword)`——**密码 hash 即 JWT secret**
- **伪造 token 死路**:ShiroRealm 先查 Redis 缓存 token(`PREFIX_USER_TOKEN+token` 不存在即失效)——签名正确也没用,别浪费时间伪造
- **密码=PBEWithMD5AndDES**(PBKDF1-MD5×1000→DES key+IV,salt=randomGen(8)):密文=DES-CBC(username) hex,**admin→16hex**(长度随 username 变)
- Python 复刻:`PBKDF1(pwd, salt.encode(), dkLen=16, count=1000, hashAlgo=MD5)`(pycryptodome,参数是 hashAlgo)
- 离线爆破判定:解密==username 即命中;演示站 admin=123456 秒破
- login 密码**明文传输**(2.4.5 官方注释掉加密);captcha=`/sys/randomImage/{key}` 字符/算数码,ddddocr 可过;**Redis 故障时 captcha 校验 500 不放行**(无降级绕过,别幻想)
- 注册链:查重先于验证码(匿名三态枚举 oracle);sms 仅同号 10min 限制(轰炸面);验证码注册后不消费可复用
## 3. quartz 定时任务面
- **kykms 系 Controller 的 @RequiresRoles("admin") 全注释**——任意登录用户可控任务(未授权高危,直接可报)
- RCE 排除实证(三连):①类须实现 Job 接口 ②JeecgBoot 只传 `parameter` 单键 vs NativeJob 等读 "command" 键名不匹配 ③NativeJob 在 quartz-jobs 独立包(spring-boot-starter-quartz 不带)——**classpath 探测法**:add status=0 的 job,报"后台找不到该类名"=不在
- 2.4.5 QuartzJobController **无 executeOnce 端点**(别找了)
## 4. 二开产品攻击面速查(kykms 范式)
- 指纹:`xiaobei-knowledge-web` title / `com.hqcloud` 包名 / `/ky` context
- 新版已删 downloadKmDoc/listTopicPageList/kmSysDbBackup;下载重构为 `/KM/kmFile/publicDownload/file/<physicalPath>`(public 前缀官方 anon,**错误消息吐服务器绝对路径**)
- IDOR→下载链:listRecently 拿文档 → kmFile/queryById 拿 physicalPath(全字段泄露)→ publicDownload 零认证直下
- **@Cacheable Redis 是总开关**:Redis 故障→一切读配置/限流/验证码接口全 60s 超时(uploadDoc 白名单检查也卡死——故障期落盘链不可用)——踩到 60s 超时先想 Redis
- URL 层穿越全死(Tomcat 规范化+nginx 400+%2f 拒);物理路径含日期目录+文件名+id 片段,匿名枚举不可行
## 5. L4/RCE 排除清单(fat jar 形态,全实证版)
quartz(三连排除)| fastjson(无 Object 字段无触发点)| Shiro-550(无 rememberMe 配置零命中)| 上传 jsp(webroot 外)| jmreport/dbBackup(新版已删)| Tika(1.17 已修)| ES groovy(默认关)→ **唯一理论出口=war 部署形态**(jsp 可解析)【推演】
排除过程本身就是报告资产(穷尽可能性记录法),全表见 references。
## 6. 官方演示站合规验证纪律
- README 的 loginRandom 类"随机登录"通道=厂商公开测试场:登录态免费合法,但仍守克制——能力证明即停、不拖全量、不读完整凭据、破坏性链不玩、测试副作用(空用户/job 记录)当场清理
- 补天规则实证:官方演示站是认可的验证渠道("有官方演示站免 10 案例"条款);厂商未注册 7 天后平台自行确认
GitHubで見る