PHP程式碼審計04之strpos函式使用不當
阿新 • • 發佈:2020-10-29
#前言
根據紅日安全寫的文章,學習PHP程式碼審計的第四節內容,題目均來自**PHP SECURITY CALENDAR 2017**,講完題目會用一個例項來加深鞏固,這是之前寫的,有興趣可以去看看:
[PHP程式碼審計01之in_array()函式缺陷](https://www.cnblogs.com/lxfweb/p/13729406.html)
[PHP程式碼審計02之filter_var()函式缺陷](https://www.cnblogs.com/lxfweb/p/13757525.html)
[PHP程式碼審計03之例項化任意物件漏洞](https://www.cnblogs.com/lxfweb/p/13822440.html)
#漏洞分析
現在咱們看第一題,程式碼如下:
```
loginViaXml($user, $pass);
}
public function loginViaXml($user, $pass) {
if (
(!strpos($user, '<') || !strpos($user, '>')) &&
(!strpos($pass, '<') || !strpos($pass, '>'))
) {
$format = '' .
' ';
$xml = sprintf($format, $user, $pass);
$xmlElement = new SimpleXMLElement($xml);
// Perform the actual login.
$this-> login($xmlElement);
}
}
}
new Login($_POST['username'], $_POST['password']);
?>
```
##題目分析
我們來看上面的程式碼,看第12~14行,這裡通過格式話字串的方式,使用XML結構來儲存使用者的登陸資訊,這樣很容易造成注入,再看上面的程式碼,最後一行例項化了這個類,17行呼叫了login來進行登陸操作。下面到重點了,看程式碼8~10行,這裡用到了strpos()函式來進行過濾<>符號,這個函式的用法如下:
![](https://img2020.cnblogs.com/blog/1996712/202010/1996712-20201027164336055-1156444674.png)
![](https://img2020.cnblogs.com/blog/1996712/202010/1996712-20201027164446406-1574164397.png)
如下:
```
```
![](https://img2020.cnblogs.com/blog/1996712/202010/1996712-20201027170015605-1423093161.png)
我們發現,找到子字串的話就會返回對應的下標,沒找到會返回false。而在PHP中,**0和false的取反都是true**,這點需要我們注意,這道題目就是開發者在使用這個函式時,只考慮了返回false的情況,而沒有考慮當首字元匹配時返回0的情況。導致了過濾被繞過從而實施XML攻擊。
現在知道了如何繞過,那麼構造payload:`user=<">`
為了更好的理解,來看一下構造這個payload時,strpos()函式的返回結果如下:
```
$user='<">