
CVE-2026-17544 익스플로잇: PHP bcmath OOB 쓰기를 메모리 전용 RCE로 변환하여, 런타임 오프셋 없는 리졸버로 disable_functions와 open_basedir을 우회합니다.
CVE-2026-17544에 대한 무기화된 개념 증명(PoC)으로, PHP의 재작성된 bcmath 확장(bc_str2num)에서 발생하는 out-of-bounds 쓰기 취약점입니다. 이는 공개적으로 알려진 DoS 전용 크래시를 완전하고 보편적이며 메모리 전용인 원격 코드 실행 프리미티브로 변환하며, 동시에 disable_functions 및 open_basedir을 모두 우회합니다.
승인된 연구 / 교육용으로만 사용하십시오. 자신이 소유했거나 명시적으로 테스트 승인을 받은 시스템에서만 실행하십시오.
![]()
bc_str2num은 수동 scale에서 소수 부분을 잘라낸 후, 뒤쪽의 0을 다시 제거하지만 fractional_end를 갱신하지 않습니다. 버퍼는 다시 제거된 길이로 크기가 할당되는 반면 복사는 제거 전 길이를 사용합니다 → Zend MM 힙에 대한 제어된 out-of-bounds 0-쓰기가 발생합니다.zend_string(길이는 유지됨)의 refcount를 0으로 만듭니다 → refcount 비동기화 use-after-free → 거대 문자열 상대 읽기/쓰기 → 오류 안전 절대 임의 읽기 → 런타임 심볼 해석 → 완전히 데이터 전용 네이티브 함수 호출.zend_class_entry + 인라인 function_table + 가짜 zend_function{ handler = zif_shell_exec }를 구축한 다음 이를 메서드로 호출합니다. 명령 출력은 문자열로 반환되어 응답/stdout으로 전달됩니다..data 및 대상 심볼은 모두 메모리 스캔을 통해 런타임에 해석됩니다 — 따라서 단일 파일이 다양한 빌드와 배포판에서 동작합니다.이는 샌드박스 탈출 / 사후 악용 프리미티브이지, 원격 입력 전용 RCE가 아닙니다.
| 시나리오 | 결과 |
|---|---|
공격자가 이미 PHP를 실행할 수 있지만(웹셸, 역직렬화, eval 싱크) disable_functions + open_basedir에 의해 제한된 경우 | ✅ 네이티브 RCE (이 PoC) |
| 애플리케이션이 단순히 원시 사용자 입력에 bcmath 함수를 호출하는 경우, 예: |
단일 bcmath 호출은 공격자 입력에 대해 피드백이 없는 블라인드 OOB 0-쓰기 하나를 제공합니다. 전체 RCE를 위해서는 힙을 정리하고, R/W 프리미티브를 구축하고, 해석기를 실행할 수 있는 임의의 PHP 실행이 필요합니다 — 이 중 어느 것도 함수 인수로 표현할 수 없습니다. 따라서 입력 전용 노출의 현실적인 한계는 **원격 서비스 거부(DoS)**입니다. 코드 실행은 기존 PHP 실행 컨텍스트를 필요로 하며, 이 PoC는 그 컨텍스트를 샌드박스에서 해방시킵니다.
이 버그는 재작성된 bcmath(PHP 8.4 / 8.5 라인)에만 존재합니다:
수정되지 않은 동일 파일로 PHP 8.4.23 및 PHP 8.5.8, amd64에서 종단 간(uid=0, 출력 캡처) 검증됨 — Zend 구조체 레이아웃은 8.4 / 8.5에서 동일합니다.
bcmath 활성화..text에서 ELF 헤더까지 페이지별로 내려갑니다. 이는 연속적으로 매핑된 모든 바이너리에서 안전합니다. 인위적인 -z separate-code 빌드처럼 매핑되지 않은 2MB 간격이 있는 경우에만 블라인드 스캔으로 자동 해석할 수 없습니다(프로덕션에서는 발견되지 않음).exit()가 서버를 죽이지 않아야 합니다: php-fpm, Apache mod_php, 또는 PHP_CLI_SERVER_WORKERS>0가 설정된 내장 서버.php exploit.php "id; uname -a"
예: shell.php로 배포한 후:
GET /shell.php?cmd=id
POST cmd=id
명령 출력은 zif_shell_exec를 통해 캡처되어 응답 본문에 기록됩니다.
bccomp()를 실행하여 OOB 0-쓰기가 인접한 zend_string의 refcount에만 닿도록 합니다(길이는 유지됨).zend_reference(간접 참조를 통해)는 대상의 refcounted 헤더를 건드리지 않는 오류 안전 절대 임의 읽기를 제공합니다..text 포인터에서: ELF 매직(기본 주소)까지 페이지 단계로 내려가고, 프로그램 헤더를 구문 분석하여 .data를 찾은 다음, .data에서 핸들러가 .text를 가리키는 shell_exec zend_function_entry를 스캔합니다.zend_class_entry, 단일 버킷을 가진 인라인 function_table(올바른 zend_string 해시, 종결된 충돌 체인), 그리고 핸들러가 인 가짜 을 구축합니다. 프로브 객체의 클래스 포인터를 손상시키고 메서드를 호출합니다. 출력은 반환되어 에코됩니다.exploit.php — 범용 메모리 전용 익스플로잇(CLI + 웹).보안 연구 및 교육을 위해 제공됩니다. 작성자는 오용에 대해 책임을 지지 않습니다. 테스트 승인을 받지 않은 시스템에 배포하지 마십시오.
bccomp($_POST['v'])| ❌ DoS / 크래시만 발생 |
| PHP 브랜치 | 취약 여부 |
|---|
| 7.x, 8.0 – 8.3 | 아니요 (이전 libbcmath, 다른 bc_str2num) |
| 8.4.0 – 8.4.23 | 예 |
| 8.5.0 – 8.5.8 | 예 |
| ≥ 8.4.24 / ≥ 8.5.9 | 패치됨 |
zif_shell_execzend_internal_function