天天看點

PHP Taint – 一個用來檢測XSS/SQL/Shell注入漏洞的擴充

 作者: Laruence( 鳥哥  )

之前, 小頓和我提過一個想法, 就是從PHP語言層面去分析,找出一些可能的注入漏洞代碼. 當時我一來沒時間, 而來也确實不知道從何處下手..

直到上周的時候, 我看到了這個RFC: RFC:Taint.

但是這個RFC的問題在于, 它需要為PHP打Patch, 修改了PHP本身的資料結構, 這對于以後維護, 更新PHP來說, 很不友善, 也會有一些隐患.

雖然這樣, 但這個RFC卻給了我一個啟發, 于是我就完成了這樣的一個擴充:Taint Extension

這個擴充使用起來, 很簡單(目前隻支援5.2.6 ~ 5.3.10,以及7.0以上):

下載下傳源代碼以後, 編譯, 安裝. 然後在php.ini中要開啟這個擴充(建議不要在生産環境開啟這個擴充):

  1. extension=taint.so
  2. 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

print

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