
CVE-2026-68121 연구 저장소로, pppoe_sendmsg()의 Linux 커널 PPPoE use-after-free 취약점을 다루며, 이는 로컬 권한 상승을 가능하게 하고 PoC, 근본 원인 분석, 실습 환경 구성을 포함합니다.
PPPoEject
PPPoE 전송 경로에서 발생하는 Linux 커널 메모리 손상 취약점으로,
디바이스 헤더 콜백이 skb head를 재할당한 후 sk_buff 헤더에 대한
stale 포인터로 인해 발생합니다.
이 저장소는 승인된 보안 연구, 커널 취약점 분석, CTF 환경, 그리고 방어적 테스트 목적으로만 사용하도록 의도되었습니다.
명시적인 승인 없이 시스템에 대해 개념 증명 코드를 실행하지 마십시오.
CVE 레코드는 이 취약점을 dev_hard_header()가 skb head를 재할당할 때
무효화될 수 있는 stale PPPoE 헤더 포인터로 식별합니다.
취약점은 다음 위치에 존재합니다:
drivers/net/ppp/pppoe.c
다음 함수 내부입니다:
pppoe_sendmsg()
취약한 시퀀스는 개념적으로 다음과 같습니다:
pppoe_sendmsg()
│
▼
PPPoE 헤더 포인터 저장
│
▼
dev_hard_header()
│
▼
skb head가 재할당될 수 있음
│
▼
이전 포인터가 stale 상태가 됨
│
▼
PPPoE가 stale 포인터를 통해 쓰기
│
▼
Use-After-Free
│
▼
커널 메모리 손상
Linux 네트워킹 코드는 디바이스 헤더 콜백이 sk_buff head를 재할당하는 것을
허용합니다. 따라서 이전 head를 가리키는 포인터는 dev_hard_header()가
반환된 후 안전하게 재사용될 수 없습니다.
핵심 문제는 수명 위반(lifetime violation) 입니다.
pppoe_sendmsg()는 다음을 호출하기 전에 PPPoE 헤더에 대한 포인터를
획득합니다:
dev_hard_header()
그러나 해당 콜백은 skb head를 이동시킬 수 있습니다.
개념적으로:
콜백 이전:
skb
┌──────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴───────────┘
▲
│
stale 포인터
skb 확장 이후:
이전 skb head ──X──► 해제됨
새 skb head
┌────────────────────────────────────┐
│ Ethernet │ PPPoE │ Payload │
└──────────┴───────┴─────────────────┘
▲
│
유효한 위치
이전 포인터는 여전히 해제된 할당을 참조합니다.
PPPoE가 이후에 해당 포인터를 통해 헤더를 쓰면, 커널은 use-after-free 쓰기를 수행합니다.
문서화된 트리거는 copy_from_user() 주변의 경쟁 조건과
team 디바이스의 헤더 연산 변경을 포함합니다.
설명된 시퀀스 중 하나는 다음과 같습니다:
PPPoE sendmsg()
│
▼
copy_from_user() 블록
│
│
├───────────────┐
│ │
▼ ▼
Team 디바이스가 첫 번째 비이더넷
헤더 연산을 변경 포트가 추가됨
│
▼
위임된 GRE 콜백
│
▼
skb head 확장
│ │
└───────────────┘
│
▼
stale PPPoE 포인터
│
▼
use-after-free 쓰기
CVE 레코드는 빈 team 디바이스에 첫 번째 비이더넷 포트가 추가되고 위임된 GRE 헤더 콜백이 skb head를 확장할 때 이것이 발생할 수 있다고 설명합니다.
이 취약점은 다음을 초래할 수 있습니다:
CVE의 공개된 CVSS 벡터는 다음과 같습니다:
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
기본 점수는 7.8 높음입니다.
관련 구성 요소는 다음과 같습니다:
PF_PPPOX / PPPoE 소켓
│
▼
pppoe_sendmsg()
│
▼
sk_buff (skb)
│
▼
dev_hard_header()
│
▼
네트워크 디바이스 헤더 콜백
│
▼
잠재적 skb head 확장
│
▼
PPPoE stale 헤더 포인터
│
▼
UAF 쓰기
따라서 취약한 코드는 단순히 일반적인 PPPoE 패킷 파서가 아니며, 핵심 조건은 PPPoE 소켓 전송과 동적 skb head 재할당 간의 상호작용입니다.
업스트림 수정의 제목은 다음과 같습니다:
pppoe: reload header pointer after dev_hard_header()
이 수정은 디바이스 헤더 생성 후 skb의 네트워크 헤더 오프셋을 통해 PPPoE 헤더를 다시 로드합니다.
중요한 속성은 다음과 같습니다:
이전:
헤더 포인터
│
▼
dev_hard_header()
│
▼
skb 이동
│
▼
포인터 = stale ❌
이후:
dev_hard_header()
│
▼
skb가 이동할 수 있음
│
▼
skb 오프셋을 사용하여 헤더 다시 로드
│
▼
포인터 = 유효 ✅
pskb_expand_head()는 skb head가 재배치될 때 관련 skb 오프셋을
업데이트하므로, 재할당 후 오프셋 기반 조회가 안전해집니다.
통제된 실험실은 다음과 같이 구성할 수 있습니다:
┌───────────────────────────────────────────────┐
│ Linux VM │
│ │
│ ┌───────────────┐ │
│ │ PPPoE 소켓 │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ pppoe_sendmsg │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Team │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ GRE │ │
│ └───────────────┘ │
│ │
└───────────────────────────────────────────────┘
유용한 커널 디버깅 도구:
gdb
pwndbg
gef
crash
objdump
readelf
pahole
커널 메시지 모니터링:
sudo dmesg -w
PPPoE 지원 확인:
lsmod | grep pppoe
사용 가능한 PPP 모듈 확인:
find /lib/modules/$(uname -r) -iname '*pppoe*'
현재 실행 중인 커널 확인:
uname -r
PPPoE 관련 구성 확인:
grep -E 'CONFIG_PPP|CONFIG_PPPOE' \
/boot/config-$(uname -r)
일반적인 관련 옵션은 다음과 같습니다:
CONFIG_PPP
CONFIG_PPP_ASYNC
CONFIG_PPP_SYNC_TTY
CONFIG_PPPOE
통제된 커널 연구를 위해:
01. 취약한 커널 빌드
↓
02. 격리된 VM 부팅
↓
03. PPPoE 지원 활성화
↓
04. 통제된 네트워킹 토폴로지 생성
↓
05. team/GRE 상호작용 구성
↓
06. PPPoE sendmsg() 실행
↓
07. skb 수명 모니터링
↓
08. 커널 진단 캡처
↓
09. 업스트림 패치 적용
↓
10. 반복 및 비교
목표는 메모리 수명 위반을 안전하게 재현하고 취약한 동작과 패치된 동작을 비교하는 것입니다.
CVE-2026-68121-PPPoEject/
│
├── README.md
│
├── exploit/
│ ├── poc.c
│ └── Makefile
│
├── analysis/
│ ├── root-cause.md
│ ├── pppoe-sendmsg.md
│ ├── skb-lifetime.md
│ └── patch-analysis.md
│
├── kernel/
│ ├── vulnerable/
│ └── patched/
│
├── lab/
│ ├── setup.sh
│ ├── cleanup.sh
│ └── topology.md
│
├── screenshots/
│
├── docs/
│ └── research-notes.md
│
└── LICENSE
권장되는 완화 방법은 업스트림 수정 또는 적절한 배포판 백포트를 포함하는 Linux 커널로 업데이트하는 것입니다.
Debian/Kali의 경우:
sudo apt update
sudo apt full-upgrade
그런 다음 재부팅:
sudo reboot
실행 중인 커널 확인:
uname -r
배포판 백포트는 다른 버전 번호를 사용할 수 있으므로, 관리자는 설치된 패키지를 배포판의 보안 권고와 대조하여 확인해야 합니다. Debian은 현재 Bookworm의 경우 6.1.187-1, Trixie의 경우 6.12.101-1을 포함한 수정 버전을 나열하고 있습니다.
Linux stable 트리는 여러 유지 관리 브랜치에 걸쳐 수정 사항을 포함하고 있습니다. CVE 레코드는 해당 stable 커밋을 나열하고 영향을 받는 소스 파일을 다음과 같이 식별합니다:
drivers/net/ppp/pppoe.c
취약한 이력은 Linux 커널 PPPoE 구현에서 시작하며, 수정 커밋 시리즈는
CVE 데이터에서 7a56e7c9b08e08fd55a1bcada24cf4fe3782b722로 표현되는
업스트림 수정에서 종료됩니다.
skb를 가리키는 포인터는 skb head를 재할당할 수 있는 콜백 이후에 유효하다고 가정할 수 없습니다.
네트워킹 콜백은 기반 메모리 레이아웃을 변경할 수 있습니다.
이 패치는 잠재적으로 재배치되는 연산 전반에 걸쳐 원시 포인터를 유지하는 것보다 skb 상대 오프셋이 더 안전한 이유를 보여줍니다.
취약한 상태는 패킷 전송과 네트워크 디바이스 구성 주변의 동시 활동에 의존합니다.
커널 네트워킹 코드의 stale 포인터는 기밀성, 무결성, 가용성에 영향을 미치는 메모리 손상 프리미티브가 될 수 있습니다.
drivers/net/ppp/pppoe.cpppoe_sendmsg()pppoe: reload header pointer after dev_hard_header()Linux Kernel · PPPoE · Use-After-Free · Kernel Security · LPE
Research • Analyze • Reproduce • Harden
| 필드 | 세부 정보 |
|---|
| CVE | CVE-2026-68121 |
| 코드명 | PPPoEject |
| 구성 요소 | Linux 커널 |
| 서브시스템 | PPPoE / 네트워킹 |
| 영향받는 파일 | drivers/net/ppp/pppoe.c |
| 주요 함수 | pppoe_sendmsg() |
| 버그 분류 | Use-After-Free |
| 영향 | 커널 메모리 손상 |
| 잠재적 영향 | 로컬 권한 상승 |
| CVSS v3.1 | 7.8 — 높음 |
| 공격 벡터 | 로컬 |
| 공격 복잡도 | 낮음 |
| 필요 권한 | 낮음 |
| 사용자 상호작용 | 없음 |
| 상태 | 패치됨 |
| 보안 속성 | 취약 | 패치됨 |
|---|
| 콜백 이전에 헤더 포인터 저장 | ✅ | — |
| skb head가 이동 가능 | ✅ | ✅ |
| 콜백 이후 포인터 갱신 | ❌ | ✅ |
| stale 포인터 역참조 | 가능 | 방지됨 |
| use-after-free 쓰기 | 가능 | 완화됨 |
| 커널 메모리 손상 | 가능 | 완화됨 |