文庫|PHP弱類型

2022-01-06 掌控安全EDU

收錄於話題 #文庫 51個

高質量的安全文章,安全offer面試經驗分享

盡在 # 掌控安全EDU #

作者:掌控安全-手電筒

一、PHP弱類型簡介

弱類型簡單來說就是數據類型可以被忽視的語言,和強類型語言的強制數據類型定義不同,弱類型可以一個變量賦不同數據類型的值

php雖然屬於弱語言,但是裡面也有一些強語言類型相關的強制定義數據類型的方法

比如php裡的 == 和 === 之間的區別

== 為鬆散比較 只比較值,不比較數據類型

而 === 為嚴格比較,不僅比較值也比較類型,可以看作是強語言的強制數據類型要相同

二、PHP弱類型影響

具體表現在比如像一些數據驗證上,兩個變量類型不匹配時進行類型轉換時可能會將傳遞的參數類型轉換,一些函數存在鬆散性的問題,調用時,給函數傳遞函數無法處理的參數類型但是沒有報錯,直接返回null,這些都有可能產生各種問題

這裡以一個ctf題,舉例:

示例代碼:

<?php

$pass=@$_GET['pass'];

$pass2=@$_GET['pass2'];

@$pass1='asdasdasd';

if(strcmp($pass,$pass2)==0&& $pass != $pass2){

echo "$pass1";

}else{

echo "aaaa!";

}

?>

這裡需要傳入兩個變量,對比兩個參數要相同且兩個字符串內容要不同

那麼怎麼才能讓它相同呢,這裡可以通過傳入數組去讓它等

分別傳入不同的數組,結果為

傳入參數相同時

通過數組就繞過了限制,具體為什麼可以看後面關於該函數的介紹

三、函數分析

常見函數:

md5(),sha1(),strcmp(),switch(),array_search(),in_array(),json_decode(),intval().strpos().is_numeric()

1.:MD5(),sha1()

這個函數用於對字符串進行MD5加密


函數格式:md5(要加密的字符串,規定的輸出格式)

繞過方法

通過傳入數組去繞過,這兩個函數不能處理數組數據,md5還有一個加密的問題

示例代碼:

<?php

$flag ="1234";

if(isset($_GET['name'])and isset($_GET['passwd']))

{

if($_GET['name']== $_GET['passwd'])

echo '<p>error</p>';

elseif(md5($_GET['name'])=== md5($_GET['passwd']))

die('Flag: '.$flag);

else

echo '<p>Invalid passwd.</p>';

}

else

echo '<p>Login first!</p>';

?>

測試效果如下

問題在於該函數不能處理數組內容,處理數組會出錯,返回結果都為false

這裡的sha1() 也是同樣道理

sha1函數用於把字符串轉換為sha-1加密處理

函數格式:


sha1(需要處理的字符串,需要的輸出格式,二進位或16進位)

測試代碼:

<?php

$flag ="flag{mkluiop}";

if(isset($_GET['name'])and isset($_GET['passwd']))

{

if($_GET['name']== $_GET['passwd'])

echo '<p>Your password can not be your name!</p>';

elseif(sha1($_GET['name'])=== sha1($_GET['passwd']))

die('Flag: '.$flag);

else

echo '<p>Invalid passwd.</p>';

}

else

echo '<p>Login first!</p>';

?>

測試效果如下

這裡處理數組的結果都返回了false 都相等,導致繞過

2. md5加密相等問題

關於md5還有個科學計數法的問題

繞過方式

php在處理0e開頭,後接的字符都為數字的的字符串的時候,會將整個字符串解析為科學計數法

當有另一個0e開頭的字符串和這個進行對比時,php會都當作0來處理

示例如下

<?phpvar_dump(『0e45511255』 == 『0e1455155』);var_dump(『0e45511255』 == 『0』);?>

得到結果為

md5編碼時,部分被加密的字符也會是0e開頭的

示例代碼

<?php

$m1 = md5('s1091221200a');

$a =@$_GET['a'];

$m2 =@md5($a);

if(isset($a)){

if($a !='s1091221200a'&& $m1 == $m2){

echo "good";

}else{

echo "hahaha";

}

}

?>

這裡我們傳入一個md5編碼後開頭是0e的字符串,網上找了一個,aabC9RqS

其他的還有很多,網址 https://www.cnblogs.com/R4v3n/articles/7716671.html

得到結果為

3.strcmp()

這個函數的作用是比較兩個字符串並且區分大小寫


當字符串1大於字符串2就返回>0,當字符串1小於字符串2就返回<0,相等則返回0


函數格式: strcmp(第一個需要比較的字符串,第二個需要比較的字符串)

繞過方式

通過傳入數組去繞過,該函數處理數組時會發生錯誤,strcmp會返回結果0,導致繞過

測試代碼

<?php

$pass1="ASDSADSADAD";

if(isset($_GET['pass'])){

if(strcmp($_GET['pass'],$pass1)==0){

echo "233";

}else{

echo " ";

}

}

?>

測試效果如下


4. json_decode()

這個函數用於解碼json格式的字符串

函數格式 json_decode(需要解碼的字符串)

繞過方式

當有不同類型的數據時,該函數會轉換為同一類型比較,這裡會把原有的數據的數據類型轉換為和傳入數據的數據類型相同

測試代碼

<?php

if(isset($_GET['m'])){

$m = json_decode($_GET['m']);

$flag ="dfdfgdg";

if($m->flag == $flag){

echo "233";

}

else{

echo "haha";

}

}

else{

echo "hahaha";

}

?>

這裡要傳入一個json格式的字符,字符要用json格式去編寫,這裡設定名稱為flag,傳入json格式字符為{「flag」:0},為什麼這裡傳入的值要是0呢?

這裡當我們傳入數字時,它會轉化為同一類型進行比較

(這裡關鍵點在於,要把字符轉換為數字有效,因為字符轉換為數字會出問題,字符會被轉為0)

這裡字符被轉為0,我們傳入的參數為0,所以相等

測試如下

5. switch函數繞過方式

switch選擇的時候,處理的變量會被強轉為int類型

這個函數一般用於根據多個條件選擇執行不同動作,和if…. else相似

函數格式

switch(表達式,通常是變量)
{
case xxxx1:
當條件符合xxxx1時執行的代碼
break;
case xxxx2:
當條件符合xxxx2時執行的代碼
break;
….
}
這裡的問題在於switch選擇的時候,處理的變量會被強轉為int類型

測試代碼

<?php

$a=$_GET['$a'];

switch($a){

case1:

echo "error";

break;

case2:

echo "error2";

break;

case3:

echo "error3";

break;

case4:

echo "233";

break;

}

?>

這裡當我們輸入字符串時,會被強轉為int類型的

當我們輸入字符串4abcdesdf的時候,這個$a就會被強轉為int類型,使$a的值為4

測試效果如下

6. in_array函數

函數格式 in_array(需要在數組內搜索的數值,被搜索的數組,一個可選參數,設置TURE檢查數據和數組值類型是否相同)

繞過方式

這個函數的作用是檢查數組中是否存在某個值,當沒有最後的檢測參數為true時,默認為鬆散比較,導致弱類型,傳入不同數據類型來繞過

關鍵就在於這個最後的檢查的參數,如果沒有這個參數的話,就會使用鬆散比較來判斷

示例代碼

<?php

$array=[1,2,3];

var_dump(in_array('aaa', $array));

var_dump(in_array('1aa', $array));

?>

測試結果如下

這裡如果沒有設置檢查參數為ture的話,會進行鬆散比較,數據類型不同的話,

會進行適當的類型轉換,這裡aaa被轉換為int類型,被轉換為0,匹配失敗,但是1aa 在轉換時被轉換為1,匹配成功

7. array_search()函數繞過方式

1.傳入不同數據類型來繞過,沒有最後的檢測參數為true時,默認為鬆散比較,導致弱類型


2.當數據類型不同會先把原有數據的數據類型的進行轉換,導致弱類型的產生

該函數的作用是在數組中搜索某個鍵值,並返回鍵名

函數格式 array_search(要搜索的鍵值,被搜索的數組,設置TURE檢查數據和數組值類型是否相同)

這個函數有兩個問題


第一個

測試代碼

<?php

$array=[1,2];

var_dump(array_search('aaa', $array));

var_dump(array_search('2aa', $array));

?>

測試效果如下


和前面in_array一樣,當沒有設定檢測參數為true時,會進行鬆散比較,會把數據類型進行轉換,然後執行

第二個問題


測試代碼:

<?php

if(!is_array($_GET['a'])){exit();}

$a=$_GET['a'];

for($b=0;$b<count($a);$b++){

if($a[$b]==="admin"){

echo "error";

exit();

}

$a[$b]=intval($a[$b]);

}

print_r($a);

if(array_search("admin",$a)===0){

echo "233";

}

else{

echo "false";

}

?>

測試效果如下

首先,這裡是判斷數組的,所以要首先弄個數組,這裡設置數組值為0

然後判斷字符串admin的值和這個0是否相等,這裡數據類型不同會先把admin這個字符串類型的進行轉換,結果為0,所以相等

8. intval() 函數

該函數用於獲取變量的整數值

函數格式 intval(要轉換的參數,指定轉換需要的進位)

繞過方法:

該函數處理本身不能處理的字符串時並不會報錯,直接返回0

當函數內有其他的操作時,會把字符串這些轉為數字類型再操作,而且在處理一些特殊數據的時候會有不同的處理結果

找了網上常用的intval函數處理不同數據的結果的測試代碼,改了一下

<?php

echo intval(25);//25

echo '<br/>';

echo intval(2.5);//2

echo '<br/>';

echo intval('25');//25

echo '<br/>';

echo intval('+25');//25

echo '<br/>';

echo intval('-25');//-25

echo '<br/>';

echo intval(025);//21

echo '<br/>';

echo intval('025');//25

echo '<br/>';

echo intval(1e10);//1410065408

echo '<br/>';

echo intval('1e10');//1

echo '<br/>';

echo intval(0x1A);//26

echo '<br/>';

echo intval(25000000);//25000000

echo '<br/>';

echo intval(250000000000000000000);//2007498752

echo '<br/>';

echo intval('420000000000000000000');//2147483647

echo '<br/>';

echo intval(25,8);//25

echo '<br/>';

echo intval('0x42');//0

echo '<br/>';

echo intval(array());//0

echo '<br/>';

echo intval(array('aaa','abb'));//1

echo '<br/>';

echo intval('aaa',8);//0

echo '<br/>';

echo intval('fgh');//0

echo '<br/>';

echo intval('1e10'+8);//1410065416

echo '<br/>';

echo intval('0x2000'+8);//8200

?>

測試結果如下

這裡網上找了一個ctf題的代碼,測試一下

<?php

@$a=$_GET['a'];

if(intval($a)<2000&& intval($a +1)>2050){

echo "hahahah";

}

else

{

echo "233";

}

?>

這裡需要你傳入$a的值小於2000,且加1後大於2050,那麼怎麼樣才能繞過呢?


回看上面的,看這個函數是怎麼處理不同類型的字符串的,看最後一條和倒數第七條

當我們只是傳入一個單引號閉合的0x2000時,這裡當作一個字符串去處理該參數,返回結果為1

當後面在該函數內進行加操作時,該參數為16進位的字符串,被解析為十進位數字去處理,可以在電腦上打開計算器試下

後續進行了加8操作,得到8200,本題就可以通過此方式來完成

傳入參數0x2000


得到結果

9. is_numeric函數

這個函數用於檢測變量是否只由數字組成,否則返回false


函數格式is_numeric(目標字符)

繞過方法

當傳入數字開頭,字母在後的字符串時,參數可以繞過某些檢測,從而進行到下一步,而php處理不同字符串時又會把兩個字符串轉換到同一類型去處理

測試代碼

<?php

@$a="hehehehehe";

@$temp= $_GET['p'];

if(is_numeric($temp)){

die("hahha");

}

elseif($temp>2010){

echo $a;

}

?>

這個代碼裡需要傳入一個參數,參數要求大於2010又不能是數字

如果數字就會中途中斷從而無法輸出變量a裡的內容

這裡我們輸入一個2020a的字符串,輸入後由於不是純數字,執行到下一步,又因為php在處理數據對比時會將兩個數據轉換為同一類型的,從而達到繞過效果

結果如下

10. strpos函數

strpos函數用於查找目標字符在字符串中出現的第一次的位置

函數格式:strpos(字符串,目標字符)

繞過方法

strpos在處理數組時直接返回null,而沒有返回false,導致問題發生

測試代碼

<?php

if(isset ($_GET['a'])){

if(@ereg("^[1-9]+$", $_GET['a'])=== FALSE)

echo '必須輸入數字才行';

elseif(strpos ($_GET['a'],'#asdafdasdadas')!== FALSE)

die("bababab");

else

echo 'hoho';

}

?>

這裡通過數組的形式去傳入一個數字,首先繞過第一道檢測,然後在第二處strpos檢測時,通過數組去繞過,直接返回null,從而繞過


聲明:本公眾號分享的內容,僅用於網安愛好者之間的技術討論,禁止用於違法途徑,否則需自行承擔後果,本公眾號及作者不承擔相應的後果.

Xray掛機刷漏洞

POC批量驗證Python腳本編寫

實戰紀實 | SQL漏洞實戰挖掘技巧

滲透工具 | 紅隊常用的那些工具分享

代碼審計 | 這個CNVD證書拿的有點輕鬆

掃碼白嫖視頻+工具+進群+靶場等資料

 

 掃碼白嫖

 還有免費的配套靶場交流群哦!

相關焦點

  • PHP弱類型總結
    弱類型語言是一種弱類型定義的語言,某一個變量被定義類型,該變量可以根據環境變化自動進行轉換,不需要經過現行強制轉換。代表有VB,PHP,JavaScript等語言。;而sumB=0;系統認為-是算數運算符,從而將B轉化為int類型,所以sum為5-5=0;php當中有兩種比較符號==與===。
  • 電擊文庫手遊倒了,還有富士見文庫:官方發表第1回角色人氣排名
    日本輕小說文庫有御三家,電擊文庫、富士見Fantasia文庫和角川Sneaker文庫,你可能不看輕小說,但如果接觸日漫的話,肯定免不了碰到這三大文庫的輕改動畫,可見這三大文庫的影響力極大。當然,在外人看來像是三大文庫相互競爭的關係,其實都是角川集團旗下的,不過對於角川來說只是相互內部競爭促成長的文庫而已。
  • 有安全研究者混入了 PHP 8.0 開發組!
    ,有些地方接受參數類型可能有多個類型,或者支持傳入null。->country;字符串數字弱類型比較優化這一個改動可能會對安全漏洞挖掘的影響較大。PHP 8 以前,在使用==比較或任何有弱類型轉換的情況時,字符串都會先轉換成數字,再和數字進行比較。
  • php反序列化漏洞
    前言本文總結php的反序列化,有php反序列字符串逃逸,php反序列化pop鏈構造,php反序列化原生類的利用,phar反序列化,session反序列化,反序列化小技巧,並附帶ctf小題來說明,還有php反序列化的預防方法(個人想法),建議按需查看,如有錯誤還望斧正。
  • 新手小白如何玩轉百度文庫~
    眾所周知,對於我們很多人來說,利用百度文庫去搜索自己所需要的文件和專業文獻是很方便的意見事情,但是由於一些文檔是需要積分或者會員的,所以現在越來越多的人參與百度文庫的創作者這個行業裡面來了。但是一開始很多人摸不著門道,總是拜拜浪費了很多的時間和精力。下面分享我玩百度文科這幾個月來總結的以下幾點,大家可以一起參考學習一下。
  • 百度文庫免費下載?找文庫貓
    百度文庫免費下載?找文庫貓 2019年10月10日 17:35作者:黃頁編輯:黃頁 我們在百度文庫官方是購買不到的,這裡給大家推薦個第三方工具,文庫貓。
  • PHP substr()函數的用法詳解
    string_length_to_cut:此參數是可選的,為整數類型。這指的是需要從原始字符串中剪切的字符串部分的長度。如果整數是正數,則它指的是從start_position開始並從頭開始提取長度。如果整數是負數,那麼它指的是從start_position開始並從字符串的結尾提取長度。
  • PHP反序列化漏洞基礎
    本文為看雪論壇精華文章看雪論壇作者ID:H3h3QAQPHP序列化與序列化一、PHP序列化和反序列化1、PHP反序列化:將變量或者對象轉換成字符串的過程,用於存儲或傳遞PHP的值的過程種,同時不丟失其類型和結構
  • PHP弱類型你真的懂了嗎?
  • windows 檢查php版本專題及常見問題 - CSDN
    2.安裝apcu.dll動態庫文件,打開php_apcu-5.1.8-7.0-nts-vc14-x86.zip壓縮包 拷貝裡面php_apcu.dll文件放到安裝目錄E:\Tools\phpstudy\PHPTutorial\php\php-7.0.12-nts\ext下面。 在php.ini文件中加載動態庫。
  • 輕小說文庫枝繁葉茂,這家文庫也不容忽視,無數圈內神作的製造機
    提到日本日本輕小說文庫,無法忽視角川Sneaker、富士見Fatasia和電擊文庫這三大文庫,三大文庫歷史悠久Sneaker和Fatasia都成立於上世紀八十年代末,電擊則是成立於90年代,三家文庫也奠定了輕小說行業的基本盤,不過隨著時代不斷的發展,也有很多新興文庫成長起來,本次就來和大家聊一聊
  • PHP 8.0重大版本更新正式發布:支持JIT編譯器,性能提升高達3倍
    PHP 8.0 是 PHP 語言的最新主要版本,帶來了許多新特性和優化,包括命名參數(named arguments)、聯合類型(union types)、屬性(attributes)、構造器屬性提升(constructor property promotion)、Match 表達式、nullsafe 運算符、JIT,以及針對類型系統、錯誤處理和一致性的諸多改進。
  • 輕小說低調的文庫,三大輕小說文庫之一,不為人知卻佳作無數
    不過很多人在閱讀輕小說或者觀看輕小說作品的同時恐怕很少真的去關注文庫極其背後的公司,其實如果稍加關注不僅可以對於輕小說行業和整個ACGN行業有自己的見解,同時也能順藤摸瓜發現一眾適合自己閱讀習慣和喜好風格的作品。今天我們就來說一說日本輕小說三大文庫中創建最早卻最低調為行業做出巨大貢獻的——角川Sneaker文庫。
  • 一個經典的PHP文件上傳類分享
    ③可以自己指定上傳文件的保存位置,可以設置上傳文件允許的大小和類型,可以由系統對上傳文件重新命名,又可以設置保留上傳文件的原名。  (說明:要求單個文件上傳和多個文件上傳要採用同樣的操作方式,對上傳進行的一些設置也要採用相同的方式)。
  • 從PHP 5到PHP 7性能全評測(含未發布的JIT版PHP 8對比)
    bench.php 和版本 5.3.29 的收益是 31.89%,意味著該腳本比 5.2.17 版本運行快 31.89%。abs。 gain:與 PHP 5.0 相比腳本運行的收益。 如果你看看bench.php 和試驗性的 JIT 分支的這個列的交集,你會注意到,對於這個特定的測試基準,PHP 8 比 PHP 5.0 快 41 倍以上。
  • 百度文庫發布不通過?洛希教你百度文庫發布容易通過的技巧
    簡介:很多企業主品牌主都希望能夠在百度文庫和百度經驗等高權重平臺發布品牌的相關正面內容文章,於消費者而言,可以更好地了解到品牌,對品牌有初印象。但是很多人卻發現百度文庫發布很難,百度文庫發布審核不通過、百度經驗發布審核不通過,本篇洛希網絡科技工作室為大家分享百度文庫發布更容易通過的技巧,讓你連接百度文庫怎樣發布上傳更容易成功。1 準備優質的百度帳號發布上傳百度文庫的第一步是需要註冊登錄百度帳號,百度文庫對於優質的百度帳號文章會優先審核展示,而且對於內容的審核會相對寬鬆一些,後期優化文章排名時權重也更高。
  • 這些常見的PHP漏洞,如果你不知道,就別說自己是個攻城獅
    { md5_str1: "0e545993274517709034328855841020", md5_str2: "0e848240448830537924465865611904", bool: true}is_numeric漏洞會忽視0x這種十六進位的數容易引發sql注入操作,暴漏敏感信息
  • PHP超實用系列·自動捕獲Fatal Error
    返回的數組包含 4 個鍵和值:[type] - 錯誤類型[message] - 錯誤消息[file] - 發生錯誤所在的文件[line] - 發生錯誤所在的行強烈注意在parse-time出錯的時候,是不會調用register_shutdown_function
  • 在日本金澤文庫訪「國寶」
    1275年(日本建治元年),北條實時從鎌倉遷居六浦莊,並在稱名寺內建立一個「文庫」,收儲他所藏的日漢文獻,這可能便是「金澤文庫」的起始。如是,金澤文庫的建立,比足利學校大約要早二百年左右。北條實時在青年時代曾經師事儒學家清原教隆,學習《春秋經傳集解》與《群書治要》等經籍,對於學問和政道,均甚關注。當時,金澤文庫所藏的漢籍,分為「儒書」與「佛典」兩大部類,皆鈐「金澤文庫」印記。
  • 10個php編程最容易犯的錯誤
    PHP中對於對象,默認是引用返回,數組和內置基本類型默認均按值返回。這個要與其它語言區別開來(很多語言對於數組是引用傳遞)。我們可以使用mysqlnd來代替mysql,mysqlnd編譯為php自身擴展,其內存使用由php內存管理模塊所控制。