PostgreSQL 18.6 - 높음 - 원격 - 파일 쓰기 - pg_basebackup이 CVE-2026-6475의 잔여 절대 tar 심볼릭 링크를 따름
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · postgres-basebackup-symlink
분류: 파일 쓰기 도달 범위: 원격
PostgreSQL 18.6 (724edf9) - PostgreSQL Global Development Group
CVE-2026-6475는 tar 멤버 이름에 대해 path_is_safe_for_extraction을 추가했다. 절대 심볼릭 링크 대상은 테이블스페이스가 작동하도록 하기 위해 여전히 해당 검사를 건너뛴다. 그런 다음 astreamer_file.c가 대상에 symlink()를 수행하고 이후 fopen(..., "wb")가 이를 따라간다. 기본 pg_basebackup 형식은 plain(-F p)이다. pg_rewind의 create_target_symlink는 경로를 검사하고 절대 링크하지 않는다.
BASE_BACKUP을 구사하는 적대적 소스는 절대 심볼릭 링크를 심고 백업 UID가 쓸 수 있는 모든 파일을 덮어쓸 수 있다. 6475와 동일한 피해자 모델이다. 이는 멤버 이름 검사의 재신고가 아니다.
| ID | 아직 CVE 없음 |
| 분류 | 파일 쓰기 (CVE-2026-6475의 절대 tar 심볼릭 링크 잔여물) |
| 도달 범위 | 원격 (UI:R 클라이언트 대 적대적 PostgreSQL) |
| CWE | CWE-59, CWE-22 |
| CVSS | High: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 제품 | PostgreSQL |
| 영향받는 버전 | 18.6 태그 REL_18_6 (724edf9bde9d356724ad384a2e196edc3c9f80f7), 트리 내 pg_basebackup / pg_rewind |
| 인증 | 피해자가 공격자 소스를 대상으로 기본 pg_basebackup -D <dir> 실행 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용 |
운영자가 자신의 PostgreSQL을 대상으로 pg_basebackup -D를 실행하도록 만들 수 있는 사람(CVE-2026-6475와 동일한 UI:R 모델)은 -D 외부에 쓸 수 있다.
| 권한 | 방법 / 싱크 | 랩 검증 또는 추론 |
|---|---|---|
무결성: -D 외부에 파일 쓰기 | 적대적 BASE_BACKUP tar: 안전한 상대 이름(pg_tblspc/16384)과 절대 링크 대상을 가진 typeflag '2' 멤버, 그런 다음 해당 이름 아래의 일반 멤버. extract_link 이후 create_file_for_extract가 O_NOFOLLOW 없이 fopen(..., "wb") 수행 | 랩 검증. /work/oracle/에 POSTGRES-BASEBACKUP-SYMLINK-WITNESS를 썼다. Dest는 심볼릭 링크를 보유한다. 대조 tar(심볼릭 링크 없음)는 oracle을 비워 두고 -D 내부에 PG_VERSION만 썼다 |
무결성: 셸 rc, authorized_keys, systemd 사용자 유닛 또는 crontab 덮어쓰기 | 동일 싱크, 클라이언트 UID가 쓸 수 있는 모든 경로 | 추론. 이 랩은 해당 파일들을 건드리지 않는다 |
| 가용성: 클라이언트 설정 또는 키 파괴 | 동일 쓰기 | 추론. 입증되지 않음 |
| 클라이언트 디스크 정찰 | extract는 읽기가 아니라 쓰기 | 해당 없음 |
.. 또는 절대 멤버 이름 탐색 | path_is_safe_for_extraction | 해당 없음. 그것이 CVE-2026-6475이다 |
| 서버 측 비권한 SQL / 비인증 프로토콜 | 18.6 기본 서버 | 해당 없음. 이 잔여물은 클라이언트다 |
| Tar 전용 백업 | pg_basebackup -F t는 추출 없이 tar를 저장 | 해당 없음 |
postgres 내부 RCE | 이 싱크가 아님 | 해당 없음 |
pg_rewind에도 동일한 create_target_symlink / open() 잔여물이 있다. 이 랩은 pg_basebackup만 구동한다.
18.6 물결(28개 CVE, 그리고 이미 이 트리에 있는 18.4/18.2 세트) 이후 postgres/postgres REL_18_6을 고정했다. 스물두 번의 사냥. 기본 서버, 비권한 SQL, 비인증 프로토콜: 이 기준에서는 아무것도 없었다. CVE-2026-6475가 다시 읽어야 할 형제였다.
멤버 이름은 검사된다. 절대 심볼릭 링크 대상은 그렇지 않다:
if (!is_absolute_path(linktarget) &&
!path_is_safe_for_extraction(member->linktarget))
{
pg_fatal("link target has unsafe path name: \"%s\"",
member->linktarget);
}
extract_link(mystreamer->filename, linktarget);
create_file_for_extract는 여전히 fopen(filename, "wb")이다. astreamer_file.c:351-356의 주석은 링크가 pg_tblspc 내부에 있는지 확인하지 않고 매핑이 적용된다고 말한다.
이미 기록된 잘못된 방향: 6475를 종결된 것으로 취급하고 떠나기; -D를 라이브 데이터 디렉터리로 지정하기; 쇼를 위해 셸 rc 덮어쓰기. 정직한 18.6 서버는 pg_tblspc/<oid> 심볼릭 링크만 내보내고 테이블스페이스 내용을 별도 아카이브에 넣는다. BASE_BACKUP을 구사하는 악성 소스는 후속 일반 멤버를 같은 tar에 넣을 수 있다. 그것이 잔여물이다.
python3 postgres-basebackup-symlink-Abraxas-Labs.py
또는
cd lab
./run.sh
소스 이미지로 postgres:18.6을 사용하며 BASE_BACKUP 스피커를 실행한다. 클라이언트는 같은 태그의 트리 내 pg_basebackup이다(pg_basebackup (PostgreSQL) 18.6). 루프백 127.0.0.1:19370. Compose 프로젝트 postgres-basebackup-symlink. -D를 라이브 데이터 디렉터리로 지정하지 말 것.
SUCCESS postgres-basebackup-symlink control-inside=yes oracle-outside=yes dest-is-symlink=yes image=postgres:18.6 how=pg_basebackup POSTGRES-BASEBACKUP-SYMLINK-WITNESS
절대 심볼릭 링크 대상을 --tablespace-mapping으로 재작성하지 않는 한 안전하지 않은 것으로 취급하라. 추출 파일을 O_NOFOLLOW / lstat로 열어 심어진 링크를 따라갈 수 없게 하라. path_is_safe_for_extraction을 rewind의 link에도 path와 마찬가지로 적용하라. 경로가 -D를 벗어난 심볼릭 링크를 통과하는 일반 멤버를 거부하라.
724edf9bde9d356724ad384a2e196edc3c9f80f7)src/fe_utils/astreamer_file.c · src/fe_utils/astreamer_tar.csrc/bin/pg_rewind/file_ops.cGNU Affero GPL v3.0. LICENSE 참조. 루프백 랩 전용. 보증 없음.