程式碼審計入門總結

wyzsk發表於2020-08-19
作者: sixwhale · 2016/02/15 9:31

0x00 簡介


之前看了seay寫的PHP程式碼審計的書,全部瀏覽了一遍,作為一個程式碼審計小白,希望向一些和我一樣的小白的人提供一下我的收穫,以及一個整體的框架和常見漏洞函式。這也算是這本書的一個學習筆記吧,可以結合我捋順的思路來看這本書。: )

0x01 整體


學習程式碼審計的目標是能夠獨立完成對一個CMS的程式碼安全監測。其通用的思路有:

  • 通讀全文程式碼,從功能函式程式碼開始閱讀,例如include資料夾下的common_fun.php,或者有類似關鍵字的檔案。
  • 看配置檔案,帶有config關鍵字的檔案,找到mysql.class.php檔案的connect()函式,檢視在資料庫連線時是否出現漏洞。
  • 繼續跟讀首頁檔案,index.php,瞭解程式運作時呼叫了哪些函式和檔案 以index.php檔案作為標線,一層一層去擴充套件閱讀所包含的檔案,瞭解其功能,之後進入其功能資料夾的首頁檔案,進行擴充套件閱讀。

0x02 各種洞洞


a.檔案操作漏洞

  • 能不用檔名引數就不用 儘量不要讓使用者可控
  • 平行使用者的許可權 管理員的許可權 操作許可權
  • 禁止傳入引數類似於這種 .. ,/,\ 檢查傳入的引數,做出限制,停止程式往下執行

1.檔案包含漏洞:

(1) 本地檔案包含:

  • 一般存在於模組載入,模板載入,cache呼叫
  • 包括函式:include()/include_once()require()/require_once()尋找可控變數

p1

p2

(2) 遠端檔案包含:

  • 前提條件:allow_url_include = on
  • 出現頻率不如本地包含

(3) 檔案包含截斷:

  • %00截斷(php版本小於5.3)
  • 問號截斷(問號後面相當於請求的引數,偽截斷)
  • 英文(.) 反斜槓(/) 截斷

2.檔案讀取(下載)漏洞:

搜尋關鍵函式:

file_get_contents(),highlight_file(),fopen(),read file(),fread(),fgetss(), fgets(),parse_ini_file(),show_source(),file()

3.檔案上傳漏洞:

搜尋關鍵函式:

move_uploaded_file() 接著看呼叫這個函式的程式碼是否存在為限制上傳格式或者可以繞過。

(1) 未過濾或本地過濾:伺服器端未過濾,直接上傳PHP格式的檔案即可利用。

(2) 黑名單副檔名過濾:

  • 限制不夠全面:IIS預設支援解析.asp,.cdx, .asa,.cer等。
  • 副檔名可繞過:

p3

不被允許的檔案格式.php,但是我們可以上傳檔名為1.php(注意後面有一個空格)

(3) 檔案頭 content-type驗證繞過:

  • getimagesize()函式:驗證檔案頭只要為GIF89a,就會返回真。
  • 限制$_FILES["file"]["type"]的值 就是人為限制content-type為可控變數。

(4) 防範:

  • 使用in_array()或 利用三等於===對比副檔名。
  • 儲存上傳檔案是重新命名,規則採用時間戳拼接隨機數:md5(time() + rand(1,1000))

4.檔案刪除漏洞:

搜尋關鍵函式:

  • unlink()利用回溯變數的方式
  • 老版本下的session_destroy(),可以刪除檔案,現已基本被修復。

Metinfo的任意檔案刪除漏洞:

p4

$action = delete即可刪除.sql的檔案,如果檔案不是sql直接刪除提交的檔名

target.com/recovery.php?&action=delete&filename=../../index.php

b.程式碼執行漏洞

1.程式碼執行函式:

搜尋關鍵函式:eval(), assert(), preg_replace(), call_user_func(), call_user_func_array(), array_map()

(1) preg_replace()函式:

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

當$pattern處存在e修飾符時,$replacement 會被當做php程式碼執行。

(2)mixed call_user_func( callable $callbank [ , mixed $parameter [ , mixed $…)

第一個引數為回撥函式,第二個引數是回撥函式的引數

p5

p6

(3)eval()assert()

當assert()的引數為字串時 可執行PHP程式碼

【區分】:

eval(" phpinfo(); ");【√】 eval(" phpinfo() ");【X】
assert(" phpinfo(); ");【√】 assert(" phpinfo() ");【√】

2.動態函式執行:

動態函式後門:

#!php
<?php
$_GET['a']($_GET['b']);
?>

p7

3.命令執行函式:

搜尋關鍵函式:system(), exec(), shell_exec(), passthru() ,pcntl_exec(), popen(),proc_open()

(1) popenproc_open()

#!php
<?php 
popen( 'whoami >> /Users/bingdaojueai/Desktop/1.txt', 'r' ); 
?>

所在路徑就會出現一個1.txt 裡面的內容為命令執行後的結果

(2) 反引號命令執行:

  • echo whoami; 直接就可以執行命令

  • 雙引號和單引號的區別:

    #!php
    $a = 1
    echo " $a "    output:1
    echo ' $a '    output:$a
    

雙引號時,可以直接解析變數,造成程式碼執行漏洞,過狗繞過。

c.變數覆蓋漏洞

1.函式使用不當:

  • int extract( array &$var_array , int $extract_type = EXTR_OVERWRITE , string $prefix = null )
  • void parse_str( string $str , array &$arr )
  • bool import_request_variables( string $type , string $prefix )

2.$$變數覆蓋:

p8

p9

d.邏輯漏洞

需要思考的問題:

  • 程式是否可以重複安裝
  • 修改密碼是否存在越權修改其他使用者密碼
  • 找回密碼驗證碼是否可以暴力破解
  • cookie是否可以預測 驗證存在繞過

1.等於與存在判斷繞過:

(1) in_array(): 比較之前會自動轉換型別

p10

p11

(2)is_numeric():當傳入引數為hex時 直接透過並返回true 並且MYSQL可以直接使用hex編碼代替字串明文 可以二次注入 並且可能造成XSS漏洞

(3)雙等於==和三等於===

  • 雙等於會在變數比較時,進行類轉換,與in_array()是一樣的問題。
  • 三等於是typevalue的雙重比較,相比之下更加安全。

2.賬戶體系中的越權問題:

  • 水平越權:A使用者能夠以B使用者的身份,進行B使用者的全部許可權操作。前提A使用者和B使用者擁有相同的許可權。
  • 垂直越權:A使用者能夠以C使用者的身份,進行C使用者的全部許可權操作,前提C使用者比A使用者擁有更高的許可權。

(1) 未exit/return/die

#!php
<?php
if(file_exists('install.lock)){
    header("Location:xxx.com");
    //exit();
}
echo "test";
?>

test 依舊會被輸出,替換成安裝流程,PHP依舊會進行。

(2) 支付漏洞:

  • 客戶端修改單價
  • 客戶端修改總價和購買數量
  • 服務端未校驗嚴格
  • 重複發包利用時間差:

    #!php
    <?php
    if (check_money($price)){
      //Do something
      //花費幾秒
      $money = $money - $price;
    }
    ?>
    

可能導致漏洞函式: str_replace()

p12

#!php
<?php
$a = addslashes($_GET['a']);
$b = addslashes($_GET['b']);
echo "$a<br>$b<br>";
$c = str_replace($a,'',$b);
echo trim($c);
?>

p13

e.會話認證漏洞

  • COOKIE驗證:沒有使用SESSION驗證,將資訊直接儲存在COOKIE中

    1. 找到傳入sql語句的引數的傳遞過程 回溯變數到最原始的函式 看它儲存在cookie的演算法 是否可逆
    2. 和MD5比起 sha1更安全 解密sha1的網站更少
    3. 限制一個使用者只能同時在一個IP上登入
  • 審計程式碼時,檢視登入處程式碼

f.二次漏洞

1.型別:

  • 不是邏輯問題,是可信問題。
  • 業務邏輯複雜度,與二次漏洞觸發率 成正比。
  • 購物車 / 訂單 / 引用資料 / 文章編輯 / 草稿 ==> SQL隱碼攻擊 / XSS

p14

p15

2.技巧:

(1) 鑽GPC等轉義的空子:

  • 不受GPC保護的$_SERVER變數:PHP5以後,$_SERVER取到的header不再受GPC影響,就算開啟特殊字元也不會被轉義,存在注入
  • 編碼問題轉換:

    1. GBK的寬位元組注入:%df ' 單引號自動被轉義成(%5c),同時%df%5c連在一起組合成字單引號依然在,成功閉合。【php與mysql互動過程中發生的編碼轉換問題】
    2. mb_convert_encoding()

      #!php
      <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> 
      <?php
      $sql = "WHERE id='".urldecode("-1%df%5c' == ")."'"; 
      print_r(mb_convert_encoding($sql,"UTF-8","GBK"));
      ?>
      

(2)字串問題:

  • 利用報錯,找到敏感資訊
  • 字串截斷:

    1. %00空字元截斷:【PHP版本小於5.3】

      #!php
      <?php                                 
      include($_GET['file'].'.php');      
      //1.php?file=2.txt%00
      //2.txt裡面是 <?php phpinfo()?>
      ?>
      
    2. iconv函式字元編碼轉換截斷:【對PHP版本有要求】

      #!php
      chr(128)—chr(255)可以截斷字元
      <?php 
      $a = '1'.chr(130).'2’; 
      echo $a."<br>";                   //1�2
      echo iconv("UTF-8", "GBK", $a);   //1
      ?>
      
  • php:// 輸入輸出流:

    #!php
    <?php
        include($_GET[‘file']);
    ?>
    1.php?file=php://filter/convert.base64-encode(內容被base64編碼)/resource=example.txt(遠端檔案)
    
  • php程式碼解析標籤:

    1. <script language="php">…</script>
    2. <?…?>php3.0.4版本後可用
    3. <%…%>asp標籤,需要asp_tags=on,預設是off
  • 正規表示式:

    1. 沒有使用^ 和 $ 限定匹配開始位置:
    2. 特殊字元未轉義:
  • 報錯注入:

    p16

    p17

  • windows findfirstfile 利用:若要搜尋12345.txt檔案,可使用1<<來代替或者12<<,不可以單獨使用一個"<"">",因為單獨一個只是代表了一個字元,兩個代表多個字元。

0x03 End


自己走上安全這條路既是興趣也是偶然,選擇白盒完全是因為喜歡php,畢竟是初識程式碼審計,seay的書確實幫了我不少,抱作者大腿(我是萌妹紙),希望這篇文章能夠幫助像我一樣小白的人,花了兩天總結的,如果有什麼缺陷也等著大家指出。

不會開發的談審計都是耍流氓!:)

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章