【代碼審計】PHP代碼審計

1. 概述


代碼審核,是對應(yīng)用程序源代碼進行系統(tǒng)性檢查的工作。它的目的是為了找到并且修復應(yīng)用程序在開發(fā)階段存在的一些漏洞或者程序邏輯錯誤,避免程序漏洞被非法利用給企業(yè)帶來不必要的風險。

代碼審核不是簡單的檢查代碼,審核代碼的原因是確保代碼能安全的做到對信息和資源進行足夠的保護,所以熟悉整個應(yīng)用程序的業(yè)務(wù)流程對于控制潛在的風險是非常重要的。審核人員可以使用類似下面的問題對開發(fā)者進行訪談,來收集應(yīng)用程序信息。

  • 應(yīng)用程序中包含什么類型的敏感信息,應(yīng)用程序怎么保護這些信息的?
  • 應(yīng)用程序是對內(nèi)提供服務(wù),還是對外?哪些人會使用,他們都是可信用戶么?
  • 應(yīng)用程序部署在哪里?
  • 應(yīng)用程序?qū)τ谄髽I(yè)的重要性?

最好的方式是做一個checklist,讓開發(fā)人員填寫。Checklist 能比較直觀的反映應(yīng)用程序的信息和開發(fā)人員所做的編碼安全,它應(yīng)該涵蓋可能存在嚴重漏洞的模塊,例如:數(shù)據(jù)驗證、身份認證、會話管理、授權(quán)、加密、錯誤處理、日志、安全配置、網(wǎng)絡(luò)架構(gòu)。

2. 輸入驗證和輸出顯示


大多數(shù)漏洞的形成原因主要都是未對輸入數(shù)據(jù)進行安全驗證或?qū)敵鰯?shù)據(jù)未經(jīng)過安全處理,比較嚴格的數(shù)據(jù)驗證方式為:

  1. 對數(shù)據(jù)進行精確匹配
  2. 接受白名單的數(shù)據(jù)
  3. 拒絕黑名單的數(shù)據(jù)
  4. 對匹配黑名單的數(shù)據(jù)進行編碼,在PHP 中可由用戶輸入的變量列表如下:
    $_SERVER 
    $_GET 
    $_POST 
    $_COOKIE 
    $_REQUEST 
    $_FILES 
    $_ENV 
    $_HTTP_COOKIE_VARS 
    $_HTTP_ENV_VARS 
    $_HTTP_GET_VARS 
    $_HTTP_POST_FILES 
    $_HTTP_POST_VARS 
    $_HTTP_SERVER_VARS

我們應(yīng)該對這些輸入變量進行檢查

1. 命令注入

PHP 執(zhí)行系統(tǒng)命令可以使用以下幾個函數(shù):system、exec、passthru、``、shell_exec、popen、proc_open、pcntl_exec我們通過在全部程序文件中搜索這些函數(shù),確定函數(shù)的參數(shù)是否會因為外部提交而改變,檢查這些參數(shù)是否有經(jīng)過安全處理。
**防范方法: **
1. 使用自定義函數(shù)或函數(shù)庫來替代外部命令的功能
2. 使用escapeshellarg 函數(shù)來處理命令參數(shù)
3. 使用safe_mode_exec_dir 指定可執(zhí)行文件的路徑

2. 跨站腳本

反射型跨站常常出現(xiàn)在用戶提交的變量接受以后經(jīng)過處理,直接輸出顯示給客戶端;存儲型跨站常常出現(xiàn)在用戶提交的變量接受過經(jīng)過處理后,存儲在數(shù)據(jù)庫里,然后又從數(shù)據(jù)庫中讀取到此信息輸出到客戶端。輸出函數(shù)經(jīng)常使用:echo、print、printf、vprintf、<%=$test%> 對于反射型跨站,因為是立即輸出顯示給客戶端,所以應(yīng)該在當前的 php 頁面檢查變量被客戶提交之后有無立即顯示,在這個過程中變量是否有經(jīng)過安全檢查。
對于存儲型跨站,檢查變量在輸入后入庫,又輸出顯示的這個過程中,變量是否有經(jīng)過安全檢查。
**防范方法: **

  1. 如果輸入數(shù)據(jù)只包含字母和數(shù)字,那么任何特殊字符都應(yīng)當阻止
  2. 對輸入的數(shù)據(jù)經(jīng)行嚴格匹配,比如郵件格式,用戶名只包含英文或者中文、下劃線、連字符
  3. 對輸出進行HTML 編碼,編碼規(guī)范
< < 
> > 
( ( 
) ) 
# # 
& & 
" " 
‘ ' 
` %60 

3. 文件包含


PHP 可能出現(xiàn)文件包含的函數(shù):include、include_once、require、require_once、show_source、highlight_file、readfile、file_get_contents、fopen、 nt>file
**防范方法: **

  1. 對輸入數(shù)據(jù)進行精確匹配,比如根據(jù)變量的值確定語言 en.php、cn.php,那么這兩個文件放在
    同一個目錄下’language/’.$_POST[‘lang’].’.php’,那么檢查提交的數(shù)據(jù)是否是en 或者cn 是最嚴格的,檢查是否只包含字母也不錯
  2. 通過過濾參數(shù)中的/、..等字符

4. 代碼注入

PHP 可能出現(xiàn)代碼注入的函數(shù):eval、preg_replace+/e、assert、call_user_func、
call_user_func_array、create_function
查找程序中程序中使用這些函數(shù)的地方,檢查提交變量是否用戶可控,有無做輸入驗證
**防范方法: **

  1. 輸入數(shù)據(jù)精確匹配
  2. 白名單方式過濾可執(zhí)行的函數(shù)

5. SQL注入

SQL 注入因為要操作數(shù)據(jù)庫,所以一般會查找SQL 語句關(guān)鍵字:insert、delete、update、
select,查看傳遞的變量參數(shù)是否用戶可控制,有無做過安全處理
**防范方法: **
使用參數(shù)化查詢

6. XPath注入

Xpath 用于操作xml,我們通過搜索xpath 來分析,提交給<font face="Arial, sans-serif">xpath</fo
函數(shù)的參數(shù)是否有經(jīng)過安全處理
**防范方法: **
對于數(shù)據(jù)進行精確匹配

7. HTTP響應(yīng)拆分

PHP 中可導致HTTP 響應(yīng)拆分的情況為:使用header 函數(shù)和使用$_SERVER 變量。注意PHP
的高版本會禁止HTTP 表頭中出現(xiàn)換行字符,這類可以直接跳過本測試。
**防范方法: **

  1. 精確匹配輸入數(shù)據(jù)
  2. 檢測輸入輸入中如果有\(zhòng)r 或\n,直接拒絕

8. 文件管理

PHP 的用于文件管理的函數(shù),如果輸入變量可由用戶提交,程序中也沒有做數(shù)據(jù)驗證,可能成為高危漏洞。我們應(yīng)該在程序中搜索如下函數(shù):copy、rmdir、unlink、delete、fwrite、chmod、fgetc、fgetcsv、fgets、fgetss、file、file_get_contents、fread、readfile、ftruncate、file_put_contents、fputcsv、fputs,但通常PHP 中每一個文件操作函數(shù)都可能是危險的。
http://ir.php.net/manual/en/re
f.filesystem.php
**防范方法: **

  1. 對提交數(shù)據(jù)進行嚴格匹配
  2. 限定文件可操作的目錄

9. 文件上傳

PHP 文件上傳通常會使用move_uploaded_file,也可以找到文件上傳的程序進行具體分析
**防范方法: **

  1. 使用白名單方式檢測文件后綴
  2. 上傳之后按時間能算法生成文件名稱
  3. 上傳目錄腳本文件不可執(zhí)行
  4. 注意%00 截斷

10. 變量覆蓋

PHP 變量覆蓋會出現(xiàn)在下面幾種情況:

  1. 遍歷初始化變量
    例:
foreach($_GET as $key => $value) 
$$key = $value; 
  1. 函數(shù)覆蓋變量:parse_str、mb_parse_str、import_request_variables
  2. Register_globals=ON 時,GET 方式提交變量會直接覆蓋
    **防范方法: **
  3. 設(shè)置Register_globals=OFF
  4. 不要使用這些函數(shù)來獲取變量

11. 動態(tài)函數(shù)

當使用動態(tài)函數(shù)時,如果用戶對變量可控,則可導致攻擊者執(zhí)行任意函數(shù)。
例:

<?php 
$myfunc = $_GET['myfunc' font>]; 
$myfunc(); 
?> 

**防范方法: **
不要這樣使用函數(shù)

3. 會話安全


1. HTTPOnly設(shè)置

session.cookie_httponly = ON 時,客戶端腳本(JavaScript 等)無法訪問該cookie,打
開該指令可以有效預防通過XSS 攻擊劫持會話ID

2. domain設(shè)置

檢查session.cookie_domain 是否只包含本域,如果是父域,則其他子域能夠獲取本域的
cookies

3. path設(shè)置

檢查session.cookie_path,如果網(wǎng)站本身應(yīng)用在/app,則path 必須設(shè)置為/app/,才能
保證安全

4. cookies持續(xù)時間

檢查session.cookie_lifetime,如果時間設(shè)置過程過長,即使用戶關(guān)閉瀏覽器,攻擊者
也會危害到帳戶安全

5. secure設(shè)置

如果使用HTTPS,那么應(yīng)該設(shè)置session.cookie_secure=ON,確保使用HTTPS 來傳輸
cookies

6. session固定

如果當權(quán)限級別改變時(例如核實用戶名和密碼后,普通用戶提升到管理員),我們就應(yīng)
該修改即將重新生成的會話ID,否則程序會面臨會話固定攻擊的風險。

7. CSRF

跨站請求偽造攻擊,是攻擊者偽造一個惡意請求鏈接,通過各種方式讓正常用戶訪問后,
會以用戶的身份執(zhí)行這些惡意的請求。我們應(yīng)該對比較重要的程序模塊,比如修改用戶密碼,添
加用戶的功能進行審查,檢查有無使用一次性令牌防御 csrf 攻擊。

4. 加密


1. 明文存儲密碼

采用明文的形式存儲密碼會嚴重威脅到用戶、應(yīng)用程序、系統(tǒng)安全。

2. 密碼弱加密

使用容易破解的加密算法,MD5 加密已經(jīng)部分可以利用md5 破解網(wǎng)站來破解

3. 密碼存儲在攻擊者能訪問到的文件

例如:保存密碼在txt、ini、conf、inc、xml 等文件中,或者直接寫在HTML 注釋中

5. 認證和授權(quán)


1. 用戶認證

- 檢查代碼進行用戶認證的位置,是否能夠繞過認證,例如:登錄代碼可能存在表單注入。 
- 檢查登錄代碼有無使用驗證碼等,防止暴力破解的手段 

2. 函數(shù)或文件的未認證調(diào)用

- 一些管理頁面是禁止普通用戶訪問的,有時開發(fā)者會忘記對這些文件進行權(quán)限驗證,導致漏洞發(fā)生 
- 某些頁面使用參數(shù)調(diào)用功能,沒有經(jīng)過權(quán)限驗證,比如 index.php?action=upload 

3. 密碼硬編碼

有的程序會把數(shù)據(jù)庫鏈接賬號和密碼,直接寫到數(shù)據(jù)庫鏈接函數(shù)中。

6. 隨機函數(shù)


1. rand()

rand()最大隨機數(shù)是32767,當使用rand 處理session 時,攻擊者很容易破解出session,
建議使用mt_rand()

2. mt_srand()和mt_rand()

e="text-indent: 0.85cm; margin-bottom: 0cm; line-height: 125%">PHP4 和PHP5<5.2.6
這兩個函數(shù)處理數(shù)據(jù)是不安全的。在web 應(yīng)用中很多使用mt_rand 來處理隨機的session,比如密碼找回功能等,這樣的后果就是被攻擊者惡意利用直接修改密碼。

7. 特殊字符和多字節(jié)編碼


1. 多字節(jié)編碼

8. PHP危險函數(shù)


1. 緩沖區(qū)溢出

  • confirm_phpdoc_compiled
    影響版本:
phpDocumentor phpDocumentor 1.3.1 
phpDocumentor phpDocumentor 1.3 RC4 
phpDocumentor phpDocumentor 1.3 RC3 
phpDocumentor phpDocumentor 1.2.3 
phpDocumentor phpDocumentor 1.2.2 
phpDocumentor phpDocumentor 1.2.1 
phpDocumentor phpDocumentor 1.2 
mssql_pconnect/mssql_connect

影響版本:PHP <= 4.4.6
crack_opendict
影響版本:PHP = 4.4.6
? snmpget
影響版本:PHP <= 5.2.3
? ibase_connect
影響版本:PHP = 4.4.6
? unserialize
影響版本:

PHP 5.0.2
PHP 5.0.1
PHP 5.0.0
PHP 4.3.9
PHP 4.3.8 
PHP 4.3.7
PHP 4.3.6
PHP 4.3.3
PHP 4.3.2
PHP 4.3.1
PHP 4.3.0
PHP 4.2.3
PHP 4.2.2
PHP 4.2.1
PHP 4.2.0
PHP 4.2-dev
PHP 4.1.2
PHP 4.1.1
PHP 4.1.0
PHP 4.1
PHP 4.0.7
PHP 4.0.6
PHP 4.0.5
PHP 4.0.4
PHP 4.0.3pl1
PHP 4.0.3
PHP 4.0.2
PHP 4.0.1pl2
PHP 4.0.1pl1
PHP 4.0.1```

####  2. session_destroy()刪除文件漏洞 
影響版本:不祥,需要具體測試 
測試代碼如下: 
`php
<?php 
session_save_path(‘./’); 
session_start(); 
if($_GET[‘del’]) { 
session_unset(); 
session_destroy(); 
}else{ 
$_SESSION[‘do’]=1; 
echo(session_id()); 
print_r($_SESSION); 
} 
?> 
`
當我們提交cookie:PHPSESSIONID=/../1.php,相當于刪除了此文件 

#### 3. unset()-zend_hash_del_key_or_index漏洞 
zend_hash_del_key_or_index PHP4 小于4.4.3 和PHP5 小于5.1.3,可能會導致
zend_hash_del 刪除了錯誤的元素。當PHP 的unset()函數(shù)被調(diào)用時,它會阻止變量被unset。 

### 9. 信息泄露
---
 
#### 1. phpinfo 
如果攻擊者可以瀏覽到程序中調(diào)用phpinfo 顯示的環(huán)境信息,會為進一步攻擊提供便利 

### 10. PHP環(huán)境
---
 
#### 1. open_basedir設(shè)置 
open_basedir 能限制應(yīng)用程序能訪問的目錄,檢查有沒有對 open_basedir 進行設(shè)置,當
然有的通過web 服務(wù)器來設(shè)置,例如:apache 的php_admin_value,nginx+fcgi 通過conf 來控
制php 設(shè)置 

#### 2. allow_url_fopen設(shè)置 
如果allow_url_fopen=ON,那么php 可以讀取遠程文件進行操作,這個容易被攻擊者利用 

#### 3.  allow_url_include 設(shè)置 
如果allow_url_include=ON,那么php 可以包含遠程文件,會導致嚴重漏洞 

#### 4. safe_mode_exec_dir設(shè)置 
這個選項能控制php 可調(diào)用的外部命令的目錄,如果PHP 程序中有調(diào)用外部命令,那么指
定外部命令的目錄,能控制程序的風險 

#### 5. magic_quote_gpc設(shè)置 
這個選項能轉(zhuǎn)義提交給參數(shù)中的特殊字符,建議設(shè)置 magic_quote_gpc=ON 

#### 6. register_globals設(shè)置 
開啟這個選項,將導致php 對所有外部提交的變量注冊為全局變量,后果相當嚴重 

#### 7. safe_mode設(shè)置 
safe_mode 是PHP 的重要安全特性,建議開啟 

#### 8. session_use_trans_sid設(shè)置 
如果啟用 session.use_trans_sid,會導致 PHP 通過 URL 傳遞會話 ID,這樣一來,
攻擊者就更容易劫持當前會話,或者欺騙用戶使用已被攻擊者控制的現(xiàn)有會話。 

#### 9. display_errors設(shè)置 
如果啟用此選項,PHP 將輸出所有的錯誤或警告信息,攻擊者能利用這些信息獲取 web 根
路徑等敏感信息 

#### 10. expose_php設(shè)置 
如果啟用 expose_php 選項,那么由 PHP 解釋器生成的每個響應(yīng)都會包含主機系統(tǒng)上
所安裝的PHP 版本。了解到遠程服務(wù)器上運行的 PHP 版本后,攻擊者就能針對系統(tǒng)枚舉已
知的盜取手段,從而大大增加成功發(fā)動攻擊的機會。 
 
**參考文檔** 
<https://www.fortify.com/vulncat/zh_CN/vulncat/index.html> 
<http://secinn.appspot.com/pstzine/read?issue=3&articleid=6> 
<http://www.owasp.org/index.php/Category:OWASP_Code_Review_Project>
<http://riusksk.blogbus.com/logs/51538334.html >

**此篇文章來自互聯(lián)網(wǎng)**
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • php.ini設(shè)置,上傳大文件: post_max_size = 128Mupload_max_filesize ...
    bycall閱讀 6,997評論 3 64
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,755評論 11 349
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 現(xiàn)在有不少的孩子患上了過敏性鼻炎,經(jīng)常流鼻涕、打噴嚏等等,很多家長都很擔心,過敏性鼻炎給人們帶來了很大的痛苦,在這...
    參漮苓s閱讀 624評論 0 0
  • 2017 10 12 星期四 多云 下班的路上出了點小插曲,騎電動車沒看清路上有塊石...
    李璽辰媽媽閱讀 207評論 0 2

友情鏈接更多精彩內(nèi)容