【代碼審計(jì)】PHP代碼審計(jì)

1. 概述


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

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

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

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

2. 輸入驗(yàn)證和輸出顯示


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

  1. 對(duì)數(shù)據(jù)進(jìn)行精確匹配
  2. 接受白名單的數(shù)據(jù)
  3. 拒絕黑名單的數(shù)據(jù)
  4. 對(duì)匹配黑名單的數(shù)據(jù)進(jìn)行編碼,在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)該對(duì)這些輸入變量進(jìn)行檢查

1. 命令注入

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

2. 跨站腳本

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

  1. 如果輸入數(shù)據(jù)只包含字母和數(shù)字,那么任何特殊字符都應(yīng)當(dāng)阻止
  2. 對(duì)輸入的數(shù)據(jù)經(jīng)行嚴(yán)格匹配,比如郵件格式,用戶名只包含英文或者中文、下劃線、連字符
  3. 對(duì)輸出進(jìn)行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. 對(duì)輸入數(shù)據(jù)進(jìn)行精確匹配,比如根據(jù)變量的值確定語言 en.php、cn.php,那么這兩個(gè)文件放在
    同一個(gè)目錄下’language/’.$_POST[‘lang’].’.php’,那么檢查提交的數(shù)據(jù)是否是en 或者cn 是最嚴(yán)格的,檢查是否只包含字母也不錯(cuò)
  2. 通過過濾參數(shù)中的/、..等字符

4. 代碼注入

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

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

5. SQL注入

SQL 注入因?yàn)橐僮鲾?shù)據(jù)庫,所以一般會(huì)查找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)過安全處理
**防范方法: **
對(duì)于數(shù)據(jù)進(jìn)行精確匹配

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

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

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

8. 文件管理

PHP 的用于文件管理的函數(shù),如果輸入變量可由用戶提交,程序中也沒有做數(shù)據(jù)驗(yàn)證,可能成為高危漏洞。我們應(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 中每一個(gè)文件操作函數(shù)都可能是危險(xiǎn)的。
http://ir.php.net/manual/en/re
f.filesystem.php
**防范方法: **

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

9. 文件上傳

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

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

10. 變量覆蓋

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

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

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

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

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

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

3. 會(huì)話安全


1. HTTPOnly設(shè)置

session.cookie_httponly = ON 時(shí),客戶端腳本(JavaScript 等)無法訪問該cookie,打
開該指令可以有效預(yù)防通過XSS 攻擊劫持會(huì)話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ù)時(shí)間

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

5. secure設(shè)置

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

6. session固定

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

7. CSRF

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

4. 加密


1. 明文存儲(chǔ)密碼

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

2. 密碼弱加密

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

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

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

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


1. 用戶認(rèn)證

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

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

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

3. 密碼硬編碼

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

6. 隨機(jī)函數(shù)


1. rand()

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

2. mt_srand()和mt_rand()

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

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


1. 多字節(jié)編碼

8. PHP危險(xiǎn)函數(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()刪除文件漏洞 
影響版本:不祥,需要具體測(cè)試 
測(cè)試代碼如下: 
`php
<?php 
session_save_path(‘./’); 
session_start(); 
if($_GET[‘del’]) { 
session_unset(); 
session_destroy(); 
}else{ 
$_SESSION[‘do’]=1; 
echo(session_id()); 
print_r($_SESSION); 
} 
?> 
`
當(dāng)我們提交cookie:PHPSESSIONID=/../1.php,相當(dāng)于刪除了此文件 

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

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

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

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

#### 3.  allow_url_include 設(shè)置 
如果allow_url_include=ON,那么php 可以包含遠(yuǎn)程文件,會(huì)導(dǎo)致嚴(yán)重漏洞 

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

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

#### 6. register_globals設(shè)置 
開啟這個(gè)選項(xiàng),將導(dǎo)致php 對(duì)所有外部提交的變量注冊(cè)為全局變量,后果相當(dāng)嚴(yán)重 

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

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

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

#### 10. expose_php設(shè)置 
如果啟用 expose_php 選項(xiàng),那么由 PHP 解釋器生成的每個(gè)響應(yīng)都會(huì)包含主機(jī)系統(tǒng)上
所安裝的PHP 版本。了解到遠(yuǎn)程服務(wù)器上運(yùn)行的 PHP 版本后,攻擊者就能針對(duì)系統(tǒng)枚舉已
知的盜取手段,從而大大增加成功發(fā)動(dòng)攻擊的機(jī)會(huì)。 
 
**參考文檔** 
<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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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

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