
phpMyAdmin 5.2.3 - 높음 - 원격 - 잔여 - setup/validate 여전히 접근 가능
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-setup-validate
분류: SSRF 도달 범위: 원격
phpMyAdmin 5.2.3 (태그 RELEASE_5_2_3, 커밋 962857e). setup/index.php는 config.inc.php가 존재하면 종료된다. setup/validate.php는 그렇지 않다. 여전히 $isMinimumCommon 하에서 로드되며, 공개 로그인 페이지에서 CSRF 토큰을 가져오고, JSON values 필드에 있는 호스트, 포트, 사용자, 비밀번호로 Validator::testDBConnection -> mysqli_connect를 호출한다.
인증되지 않은 클라이언트가 /를 GET하여 세션 쿠키와 토큰을 얻은 다음, 원하는 Servers/1/host와 Servers/1/port를 담아 setup/validate.php id=Server를 POST한다. phpMyAdmin 호스트는 해당 주소로 TCP MySQL 핸드셰이크를 연다. 이것이 MySQL 프로토콜을 통한 SSRF다: 내부 3306, 내부 서버에 대한 크리덴셜 스터핑, 타이밍과 mysqli 오류로부터의 포트 오라클. 해당 포트에서 MySQL을 말하는 무언가가 있지 않은 한 HTTP 메타데이터 SSRF는 아니다. hide_db는 또한 사용자 정규식을 preg_match에 보간한다. 이 랩에서는 그 ReDoS 경로를 실행하지 않았다.
공식 phpmyadmin:5.2.3 이미지는 setup/을 삭제한다. 이 잔여물은 해당 디렉터리가 여전히 웹 루트에 있을 때만 적용되며, 이는 설치 후 흔한 잔여물이다. 랩은 5.2.3 tarball에서 setup/을 복원하여 핀이 RELEASE_5_2_3과 일치하도록 한다.
PMASA-2016-44 / CVE-2016-6621은 일부 setup SSRF를 다루었다. "config가 존재하면 setup 비활성화" 검사는 validate.php / config.php에 적용된 적이 없다.
| ID | 아직 CVE 없음 |
| 분류 | SSRF (MySQL 프로토콜) |
| 도달 범위 | 원격 (setup/이 여전히 웹에서 접근 가능하면 인증 불필요) |
| CWE | CWE-918 |
| CVSS | High: 7.2 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N |
| 제품 | phpMyAdmin |
| 영향받음 | 5.2.3 태그 RELEASE_5_2_3 (962857e), setup/이 여전히 docroot에 있는 경우 |
| 인증 | 인증 불필요. 공개 로그인 페이지에서 CSRF 토큰 획득. MySQL 로그인 없음. |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1:19230 전용 |
잔여 setup/ 트리에 도달할 수 있는 누구든지 phpMyAdmin 호스트가 자신이 선택한 호스트와 포트로 MySQL 프로토콜 TCP 연결을 열도록 만들 수 있다.
| 권한 | 메서드 / 경로 | 랩 검증 또는 추론 |
|---|---|---|
| PMA 호스트에서 공격자 host:port로 TCP 열기 (아웃바운드 연결 무결성, 해당 포트 정찰) | 인증 없이 POST /setup/validate.php id=Server에 Servers/1/host + Servers/1/port 및 GET /에서 얻은 토큰 | 랩 검증. oracle:13306의 오라클이 PMA 컨테이너로부터 PMA-SETUP-VALIDATE-WITNESS를 기록함 |
| validate는 켜져 있는데 setup UI는 꺼져 있음을 확인 | GET /setup/index.php | 랩 검증. 본문에 "setup is disabled" / configuration already exists 포함 |
| 로그인 페이지 CSRF 토큰 없이 fail closed | 동일 POST, token 없음 | 랩 검증. 오라클 히트 0회 |
| mysqli 오류와 타이밍으로부터의 포트 / 크리덴셜 오라클 | 동일 testDBConnection | 추론. 오라클이 수락 후 닫은 뒤 랩 본문은 mysqli_connect(): (HY000/2006): MySQL server has gone away였음 |
| 내부 3306에 MySQL로 접속하여 POST된 user/password 시도 | 동일 mysqli_connect | 추론. 랩 db 서비스로 향하지 않음 |
사용자 정규식을 보간하는 validateRegex를 통한 ReDoS | id=Servers/1/hide_db | 추론. 실행되지 않음 |
이 랩에서 제외됨: HTTP 메타데이터 SSRF (핸드셰이크는 MySQL이며 GET /latest/meta-data가 아님), 인증 없는 PMA 로그인, OS 셸, 그리고 setup 마법사 자체 (index.php는 비활성 상태 유지). setup/이 배포되지 않은 경우(공식 이미지 기본값) FAIL.
RELEASE_5_2_3에 대한 8개의 병렬 소스 탐색. setup/index.php에는 config-exists fatal이 있다. setup/validate.php에는 없다. setup/lib/common.inc.php는 $isMinimumCommon을 설정하고 CONFIG_FILE을 찾지 않는다.
잘못된 방향: 공식 이미지를 이 잔여물로 취급함 (공식 이미지는 setup/을 삭제함); 로그인 페이지 토큰 없이 POST함 (오라클 히트 0회); 이를 HTTP 메타데이터 SSRF로 취급함 (핸드셰이크는 MySQL임).
python3 phpmyadmin-setup-validate-Abraxas-Labs.py
또는
cd lab
./run.sh
루프백 전용: http://127.0.0.1:19230. Compose 프로젝트 phpmyadmin-setup-validate. Dockerfile은 5.2.3 tarball에서 setup/을 복원하고 포트 13306에서 TCP 오라클을 실행한다. Witness PMA-SETUP-VALIDATE-WITNESS.
SUCCESS phpmyadmin-setup-validate how=live tcp=yes setup-index-disabled=yes PMA-SETUP-VALIDATE-WITNESS
file_exists(CONFIG_FILE) fatal을 setup/lib/common.inc.php에 넣어 모든 setup 스크립트가 종료되도록 하라. testDBConnection 호스트를 제한하라. 사용자 문자열로 preg_match 구분자를 구성하지 말라.
962857e)setup/index.php config-exists fatalsetup/validate.php 해당 검사 없음libraries/classes/Config/Validator.php testDBConnection / mysqli_connectGNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.