
개요
- CVE ID: CVE-2026-56705
- 대상: Adminer (vrana/adminer), 최신 안정 버전 adminer-5.4.2.php 기준
- CVSS: 9.8 (Critical)
- 공격 조건: 인증 불필요(Pre-Auth), pdo_sqlsrv 확장 + MS ODBC Driver 설치 환경
- 영향: 원격 코드 실행(RCE)
Adminer는 PHP 파일 하나만 웹 루트에 올려두면 동작하는 데이터베이스 관리 도구다. 편리한 만큼 로그인 페이지 하나가 인터넷에 그대로 노출되는 경우가 많고, 이번 취약점은 그 로그인 페이지에서 인증 시도 자체가 실패해도 공격자가 원하는 PHP 코드를 웹 루트에 파일로 떨어뜨릴 수 있게 만든다.
취약점이 발생하는 위치
Adminer는 로그인 폼에서 driver, server, username, password 값을 받아 각 데이터베이스 드라이버의 attach() 함수에 그대로 전달한다. MSSQL 드라이버 코드는 다음과 같다.
adminer/drivers/mssql.inc.php:185

여기서 문제는 두 가지다.
- $host가 문자열 결합(concatenation)으로 그대로 DSN에 들어간다. 이스케이프가 전혀 없다.
- host_port()가 걸러주는 값은 IPv6 대괄호 표기([::1]:1433)뿐이다.
include/functions.inc.php:851

패턴에 맞지 않는 입력, 즉 우리가 흔히 넣는 IP;옵션=값 같은 문자열은 정규식이 매치되지 않아 아무 가공 없이 그대로 반환된다. 결국 로그인 폼의 server 필드에 입력한 문자열이 한 글자도 걸러지지 않고 DSN 문자열 안에 박히게 된다.
왜 세미콜론 하나가 치명적인가
ODBC 연결 문자열(DSN)은 세미콜론(;)을 파라미터 구분자로 사용한다. 즉 server 값에 세미콜론을 넣으면 그 뒤는 전부 "새로운 DSN 옵션"으로 해석된다.
여기서 공격자가 노리는 옵션이 TraceFile과 TraceOn이다. 이 두 옵션이 켜지면 ODBC 드라이버는 연결을 시도하는 과정 자체를 지정된 경로의 파일에 기록한다. 연결이 성공하든 실패하든 상관없이, 시도했다는 사실만으로 로그 파일이 생성된다. 그리고 이 로그에는 연결 문자열 전체, 즉 UID={...} 필드에 우리가 로그인 폼에 넣은 username 값이 그대로 찍힌다.

정리하면 공격자가 통제할 수 있는 지점은 세 곳이다.
- TraceFile 값 → 로그 파일의 경로와 이름을 공격자가 정한다 (shell.php)
- TraceOn=1 → 추적 로그 기능을 활성화한다
- username 값 → 로그 안의 UID={...} 필드에 PHP 코드를 심는다
최종 페이로드 (attach()부터 PDO까지)
dsn() 함수는 pdo.inc.php:13에서 new \PDO($dsn, $username, $password, $options)를 그대로 호출한다.

즉 로그인 폼 → attach() → dsn() → new PDO() 로 이어지는 경로 전체에 이스케이프나 검증이 단 한 번도 끼어들지 않는다.
실제 요청은 다음과 같이 구성한다.

이 요청이 서버에 도달하면 Adminer는 다음 DSN을 만들어 PDO에 넘긴다.

ODBC 드라이버는 shell.php 파일을 열어 연결 메타데이터(우리가 심은 PHP 코드가 들어있는 UID={...} 포함)를 기록한 다음, 127.0.0.1에 연결을 시도하고 실패한다. 연결 실패는 아무 의미가 없다. 이미 adminer.php 옆에 shell.php가 만들어진 뒤이기 때문이다.
두 번째 요청 한 번으로 명령 실행이 끝난다.

전체 흐름을 그림으로 정리하면 다음과 같다.

왜 이 취약점이 위험한가 (기술적 요인 정리)
- Pre-Auth: 로그인은 실패로 끝난다. 유효한 SQL Server 자격 증명이나 실제로 도달 가능한 MSSQL 서버조차 필요 없다.
- 파일 쓰기 시점: 인증 로직이 도는 시점이 아니라 ODBC 드라이버가 연결을 시도하는 시점에 파일이 생성되므로, Adminer 애플리케이션단의 어떤 검증도 이 시점을 가로챌 수 없다.
- 전제 조건: pdo_sqlsrv 확장과 Microsoft ODBC Driver가 설치되어 있어야 한다. 이는 Azure SQL Database나 MS SQL Server 백엔드를 쓰는 표준 구성에서 흔하다.
- 웹 루트 쓰기 권한: 컨테이너 기반 PHP 배포에서는 기본값으로 주어지는 경우가 많다.
동일한 구조가 pdo_dblib 분기(mssql.inc.php:195, DSN 템플릿 dblib:charset=utf8;host=$host)에도 그대로 존재한다. 다만 실제 dblib 환경에서 가젯을 확인하지는 못했다는 것이 원 보고서의 설명이다.
'CVE 취약점' 카테고리의 다른 글
| Metabase 비밀번호 재설정 SQL 인젝션 취약점 분석 (CVE-2026-72898) (0) | 2026.09.04 |
|---|---|
| Dovecot SQL 기반 인증 우회 (auth_username_chars 회귀 취약점) CVE-2026-24031 (0) | 2026.09.02 |
| Keycloak reset-credentials 플로우 인증 우회로 인한 계정 탈취 분석 (CVE-2026-18963) (0) | 2026.08.30 |
| PostgreSQL pgcrypto pgp_pub_decrypt_bytea() 힙 버퍼 오버플로우 (RCE) (CVE-2026-2005) (0) | 2026.08.28 |
| GEO my WP 플러그인 미인증 SQL 인젝션 (CVE-2026-52715) (0) | 2026.08.25 |