php session利用總結(jié)
??當(dāng)用戶請求來自應(yīng)用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務(wù)器將自動創(chuàng)建一個 Session 對象。當(dāng)會話過期或被放棄后,服務(wù)器將終止該會話。
??Session機制:session內(nèi)容一般以文件的形式存儲于服務(wù)器中,而本地瀏覽器會存儲一個與服務(wù)器中session文件對應(yīng)的Cookie值,Cookie存儲的是鍵值為“PHPSESSID”的Seeion_id值,用戶在訪問web應(yīng)用時,每次跳轉(zhuǎn)發(fā)生http請求時,會自動把這個存儲session_id的Cookie值發(fā)送過去,因此web應(yīng)用的所有頁面都可以獲取到這個SESSION_ID值,也就可以通過session_id獲取服務(wù)器中存儲的session值,當(dāng)用戶關(guān)閉瀏覽器后,cookie存儲的session_id自動清除,一般服務(wù)器存儲的session文件也會在30分鐘后自動清除。
??一、比如在wamp環(huán)境下,index.php如下:
??session_start();
??phpinfo();
???>
??首先理解一下session_start()
??當(dāng)會話自動開始或者通過 session_start() 手動開始的時候, PHP 內(nèi)部會依據(jù)客戶端傳來的PHPSESSID來獲取現(xiàn)有的對應(yīng)的會話數(shù)據(jù)(即session文件),PHP 會自動反序列化session文件的內(nèi)容,并將之填充到 $_SESSION 超級全局變量中。如果不存在對應(yīng)的會話數(shù)據(jù),則創(chuàng)建名為sess_PHPSES SID(客戶端傳來的)的文件。如果客戶端未發(fā)送PHPSESSID,則創(chuàng)建一個由32個字母組成的PHPSESSID,并返回set-cookie。
??可以看到請求中對應(yīng)的PHPSESSID:ifrvi9r7ui81r0fjq569b06862
??在服務(wù)器端,即/wamp/tmp下我們就可以發(fā)現(xiàn)一個生成的記錄Session的文件,因為也沒有記錄什么會話信息,因此該文件是一個空文件。
??補充一下關(guān)于php-Session相關(guān)配置的說明
??在php.ini中對Session存在許多配置,這里我們通過phpinfo來說明幾個重要的點。
??說明如下:
??session.save_path="" --設(shè)置session的存儲路徑
??session.save_handler="" --設(shè)定用戶自定義存儲函數(shù),如果想使用PHP內(nèi)置會話存儲機制之外的可以使用本函數(shù)(數(shù)據(jù)庫等方式),默認files以文件存儲
??session.auto_start boolen --指定會話模塊是否在請求開始時啟動一個會話,默認為0不啟動
??session.serialize_handler string --定義用來序列化/
??二、常見的php-session存放位置
??/var/lib/php5/sess_PHPSESSID/var/lib/php7/sess_PHPSESSID/var/lib/php/sess_PHPSESSID/tmp/sess_PHPSESSID/tmp/sessions/sess_PHPSESSED0x02 Session可能導(dǎo)致的攻擊面
??Session序列化攻擊Session文件包含Session偽造用戶登錄Session邏輯漏洞0x03 Session序列化攻擊
??Serialize_handler
??要了解Session序列化攻擊,先來了解一下Session機制中對序列化是如何處理的。
??在php中存在三種序列化處理引擎
??本地測試如下:
??Session文件內(nèi)容分別對應(yīng)結(jié)果為
??test|s:7:"CoCo1er";
??tests:7:"CoCo1er";
??a:1:{s:4:"test";s:7:"CoCo1er";}
??攻擊利用原理
??payload千萬條,原理第一條。
??(這里補充說一點,PHP中的Session的實現(xiàn)是沒有的問題,危害主要是由于程序員的Session使用不當(dāng)而引起的。如下)
??使用不同引擎來處理session文件
??如果在PHP在反序列化存儲的$_SESSION數(shù)據(jù)時使用的引擎和序列化使用的引擎不一樣,會導(dǎo)致數(shù)據(jù)無法正確第反序列化。通過精心構(gòu)造的數(shù)據(jù)包,就可以繞過程序的驗證或者是執(zhí)行一些系統(tǒng)的方法。例如:
??在這么一種情況下:
??假如我們使用php_serialize引擎時進行數(shù)據(jù)存儲時的序列化,可以得到內(nèi)容
??$_SESSION[‘key’] = ‘Boby’;
??a:1:{s:3:”key”;s:4:”Boby”;}
??三、這時我們的解析采用了另一種引擎:php
??思考一下這時會發(fā)生什么情況?(php引擎中以豎線來分隔鍵和值)
??如果像上面我們的payload換一下,傳入內(nèi)容以及得到的存儲內(nèi)容如下:
??$_SESSION['key'] = '|O:4:"User":0:{}';
??a:1:{s:3:"key";s:16:"|O:4:"User":0:{}";}
??這時候a:1:{s:3:"key";s:16:"被當(dāng)作了key,而后續(xù)的O:4:"User":0:{}";}被當(dāng)作了value從而被反序列化。這里可能有人會問了,為什么會被反序列化?
??看看官方文檔
??這里可能還會有人問?那串value不符合"正常"的被反序列化的字符串規(guī)則。這個也不用擔(dān)心,這里提到一個unserialize的特性,之前也做題也遇到過。在執(zhí)行unserialize的時候,如果字符串前面滿足了可被反序列化的規(guī)則即后續(xù)的不規(guī)則字符會被忽略。
??四、如果不太好理解不如直接來看一個在線測試用例:
??總結(jié)一下,在php以php_serialize引擎生成session,然而又以php引擎來解析時,我們通過傳入類似
??$_SESSION[‘name’] = |序列化內(nèi)容
??這種形式的payload即有可能觸發(fā)反序列化漏洞。當(dāng)然這里只是提到了能夠找到反序列化利用的點,至于能不能真正觸發(fā)反序列化漏洞還需要結(jié)合當(dāng)前環(huán)境以及一些魔術(shù)函數(shù)中是否存在可利用點。這就涉及到php反序列化漏洞的利用知識點了,這里也就不詳細講了。關(guān)于Session反序列化攻擊的復(fù)雜利用方式,可以參考2018LCTF中的bestphp’s revenge一題。
??五、沒有$_SESSION變量賦值
??從上面的情況中我們可以發(fā)現(xiàn)我們對session的賦值可控。那如果代碼中不存在對$_SESSION變量賦值的情況下如何利用呢?來看下面一個點。
??php還存在一個upload_process機制,即自動在$_SESSION中創(chuàng)建一個鍵值對,值中剛好存在用戶可控的部分。
??寫入的方式主要是利用PHP中Session Upload Progress來進行設(shè)置,具體為,在上傳文件時,如果POST一個名為PHP_SESSION_UPLOAD_PROGRESS的變量,就可以將filename的值賦值到session中。
??//上傳表單
??既然filename字段能夠?qū)懭雜ession中那么就滿足了session可控條件,后續(xù)的利用條件同上面所述的情景一致,兩種不同引擎先后作用導(dǎo)致了惡意的序列化字符串被解析。
??六、0x04 Session文件包含
??這個也是一個比較舊的知識點了,其實不僅是Session文件包含,仔細想想,理論上只要能夠在文件中寫入php代碼,再被include包含進來不都可以實現(xiàn)getshell嘛?只不過在這里我們的可控點是Session文件,如果能向其中寫入php代碼,也是可以實現(xiàn)文件包含漏洞利用的。
??作為文件包含的利用這里就不展示了,網(wǎng)上關(guān)于這個的基礎(chǔ)資料早就爛大街了。
??值得一提的是,往往現(xiàn)在的CTF出題不會僅限于文件包含這一個點來出題,而是利用諸如session+lfi的形式來入題獲取源碼等。而且可能加入open_basedir來限制路徑,此時就需要熟悉了解session的機制,通過函數(shù)來改變save路徑來利用。這個思路是在XCTF Final中出現(xiàn)的bestphp一題中的考點。感興趣的同學(xué)可以去找到環(huán)境復(fù)現(xiàn)一波。
??七、0x05 Session偽造用戶登錄
??前幾天正好3CTF出了一個這個考點,這里以那個題目來說明一下利用方式。(由于沒有提供復(fù)現(xiàn)環(huán)境,此處也只能限于“紙上談兵”,希望大家能夠理解一下利用原理即可。)
??**利用前提:**session可控;知道session存儲格式。
??這里的考題是多個攻擊面的組合。題面index.php下提示要以admin登錄。
??sql盲注可以跑sqlmap拿到執(zhí)行shellsql root用戶存在file權(quán)限,但是往站點直接寫shell無法成功(猜測應(yīng)該是站點根目錄有限制,但是可以猜測/tmp可寫掃后臺發(fā)現(xiàn)test.php,訪問發(fā)現(xiàn)回顯了session的數(shù)據(jù)結(jié)構(gòu)Array([username]=>test),知道了session的格式。key為username,至于采用了哪種序列化引擎?三種都測一下就完事。這里滿足了兩個利用前提。通過sqlmap-shell往/tmp寫入文件偽造adminpayload:select 'username|s:5:"admin";' into outfile '/tmp/sess_PHPSESSID'最后修改成對應(yīng)設(shè)計的PHPSESSID即可偽造admin登錄拿到flag。0x06 Session邏輯漏洞
??很遺憾這個點也沒有可以復(fù)現(xiàn)的環(huán)境。(官方買斷...)這個是上兩周unctf中出現(xiàn)的一道web題考點。這個邏輯漏洞處在重置密碼處。過程大致如下。
??八、密碼重置分為三個步驟
??填寫需要重置的用戶名用戶名綁定的郵箱中收到驗證碼填寫驗證碼,進入重置密碼頁面,填寫完新密碼完成重置。這里存在的邏輯漏洞在于第一個頁面的填寫用戶名處,猜測后臺有設(shè)置session。類似:$_SESSION[‘name’] = $_POST['name'];
??九、利用方式:重置admin密碼
??打開一個正常頁面完整流程走到最后一步,填寫完驗證碼通過后,填寫新密碼,此時并不提交。新開另外一個頁面完成第一步,重置用戶填寫admin,此時Session不再是我們之前自己的用戶,而變成了admin。這時完成之前頁面的提交。成功重置admin密碼。這里邏輯漏洞產(chǎn)生的原因在于對填寫驗證碼后沒有對相關(guān)用戶綁定做記錄,在最后一步重置密碼時沒有對Session的可靠性進行檢查就直接執(zhí)行了功能。而我們都知道Session存儲在服務(wù)器端,因此我們再開一個頁面即可完成對單一session文件內(nèi)容的修改(保證在同一個PHPSEEID下)。
??這里僅僅是記錄了自己關(guān)于PHP的session機制相關(guān)的學(xué)習(xí),舉的都是自己最近在CTF題中接觸到的點,但關(guān)于session的利用點怎么可能只有這幾個?遇到了再補充學(xué)習(xí)吧。限于篇幅沒有展開講拓展利用,但是說白了,拓展利用就是多個復(fù)雜知識點的綜合。我認為只有把原理性的問題搞清楚了才有可能去理解復(fù)雜的組合攻擊。另外如果文中有什么理解表達錯誤的地方還望師傅們指正。小伙伴們要想獲得更多php session的內(nèi)容,請關(guān)注新網(wǎng)!
聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請發(fā)
送郵件至:operations@xinnet.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時
需注明出處:新網(wǎng)idc知識百科