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 사용자라면 누구나 다른 약속(appointment)의 id를 사용하고 owner를 생략한 채 POST /services/calendar/를 호출할 수 있습니다. 저장(save) 판정 로직은 영속화된 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으로 변경됨. |
동일한 save; room.closed=true | RoomMapper.get이 관리 엔티티에 기록 (RoomMapper.java:62-92) 후 dao.update | 무결성 + 가용성 (랩 입증): 공개 회의실이 closed=true, isPublic=false로 영속화됨. SOAP GET /room/2가 그 결과를 반환함. |
저장 후 공격자의 GET 제목/범위 조회 | 응답 DTO는 쓰기 이후 행 | 정찰 (랩 입증): witness 제목. owner 탈취 후 피해자 범위는 비어 있음. |
랩 입증 vs 추론: save HTTP 200, 제목, owner 탈취, room 닫기는 랩에서 입증됨. 동일한 매퍼의 capacity / moderated 비트는 추론임.
요구 사항: /openmeetings/services로의 네트워크 경로. LOGIN 계정. 피해자 약속 id (순차적이거나, 하나 생성 후 대기). 기본 개방형 가입.
| 표면 | 이유 |
|---|---|
DELETE /calendar/{id} | owner 또는 SOAP/ADMIN. 일반 LOGIN은 타인의 항목을 삭제할 수 없음. |
| 범위 / next / 제목 읽기 | owner 범위로 제한됨. 공격자는 원본 행을 깔끔하게 읽을 수 없음. |
| 녹화 MP4 | 다른 ACL (RecordingResourceReference). |
| SOAP 전용 userid별 목록 조회 | Right.SOAP. 기본 등록 사용자는 이를 보유하지 않음. |
| 비인증 save | performCall은 LOGIN이 있는 SID를 요구함. |
9.1.0은 CVE-2026-49488 (화이트보드 fuid OS 읽기)을 해결했습니다. 저는 REST 객체 id를 계속 탐색했습니다. Calendar delete는 a.isOwner(sd.getUserId())를 검사합니다. Calendar save는 요청 DTO의 owner를 검사하거나 null을 허용합니다. CalendarMapper.get은 owner 범위 없이 appointmentDao.get(dto.getId())를 로드합니다. 이어서 RoomMapper가 dao.update 전에 room JPA 엔티티를 변경(dirty) 상태로 만듭니다.
SOAP에서 모든 약속을 나열하는 것은 LMS 통합 계정입니다. 이 잔여 항목은 LOGIN 대 owner입니다.
cd lab
./run.sh
루프백 https://127.0.0.1:18150/openmeetings. 공식 docker 관리자 om_admin / 1Q2w3e4r5t^y. 자체 서명 TLS. Witness 마지막 줄:
SUCCESS OPENMEETINGS-CALENDAR-SAVE-WITNESS
저장 전에 영속된 약속을 로드하십시오. SOAP/ADMIN이 아닌 경우 a.isOwner(caller)를 요구하십시오. 호출자가 중재할 수 없는 회의실에 RoomMapper 쓰기를 적용하지 마십시오. 생략된 소유자를 "영속된 소유자 유지"로 처리하고, "호출자가 소유자가 됨"으로 처리하지 마십시오.
Abraxas Labs - https://abraxaslabs.tech - https://github.com/abraxas - https://x.com/abraxas_null - [email protected]
공급업체: [email protected]