🔥 CVE-2026-31431 深床独立研究源码审计 · 二次发现 · 利甚方案

🔥 高危挏掞深床独立研究 · CVSS ≥ 9.8

CVE-2026-31431 深床独立研究源码审计 · 二次发现 · 利甚方案

📊 8 来源🔍 源码审计🧪 PoC
NVD-LatestGitHub-AdvisoryPoC-in-GitHubExploit-DB-RSSOrca Security

🔍 源码独立审计

对 https://github.com/theori-io/copy-fail-CVE-2026-31431 源码进行独立审计眮信床 0%。

🧬 根因独立理解

审计解析倱莥

🛀 挏掞觊发铟路

🧪 PoC 倍现

从 GitHub 公匀仓库抓取的实际 PoC 代码仓库。

📋 代码元数据语蚀md来源tgies/copy-fail-c针对性✅ 已验证䞎挏掞盞关代码含 CVE 匕甚䟝赖见代码泚释/README甚法诊见代码泚释䞭的䜿甚诎明

# Copy Fail (CVE-2026-31431) - C port

*[English (en)](README.md) ∙ [日本語 (ja)](README.ja.md) ∙ [简䜓䞭文 (zh-cn)](README.zh-cn.md) ∙ [한국얎 (ko)](README.ko.md) ∙ [РусскОй (ru)](README.ru.md)*

Copy Fail Linux LPE (CVE-2026-31431) のクロスプラットフォヌムC蚀語による再実装です。この脆匱性はTheori / Xintによっお2026幎4月29日に公開されたした。脆匱性の詳现、タむムラむン、Theoriによる発芋プロセスに぀いおは、[copy.fail](https://copy.fail/) の公匏レポヌトを参照しおください。

公開されおいるProof-of-Concept (PoC) は732バむトのPythonスクリプトです。このC蚀語ぞの移怍版は、プロゞェクト独自の゜ヌス内にアヌキテクチャごずの16進数バむナリやむンラむンアセンブリを含めるこずなく、nolibcがサポヌトする任意のアヌキテクチャにコンパむル可胜なポヌタブルなC蚀語ずしお同じ゚クスプロむトを衚珟できるこずを実蚌しおいたす。

本移怍版の䜜成者: Tony Gies <tony.gies@crashunited.com>
発芋および圓初の公開: Theori / Xint

## リポゞトリ構成

```
copy-fail-c/
├── exploit.c           ドロッパヌ (バむナリ曞き換えバリアント)
├── exploit-passwd.c    ドロッパヌ (/etc/passwd UID曞き換えバリアント)
├── vulnerable.c        非砎壊的な脆匱性チェッカヌ
├── payload.c           ドロップされる本䜓 (setgid+setuid+execve sh)
├── utils.c,
utils.h    AF_ALG/splice ペヌゞキャッシュ曞き換えプリミティブ (共有)
├── Makefile            ビルドのオヌケストレヌション
├── nolibc/             torvalds/linux の tools/include/nolibc からのベンダヌコヌド
└── README.md           このファむル
```

`make` 埌:

```
├── payload             ドロッパヌにバむト列ずしお埋め蟌たれる小さな静的ELF
├── payload.o           `ld -r -b binary` によっお再配眮可胜な .o ずしおラップされたペむロヌド
├── exploit             ドロッパヌ、バむナリ曞き換えバリアント
├── exploit-passwd      ドロッパヌ、/etc/passwd UID曞き換えバリアント
└── vulnerable          非砎壊的な脆匱性チェッカヌ
```

`exploit.c` は察象バむナリを読み取り専甚で開き、埋め蟌たれたペむロヌドの4バむトのりィンドりごずにAF_ALGを介しおダミヌのAEAD埩号を1回実行したす。このずきの暗号文入力は、タヌゲットのペヌゞキャッシュペヌゞからsplice()を介しお提䟛されたす。authencesnテンプレヌトのむンプレヌス最適化により、spliceされた゜ヌスペヌゞは暗号文入力ず平文出力先のアドレスの䞡方ずしお扱われるため、認蚌怜蚌がリク゚ストを拒吊する頃には、倱敗する埩号によっおすでにペヌゞキャッシュペヌゞが䞊曞きされおいたす。4 * N回の反埩埌、タヌゲットのキャッシュされたむメヌゞはペむロヌドずバむト単䜍で完党に眮き換えられたす。タヌゲットをexecve()するず、倉異したペヌゞがロヌドされたす。ディスク䞊のinodeは䟝然ずしおsetuid rootであるため、カヌネルはroot暩限を付䞎し、ペむロヌドを実行したす。

`payload.c` は玔粋なポヌタブルC蚀語です: `setgid(0);
setuid(0);execve("/bin/sh",
...)`。nolibcは `_start`、システムコヌル機構、およびアヌキテクチャごずのレゞスタ操䜜を提䟛したす。

2番目のバリアントである `exploit-passwd.c` は、setuidバむナリのむメヌゞの代わりに /etc/passwd のペヌゞキャッシュの4バむトを曞き換えたす。埋め蟌みペむロヌドを必芁ずせず、バむナリ曞き換えのルヌトがブロックされおいるシステムでも機胜したすが、キャッシュアりトの暩限昇栌を達成するサヌフェスははるかに狭くなりたす。

`vulnerable.c` ぱクスプロむトではありたせん。文字列 `init` を含むロヌカルの `testfile` を䜜成し、そのファむル自身のペヌゞキャッシュに察しお同じ `patch_chunk()` プリミティブを実行しお、バむトを `vulnerable` に䞊曞きしようずしたす。読み戻したファむル内容が䞀臎すれば、実行䞭のカヌネルは CVE-2026-31431 の圱響範囲内です。ディスク䞊のinodeは倉曎されたせん。`testfile` は終了時に削陀され、ペヌゞキャッシュの曞き換えもそれず共に消えたす。特暩なしで実行できたす。終了コヌドは、脆匱な堎合は100、プリミティブは実行できたが曞き換えが起きなかった堎合は0、AF_ALG゜ケットファミリたたはauthencesnテンプレヌトが利甚できずパッチ状態を刀定できない堎合は2、その他の実行時゚ラヌでは1です。

## ビルド

デフォルト (ホストアヌキテクチャ向けネむティブ):

```sh
make
```

aarch64 ぞのクロスコンパむル (たたはクロスツヌルチェヌンがむンストヌルされおいる他のLinuxアヌキテクチャ):

```sh
make CC=aarch64-linux-gnu-gcc LD=aarch64-linux-gnu-ld
```

ベンダヌ化されたnolibcがサポヌトするアヌキテクチャアップストリヌムに準拠: x86_64,
i386,arm,aarch64,riscv32/64,mips,ppc,s390x,loongarch,m68k,sh,sparc。nolibcはコンパむラのアヌキテクチャマクロに基づいおディスパッチするため、適切な `CC`/`LD` を遞択するだけで十分です。

ビルドの芁件:

* Cコンパむラ (`cc`,`gcc` たたは任意のクロスバリアント)
* `ld -r -b binary` をサポヌトするリンカヌ (binutils ld および lld は察応)
* `linux/if_alg.h` ず `<asm/unistd.h>` を提䟛するカヌネルUAPIヘッダヌ (Debian/Ubuntu: `linux-libc-dev`;
クロスバリアント: 通垞、クロスツヌルチェヌンパッケヌゞに含たれたす)

Linux 5.6 より叀いヘッダヌセットは、ベンダヌ化されたnolibcが䜿甚する `__kernel_old_time_t` および `struct __kernel_old_timespec` よりも前のものです。`compat.h` (ペむロヌドのビルドに匷制むンクルヌドされたす) は、これらが存圚しない堎合に提䟛するため、叀い `linux-libc-dev` でも匕き続きビルドできたす。5.6 以降のヘッダヌでは䜕もしたせん。

倖郚ラむブラリぞの䟝存関係はありたせん。ペむロヌドはnolibcに察しおフリヌスタンディングずしおビルドされたす。ドロッパヌは `fprintf` ず `perror` のためだけにホストのlibcずリンクしたす。

## アヌキテクチャの遞択

゜ヌスのポヌタビリティを維持し、ペむロヌドを小さく保぀ために、ツヌルチェヌンのいく぀かの小さな機胜が倧きな圹割を果たしおいたす。

### nolibc

`nolibc/` はカヌネルの小さなヘッダヌオンリヌなlibcの代替であり、torvalds/linux の `tools/include/nolibc/` から取り蟌たれたものです。これは `_start`、ポヌタブルな `syscall()` マクロ、およびむンラむンシステムコヌルラッパヌを提䟛し、アヌキテクチャごずのレゞスタの芏則は `nolibc/arch-*.h` に゚ンコヌドされおいたす。`-nostdlib -static -ffreestanding -Inolibc` でペむロヌドをビルドするず、glibcのスタヌトアップ、TLSの初期化、たたはスタックカナリアの仕組みを組み蟌むこずなく、盎接カヌネルを呌び出す小さな静的ELFが生成されたす。結果: パックおよびセクションヘッダヌの削陀埌 (いずれも埌述)、x86_64で玄720バむト、aarch64で玄1.2 KBになりたす。同じ `payload.c` をmusl-staticでリンクするず玄17 KB、glibc-staticでは玄700 KBになりたす。

### 埋め蟌み甚の `ld -r -b binary`

Makefileは `ld -r -b binary -o payload.o payload` を介しお、ビルドされた `payload` ELFを `payload.o` に倉換したす。リンカヌは入力バむトを再配眮可胜なオブゞェクトファむルのデヌタセクションずしおそのたた出力し、入力ファむル名から3぀のシンボルを合成したす。

```
_binary_payload_start    最初のペむロヌドバむトのアドレス
_binary_payload_end      最埌のペむロヌドバむトの1぀埌のアドレス
_binary_payload_size     絶察シンボル倀はバむト単䜍のサむズ
```

`exploit.c` は最初の2぀を `extern const unsigned char[]` ずしお宣蚀し、サむズを `_binary_payload_end - _binary_payload_start` ずしお蚈算したす。

### `-Wl,-N` ず厳しい `max-page-size`

ペむロヌドは `-Wl,-N -Wl,-z,max-page-size=0x10` で静的リンクされたす。これにより、カヌネルのペヌゞ境界に合わせたセグメントあたり4 KBのデフォルトの代わりに、16バむトのファむルアラむンメントで `.text`/`.rodata`/`.data` が単䞀のLOADセグメントにたずめられたす。これにより `ld` から「RWX permissions」の譊告が出たすが、これは情報提䟛のみです。ペむロヌドの実行時メモリ保護は、この単䞀目的のプログラムにずっお重芁ではありたせん。このフラグがない堎合、同じコヌドはx86_64で玄13 KB倧郚分はセグメント間のれロパディングにリンクされたすが、これを䜿甚するず、埌述のセクションヘッダヌ削陀前で玄1.3 KBになりたす。

### セクションヘッダヌの削陀

リンク埌、`objcopy --strip-section-headers` はペむロヌドのセクションヘッダヌテヌブルず `.shstrtab` を削陀したす。カヌネルのELFロヌダヌはプログラムをそのプログラムヘッダヌのみからマップするため、これらのバむトは実行時にはロヌドされたせんが、`payload` はそのたた埋め蟌たれるため、ドロップず `patch_chunk` の反埩回数を増倧させたす。これらを削陀するず、x86_64のペむロヌドは玄1.3 KBから720バむトになりたす322回の4バむト反埩が180回に枛少。2぀のリンク時フラグが残りを削りたす: `-Wl,--build-id=none` はbuild-idノヌトを削陀し、`-fcf-protection=none` はコンパむラがサポヌトしおいる堎合にx86のCETノヌトを削陀したす。

この削陀には binutils >= 2.40 が必芁です。クロスビルドでは `OBJCOPY=` を介しおタヌゲットのobjcopyを枡したす (䟋: `OBJCOPY=aarch64-linux-gnu-objcopy`)。objcopyが削陀を実行できない堎合、ビルドは泚意メッセヌゞを衚瀺し、有効でより倧きなペむロヌドを保持したす。


## バリアントずキャッシュアりトの実珟可胜性

このリポゞトリは、AF_ALG/splice ペヌゞキャッシュの曞き換えプリミティブを共有し぀぀、異なる方法でroot実行にキャッシュアりト暩限昇栌を達成する2぀の゚クスプロむトバリアントを提䟛しおいたす。それらの信頌性プロファむルは同等ではなく、珟実䞖界の脅嚁モデルを掚論する際にこの違いが重芁になりたす。

### バむナリ曞き換えバリアント (`exploit`)

タヌゲットのsetuidバむナリのペヌゞキャッシュを埋め蟌たれたペむロヌドバむトで曞き換え、バむナリをexecしたす。カヌネルは、バむナリのディスク䞊の倉曎されおいないsetuidビットからroot暩限を付䞎し、メモリ䞊の砎損したむメヌゞをロヌドしお、ペむロヌドを実行したす。

攻撃者がシステム䞊の任意のroot-setuidバむナリに察しお `open(target,
O_RDONLY)` できる堎所であればどこでも機胜したす。制限された読み取りディレクトリの背埌にあるsetuidバむナリの環境や、setuidを䜿甚しないシステム蚭蚈によっおおおむね防埡されたす。

### /etc/passwd UID曞き換えバリアント (`exploit-passwd`)

/etc/passwd のペヌゞキャッシュの4バむトを曞き換えお、実行䞭のナヌザヌのUIDフィヌルドを "0000" に蚭定したす。/etc/passwd はすべおの暙準的なLinuxシステムで誰でも読み取り可胜であるため、*曞き換え* 自䜓は普遍的です。これをroot実行に倉換するには、root偎のプロセスが getpwnam/getpwuid を介しおナヌザヌを解決し、クロスチェックを行わずに解決されたuidに基づいお行動するこずに䟝存したす。そのようなコンシュヌマヌは倚く存圚したすが、その倚くは呌び出し元のuidに察するカヌネルのビュヌや、ディスク䞊のファむルの所有暩ず防衛的なクロスチェックを行うため、キャッシュアりトが機胜しなくなりたす。

#### キャッシュアりト実珟可胜性マトリックス

|
キャッシュアりト |事前のroot蚭定の必芁性 |備考 ||---|---|---||WSL2 セッションのスポヌン |なし |WSLのセッションごずの `setuid(getpwnam(default_user)->pw_uid)` は怜蚌を行いたせん。クリヌンに動䜜したす。 ||util-linux `su` |なし |呌び出し元の識別凊理が寛容です。 ||shadow-utils `su` |あり |`getpwuid(getuid())` 呌び出し元の識別チェックは、曞き換えによっお実際のuidがマッピングされなくなるため倱敗したす。 ||sshd (デフォルト `StrictModes yes`) |あり (StrictModes の無効化) |
StrictModes はホヌムディレクトリが root たたは `pw->pw_uid` に所有されおいるこずを芁求したす。曞き換えにより pw_uid=0 になりたすが、ディスク䞊の所有者は元のuidのたたです。䞍䞀臎のため認蚌が拒吊されたす。 ||MTA ロヌカル配信 (postfix,exim など) |倉動あり |MDAのホヌム暩限怜蚌に䟝存したす。MTAごずのテストが必芁です。 |
#### `su` 倱敗埌のピボット

`exploit-passwd` は曞き換え埌に最も単玔なキャッシュアりトずしお `su <user>` をexecしたす。これは util-linux の `su` に察しおは機胜したすが、shadow-utils の `su` に察しおは "Cannot determine your user name." で倱敗したす。この時点でもペヌゞキャッシュの曞き換えは有効であり、他のキャッシュアりト䟋: クロスチェックなしで getpwnam を介しおナヌザヌを解決するデヌモンを䜿甚するぞのピボットは可胜です。
テスト完了埌に砎損したペヌゞキャッシュをクリアするには、rootずしお `echo 3 >
/proc/sys/vm/drop_caches` を実行しおください。

## 圱響を受けるカヌネル

```
例限:    torvalds/linux 72548b093ee3   2017幎8月,v4.14
                                        (AEADスキャッタヌリストぞのspliceを介した
                                         ファむルペヌゞ曞き蟌みプリミティブを
                                         導入したAF_ALG iov_iterの再構築)

侊限:    torvalds/linux a664bf3d603d   2026幎4月,
メむンラむン
                                        (2017幎のalgif_aeadむンプレヌス最適化を元に戻す;
゜ヌスず宛先のスキャッタヌリストを分離し、
                                         ペヌゞキャッシュペヌゞが曞き蟌み可胜な
                                         暗号化の宛先にならないようにした)
```

この間の期間: 修正をバックポヌトしなかったすべおの䞻芁なディストリビュヌションカヌネル。
Ubuntu、RHEL、SUSE、Amazon Linux、およびDebianはすべお、情報公開時にストッククラりドむメヌゞカヌネルで脆匱性が確認されおいたした。ディストリビュヌションレベルのバックポヌトは、䞀般公開ず䞊行しお2026幎4月29日頃から展開され始めたした。タヌゲットカヌネルが該圓期間内にあるかどうかを確認するには、カヌネルのgitログたたはディストリビュヌションのチェンゞログに `a664bf3d603d` (たたはそのディストリビュヌション固有のバックポヌト) が存圚するかどうかを確認しおください。

## 商甚サポヌト

有償のセキュリティレビュヌ、カスタム移怍、非公開のセキュリティアドバむザリに぀いおは、䜜成者のコンサルティング䌚瀟である Crash United,
LLC を通じおお問い合わせください。

連絡先: tony.gies@crashunited.com · https://crashunited.com  
GitHub: [@tgies](https://github.com/tgies) · X/Twitter: [@me_irl](https://x.com/me_irl)

## ラむセンスずクレゞット

CVE-2026-31431の発芋ず圓初の公開: Theori / Xint
公匏レポヌト: <https://copy.fail/>本C移怍版: Tony Gies <tony.gies@crashunited.com>
`nolibc/`: Linuxカヌネルツリヌからのベンダヌコヌド、デュアルラむセンス
LGPL-2.1-or-later たたは MIT (`nolibc/nolibc.h` および各ファむルのSPDXヘッダヌを参照)。

このリポゞトリのドロッパヌおよびペむロヌドの゜ヌスは、䟝存するnolibcツリヌず同じLGPL-2.1-or-later たたは MIT のデュアルラむセンス条項の䞋でリリヌスされおいたす。これは、このディレクトリ党䜓を自分の䜜業環境に取り蟌むナヌザヌに察しおラむセンスの互換性を容易に維持するためです。

゚クスプロむトずペむロヌドは、セキュリティ研究および防衛的な怜出の目的で公開されおいたす。所有しおいない、たたは明瀺的なテストの蚱可を埗おいないシステムに察する䜿甚は、䜜成者ではなくあなた自身の責任です。

⚔ EXP 利甚代码

截至分析时Exploit-DB 未收圕该 CVE 的公匀利甚代码。可利甚䞊述 PoC 进行验证或关泚 Exploit-DB 曎新。

🕵 检测指纹

针对该 CVE 的自劚化检测规则可盎接甚于扫描䞎审计。

🛡 Semgrep 审计规则: CVE-2026-31431.yaml

📋 代码元数据语蚀yaml来源rules/semgrep/CVE-2026-31431.yaml针对性✅ 按 CVE 匹配䟝赖semgrep甚法semgrep --config CVE-2026-31431.yaml

rules:
  - id: CVE-2026-31431-rce-go
    languages:
      - go
    severity: ERROR
    message: "Potential page cache corruption via AF_ALG and splice() leading to local privilege escalation. Avoid direct usage of AF_ALG sockets with splice() on file page-cache pages."
    patterns:
      - pattern: |syscall.Splice($R,nil,$W,nil,$N,0)
    fix: |
// Avoid using splice() with AF_ALG sockets on file-backed pages.
      // Use safe I/O operations like io.Copy instead of splice.
    metadata:
      cwe: "CWE-277"
      owasp: "A5: Broken Access Control"
      technology: talos
      references:
        - "https://github.com/advisories/GHSA-m38g-vww2-mvgx"
  - id: CVE-2026-31431-rce-go-alg
    languages:
      - go
    severity: ERROR
    message: "Potential page cache corruption via AF_ALG and splice() leading to local privilege escalation. Avoid direct usage of AF_ALG sockets with splice() on file page-cache pages."
    patterns:
      - pattern: |
syscall.Splice($R,nil,$W,nil,$N,0)
    fix: |// Avoid using splice() with AF_ALG sockets on file-backed pages.
      // Use safe I/O operations like io.Copy instead of splice.
    metadata:
      cwe: "CWE-277"
      owasp: "A5: Broken Access Control"
      technology: talos
      references:
        - "https://github.com/advisories/GHSA-m38g-vww2-mvgx"

🛡 CodeQL 审计规则: CVE-2026-31431.ql

📋 代码元数据语蚀ql来源rules/codeql/CVE-2026-31431.ql针对性✅ 按 CVE 匹配䟝赖codeql甚法codeql database run

/**
 * @kind path-problem
 * @id go/command-injection/cve-2026-31431
 * @name Unsafe splice() in AF_ALG leading to arbitrary code execution via nftables
 * @description Untrusted workload using AF_ALG and splice() can corrupt page-cache pages,
leading to arbitrary code execution in kube-proxy via nft binary poisoning
 * @problem.severity error
 * @tags security
 *       external/cwe/cwe-078
 */
import go
import semmle.go.security.dataflow.CommandInjectionCustomizations
import CommandInjectionFlow::PathGraph

/**
 * A source of untrusted input from inside a container (workload)
 */
class WorkloadSource extends DataFlow::Node {
WorkloadSource() {// Environment variables,command line arguments,network input,etc.
    any(DataFlow::Node src).(RemoteFlowSource) = src
    or
    // Any input received via AF_ALG socket from the container
    exists(FileReadAccess f |f.getFile().getAbsolutePath().matches("%/proc/%/fd/%"))
  }}
/**
 * A sink that represents the splice() system call on AF_ALG socket
 * which can corrupt page-cache pages
 */
class SpliceAlgSink extends DataFlow::Node {SpliceAlgSink() {exists(FunctionCall fc |fc.getTarget().getName() = "splice" and
      fc.getAnArgument().(DataFlow::Node).asExpr().getType().(PointerType).getBaseType().getName() = "alg_socket"
    )
  }}
/**
 * Sink for nft execution which can be poisoned via page-cache corruption
 */
class NftExecutionSink extends DataFlow::Node {NftExecutionSink() {exists(FunctionCall fc |
fc.getTarget().getName() = "exec" or
      fc.getTarget().getName() = "execve" or
      fc.getTarget().getName() = "syscall.Exec"
    ) and
    fc.getAnArgument().(DataFlow::Node).asExpr().(StringLiteral).getValue().matches("*/nft*")
  }}class PoC_CommandInjectionConfig extends TaintTracking::Configuration {PoC_CommandInjectionConfig() {this = "PoC_CommandInjectionConfig" }
override predicate isSource(DataFlow::Node source) {source instanceof WorkloadSource
  }override predicate isSink(DataFlow::Node sink) {sink instanceof SpliceAlgSink or
    sink instanceof NftExecutionSink
  }}from PoC_CommandInjectionConfig cfg,DataFlow::PathNode source,DataFlow::PathNode sink
where cfg.hasFlowPath(source,sink)
select sink.getNode(),source,sink,
"Untrusted workload data flows to splice() or nft execution,enabling page-cache corruption and privilege escalation"

🀖 高危挏掞深床独立研究匕擎生成 · 2026-08-02 21:31

[!] CONTACT_CHANNELS

劂需商务合䜜、技术咚询或挏掞反銈请通过以䞋犻岞节点联系䜜者。

> PING_AUTHOR (@A1RedTeam)