當前位置:
首頁 > 最新 > PHP代碼安全雜談鵬越·學霸專區

PHP代碼安全雜談鵬越·學霸專區

當然PHP是世界上最好的語言之一,但是也有一些因為弱類型語言的安全性問題出現。WordPress歷史上就出現過由於PHP本身的缺陷而造成的一些安全性問題,如CVE-2014-0166 中的cookie偽造就是利用了PHP Hash比較的缺陷。 當然一般這種情況實戰中用到的不是很多,但是在CTF競賽中卻是一個值得去考察的一個知識點,特此記錄總結之。


精度繞過缺陷

理論

在用PHP進行浮點數的運算中,經常會出現一些和預期結果不一樣的值,這是由於浮點數的精度有限。儘管取決於系統,PHP 通常使用 雙精度格式,則由於取整而導致的最大相對誤差為 。非基本數學運算可能會給出更大誤差,並且要考慮到進行複合運算時的誤差傳遞。下面看一個有趣的例子:

以十進位能夠精確表示的有理數如 或 ,無論有多少尾數都不能被內部所使用的二進位精確表示,因此不能在不丟失一點點精度的情況下轉換為二進位的格式。這就會造成混亂的結果:例如, 通常會返回 而不是預期中的 ,因為該結果內部的表示其實是類似 。


問鼎杯2017 老眼昏花網上很多write-up感覺就像是看著答案寫write-up,個人感覺真正的write-up中應該體現自己的思考在裡面。


題目言簡意賅,讓我們把這個值傳遞給伺服器。


PHP浮點精確度


所以第一反應是直接給參數賦值為:

然而結果如下:

有提示了,說明這個參數是對的,但是中不可以出現,這裡如果不了解php精度的話,肯定是對進行各種編碼繞過,但是這裡對編碼也進行過濾了:

所以最後一種可能就是利用PHP精度來繞過:


類型轉換的缺陷


PHP提供了函數,用來變數判斷是否為數字。PHP弱類型語言的一個特性,當一個整形和一個其他類型行比較的時候,會先把其他類型intval數字化再比。

用於判斷是否是數字,通常配合數值判斷。


PHP類型轉換缺陷


分析下代碼:首先對GET方式提交的參數的值進行檢驗。通過函數來判斷是否為數字,如果為數字的話,GG。如果不是數字的話,和進行比較,的值大於的時候輸出。

乍看上去又好像不可能這裡,但是如果知道。這個特性的話就可以很好的繞過。


鬆散比較符的缺陷

理論

php比較相等性的運算符有兩種,一種是嚴格比較,另一種是鬆散比較。

如果比較一個數字和字元串或者比較涉及到數字內容的字元串,則字元串會被轉換成數值並且比較按照數值來進行

嚴格比較符嚴格比較符,會先判斷兩種字元串的類型是否相等,再比較。

鬆散比較符鬆散比較符,會先將字元串類型轉換成相同,再比較。

PHP 會根據變數的值,自動把變數轉換為正確的數據類型。這一點和C 和 C++ 以及 Java 之類的語言明顯不同。雖然這樣PHP方便了程序員,但是隨之而來卻會帶來一些安全性的問題。


由於php對變數自動轉換的特性,這裡面的

所以頁面輸出的結果為:


下面結合PHP 相等性比較缺陷再解釋下會好懂一點:

與進行鬆散性質的不嚴格比較,會將轉換為數值,強制轉換,由於是字元串,轉化的結果是,所以 輸出

與進行嚴格 性質的嚴格比較,這裡的是字元串類型,和int類型的不相等,所以輸出

與進行鬆散性質的不嚴格比較,會將轉換為數值,強制轉換,由於是字元串,轉化的結果是,不等於,所以輸出

與進行鬆散性質的不嚴格比較,這裡被強制轉換為int類型的時候會從字元串的第一位開始做判斷進行轉換,這裡的第一位是,所以這裡被轉換為,所以輸出

與進行嚴格 性質的嚴格比較,字元串的第一位不是數字,所以它被強制轉換為,所以輸出

這裡比較特殊,字元串中出現了,PHP手冊介紹如下:

與相互不嚴格性質比較的時候,會將這類字元串識為科學技術法的數字,0的無論多少次方都是零,所以相等,輸出

與相互進行不嚴格性質比較的時候,本應該將這類字元串識為科學技術法的數字,但是這裡的後面跟著的是,數學中科學計數的指數不可以包含字母。所以這裡字元串中雖然是開頭,但是後面的卻不符合科學技法的規範,所以輸出是


md5繞過(Hash比較缺陷)南京郵電大學網路攻防訓練平台中一道比較經典的題,關於這道題目的WriteUp網上很多,但是真正深入分析的少之又少~~


md5 collision源碼


簡單的PHP代碼審計

PHP弱類型的Hash比較缺陷

從源碼中可以得輸入一個a的參數的變數,a首先不等於並且a得md5值必須等於加密後的md5值。 乍一看好像不可能存在這樣的值,但是這裡加密後的md5值為 這裡是開頭的,在進行等於比較的時候,PHP把它當作科學計數法,0的無論多少次方都是零。 所以這裡利用上面的弱類型的比較的缺陷來進行解題:

字元串加密後為0exxxx的字元串(x必須是10進位數字)列表


sha1()md5()加密函數漏洞缺陷

理論

和對一個數組進行加密將返回 NULL


Boston Key Party CTF 2015: Prudential


I dont think sha1 isbroken.Prove me wrong.

題目給了一個登陸框:


sha1()函數漏洞缺陷

源代碼給出如下:

分析一下核心登錄代碼如下:

類型提交了兩個欄位和,獲得flag要求的條件是:

name != password

sha1(name) == sha1(password)

這個乍看起來這是不可能的,但是這裡利用函數在處理數組的時候由於無法處理將返回可以繞過if語句的驗證,if條件成立將獲得。 構造語句如下:

?name[]=a&password[]=b

這裡符合了2個拿到flag的條件:

a不等於b

name和password由於是數組,經過sha1()函數嫁給後都返回

拿到flag:


經過驗證,不僅函數無法處理數組,這裡函數也有同樣的問題,在處理數組的時候,都將返回

測試代碼如下:

這裡面的核心代碼如下:

同樣利用函數無法處理數組的這個漏洞,構造get請求拿到flag:

?username[]=a&password[]=b


字元串處理函數漏洞缺陷

理論

函數:比較兩個字元串(區分大小寫).

用法如下:

具體的用法解釋如下:

這個函數接受到了不符合的類型,例如類型,函數將發生錯誤。但是在之前的php中,顯示了報錯的警告信息後,將 !!!! 也就是雖然報了錯,但卻判定其相等了。

函數:字元串正則匹配。

函數:查找字元串在另一字元串中第一次出現的位置,對大小寫敏感。

這2個函數都是用來處理字元串的,但是在傳入數組參數後都將返回。


Boston Key Party CTF 2015: Northeastern Univ


Of course, a timing attack might be the answer, but Im quite sure that you can do better than that. 題目給了一個登陸框:


字元串處理函數漏洞缺陷


給出源代碼如下:

分析一下核心登錄代碼如下:

這裡使用了鬆散比較了和通過GET方式提交的的值,如果想等的話,拿到flag。這裡用的是鬆散性質的比較,再利用字元串處理數組時將會報錯,在之前的php中,顯示了報錯的警告信息後,將。所有這裡將參數指定為數組,利用函數漏洞拿到:


除了函數外,和函數在處理數組的時候也會異常,返回。測試代碼如下:

將參數password賦值一個數組傳遞進去:

是處理字元串的,傳入數組後返回,和 ,是不恆等(===)的,滿足第一個條件;而也是處理字元串的,傳入數組後返回L,,滿足條件,拿到flag:

理論

函數的作用就是解析字元串並註冊成變數,在註冊變數之前不會驗證當前變數是否存在,所以直接覆蓋掉已有變數。

str 輸入的字元串。

arr 如果設置了第二個變數 arr,變數將會以數組元素的形式存入到這個數組,作為替代。


測試代碼:


parse_str變數覆蓋缺陷


找到核心代碼:

因為這裡用到了函數來傳遞,if的語句的條件是拿來比較的,有因為這裡的變數a的值已經三是固定的了:

這裡其實是我博客的地址~~ 不過不重要。 整體代碼乍看起來又不可能,但是利用變數覆蓋函數的缺陷這裡可以對的變數進行重新賦值,後面的的if語句再利用本文前面提到的比較缺陷進行繞過:


參考文獻

PHP 比較運算符

PHP Float 浮點型

PHP 類型比較表

PHP 弱類型總結

PHP Hash比較存在缺陷,影響大量Web網站登錄認證、忘記密碼等關鍵業務

PHP代碼審計片段講解(入門代碼審計、CTF必備)

淺談PHP弱類型安全

NJCTF2017 線上賽 web 題解

CTF之PHP黑魔法總結

Some features of PHP in CTF

PHP浮點數運算精度的問題

php strcmp()漏洞

危險的is_numeric——PHPYun 2015-06-26 二次注入漏洞分析

【代碼審計】變數覆蓋漏洞詳解

(轉載來源:FreeBuf.COM,作者:國光)

現在關注「鵬越網路空間安全研究院」微信公眾號,在對話框中輸入「工控」、「培訓」、「CTF」 、「物聯網」、 「人工智慧」、「招聘」等關鍵字,系統自動推送相應內容。今後我們還會推出更多方便搜索和閱讀的服務,敬請期待!

長按下方二維碼關注我


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!

TAG: |