英文自助建站排行榜哪個(gè)網(wǎng)站最好
python venv環(huán)境
可以把它想象成一個(gè)容器,該容器供你用來存放你的Python腳本以及安裝各種Python第三方模塊,容器里的環(huán)境和本機(jī)是完全分開的
創(chuàng)建venv環(huán)境安裝flask
#apt install python3.10-venv
#cd /opt
#python3 -m venv flask1
#cd /opt?? 選擇路徑
#python3 -m venv flask1?? 創(chuàng)建名為flask1的venv環(huán)境
#Is
#cd falsk1? 多一個(gè)文件夾flask1
#ls?? 包含所有python組件
#vim demo.py?
#vim demo.py
print("this is test")??? 在/opt下創(chuàng)建demo.py
#python3 demo.py?? 直接使用python是系統(tǒng)的組件
執(zhí)行flask1路徑下的python
?
方法一
#/opt/flask1/bin/python3 demo.py絕對(duì)路徑
方法二
#cd flask1??? 進(jìn)入flask1虛擬環(huán)境
#source ./bin/activate
##python3 demo.py
#deactivate???? 退出虛擬環(huán)境
安裝flask
pip3 install flask --root-user-action=ignore mediapipe -i https://pypi.tuna.tsinghua.edu.cn/simple some-package?
#python3
>>>import flask
>>>quit()
python flask
Flask是一個(gè)使用 Python 編寫的輕量級(jí) Web 應(yīng)用框架
其 WSGI 工具箱采用 Werkzeug ,模板引擎則使用 Jinja2 。Flask使用 BSD 授權(quán)。
Flask的特點(diǎn): 良好的文檔、豐富的插件、包含開發(fā)服務(wù)器和調(diào)試器 (debugger) 、集成支持單元測(cè)試、RESTful請(qǐng)求調(diào)度、支持安全cookies、基于Unicode。
Python可直接用flask啟動(dòng)一個(gè)web服務(wù)頁面。
進(jìn)入虛擬環(huán)境flask1
#/opt
#vim demo.py 在/opt路徑下編輯demo.py
from flask import Flask 啟動(dòng)flask模塊,創(chuàng)建一個(gè)Flask類app = Flask(__name__) name 是系統(tǒng)變量,指的是本py文件的文件名
@app.route('/')路由def hello():return "hello benben"if __name_=='__main__'app.run() 只能被python直接運(yùn)行而不能被作為組件或模塊被調(diào)用。
監(jiān)聽所有物理端口
添加端口為80
ssti漏洞成因
渲染模板時(shí),沒有嚴(yán)格控制對(duì)用戶的輸入;
使用了危險(xiǎn)的模板,導(dǎo)致用戶可以和flask程序進(jìn)行交互,可能造成任意文件讀取和RCE遠(yuǎn)程控制后臺(tái)系統(tǒng)
演示
這段代碼最大的漏洞,就是通過 format() 方法直接對(duì)頁面的 {0}
參數(shù)進(jìn)行替換,這將造成當(dāng)用戶對(duì)參數(shù) id 按照 flask 框架的語法進(jìn)行賦值時(shí),模板引擎渲染時(shí)將會(huì)把用戶輸入當(dāng)作 python 代碼進(jìn)行執(zhí)行(但并不能直接執(zhí)行 python 代碼)
from importlib.resources import contents
import time
from flask import Flask,request,render_template_string
app = Flask(__name__)
@app.route('/',methods =['GET'])
def index():str = request.args.get('ben') //str值通過format0)函數(shù)填充到body中間html_str ='''<html><head></head><body>{0}</body> //0里可以定義任何參數(shù)</html>'''.format(str)return render_template_string(html_str) //return render template string會(huì)把內(nèi)的字符串當(dāng)成代碼指令
if __name__== '__main__': app.debug = Trueapp.run('127.0.0.1','8080')
__name__ 是python的內(nèi)置屬性,是系統(tǒng)全局變量!每一個(gè)py文件都有一個(gè)屬于自己的__name__:
如果py文件作為模塊被導(dǎo)入(import),那么__name__就是該py文件的文件名(也稱 模塊名);
如果py文件直接運(yùn)行時(shí)(Ctrl+Shift+F10),那么__name__默認(rèn)等于字符串”__main__”;
舉個(gè)簡(jiǎn)單的例子:假如你名字是張三,在朋友眼中,你是張三(__name__ == '張三')
;在你自己眼中,你是你自己(__name__ == '__main__')
?
{{7*7}}可用來檢測(cè)漏洞?
?
模板分析
?
python繼承關(guān)系和魔術(shù)方法
幾種魔術(shù)方法
在 python 中,魔術(shù)方法是一種兩邊以雙下劃線 __
包裹的特殊方法,利用這些方法,我們可以實(shí)現(xiàn)類的尋找,初始化對(duì)象的成員,以及最后的利用。
__class__# 查找當(dāng)前類型的所屬對(duì)象__base__# 沿著父子類的關(guān)系往上走,用來查看類的基類,注意是類的基類,所以格式為變量.__class__.__bases__,同時(shí)也能加上數(shù)組,比如變量.__class__.__bases__[0]來獲得第一個(gè)基類。__mro__ # 查找當(dāng)前類對(duì)象的所有繼承類,顯示類和基類__subclasse__()# 查找父類下的所有子類,格式變量.__class__.__bases__[0].__subclasses__()
這個(gè)類也可以加數(shù)組來查看指定的索引值,例如變量.__class__.__bases__[0].__subclasses__()[1]__init__ : 構(gòu)造函數(shù),當(dāng)類被實(shí)例化時(shí)可以用它來快捷的初始化一些屬性。SSTI 中可以用它獲取選定子類的初始化方法。__globals__ #函數(shù)會(huì)議字典的形式返回當(dāng)前對(duì)象的全部全局變量。當(dāng)其在 __init__ 后使用時(shí),即獲取初始化方法的全局變量字典。這些變量可能是模塊、方法、變量。__builtins__ #提供對(duì)Python的所有"內(nèi)置"標(biāo)識(shí)符的直接訪問eval()計(jì)算字符串表達(dá)式的值popen()執(zhí)行一個(gè) shell 以運(yùn)行命令來開啟一個(gè)進(jìn)程
通過以上魔術(shù)方法,再配合一些系統(tǒng)命令,就可以構(gòu)造出基本的 payload 了
舉個(gè)栗子
name={{''.__class__.__mro__[-1].__subclasses__()[199].__init__.__globals__['os'].popen("ls -l /opt").read()}}
payload 前的 ''
表示一個(gè)空字符串,類似的,還可以使用:"" 字符串
() 元組
[] 列表
{} 字典
。它們都是數(shù)據(jù)類型的實(shí)例對(duì)象。
繼承關(guān)系
在 python 中,類之間是會(huì)有繼承關(guān)系的,也就是派生類(子類)與基類(父類)的關(guān)系,這可以理解為父子關(guān)系。在這個(gè)父子關(guān)系中的最高級(jí),就是 object 。也就是說,object 是祖宗類。
一般來說,SSTI 構(gòu)造 payload 的思想,就是要通過各個(gè)數(shù)據(jù)類型 Numbers(數(shù)字)String(字符串)List(列表)Tuple(元組)Dictionary(字典) 這些子類,一直往上找到 object ,然后再通過找 object 類可以利用的子類。可以利用的子類,就是這個(gè)子類的方法(popen() eval()等方法)或?qū)傩钥梢岳谩?br />
子類調(diào)用父類下的其他子類
Python flask腳本沒有辦法直接執(zhí)行python指令
class A:pass
class B(A):pass
class C(B):pass
class D(B):pass
c=C()
print(c.__class__)
當(dāng)前類C?
?
當(dāng)前類C的父類B
print(c.__class__.__base__)
?
父類的父類?
print(c.__class__.__base__.__base__)
?
層層遞進(jìn)?
print(c.__class__.__base__.__base__.__base__)
?
?
羅列所有父類關(guān)系
C-B-A-object
print(c.__class__.__mro__)
?B下的所有子類(數(shù)組形式)
print(c.__class__.__base__.__subclasses__())
?
調(diào)用子類D?
print(c.__class__.__base__.__subclasses__()[1])
?