
PJSIP DNS 압축 포인터 힙 OOB 읽기 (원격 DoS)
PJSIP DNS 압축 포인터 힙 OOB 읽기 (원격 DoS)
pjlib-util/src/pjlib-util/dns.c의 get_name_len() 및 get_name() 함수는 두 바이트가 모두 패킷 버퍼 내에 있는지 확인하지 않고 pj_memcpy(&offset, p, 2)를 통해 2바이트 DNS 압축 포인터를 읽습니다. 0xC0 바이트(압축 포인터 마커)가 DNS 응답의 맨 마지막 바이트인 경우, memcpy는 힙 할당 경계를 1바이트 초과하여 읽습니다.
단일 20바이트로 조작된 DNS 응답은 OOB 읽기를 유발하며, 네트워크 제어 DNS 서버를 통해 도메인을 해석하는 모든 PJSIP 애플리케이션(Asterisk 및 FreeSWITCH 포함)을 충돌시킵니다.
ASan이 확인: get_name_len()에서 heap-buffer-overflow READ of size 2, 0 bytes after 20-byte region.
이는 2022년 이후 pjproject의 dns.c에서 세 번째 DNS 파서 CVE입니다(CVE-2022-24793 및 CVE-2023-27585 이후). CVE-2022-24793 수정은 파서 전체에 길이 검사를 추가했지만 압축 포인터 경로는 누락되었습니다.
영향: pjproject <= 2.16. pjproject 2.17(커밋 5311aee)에서 수정됨.
# 독립형 ASan 하네스 (pjproject 설치 불필요):
./run.sh
# 또는 수동으로 빌드 및 실행:
gcc -fsanitize=address,undefined -g -O0 harness.c -o harness
./harness
# 네트워크 PoC -- 악성 DNS 서버:
python3 poc.py --port 5353
# 그런 다음 PJSIP 애플리케이션을 악성 서버로 지정:
# pjsua --nameserver 127.0.0.1:5353 sip:[email protected]
# Docker (ASan으로 pjproject 2.16 소스 빌드):
docker compose build
docker compose run harness
gcc이 프로젝트는 GNU GPLv3에 따라 배포됩니다.
방어적 보안 연구, 교육 및 승인된 테스트를 위해 제공됩니다. 소유자의 명시적 허가 없이 시스템이나 서비스에 이 코드를 사용하지 마십시오.
무단 사용은 관련 법률을 위반할 수 있습니다. 저자는 제3자 시스템을 테스트할 권한을 부여하지 않으며 오용에 대해 책임을 지지 않습니다.
보증 및 책임 조건은 LICENSE 파일을 참조하십시오.
| 파일 | 설명 |
|---|
harness.c | 독립형 ASan 하네스 -- 정확한 pjproject 타입으로 취약한 get_name_len()을 재구현 |
harness_pjlib.c | 실제 pj_dns_parse_packet()을 호출하는 대체 하네스 (Docker용) |
poc.py | 악성 DNS 서버 -- 모든 쿼리에 조작된 20바이트 패킷으로 응답 |
run.sh | ASan 하네스 빌드 및 실행 |
Dockerfile | ASan으로 pjproject 2.16을 소스에서 빌드 |
docker-compose.yml | pjlib 하네스용 Docker 설정 |
proof_output.txt | 실시간 검증의 전체 ASan 출력 |