iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
Security

Agentic Era,一年來 LLM 到底都挖了些什麼洞!系列 第 6

Day 6. 拆家:Mythos 的流水式奇襲,突破沙盒保護網

  • 分享至 

  • xImage
  •  

回到了 Agent Finding 的一天,今天要講的是 Anthropic Mythos 發現的
twigphp/twig - code injection [1]

Code Tracing

這邊先簡單說明一個 Template 具體被 Compile 成我們看到的前端畫面到底經過了哪些流程:

網路上找不到好的圖所以我把文字丟給 Gemini 生了這張東西
image

簡單來說,每一個模板段落 {%...%} 會被拆成一個個 Node 再塞進 AST (語法樹)解析,分段進去獨立的 PHP Code Generation。

接著產生這份 PHP Code 後,才會再回去原本的 Context 做其餘執行/Render 等動作,而直到這邊才加入了我們的 Sandbox 保護。
如果 Pre Compile 的過程中就有漏洞了呢...?
這就是我們的 CVE-2026-46633 Sandbox Bypass

以有漏洞的 v3.25.0 為例
https://github.com/twigphp/Twig/blob/v3.25.0/src/Node/ModuleNode.php#L245-L274 [2]

這段是在使用者嘗試引入的模板不在當前 block 內時提出報錯的程式碼

foreach ($trait->getNode('targets') as $key => $value) {
        $compiler
            ->write(\sprintf('if (!isset($_trait_%s_blocks[', $i))
            ->string($key)
            ->raw("])) {\n")
            ->indent()
            ->write("throw new RuntimeError('Block ")
            ->string($key)
            ->raw(' is not defined in trait ')
            ->subcompile($trait->getNode('template'))
            ->raw(".', ")
            ->repr($node->getTemplateLine())
            ->raw(", \$this->source);\n")
            ->outdent()
            ->write("}\n\n")

...<SNIP>...
    
    }
}

理論上名稱經過 subcompile 後,應該產生的結果是:

throw new RuntimeError('Block absent is not defined in trait "traits.html".');

可是在經過 Compiler::string() 時, Compiler 忘記去過濾單引號(這邊有記得過濾別的唯獨沒有單引號 XD):
https://github.com/twigphp/Twig/blob/v3.25.0/src/Compiler.php#L144-L149 [3]

    public function string(string $value)
    {
        $this->source .= \sprintf('"%s"', addcslashes($value, "\0\t\"\$\\"));

        return $this;
    }

就這樣導致在 throw error 時可以達成 code injection。
e.g. 引入一個 trait 是

'.system('whoami').'.html

就直接 RCE 了,因為生成出來的內容是:

throw new RuntimeError('Block absent is not defined in trait "'.system('whoami').'.html".');

單引號閉合!

整體而言攻擊流程就是:不合法的 trait name 引入 => 走到報錯分支產生 Code Injection 程式碼

燈下黑

2023 年就有來自頂會 USENIX 的 Paper 在討論這件事情了:
Remote Code Execution from SSTI in the Sandbox: Automatically Detecting and Exploiting Template Escape Bugs [4]

甚至當時還未成功 FUZZ 出任何 Twig Sandbox Escape 呢 xDDD
其實可以想見過去有很多各種(尤其針對邏輯洞的) Fuzzer 會因為走不到一些神奇的 Exception/走到 Exception 就直接判斷不合法退出 等等原因導致許多這樣的分支被漏看,但對於 Agent 不論是直接追完整份 code;抑或是 source <-> sink 這樣下去想辦法串起來,我相信在輔佐人類過去的 Fuzzing 科技上都會很有幫助!

References


上一篇
Day5. SSTI 之二:沙盒之力 啟動!
下一篇
Day 7. 你可能不知的 HTTP 細節:RFC 7541
系列文
Agentic Era,一年來 LLM 到底都挖了些什麼洞!8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言