溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

php安全代碼審計小結(jié)

發(fā)布時間:2020-06-20 22:30:16 來源:網(wǎng)絡(luò) 閱讀:460 作者:aaccee12 欄目:web開發(fā)

文章僅為一段時間整理的php安全代碼審計筆記總結(jié),一個分析框架,沒有實例化分析。

一、工具篇

編輯器(notepad++,editplus,UE等等,看個人習(xí)慣)

TommSearch(字符串檢索) || grep

HttpProtocolDebugger(http協(xié)議調(diào)試器)

Fiddler(分析包,改包)

Seay PHP代碼審計工具(php-code-audit分析輔助)

幾個有趣的項目

dvwa(代碼審計測試平臺)

phpmvs

php security audit check

PHP Vulnerability Hunter

二、函數(shù)篇

addslashed()添加反斜杠

stripslashed()去掉反斜杠

get_magic_quotes_gpc() 判斷是否開啟gpc

expode(".",$array)分割成數(shù)組

is_numeric()判斷是否為數(shù)字

sizeof()判斷長度

trim() 去除字符串開頭和末尾的空格或其他字符

system() 輸出并返回最后一行shell結(jié)果。

exec() 不輸出結(jié)果,返回最后一行shell結(jié)果,所有結(jié)果可以保存到一個返回的數(shù)組里面。

passthru() 只調(diào)用命令,把命令的運行結(jié)果原樣地直接輸出到標(biāo)準(zhǔn)輸出設(shè)備上。

EscapeShellCmd(),把一個字符串中所有可能瞞過Shell而去執(zhí)行另外一個命令的字符轉(zhuǎn)義。這些字符在Shell中是有特殊含義的,象分號(;),重定向(>)和從文件讀入 (<)等。

EscapeShellArg() 。在給定的字符串兩邊加上單引號,并把字符串中的單引號轉(zhuǎn)義,這樣這個字符串就可以安全地作為命令的參數(shù)。

用popen()函數(shù)打開進(jìn)程

上面的方法只能簡單地執(zhí)行命令,卻不能與命令交互。但有些時候必須向命令輸入一些東西,如在增加Linux的系統(tǒng)用戶時,要調(diào)用su來把當(dāng)前用戶換到root才行,而su命令必須要在命令行上輸入root的密碼。這種情況下,用上面提到的方法顯然是不行的。

popen ()函數(shù)打開一個進(jìn)程管道來執(zhí)行給定的命令,返回一個文件句柄。既然返回的是一個文件句柄,那么就可以對它讀和寫了。在PHP3中,對這種句柄只能做單一 的操作模式,要么寫,要么讀;從PHP4開始,可以同時讀和寫了。除非這個句柄是以一種模式(讀或?qū)?打開的,否則必須調(diào)用pclose()函數(shù)來關(guān)閉 它。

例子1:

/* PHP中如何增加一個系統(tǒng)用戶

下面是一段例程,增加一個名字為james的用戶,

root密碼是 verygood。僅供參考

*/

$sucommand = "su --login root --command";

$useradd = "useradd ";

$rootpasswd = "verygood";

$user = "james";

$user_add = sprintf("%s "%s %s"",$sucommand,$useradd,$user);

$fp = @popen($user_add,"w");

@fputs($fp,$rootpasswd);

@pclose($fp);

require在被包含文件有錯誤代碼時將不再往下執(zhí)行

include在被包含文件有錯誤代碼時仍然往下執(zhí)行

htmlspecialchars() 函數(shù)把一些預(yù)定義的字符轉(zhuǎn)換為 HTML 實體。

預(yù)定義的字符是:

& (和號) 成為 &

" (雙引號) 成為 "

' (單引號) 成為 '

< (小于) 成為 <

> (大于) 成為 >

move_uploaded_file() 函數(shù)將上傳的文件移動到新位置。

extract() 函數(shù)從數(shù)組中把變量導(dǎo)入到當(dāng)前的符號表中。

對于數(shù)組中的每個元素,鍵名用于變量名,鍵值用于變量值。

第二個參數(shù) type 用于指定當(dāng)某個變量已經(jīng)存在,而數(shù)組中又有同名元素時,extract() 函數(shù)如何對待這樣的沖突。

本函數(shù)返回成功設(shè)置的變量數(shù)目。

語法

extract(array,extract_rules,prefix)

parse_str() 函數(shù)把查詢字符串解析到變量中. (常見于變量覆蓋漏洞)

語法

parse_str(string,array)

參數(shù) 描述

string 必需。規(guī)定要解析的字符串。

array 可選。規(guī)定存儲變量的數(shù)組名稱。該參數(shù)指示變量存儲到數(shù)組中。

針對變量指定***

不使用foreach遍歷$_GET變量,改用$_GET[(index)]

eval() 函數(shù)把字符串按照 PHP 代碼來計算。該字符串必須是合法的 PHP 代碼,且必須以分號結(jié)尾。

如果沒有在代碼字符串中調(diào)用 return 語句,則返回 NULL。如果代碼中存在解析錯誤,則 eval() 函數(shù)返回 false。

preg_replace 執(zhí)行一個正則表達(dá)式的搜索和替換

/e參數(shù)執(zhí)行代碼

三、漏洞篇

-----------------------------------------------

[1].Sql-Injection

留意:cookie及x-forward-for,寬字節(jié),報錯注射等

挖掘漏洞參考

變量

$_GET[""],$_POST[""],$_COOKIE[""], $SERVER[""]

數(shù)據(jù)庫操作函數(shù)

mysql_query()

數(shù)字型注入防范:

1.is_numeric() ctype_digit() intval()

2.str_length()確定長度

字符型注入防范:

1.mysql_real_escape_string()

2.數(shù)據(jù)庫查詢語句前加@防爆錯

3.str_length()確定長度

-----------------------------------------------

[2].Command-Execution

函數(shù):

system(),passthru(),popen(),exec()

數(shù)據(jù)庫操作函數(shù):

exec,system,popen,passthru,proc_open,shell_exec

執(zhí)行命令管道符 % | >

測試如0 | dir c:

|| 雙豎線的作用,前面語句執(zhí)行錯誤則執(zhí)行后面語句

如xx"+||+whoami+||+echo

-----------------------------------------------

[3].File-Inclusion

函數(shù):

include(),require(),include_once(),require_once()

遠(yuǎn)程文件包含漏洞要求

allow_url_fopen() allow_url_include() file_get_contents()

繞過:zlib://和ogg://

5.2.0之后版本

data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8+ //

@eval(file_get_contents('php://input')); //POST phpinfo();

配合%00截斷,新版本自動轉(zhuǎn)義\0

-----------------------------------------------

[4].CSRF

CSRF防范策略

1>驗證http-referer字段

安全性低,易被偽造

2>在請求地址中添加token并驗證

token可在用戶登錄后存放在session中,每次請求時將token從session中取出,去請求的token對比以防范CSRF

GET方式:http://url/?=token

如果一個網(wǎng)站接受請求地方比較多,則在每次頁面加載時遍歷整個dom樹,在dom中每個a和form標(biāo)簽后加入token

但在動態(tài)頁面加載后產(chǎn)生的html代碼,則需要以硬編碼的形式手工添加

這種方式安全性弱點在于,如在論壇等交互比較頻繁的地方hacker可構(gòu)造環(huán)境盜取token并進(jìn)而構(gòu)造csrf***

故手工關(guān)閉referer

3>在HTTP頭中自定義屬性并進(jìn)行驗證。通過XMLHttpRequest類。

通常用于Ajax方法對頁面局部的異步刷新

但適應(yīng)性一般,對已有的網(wǎng)站架構(gòu)局限性較大

-----------------------------------------------

[5].XSS(Cross Site Script)

反射型與存儲型

控制$_GET,$_POST,$_COOKIE 各種傳入的變量

使用htmlspecialchars()函數(shù)進(jìn)行基礎(chǔ)過濾

結(jié)合CSRF實現(xiàn)自動化利用

-----------------------------------------------

[6].File_Upload

函數(shù):move_uploaded_file()

變量:$_FILES

php文件上傳利用form表單進(jìn)行文件上傳時必須為post使用multipart/form-data才能完整的傳遞文件數(shù)據(jù)

php利用$_FILES系統(tǒng)函數(shù)的相關(guān)參數(shù)與函數(shù)move_upload_file函數(shù)來實例把由$_FILES全局變量生成的臨時文件移動到指定目錄完成文件的上傳

$_FILES['files']['name']客戶端文件的原名稱

$_FILES['files']['type']文件的MIME類型

$_FILES['files']['size']已上傳文件的大小

$_FILES['files']['tmp_name']儲存的臨時文件名,一般為系統(tǒng)默認(rèn)

$_FILES['files']['error']該文件上傳到相關(guān)的錯誤代碼

防范方式:

1>判斷MIME TYPE文件類型如$_FILES['files']['type']=="p_w_picpath/jpeg",判斷文件大小,如$_FILES['files']['size']<10000 && $_FILES['files']['size']>100

2>指定上傳文件名,如依賴時間生成hash(time).jpg等方式

3>根據(jù)文件后綴名判斷文件

如file_ext=substr($filename,$strrpos($filename,'.')+1);

注意是否可能有雙擴(kuò)展名,二次上傳突破等邏輯問題

4>服務(wù)器嘗試渲染文件等方式判斷是否為圖片

5>不依賴于客戶端js腳本限制上傳文件類型

6>白名單規(guī)則

apache服務(wù)器常見上傳安全問題

1>配合.htaccess利用上傳

AllOverride ALL 允許子規(guī)則覆蓋父規(guī)則

.htaccess添加AddType Application/x-httpd-php .jpg

2>文件名解析漏洞

*.php.123

在.htaccess添加AddHandler php5-script .php,文件名中包含php擴(kuò)展名可以php腳本執(zhí)行,如x.php.jpg

.php3 .php4擴(kuò)展名


四、配置篇

1>關(guān)注漏洞信息,及時更新版本

2>php.ini httpd.conf .htaccess文件配置

1)safe_mode相關(guān)配置

2)register_globals關(guān)閉

3)open_basedir配置,防范目錄遍歷

4)allow_url_fopen關(guān)閉

5)disable_functions配置

6)magic_quotes_gpc打開

7)error_reporting=E_ALL & ~E_NOTICE

8)display_errors=Off避免***者獲取更多信息

9)expose_php=Off隱藏版本信息

3>最小化服務(wù)器其他賬戶權(quán)限

4>第三方安全加固軟件安裝

5>調(diào)用第三方安全防護(hù)文件,配置php.ini

include_path=".:/php/includes"

auto_pretend_file="anti-inj.php"

auto_appent_file=

五、思路篇

剛開始練習(xí)審計時,拿到一套源碼,馬上做的事情就是,丟到工具里,去掃敏感的函數(shù),然后去一個一個的回溯它,找到入口點。但是,這樣審計很浪費時間,每次都要在回溯過程中,不斷的去尋找源碼中定義的一些通用函數(shù)。由于不了解整個源碼的流程,導(dǎo)致在找這些通用函數(shù)的過 程中浪費了很多的時間與精力。

所以,我重新調(diào)整了我的審計流程。在拿到源碼之后,先從它開始的地方(一般是根目錄下的index文件)按照執(zhí)行的順序去讀代碼,一直到它的初始化內(nèi)容, 和基本功能實現(xiàn)完畢為止。這樣,可以明確的了解整套源碼的結(jié)構(gòu),哪一種函數(shù)文件放在哪個文件夾下;知道通用函數(shù)放在哪個文件中。這對我們在之后閱讀“疑似”有問題的代碼時,有很好的幫助,例如,在看到一個通用函數(shù)時,我們可以快速的切換到通用函數(shù)文件,查找這個函數(shù)的實現(xiàn)代碼。

注:此處引用修改唐門三少文章《PHP代碼審計學(xué)習(xí)總結(jié)》

六、小結(jié)

代碼審計一如逆向工程,均需要耐心與細(xì)心。

此外,關(guān)注漏洞發(fā)布平臺上最新漏洞并跟蹤加以分析也是一個很快提升自己能力的方法。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI