作者:漂亮鼠
原文鏈接:https://mp.weixin.qq.com/s/3phgI8yaPns3Dx5oSkdeYg
0x00 引言
這些年看到幾個很有靈性的年輕人從一個啥也不懂的腳本小子一年時間就成長為業內漏洞挖掘機,一路交流下來也有不少的想法。當然也有看到一些年輕人好像一直很努力的在學,但是半年一年了,學了又好像沒有學還是停留在復現漏洞用腳本的水平。這一上一下的差距一直令我困惑不已,是真的天賦問題?答案肯定是NO的,因為我一直認為天賦只會造成時間效率差距,不會在一個有手就行的地方帶來門檻。就在最近p??直播了一場,也看到不少彈幕的同學在問:“我學了好久java還是挖不到洞,到底要學到什么程度才能挖0day呢?”這么一看這個問題是一個共性的問題,有必要深度解讀一下如何破局。我之前有寫過關于如何學習的文章,也寫過挖洞思維建設,如果這兩篇沒有看過的話可以提前看一看,一些學習方法和思維模型在這里面都提過了比如設置checklist、項目管理、復盤等就不再說了。
0x01 明確觀點
今天和群友也討論了下這個問題,大家都有提到一些點:
- 怕麻煩,覺得這個環境麻煩,那個操作麻煩
- 怕代碼,不愛動手,害怕動手
- 機械式復現,無論是打payload,還是動手跟著調試,都處于一種機械復現
- 缺少自信,認為rce很高端
- 沉迷學習,缺少實踐
上面這些點確實都是很多同學的毛病,可能還會有別的點,如果你真的有這些毛病就趕緊改掉。除了改掉毛病以外,還要樹立以下幾個核心觀念:
- 挖洞有手就行,不一定需要很高超的技巧(不是開玩笑,認真理解這句話記在心里)
- 挖洞需要學習基礎,但不能陷入到無限理論中
- 挖洞需要的不是天賦,需要的是專注、勇氣、自信和努力
當然如果你改掉了還是挖不到,那么你就可以繼續往下看了。
0x02 為什么漏洞復現很多卻挖不到洞
先說一下漏洞挖掘和漏洞復現這兩個流程在模式上的根本區別。當你需要去復現一個漏洞的時候,你獲得了幾個前提:
- xxx組件存在xxx漏洞這個信息提示
- 你可能有了一些泄漏部分的payload截圖
- 你可能有了完整的復現文章
在這些前提下,你的目標會變得很明確,隨著條件的完善復現的難度越來越低,當已經有完整復現文章的時候,你甚至不需要自己去思考跟著操作即可。那么你在復現的時候如果不進行反思和歸納就會淪為F8工具人,整個流程下來你只是知道了這回事。如果你長期從事漏洞復現,然后第一次接到一個漏洞挖掘項目的時候會發生什么?你失去了前面漏洞復現時候所說的幾個前提條件,失去了這些條件給你框定的明確路徑后,由于你從來沒有真正的自我決策過所以你陷入了無法決策的思維恐慌中。在一個真正挖掘項目里,你需要獨立的去規劃自己的工作流程,對每一次測試方向做決策,如果你缺少這種能力就應該從復現工作中進行總結歸納鍛煉自己這種思維。
0x03 漏洞利用的邏輯
我沒學過什么程序分析或者亂七八糟的理論基礎,我根據我自己的理解定義幾個概念吧。
- 可控輸入,大家喜歡叫source,我可以控制的輸入點
- 目標輸出,大家喜歡叫sink,我在意的輸出點
- 程序機制,這個簡單來說就是處于輸入與輸出之間對整個數據進行各種花式變換和轉移的固有程序邏輯或者是系統機制
- trick,一些技巧類的集合,比如繞沙箱、利用技巧繞過過濾、溢出到執行命令的利用等
那么一個簡單漏洞的利用可以看成這么一個圖

這里的輸入1是我們可控的輸入,機制1是整個程序流轉的過程,輸出1比如是一個命令執行函數,那么我們就可以注入命令做到RCE了。這很簡單沒什么好說的,那么復雜一點呢?

這個圖里輸入1依舊是用戶側可控的輸入,輸出3可以認為是最終的命令執行函數,那么中間的輸出1可能是寫配置文件,輸出2可能是發送請求到別的端口,通過機制4和機制5將這些中間輸出進行轉化與搬運,最終把幾個點串聯起來做到輸入1到輸出3的命令執行。上面這個圖主要還是關注一個數據傳播和轉化,那么再加上各個流程中可能會用到的trick就最終得到了一個完整的利用
0x04 技能分類
有了整體的利用思路后,我們需要對漏洞進行一定的分類
| 漏洞類型 | 分類標簽 | 效果 |
|---|---|---|
| SQL注入 | 代碼執行 | 執行部分SQL語句,可能造成命令執行、數據獲取、讀寫文件 |
| XSS | 代碼執行 | 有限或無限的Javascript代碼執行,可能獲取cookie憑證 |
| 命令注入 | 命令執行 | 直接拼接命令執行系統命令 |
| 反序列化 | 代碼執行 | 有限或無限的執行java代碼,或根據gadget的不同執行各類操作,比如讀寫文件、發起請求等 |
| SSRF | 網絡請求 | 有限制或無限制的發起各類請求轉發,將部分可控數據通過網絡進行轉發 |
| 加密缺陷 | 偽造 | 加解密的問題可以統一歸為各類偽造,包括偽造憑證、數據包簽名等 |
| 任意讀 | 敏感信息獲取 | 讀取各類敏感信息 |
| 任意寫 | 寫文件 | 寫各種文件,通常配合系統機制或者框架機制,任意寫文件大概率可以串代碼執行或者命令執行 |
| 未授權訪問 | 權限校驗缺失 | 權限校驗缺失,可以訪問各類需要鑒權的接口 |
| 內存溢出 | 代碼執行 | 內存溢出后如果利用成功通常可以造成任意代碼執行、改變程序判斷條件 |
當然漏洞類型不止這些,這里只是示意的舉了例子,大家可以參考owasp的所有漏洞類型然后列一個類似的表格,把每一個類型的漏洞所能達到的效果給列舉一下。列舉完成后我們就可以開始組合RCE的combo了,比如常見的連招:
- 未授權訪問+命令執行
- 未授權訪問+反序列化
- 未授權訪問+任意寫+系統機制(PHP的webshell或者Linux的crontab)
- 未授權訪問+SSRF+本地進程未授權+命令注入
- 加密缺陷可構造憑證+后臺命令執行功能
- 未授權訪問+SSRF+內存溢出
還有一些特定場景的連招:
- XSS+electron
- 未授權+fastjson
- 人工點擊+XSS+electron
當然不止這些combo,你能想象到的組合都可以試一試,一般來說要實現RCE,最后一個終結技都是要跟上代碼執行或者命令執行或者是寫文件的漏洞類別,而在終結技前面的漏洞類別通常選各類未授權以及各類數據搬運如SSRF,甚至于XXE也能作為SSRF來用。這也是為什么我們需要把每種漏洞類型所能造成的效果都羅列一下,這種羅列有助于組合combo。(一旦你思路打開,受限制的反序列化也可以是一種SSRF) 在我們羅列各類漏洞類型和他們所能造成的影響時,我們不應該過多的關注自己是否實際掌握具體的利用方式,比如學web的通常不懂內存溢出,那么他們可能就不會考慮內存溢出作為其中一個RCE的終結技。但實際上,你就算是不會,你在尋找整個利用鏈路的時候都應該把它考慮進去,如果鏈路能走通再考慮實際的利用。
0x05 決策路徑
有了前面的鋪墊,我們在拿到一個全新的項目的時候就可以開始為RCE做規劃了。可以分為幾個步驟:
- 搜集信息,對功能和三方組件進行了解,大致對可能的combo有個預測
- 根據預測的combo搜尋對應的sink,找出幾個可能的獨立的漏洞片段
- 嘗試進行簡單的片段串聯,如果能夠快速串聯那么很有可能就已經RCE了
- 如果幾個漏洞片段無法串聯,那么需要深入學習整個程序的內在運作機制包括所在系統的一些機制
- 利用各種機制曲線的將幾個漏洞片段串聯到一起
- 串聯完畢后,深入到解決具體的細節問題,比如利用一些trick來繞過過濾、穿透沙箱等
- 期間可以配合黑盒測試的一些方式來進行調試,避免純白盒的單步跟進
- 最終完成RCE
0x06 學習別人RCE的時候我們關注什么
我們學習各種漏洞復現技巧的時候,我們應該關注什么?根據我前面說的,我們應該重點看這個文章里運用了哪些技巧,比如如何繞過過濾、用了哪些偏門gadget。其次關注這個產品、這個組件它的整體框架邏輯是什么樣的,他有哪些有趣的功能機制是可以拿來串聯鏈。我們可以忽略什么?繁瑣的各種函數跟進,根本毫無意義,隨便看看就行了,除非你也專門研究這個產品的0day挖掘那么你可以細致的看一看,如果你想用它來挖別的產品那么你可以直接忽略掉很多沒有用的函數跟進,只看那些對數據有一定復雜過濾操作的典型函數就行了。
0x07 結語
由于是半夜寫的,有點困寫的有點亂,如果展開講其實還有很多其他經驗可以再講講,這里重要的還是3、4、5章所講的幾個概念,看過了自己再去實施就行了。不要總是想著基礎差就挖不到,我之前復現jumpserver和grafana的時候,我壓根就不懂Go語法,就純粹的按照上述的方法論來走,即使我不懂Go,我知道我需要找到什么、需要去串聯什么,剩下的不過是百度百度看不懂的語法罷了。總之就是一句話:just do it
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1809/