Apache OpenMeetings 9.1.0 - 高危 - 远程 - IDOR - LOGIN calendar save 覆盖预约并关闭公共房间
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · openmeetings-calendar-save-idor
类别: IDOR 可达性: 远程
Apache OpenMeetings 9.1.0(9773c59e) - Apache Software Foundation
任何 LOGIN 用户都可以使用另一个预约的 id 并省略 owner 来 POST /services/calendar/。保存谓词从不加载持久化的 owner。随后 CalendarMapper 和 RoomMapper 在关联的 room 上写入 closed / ispublic / name。已注册用户可覆盖他人的会议并关闭公共会议室。
| ID | 暂无 CVE |
| 类别 | IDOR |
| 可达性 | 远程(已认证 LOGIN REST) |
| CWE | CWE-639、CWE-284 |
| CVSS | 高危:7.6 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:H/A:L |
| 产品 | Apache OpenMeetings |
| 受影响版本 | 9.1.0(9773c59e1af327bf988018e661f456ae9997c29f) |
| 认证 | LOGIN(默认自助注册即可获得) |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18150。apache/openmeetings:min-9.1.0 加 Temurin 21。 |
我固定了标签 9.1.0,剥离 9773c59e1af327bf988018e661f456ae9997c29f(2026-07-14)。最新 GA。Java 21。不是 master。
注册(向导 allowFrontendRegister=true)或持有任意 LOGIN 密码。POST /openmeetings/services/user/login 会签发一个 SID。预约 id 是连续的。公共 room id 2 是默认会议室。
| 方法 | 汇聚点 | 权限影响 |
|---|---|---|
POST /services/calendar/?sid= 表单 appointment JSON,省略 owner,使用受害者的 id | CalendarWebService.save 谓词(CalendarWebService.java:310-329) | 完整性(实验验证): 覆盖标题、时间、成员。实验:标题变为 OPENMEETINGS-CALENDAR-SAVE-WITNESS,owner 2→3。 |
同样的保存;room.closed=true | RoomMapper.get 在受管实体上写入(RoomMapper.java:62-92),然后 dao.update | 完整性 + 可用性(实验验证): 公共会议室被持久化为 closed=true、isPublic=false。SOAP GET /room/2 返回了该结果。 |
保存后攻击者 GET 标题/范围 | 响应 DTO 是写入后的行 | 侦察(实验验证): 见证标题。owner 被窃取后受害者范围为空。 |
实验验证与推断: 保存 HTTP 200、标题、owner 窃取、room 关闭均为实验验证。同一 mapper 上的容量/主持位标志为推断。
前提条件: 到 /openmeetings/services 的网络路径。一个 LOGIN 账户。一个受害者预约 id(连续,或创建一个并等待)。默认开放注册。
| 攻击面 | 原因 |
|---|---|
DELETE /calendar/{id} | owner 或 SOAP/ADMIN。普通 LOGIN 无法删除他人。 |
| 范围 / next / 标题读取 | 按 owner 限定。攻击者无法干净地读取原始行。 |
| 录制 MP4 | 不同的 ACL(RecordingResourceReference)。 |
| 仅 SOAP 的按 userid 列表 | Right.SOAP。默认注册用户没有该权限。 |
| 未认证保存 | performCall 需要带 LOGIN 的 SID。 |
9.1.0 修复了 CVE-2026-49488(白板 fuid 操作系统读取)。我继续寻找 REST 对象 id。日历删除会检查 a.isOwner(sd.getUserId())。日历保存检查请求 DTO 的 owner,或为 null。CalendarMapper.get 加载 appointmentDao.get(dto.getId()),没有 owner 范围限定。随后 RoomMapper 在 dao.update 之前弄脏 room JPA 实体。
SOAP 列出所有预约记录的是 LMS 集成账户。这个遗留项是 LOGIN 与所有者之间的差异。
cd lab
./run.sh
回环地址 https://127.0.0.1:18150/openmeetings。官方 docker 管理员 om_admin / 1Q2w3e4r5t^y。自签名 TLS。见证最后一行:
SUCCESS OPENMEETINGS-CALENDAR-SAVE-WITNESS
在保存前加载已持久化的预约。除非是 SOAP/ADMIN,否则要求 a.isOwner(caller)。不要将 RoomMapper 的写入应用到调用者无权主持的房间。将省略的 owner 视为“保留已持久化的 owner”,而不是“调用者成为 owner”。
Abraxas Labs - https://abraxaslabs.tech - https://github.com/abraxas - https://x.com/abraxas_null - [email protected]