
MySQL Community Server 26.7.0 - High - mysqldump SHOW TABLES 스택 오버플로 - 크래시 덤프 UID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · mysql-mysqldump-show-tables-overflow
분류: 크래시 도달 범위: 원격
MySQL Community Server mysqldump 26.7.0 (06a5c1c) - Oracle
기본 mysqldump는 SHOW TABLES 이름을 NAME_LEN 제한 없이 복사한다. getTableName은 원시 mysql_fetch_row를 반환한다. dump_all_tables_in_db는 그 문자열을 hash_key[2*NAME_LEN+2]로 my_stpcpy하고, quote_name은 이를 387바이트 스택 버퍼에 아무런 바운드 없이 기록한다. 192바이트보다 긴 테이블 이름에 응답하는 악성 서버는 덤프 UID를 크래시시킨다.
실제 mysqld는 그렇게 긴 식별자를 내보내지 않는다. 남은 것은 프로토콜을 신뢰하는 클라이언트다.
| ID | 아직 CVE 없음 |
| 분류 | 크래시 (클라이언트 SIGSEGV; RCE는 입증되지 않음) |
| 도달 범위 | 원격 (피해자가 공격자 MySQL에 대해 mysqldump 실행; UI:R) |
| CWE | CWE-120, CWE-121 |
| CVSS | 높음: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 제품 | MySQL Community Server mysqldump |
| 영향받는 버전 | 26.7.0 (06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8) |
| 인증 | 피해자가 공격자 MySQL에 대해 기본 mysqldump 실행 |
| 라이선스 | GNU Affero GPL v3.0 |
| 랩 | 127.0.0.1 전용. 크래시 증거. RIP 페이로드 없음. |
MySQL 프로토콜 서버를 세운다. 핸드셰이크를 완료한다. 세션 SET에 응답한다. 클라이언트가 show tables를 보내면, 이름이 수십 킬로바이트인 행 하나를 반환한다.
mysqldump testdb를 그 호스트로 향하게 한 운영자는 덤프 프로세스의 스택 버퍼를 오버플로시킨다. mysqldump Ver 26.7.0에서의 랩은 SIGSEGV다. 신뢰할 수 있는 명령 포인터 제어는 이 팩의 일부가 아니다. 크래시는 그렇다.
악성 서버를 향한 백업 클라이언트와 동일한 피해자 모델. lock_tables는 --opt를 통해 기본값이다. 오버플로는 그 첫 SHOW TABLES 루프에서 발생한다.
https://github.com/mysql/mysql-server 태그 https://github.com/mysql/mysql-server/tree/mysql-26.7.0에 대해 서른한 번의 소스 사냥을 실행했다. 기본 mysqld의 미공개 Crit/High는 빈손으로 돌아왔다. 2026년 7월 CPU High Server 행들은 이 핀에서 닫혀 있다. 클라이언트 도구가 남은 클래스였고, 악성 경로를 따르는 PostgreSQL pg_basebackup과 같은 형태였다.
static char *getTableName(int reset) {
static MYSQL_RES *res = nullptr;
MYSQL_ROW row;
if (!res) {
if (!(res = mysql_list_tables(mysql, NullS))) return (nullptr);
}
if ((row = mysql_fetch_row(res))) return ((char *)row[0]);
static char *quote_name(char *name, char *buff, bool force) {
char *to = buff;
const char qtype = ansi_quotes_mode ? '"' : '`';
if (!force && !opt_quoted && !test_if_special_chars(name)) return name;
*to++ = qtype;
while (*name) {
if (*name == qtype) *to++ = qtype;
*to++ = *name++;
}
NAME_LEN은 64 * 3 = 192이다. hash_key는 386바이트다. dump_table의 quote_name은 table_buff[NAME_LEN+3]에 기록한다.
이미 기록된 잘못된 방향들: 실제 mysqld를 오라클로 취급하기(193바이트 식별자를 내보내지 않음); hash_key와 같은 프레임의 real_columns[MAX_FIELDS]에 흡수된 4KiB 이름; 전체 서버 트리에서 ASan 컴파일하기; 크래시를 명령 포인터 제어라고 부르기.
cd lab
./run.sh
이미지 mysql:26.7.0. compose stub:3306(제어, 테이블 t)과 stub:3307(오버플로, 64KiB 이름 및 증거)의 악성 스텁. 127.0.0.1:18600 / 18601 게시. 루프백에 바인딩하라.
control-rc=2 control-signal=0
overflow-rc=139 overflow-signal=SIGSEGV
SUCCESS mysql-mysqldump-show-tables-overflow ... MYSQL-DUMP-SHOW-TABLES-OVERFLOW-WITNESS
제어는 26.7.0 덤프 헤더를 출력하고 SQL 1146에서 종료 코드 2로 끝난다. 오버플로는 show tables 직후에 죽는다. 그 연결에는 LOCK TABLES가 없다.
getTableName을 NAME_LEN으로 제한하라. quote_name에 버퍼 길이를 주고 그 이상 기록을 거부하라. hash_key로의 my_stpcpy는 바운드된 복사여야 한다. 악성 SHOW TABLES 이름은 테이블이 아니다.
06a5c1c99c377fc41b2eba1ea244e8b220bdc3c8)getTableName, quote_name, dump_all_tables_in_dbNAME_LENmysql_list_tables