日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php的一些不安全函数,php中可能会产生安全问题一些函数

發布時間:2023/12/19 php 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php的一些不安全函数,php中可能会产生安全问题一些函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

php中可能會產生安全問題的一些函數

本文章適合正在學習代碼審計的朋友,或者準備學習安全的朋友,大佬就可以繞過了,寫的比較基礎。我也是一個小白,總結一下對于php函數的理解,也分享一些自己覺得好用的方法給大家,歡迎大家幫我補充,有什么好用的技巧也可以分享一下,大家共同進步。本篇有自己的理解,如果有什么不對的或者不好的地方希望大家不要噴我,但是歡迎幫我指正。最后希望大家可以關注我的專欄

1:in_array函數

in_array?:(PHP 4, PHP 5, PHP 7)

功能?:檢查數組中是否存在某個值

定義?:?bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

可能會產生安全問題的場景:

1:對于sql語句參數的檢查,如果僅僅使用沒有true參數的in_array()函數去檢測整數類型,那么很有可能會被繞過

2:利用in_array?函數檢測文件后綴

為了便于大家的理解,下面準備幾個例子

Demo1:<?php

$xiaobao = $_POST['xiaobao'];

$dic['xiaobao_items'] = array(0,1,2,3,4,5,6);

if (in_array($xiaobao,$dic['xiaobao_items']))

{

echo 'success1';

}

else

{

echo 'false1';

}

?>

這里由于沒有對in_array的第三個參數進行設置,導致了數據類型的轉換,從而成功繞過了if的判斷語句。

正確使用方法

Demo2:

這一次我們設置第三個參數為True,強制讓其不進行數據類型轉換<?php

$xiaobao = $_POST['xiaobao'];

$dic['xiaobao_items'] = array(0,1,2,3,4,5,6);

if (in_array($xiaobao,$dic['xiaobao_items'],true))

{

echo 'success2';

}

else

{

echo 'false2';

}

?>

2:filter_var函數

filter_var?: (PHP 5 >= 5.2.0, PHP 7)

功能?:使用特定的過濾器過濾一個變量

定義?:mixed?filter_var?(?mixed?$variable?[, int?$filter?= FILTER_DEFAULT [,?mixed?$options?]] )

可能會產生安全問題的場景:

1:使用filter_var來判斷url,導致偽協議繞過問題

filter_var繞過

Demo:<?php

$xiaobao_url = filter_var($_GET['url'],FILTER_VALIDATE_URL);

var_dump($xiaobao_url);

$xiaobao_url1 = htmlspecialchars($xiaobao_url);

var_dump($xiaobao_url1);

echo "xiaobao";

?>

這里的//是為了滿足filter_var($_GET['url'],FILTER_VALIDATE_URL);對于url的判斷,但是在js當中//表示注釋,因此需要加入%0a,利用換行符去繞過注釋的限制,同時對%進行url編碼。最后的payload就是http://127.0.0.1/testphp/flitervar.php?url=javascript://xiaobao%250aalert(1)

這對XSS漏洞,最好的解決方案就是過濾關鍵詞,將特殊字符進行HTML實體編碼替換,這個網上已經有提供了很多防御的方法了。

3:parse_str()函數

parse_str

功能?:parse_str的作用就是解析字符串并且注冊成變量,它在注冊變量之前不會驗證當前變量是否存在,所以會直接覆蓋掉當前作用域中原有的變量。

定義?:void?parse_str(?string?$encoded_string?[,?array?&$result?] )

如果?encoded_string?是 URL?傳入的查詢字符串(query string),則將它解析為變量并設置到當前作用域(如果提供了 result?則會設置到該數組里 )。

可能會產生安全問題的場景:

1:parse_str函數導致的變量覆蓋問題

parse_str函數導致的變量覆蓋問題

Domo1:<?php

$xiaobao = "xiaobao";

parse_str('xiaobao=baobao');

var_dump($xiaobao);

?>

在調試過程我們可以清楚的看到之前定義的$xiaoboa變量被后面的parse_str函數中的給覆蓋掉了。

再來看個例子加深理解

Domo2:<?php

$xiaobao = 'fail';

parse_str($_GET['baobao']);

echo $xiaobao;

?>

實際上php中造成變量覆蓋的情形遠不止這么一種,大家下去可以自行研究。

4:strpos()函數

strpos?—?查找字符串首次出現的位置

作用:主要是用來查找字符在字符串中首次出現的位置。

結構:int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

可能會產生安全問題的場景:

1:利用數組繞過判斷條件

2:第一次匹配字符下標為0去繞過判斷條件

利用數組繞過判斷條件

Demo1:<

?php

$flag = "{xiaobao success}";

if(strpos($_GET["url"],"secxiaobao") !== FALSE)

{

echo $flag;

}

else

{

echo 'fail';

}

?>

strpos()函數需要的是一個字符串,如果傳一個數組給它會發生什么呢?strpos()會出錯返回null,而判斷條件null!==false,所以符合我們的要求。成功得到flag。

利用匹配下標去繞過

Demo2:

這次我們再看另一種繞過情況,先來看一下strpos()正常使用方法<?php

echo strpos("I love liebao, I love liebao too!","liebao");

?>

執行結果為7,也就是去匹配liebao字符串首次出現的位置下標。

我們試一下下標不為0的情況<?php

$flag = "{xiaobao success}";

$a = strpos($_GET["url"],"secxiaobao");

if(!$a == true)

{

echo $flag;

}

else

{

echo 'fail';

}

?>http://127.0.0.1/testphp/strops.php?url=123secxiaobao

看到獲得的下標為3,非運算之后當然和true不相等了

那么,首次出現位置的下標為0又會發生什么?http://127.0.0.1/testphp/strops.php?url=secxiaobao

這里獲得的下標為0,非運算之后等于true,成功的輸出flag。

5:MD5函數

提到php中的MD5函數小豹會想起幾個字符串,ffifdyop和129581926211651571912466741651878684928,QNKCDZO,240610708

這些字符串有什么神奇的地方?小豹先留個懸念,我們接著往下看

首先是php中MD5函數官方釋義

md5?— 計算字符串的 MD5 散列值

string md5 ( string $str [, bool $raw_output = false ])

可能會產生安全問題的場景:

1:MD5函數true繞過

2:MD5函數==弱比較繞過

MD5函數true繞過

Demo1:<?php

$password = $_POST['password'];

$sql = "SELECT * FROM xiaobao WHERE username = 'baobao' and password ?= '".md5($password,true)"'";

$result = mysql_query($link,$sql);

if(mysql_num_rows(($result)>0){

echo 'success';

}

else{

echo 'login fail'

}

?>

這部分代碼是模擬對數據庫進行操作的真實情景。

從代碼中我們可以看出,只有查詢后的sql數據不為空也就是大于0的時候,才會輸出success。同時這部分代碼里出現了需要關注的MD5函數,當$raw_output設置為true的時候,md5函數會返回前16字節長度的原始二進制,并會將二進制轉換成字符串。而在這個轉換為字符串的過程中是否可能帶來問題?例如原始的二進制轉換為字符串后會不會影響本來的sql語句?答案當然是會的,這里已經有大佬幫我們找到了,小豹在前邊也提到了,不過這次可以了解他們的真實面貌:ffifdyop

129581926211651571912466741651878684928

接下來看下實際效果:<?php

$password = md5("ffifdyop",true);

echo $password;

$password1 = md5("129581926211651571912466741651878684928",true);

echo "";

echo $password1;

$sql = "SELECT * FROM xiaobao WHERE username = 'baobao' and password ?= '$password'";

$sql1 = "SELECT * FROM xiaobao WHERE username = 'baobao' and password ?= '$password1'";

var_dump($sql);

var_dump($sql1);

?>

回到上面的問題,我們的sql語句變成了SELECT * FROM xiaobao?WHERE username = 'baobao' and password = ''or'xxxx'

前邊的條件執行后會與后邊的or?'xxxx'進行或運算,導致整個where條件為真,從而繞過了密碼的限制。

MD5函數==弱比較繞過

Demo1:<?php

$flag = 'flag{xiaobao}';

$p = '/^[A-Za-z0-9]{6,12}$/';

$a = $_POST['password'];

if (preg_match($p, $_POST['password'])) {

if(md5($_POST['password'])=="0")

{

echo $flag;

}

else

{

echo 'fail';

}

}

else

{

echo 'Password format is wrong';

}

?>

從上面的代碼中可以看出對post形式獲取到的password進行了限制,只能是6-12位由數字和大小寫字母組成的字符串。對滿足條件的參數值進行MD5

加密,加密后與字符0進行比較,如果相等,就會輸出flag。http://127.0.0.1/testphp/MD5test.php

Post數據分別為:

password =240610708

password =QNKCDZO

為什么MD5加密后的這兩個特殊字符會與字符0相等?

來看一下這兩個特殊字符串MD5加密后的樣子

因為==對比的時候會進行數據轉換,0eXXXXXXXXXX 被轉換成了字符0。

總結

以上是生活随笔為你收集整理的php的一些不安全函数,php中可能会产生安全问题一些函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。