
phpMyAdmin 5.2.3 - 높음 - 원격 - SQLi - ImportLdi TERMINATED BY 잔여물
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-importldi
분석 문서: https://abraxaslabs.tech/research/phpmyadmin-importldi
분류: SQLi 도달 범위: 원격
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
ImportLdi.php는 POST의 ldi_terminated와 ldi_new_line으로부터 FIELDS/LINES TERMINATED BY를 포함한 LOAD DATA를 구성합니다. 이 두 문자열은 작은따옴표로 감싼 SQL에 그대로 연결됩니다. ldi_enclosed와 ldi_escaped는 escapeString을 거칩니다. phpMyAdmin은 /import에서 PMA_ENABLE_LDI를 설정하므로 MYSQLI_OPT_LOCAL_INFILE이 켜집니다.
로그인한 사용자가 ldi_terminated에 따옴표를 넣어 format=ldi를 POST합니다. 발행되는 LOAD DATA에는 TERMINATED BY 안에 원시 POST 값이 그대로 포함됩니다. 제어 사용자가 아닌 사용자 연결로의 SQL 인젝션입니다.
| ID | 아직 CVE 없음 |
| 분류 | SQLi |
| 도달 범위 | 원격 (인증된 쿠키 로그인, 테이블 가져오기, 형식 ldi) |
| CWE | CWE-89 |
| CVSS | 중간: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N |
| 제품 | phpMyAdmin |
| 영향받는 버전 | 5.2.3 태그 RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| 인증 | 인증된 쿠키 로그인. 테이블 가져오기, 형식 ldi |
| 라이선스 | GNU Affero GPL v3.0 |
| 실습 환경 | 127.0.0.1 전용 |
테이블 가져오기를 열 수 있는 로그인한 phpMyAdmin 사용자는 자신의 MySQL 연결에서 LOAD DATA ... TERMINATED BY에 SQL을 주입할 수 있습니다.
| 권한 | 방법 / 싱크 | 정찰 / 무결성 / 가용성 | 실습 입증 또는 추론 |
|---|---|---|---|
FIELDS TERMINATED BY 리터럴 깨기 | POST index.php?route=/import format=ldi ldi_terminated에 따옴표 삽입 | PMA가 구성하는 구문의 무결성 | 실습 입증. HTML SQL 박스: TERMINATED BY '',PMA-IMPORTLDI-WITNESS' |
ENCLOSED BY를 인밴드로 유지 | 동일 POST, ldi_enclosed에 따옴표 삽입 | 음성 대조 | 실습 입증. ENCLOSED BY는 이스케이프됨 |
| 사용자 연결에 추가 SQL (INTO OUTFILE / 허용 시 스택 쿼리) | 문자열이 닫힌 후 동일 싱크 | 사용자 연결의 무결성 | 추론. 실습은 깨진 구분자에서 멈춤. 기본 mysqli::query는 단일 문장 |
| MySQL 측 파일 읽기/쓰기 | 계정에 FILE 권한이 있거나 웹 서버로의 LOCAL INFILE이 가능한 경우 동일 LOAD DATA | mysqld가 접근할 수 있는 파일의 무결성 | 추론. 여기서는 부여되지 않음. 주장하지 않음 |
이 실습에서 배제된 항목: 미인증 접근, 제어 사용자 / pmadb, OS include LFI, FILE 권한이 필요한 읽기/쓰기. 로그인한 사용자는 이미 SQL 박스를 가지고 있으며, 이 잔여 취약점은 PMA가 그들을 위해 구성하는 구문 내부의 이스케이프되지 않은 구분자입니다.
동일 핀: WebAuthn CustomServer 잔여 취약점.
phpMyAdmin RELEASE_5_2_3을 핀했습니다. LOAD DATA를 직접 구성하는 가져오기 플러그인은 인용 부호 감사 대상입니다. 네 개의 구분자 필드 중 두 개는 이스케이프되었고, 두 개는 그렇지 않았습니다:
$sql .= ' FIELDS TERMINATED BY \'' . $ldi_terminated . '\'';
...
$sql .= ' LINES TERMINATED BY \'' . $ldi_new_line . '\'';
ldi_enclosed / ldi_escaped는 $dbi->escapeString을 호출합니다. Common.php는 /import + format=ldi에서 PMA_ENABLE_LDI를 설정합니다. 라우트는 GET|POST /import 및 GET|POST /table/import입니다.
이미 기록된 잘못된 방향: FILE 권한 없이 LFI를 주장하는 것; SQL 상자를 발견 사항으로 취급하는 것(PMA가 연결하는 이스케이프되지 않은 구분자가 남는 부분임); control-user / pmadb를 주장하는 것; 리버스 셸. 다 연극일 뿐입니다.
python3 phpmyadmin-importldi-Abraxas-Labs.py
# or: cd lab && ./run.sh
오직 http://127.0.0.1:19290만 대상으로 합니다. 이미지 phpmyadmin:5.2.3 및 mysql:8.0. Compose 프로젝트 phpmyadmin-importldi. 실행 후 스택은 종료됩니다.
쿠키 로그인. format=ldi와 ldi_terminated에 따옴표를 넣어 /import에 POST합니다. LOAD DATA LOCAL INFILE ... INTO TABLE \ldi_target` FIELDS TERMINATED BY '',PMA-IMPORTLDI-WITNESS'가 발행되었습니다. ldi_enclosed에 있는 동일한 따옴표는 이스케이프된 ENCLOSED BY로 저장됩니다. 5.2.3 이미지의 고정 소스에는 여전히 '.$ldi_terminated.'와 $dbi->escapeString($ldi_enclosed)`가 있습니다.
SUCCESS phpmyadmin-importldi pin=RELEASE_5_2_3 how=live TERMINATED-BY-raw ENCLOSED-escaped PMA-IMPORTLDI-WITNESS
ldi_terminated와 ldi_new_line에 escapeString을 적용하며, enclosed 및 escaped의 경우와 동일합니다. skip_queries는 int로 캐스팅합니다.
962857e4f63d42e38f11ff4d63f5e722018add76)libraries/classes/Plugins/Import/ImportLdi.phpGNU Affero GPL v3.0. LICENSE를 참조하십시오. 루프백 실습 환경 전용입니다. 보증은 제공되지 않습니다.