作者: Laruence( 鳥哥 )
之前, 小頓和我提過一個想法, 就是從PHP語言層面去分析,找出一些可能的注入漏洞代碼. 當時我一來沒時間, 而來也确實不知道從何處下手..
直到上周的時候, 我看到了這個RFC: RFC:Taint.
但是這個RFC的問題在于, 它需要為PHP打Patch, 修改了PHP本身的資料結構, 這對于以後維護, 更新PHP來說, 很不友善, 也會有一些隐患.
雖然這樣, 但這個RFC卻給了我一個啟發, 于是我就完成了這樣的一個擴充:Taint Extension
這個擴充使用起來, 很簡單(目前隻支援5.2.6 ~ 5.3.10,以及7.0以上):
下載下傳源代碼以後, 編譯, 安裝. 然後在php.ini中要開啟這個擴充(建議不要在生産環境開啟這個擴充):
- extension=taint.so
- taint.enable=1
啟用這個擴充以後, 如果在一些關鍵函數(或者語句: echo, print, system, exec, 等等), 或者輸出的地方*直接*(沒有經過轉義, 安全過濾處理)
使用了來自$_GET, $_POST或者$_COOKIE的資料, 則Taint就會提示你:
<?php
$a = $_GET['a'];
$file_name = '/tmp' . $a;
$output = "Welcome, {$a} !!!";
$var = "output";
$sql = "Select * from " . $a;
$sql .= "ooxx";
echo $output;
//Warning: main(): Attempt to echo a string which might be tainted in xxx.php on line x
print $$var;
//Warning: main(): Attempt to print a string which might be tainted in xxx.php on line x
include($file_name);
//Warning: include() [function.include]: File path contains data that might be tainted in xxx.php on x
mysql_query($sql);
//Warning: mysql_query() [function.mysql-query]: First argument contains data that might be tainted in xxx.php on line x
?>
能夠進行識别的XSS漏洞就是直接輸出了一段外部輸入的内容,即以下形式的代碼
<?php
$id = $_GET['id'];
//...
?>
<a><?php echo $id;?></a>
如果輸入的内容包含html标簽,就可以向頁面中注入一段自定義的内容,雖然這段内容不能夠進入資料庫,但攻擊者可以制造一個這種連接配接,
并引導讓使用者點選後就可以讀取到一些使用者資訊之類的内容(對于這類問題可以将使用者關鍵的Cookie資訊設定為Http Only)或讓使用者自動進行一些行為(如給好友發帶有這種連接配接的消息進行傳播),
在安裝了Taint的情況下,如果執行以上代碼就有相應的警告提示如下
Warning: main() [echo]: Attempt to echo a string that might be tainted in /srv/http/index.php on line 4
而如果做了相關的過濾處理則就不會有相應的警告了,例如使用strip_tags或是intval等方法。
<?php
$id = strip_tags($_GET['id']);
//...
?>
<a><?php echo $id;?></a>
###附錄
A. 驗證的字元串
所有來自GET,GET,_POST, $_COOKIE的變量, 都被認為是Tainted String
B. taint檢測的函數/語句清單, 當這些函數使用tainted string參數的時候, taint會給出警告:
1. 輸出函數/語句系列
echo
printf
file_put_contents
2. 檔案系統函數
fopen
opendir
basename
dirname
file
pathinfo
3. 資料庫系列函數/方法
mysql_query
mysqli_query
sqlite_query
sqlite_single_query
oci_parse
Mysqli::query
SqliteDataBase::query
SqliteDataBase::SingleQuery
PDO::query
PDO::prepare
4. 指令行系列
system
exec
proc_open
passthru
shell_exec
5. 文法結構
eval
include(_once)
require(_once)
C. 消除tainted資訊的函數, 調用這些函數以後, tainted string就會變成合法的string:
escapeshellcmd
htmlspecialchars
escapeshellcmd
addcslashes
addslashes
mysqli_escape_string
mysql_real_escape_string
mysql_escape_string
sqlite_escape_string
PDO::quote
Mysqli::escape_string
Mysql::real_escape_string
D. 調用中保持tainted資訊的函數/語句, 調用這些函數/語句時, 如果輸入是tainted string, 則輸出也為tainted string:
=
.
"{$var}
.=
strval
explode
implode
sprintf
vsprintf
trim
rtrim
ltrim
php 擴充位址: http://pecl.php.net/package/taint
注意:預設Taint不會被開啟,需要在PHP配置中增加以下配置,并且注意不要在正式的環境中使用Taint,其會一定程度影響代碼的執行效率
轉載于:https://www.cnblogs.com/wjq310/p/8868033.html