作者:啟明星辰ADLab
原文鏈接:https://mp.weixin.qq.com/s/OwQ3B5vjpr9ZsvOXftJoQg
一、漏洞概述
4月7日,seongil-wi在github上披露了Node.js模塊 vm2 的沙箱逃逸漏洞(CVE-2023-29017),CVSSv3評分為10.0,漏洞定級為嚴重,影響版本為3.9.14之前。隨后Xion又在修復的vm2 3.9.15版本中披露了同級別的另一沙箱逃逸漏洞(CVE-2023-29199)。啟明星辰ADLab在第一時間對漏洞進行了分析并給出修復建議。沙箱對Node.js 宿主對象的操作進行代理,以達到在Node.js 中執行受信任的代碼。如果Node.js的宿主對象未經沙箱處理直接使用,可執行任意代碼,從而繞過沙箱保護。
二、漏洞分析與修復
(一)漏洞CVE-2023-29017:
1.漏洞分析:
該漏洞通過函數Error.prepareStackTrace 繞過沙箱。當異常發生時,函數Error.prepareStackTrace可用來定制輸出棧的信息。
當在vm2 沙箱環境下執行代碼時,vm2通過vm配置程序運行的虛擬環境,將Node.js環境中的全局變量eval、Function等進行代理:
對宿主環境中的對象和代理對象進行映射,對于宿主對象的操作實際上操作的是代理對象,這種機制可阻斷宿主環境中不可信的代碼對不安全模塊或對象的訪問。
如在沙箱的環境下獲得當前進程的process對象,會出現該對象沒有定義的錯誤,一定程度上阻止了沙箱中代碼訪問一些可能帶來安全隱患的對象:
在沙箱環境的配置中設置了Error.prepareStackTrace 中的getter 和setter方法,使該方法執行時的調用棧對象為私有的調用棧:
問題在于沙箱程序并沒有考慮變量sst是否是沙箱處理過的對象,如果是宿主對象,那么該變量可直接在方法prepareStackTrace執行的時候直接使用,也就是漏洞的導火索。
在正常情況下,當執行錯誤時(line285),會在當前沙箱環境下拋出異常,前述的sst是安全的。
但當執行的異常是在一個異步函數中出現的異常,line285 直接返回的ret是一個promise對象,只不過該對象的狀態是rejected,這樣就跳過了line288在沙箱環境下拋出的異常。
在跳出了沙箱環境后,Node.js會處理Promise rejected的情況 ,使用reason創建錯誤直接拋出:
這時在prepareStackTrace中捕獲的異常棧信息sst就不是沙箱中的對象,即宿主對象。由于reason是沙箱對象,創建的err也是沙箱對象,即error信息的對象是安全的:
當prepareStackTrace執行時,使用宿主對象sst索引到的Function正是原始的對象,獲得原始的Function的對象,即可創建任意代碼來執行。
2.漏洞修復:
在漏洞補丁中,傳遞給prepareStackTrace的棧幀數組,使用ensureThis函數確保該數組是經過proxy處理的對象。由于當前環境是在沙箱內,所以創建的數組也是安全的。
(二)漏洞CVE-2023-29199
1.漏洞分析:
不同于Error.prepareStackTrace傳遞Node.js宿主對象,該漏洞利用沙箱在對要執行的代碼預處理的過程繞過沙箱。
在代碼執行前,沙箱使用transform函數遍歷代碼的AST,對于catch語句塊中會插入代碼,調用handleException 確保捕獲的錯誤對象是受沙箱保護的:
在插入前的代碼如:
執行插入后會在catch body中插入:
在隨后的transform中會將$tmpname 替換為tmpname:
tmpname的值為VM2_INTERNAL_TMPNAME:
替換后的catch塊為:
aVM2_INTERNAL_TMPNAME=VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL.handleException(aVM2_INTERNAL_TMPNAME);
沙箱本意是想保護atmpname這個宿主對象未經保護可直接使用。為了保證程序正常執行,在POC中定義了變量aVM2_INTERNAL_TMPNAME:
同第一個漏洞,通過a$tmpname 可以索引到Function對象,可執行任意代碼。
2.漏洞修復:
在3.9.16的修復中,插入的代碼放在了一個函數中,即將code轉化為coder,直接對catch變量進行沙箱保護:
在后續的獲取代碼的循環中,省去了對變量名的替換,這樣就避免了保護對象錯位的問題:
三、漏洞驗證
在兩個漏洞的驗證中,都是使用前述的process對象在本地創建了新的文件,成功繞過了沙箱,如下圖所示。
參考鏈接:
[1] https://gist.github.com/seongil-wi/2a44e082001b959bfe304b62121fb76d
[2] https://nvd.nist.gov/vuln/detail/CVE-2023-29017
[3] https://mp.weixin.qq.com/s/LiFjTw2tQpQaPuLH
[4] https://mp.weixin.qq.com/s/Q7thK-z_X71SQvllp
[6] https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
[7] https://github.com/patriksimek/vm2/commit/d534e5785f38307b70d3aac1945260a261a94d50
[8] https://github.com/patriksimek/vm2/security/advisories/GHSA-xj72-wvfv-8985
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/2062/
暫無評論