Sploitus

Exploit for block-copyfail

kitploit Β· 2026-08-27

Exploit Code

MARKDOWN320 lines
## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-MRUNALP-BLOCK-COPYFAIL
## μš”μ•½

CVE-2026-31431("Copy Fail")은 Linux μ»€λ„μ˜ `algif_aead` μ•”ν˜Έν™” μΈν„°νŽ˜μ΄μŠ€μ—μ„œ λ°œμƒν•˜λŠ” κΆŒν•œ μƒμŠΉ μ·¨μ•½μ μž…λ‹ˆλ‹€. κ³΅κ²©μžλŠ” `authencesn` μ•Œκ³ λ¦¬μ¦˜κ³Ό `splice()`λ₯Ό μ‚¬μš©ν•˜λŠ” AF_ALG μ†ŒμΌ“μ„ μ΄μš©ν•˜μ—¬ `/usr/bin/su`와 같은 setuid λ°”μ΄λ„ˆλ¦¬λ₯Ό ν¬ν•¨ν•œ 컀널 νŽ˜μ΄μ§€ μΊμ‹œμ˜ μž„μ˜ νŒŒμΌμ„ μ†μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

이 λ¬Έμ„œλŠ” Copy Fail이 μ•…μš©ν•˜λŠ” ν•˜μœ„ μ‹œμŠ€ν…œμΈ λͺ¨λ“  AF_ALG AEAD λ°”μΈλ“œλ₯Ό μ°¨λ‹¨ν•˜λŠ” BPF LSM DaemonSet을 μ‚¬μš©ν•œ **μž¬λΆ€νŒ… μ—†λŠ” μ™„ν™” 방법** 을 μ œκ³΅ν•©λ‹ˆλ‹€. μ΄λŠ” μ•”ν˜Έν™” ν…œν”Œλ¦Ώ 쀑첩(예: `pcrypt(authencesn(...))`)을 ν†΅ν•œ 우회λ₯Ό λ°©μ§€ν•©λ‹ˆλ‹€. λ‹€λ₯Έ AF_ALG μ‚¬μš©(ν•΄μ‹œ, skcipher)은 영ν–₯을 λ°›μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ³„λ„μ˜ OCP 4.22 ν΄λŸ¬μŠ€ν„° 3κ°œμ—μ„œ μ—”λ“œνˆ¬μ—”λ“œλ‘œ ν…ŒμŠ€νŠΈλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

## λΉ λ₯Έ μ‹œμž‘

root@kitploit:~
    
    
    # 1. BPF LSM이 ν™œμ„±ν™”λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€ (RHEL CoreOS 9.8μ—λŠ” 기본적으둜 ν™œμ„±ν™”λ˜μ–΄ 있음)
    oc debug node/<any-node> -- chroot /host cat /sys/kernel/security/lsm
    # "bpf"κ°€ ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€
    
    # 2. λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό λ°°ν¬ν•˜κ³  privileged SCCλ₯Ό λΆ€μ—¬ν•©λ‹ˆλ‹€
    oc apply -f daemonset.yaml
    
    # 3. DaemonSet νŒŒλ“œλŠ” λͺ¨λ“  λ…Έλ“œμ—μ„œ μžλ™μœΌλ‘œ μ‹œμž‘λ©λ‹ˆλ‹€
    
    # 4. 확인
    oc get pods -n block-copyfail     # λͺ¨λ“  λ…Έλ“œμ—μ„œ Running μƒνƒœμ—¬μ•Ό ν•©λ‹ˆλ‹€
    oc logs -n block-copyfail -l app=block-copyfail
    # μ˜ˆμƒ 좜λ ₯: "block-copyfail: blocker active β€” all AF_ALG AEAD binds blocked"
    

μž¬λΆ€νŒ…μ΄ ν•„μš” μ—†μŠ΅λ‹ˆλ‹€. λ…Έλ“œ λ“œλ ˆμΈμ΄ ν•„μš” μ—†μŠ΅λ‹ˆλ‹€. νŒŒλ“œ μž¬μ‹œμž‘μ΄ ν•„μš” μ—†μŠ΅λ‹ˆλ‹€. λ³΄ν˜ΈλŠ” μ¦‰μ‹œ 적용되며 λͺ¨λ“  λ…Έλ“œμ˜ λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€λ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€(100% 적용 λ²”μœ„).

## λͺ©μ°¨

  1. 취약점 μž‘λ™ 방식
  2. ν΄λŸ¬μŠ€ν„°μ˜ 취약점 확인
  3. BPF LSM DaemonSet 배포
  4. 배포 ν›„ 검증
  5. μ†ŒμŠ€μ—μ„œ 이미지 λΉŒλ“œ
  6. 제거



* * *

## 취약점 μž‘λ™ 방식

이 취약점은 μ„Έ κ°€μ§€ 컀널 κΈ°λŠ₯을 μ—°κ²°ν•©λ‹ˆλ‹€:

  1. **AF_ALG μ†ŒμΌ“** β€” `socket(AF_ALG, SOCK_SEQPACKET, 0)`을 톡해 컀널 μ•”ν˜Έν™”μ— λŒ€ν•œ μ‚¬μš©μž 곡간 핸듀을 μƒμ„±ν•©λ‹ˆλ‹€
  2. **AEAD λ°”μΈλ“œ** β€” νŠΉμ • 인증 μ•”ν˜Έν™” μ•Œκ³ λ¦¬μ¦˜μΈ `authencesn(hmac(sha256),cbc(aes))`에 λ°”μΈλ”©ν•©λ‹ˆλ‹€
  3. **splice() + sendmsg()** β€” 컀널이 μ†ŒμŠ€μ™€ λŒ€μƒ νŽ˜μ΄μ§€ 맀핑이 λ‹€λ₯Έ "제자리" μž‘μ—…μ„ 잘λͺ» μˆ˜ν–‰ν•˜μ—¬ 읽기 μ „μš© 파일의 νŽ˜μ΄μ§€ μΊμ‹œλ₯Ό μ†μƒμ‹œν‚΅λ‹ˆλ‹€



κ³΅κ²©μžλŠ” (νŒŒμΌμ— λŒ€ν•œ μ“°κΈ° κΆŒν•œ 없이) νŽ˜μ΄μ§€ μΊμ‹œμ˜ `/usr/bin/su`λ₯Ό μ†μƒμ‹œν‚¨ λ‹€μŒ μ‹€ν–‰ν•˜μ—¬ root κΆŒν•œμ„ μ–»μŠ΅λ‹ˆλ‹€.

* * *

## ν΄λŸ¬μŠ€ν„°μ˜ 취약점 확인

ν΄λŸ¬μŠ€ν„°μ— μƒˆ `cve-2026-31431-test` λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€κ³  `test` λ””λ ‰ν† λ¦¬μ˜ λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό μ μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈ 슀크립트λ₯Ό μ‹€ν–‰ν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc apply -f test
    

κ²°κ³Όλ₯Ό ν™•μΈν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc wait pod/cve-test -n cve-2026-31431-test \
      --for=jsonpath='{.status.phase}'=Succeeded --timeout=120s
    oc -n cve-2026-31431-test logs -l app=cve-2026-31431-test
    

**μ·¨μ•½ν•œ ν΄λŸ¬μŠ€ν„°μ—μ„œ** λ‹€μŒκ³Ό 같은 좜λ ₯이 ν‘œμ‹œλ©λ‹ˆλ‹€:

root@kitploit:~
    
    
    === CVE-2026-31431 Vulnerability Test ===
    Target: /usr/bin/su
    
    Original SHA256: 8969560ae8e6e21c6184c1451f59418822ee69dd5d946d71987b55236bbc0feb
    Attempting splice + AF_ALG page-cache corruption (160 bytes in 40 chunks)...
    After SHA256:    30b0f5b5a054c4df65b48ca792863bf7054b4d793f15f57163792ba6c2b151ae
    
    PAGE CACHE CORRUPTION: YES - /usr/bin/su was modified in the page cache
    
    Attempting to execute corrupted /usr/bin/su ...
      exit code: 0
    
    RESULT: PARTIALLY MITIGATED
      Page-cache corruption succeeded (kernel is vulnerable)
      Privilege escalation blocked (allowPrivilegeEscalation=false)
    

### 4단계: 정리

root@kitploit:~
    
    
    oc delete namespace cve-2026-31431-test
    

* * *

## BPF LSM DaemonSet 배포

BPF LSM μ ‘κ·Ό 방식은 컀널 μˆ˜μ€€μ—μ„œ `socket_bind`λ₯Ό ν›„ν‚Ήν•˜κ³  ν…œν”Œλ¦Ώ 쀑첩에 관계없이 λͺ¨λ“  AF_ALG AEAD λ°”μΈλ“œλ₯Ό μ°¨λ‹¨ν•©λ‹ˆλ‹€. μ΄λŠ” OCP 배포λ₯Ό μœ„ν•΄ libbpfλ₯Ό μ‚¬μš©ν•˜μ—¬ C둜 λ‹€μ‹œ μž‘μ„±λœ block-copyfail을 기반으둜 ν•©λ‹ˆλ‹€.

### 사전 μš”κ΅¬ 사항

BPF LSM이 ν™œμ„±ν™”λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. RHEL CoreOS 9.8(OCP 4.22)μ—λŠ” 기본적으둜 ν™œμ„±ν™”λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒμœΌλ‘œ ν™•μΈν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc debug node/<any-node> -- chroot /host cat /sys/kernel/security/lsm
    

μ˜ˆμƒ 좜λ ₯μ—λŠ” `bpf`κ°€ ν¬ν•¨λ©λ‹ˆλ‹€:

root@kitploit:~
    
    
    lockdown,capability,landlock,yama,selinux,bpf
    

`bpf`κ°€ **μ—†λŠ”** 경우 μΌνšŒμ„± MachineConfigκ°€ ν•„μš”ν•©λ‹ˆλ‹€(μž¬λΆ€νŒ…μ΄ ν•„μš”ν•œ μœ μΌν•œ μ‹œλ‚˜λ¦¬μ˜€):

root@kitploit:~
    
    
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: worker
      name: 99-enable-bpf-lsm
    spec:
      kernelArguments:
        - lsm=lockdown,capability,selinux,bpf
    

### 1단계: λ„€μž„μŠ€νŽ˜μ΄μŠ€ 생성, SCC λΆ€μ—¬, 배포

μƒˆ `block-copyfail` λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€κ³  SCCλ₯Ό λΆ€μ—¬ν•œ λ‹€μŒ `daemonset.yaml` λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό μ μš©ν•˜μ—¬ DaemonSet을 λ°°ν¬ν•©λ‹ˆλ‹€. DaemonSet νŒŒλ“œκ°€ μƒμ„±λ˜κΈ° 전에 privileged SCCκ°€ λΆ€μ—¬λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ SCC 검증 였λ₯˜λ‘œ νŒŒλ“œ 생성이 μ‹€νŒ¨ν•©λ‹ˆλ‹€.

root@kitploit:~
    
    
    oc apply -f daemonset.yaml
    

### 2단계: λͺ¨λ“  λ…Έλ“œμ—μ„œ νŒŒλ“œκ°€ μ‹œμž‘λ  λ•ŒκΉŒμ§€ λŒ€κΈ°

root@kitploit:~
    
    
    oc get pods -n block-copyfail -o wide
    

μ˜ˆμƒ: λ…Έλ“œλ‹Ή ν•˜λ‚˜μ˜ νŒŒλ“œ, λͺ¨λ‘ `Running` μƒνƒœ:

root@kitploit:~
    
    
    NAME                   READY   STATUS    AGE   NODE
    block-copyfail-2jhzf   1/1     Running   34s   ci-...-master-2
    block-copyfail-4dfq7   1/1     Running   34s   ci-...-master-1
    block-copyfail-c2ts8   1/1     Running   34s   ci-...-worker-c
    block-copyfail-ctblk   1/1     Running   34s   ci-...-worker-a
    block-copyfail-m26sx   1/1     Running   34s   ci-...-worker-b
    block-copyfail-xsh6d   1/1     Running   34s   ci-...-master-0
    

### 3단계: 차단기가 ν™œμ„± μƒνƒœμΈμ§€ 확인

root@kitploit:~
    
    
    oc logs -n block-copyfail -l app=block-copyfail
    

μ˜ˆμƒ:

root@kitploit:~
    
    
    block-copyfail: blocker active β€” all AF_ALG AEAD binds blocked
    

* * *

## 배포 ν›„ 검증

취약점 확인 μ„Ήμ…˜μ˜ λ™μΌν•œ 취약점 ν…ŒμŠ€νŠΈλ₯Ό λ‹€μ‹œ μ‹€ν–‰ν•©λ‹ˆλ‹€.

**BPF LSM DaemonSet 배포 ν›„** 좜λ ₯은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

root@kitploit:~
    
    
    === CVE-2026-31431 Vulnerability Test ===
    Target: /usr/bin/su
    
    Original SHA256: 30b0f5b5a054c4df65b48ca792863bf7054b4d793f15f57163792ba6c2b151ae
    Attempting splice + AF_ALG page-cache corruption (160 bytes in 40 chunks)...
      AF_ALG bind failed: [Errno 1] Operation not permitted
    
    RESULT: CANNOT TEST - AF_ALG or splice not available/permitted
    

DaemonSet λ‘œκ·Έμ—λŠ” μ°¨λ‹¨λœ μ‹œλ„κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc logs -n block-copyfail -l app=block-copyfail
    

root@kitploit:~
    
    
    block-copyfail: blocker active β€” all AF_ALG AEAD binds blocked
    block-copyfail: BLOCKED pid=16777    comm=python3 time=2026-05-01 16:37:23
    

### λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜μ΄ 영ν–₯을 λ°›μ§€ μ•ŠλŠ”μ§€ 확인

λ…Έλ“œμ—μ„œ `verify-algos.py`λ₯Ό μ‹€ν–‰ν•˜μ—¬ λͺ¨λ“  AEAD μ•Œκ³ λ¦¬μ¦˜μ΄ μ°¨λ‹¨λ˜λŠ” λ™μ•ˆ λ‹€λ₯Έ AF_ALG μœ ν˜•(ν•΄μ‹œ, skcipher)이 계속 μž‘λ™ν•˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc debug node/<any-node> -- chroot /host python3 -c "
    import socket
    tests = [
        ('aead',     'gcm(aes)'),
        ('aead',     'ccm(aes)'),
        ('aead',     'rfc4106(gcm(aes))'),
        ('hash',     'sha256'),
        ('skcipher', 'cbc(aes)'),
        ('aead',     'authencesn(hmac(sha256),cbc(aes))'),
    ]
    for t, n in tests:
        s = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
        try:
            s.bind((t, n))
            print(f'  ALLOWED  {t}/{n}')
        except OSError as e:
            print(f'  BLOCKED  {t}/{n} -- {e}')
        finally:
            s.close()
    "
    

μ˜ˆμƒ 좜λ ₯:

root@kitploit:~
    
    
      BLOCKED  aead/gcm(aes) -- [Errno 1] Operation not permitted
      BLOCKED  aead/ccm(aes) -- [Errno 1] Operation not permitted
      BLOCKED  aead/rfc4106(gcm(aes)) -- [Errno 1] Operation not permitted
      ALLOWED  hash/sha256
      ALLOWED  skcipher/cbc(aes)
      BLOCKED  aead/authencesn(hmac(sha256),cbc(aes)) -- [Errno 1] Operation not permitted
    

μ΄λŠ” BPF LSM이 λ‹€λ₯Έ AF_ALG μœ ν˜•μ€ κ·ΈλŒ€λ‘œ λ‘λ©΄μ„œ λͺ¨λ“  AEAD λ°”μΈλ“œλ₯Ό 차단함을 ν™•μΈν•©λ‹ˆλ‹€.

* * *

## μ†ŒμŠ€μ—μ„œ 이미지 λΉŒλ“œ

BPF LSM 차단기 μ†ŒμŠ€λŠ” `block-copyfail/`에 μžˆμŠ΅λ‹ˆλ‹€:

root@kitploit:~
    
    
    block-copyfail/
      block_copyfail.bpf.c     # BPF 컀널 ν”„λ‘œκ·Έλž¨ (LSM 후크)
      block_copyfail.c          # μ‚¬μš©μž 곡간 λ‘œλ” (libbpf μŠ€μΌˆλ ˆν†€)
      block_copyfail.h          # 곡유 이벀트 ꡬ쑰체
      Makefile                  # λΉŒλ“œ νŒŒμ΄ν”„λΌμΈ
      Dockerfile                # 닀단계 λΉŒλ“œ
      daemonset.yaml            # λ„€μž„μŠ€νŽ˜μ΄μŠ€ + DaemonSet λ§€λ‹ˆνŽ˜μŠ€νŠΈ
      trigger-test.py           # λΉ λ₯Έ 검증 슀크립트
    

λΉŒλ“œ 및 ν‘Έμ‹œ:

root@kitploit:~
    
    
    cd block-copyfail/
    podman build -t quay.io/<org>/block-copyfail:latest .
    podman push quay.io/<org>/block-copyfail:latest
    

Dockerfile은 닀단계 λΉŒλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€: μ»΄νŒŒμΌμ„ μœ„ν•œ clang/bpftool/libbpf-devel이 ν¬ν•¨λœ Fedora, λŸ°νƒ€μž„ μ΄λ―Έμ§€μš© UBI 9 μ΅œμ†Œ(~122 MB).

* * *

## 제거

DaemonSet을 μ‚­μ œν•˜λ©΄ λͺ¨λ“  λ…Έλ“œμ—μ„œ μ™„ν™” μ‘°μΉ˜κ°€ μ¦‰μ‹œ μ œκ±°λ©λ‹ˆλ‹€:

root@kitploit:~
    
    
    oc delete -f daemonset.yaml
    # λ˜λŠ”
    oc delete namespace block-copyfail
    

BPF ν”„λ‘œκ·Έλž¨μ€ λ‘œλ” ν”„λ‘œμ„ΈμŠ€κ°€ μ’…λ£Œλ˜λ©΄ μžλ™μœΌλ‘œ λΆ„λ¦¬λ©λ‹ˆλ‹€. μž¬λΆ€νŒ…μ΄λ‚˜ νŒŒλ“œ μž¬μ‹œμž‘μ΄ ν•„μš” μ—†μŠ΅λ‹ˆλ‹€.