天天看點

代碼審計入門總結

參考文獻: http://www.vuln.cn/6701 通用思路

  • 通讀全文代碼,從功能函數代碼開始閱讀,例如include檔案夾下的

    common_fun.php

    ,或者有類似關鍵字的檔案。
  • 看配置檔案,帶有config關鍵字的檔案,找到

    mysql.class.php

    檔案的connect()函數,檢視在資料庫連接配接時是否出現漏洞。
  • 繼續跟讀首頁檔案

    index.php

    了解程式運作時調用了哪些函數和檔案,以

    index.php

    檔案作為标線,一層一層去擴充閱讀所包含的檔案,了解其功能,之後進入其功能檔案夾的首頁檔案,進行擴充閱讀。

漏洞總結:

1.檔案操作漏洞

①.檔案包含漏洞:(詳細可看:

https://www.jianshu.com/p/41bb503abe61

)

(1) 本地檔案包含:

一般存在于子產品加載,模闆加載,cache調用

包括函數:include()/include_once(),require()/require_once()尋找可控變量

(2)* 遠端檔案包含:*

前提條件:allow_url_include = on

(3) 檔案包含截斷:

%00截斷(php版本小于5.3)

問号截斷(問号後面相當于請求的參數,僞截斷)

英文(.) 反斜杠(/) 截斷

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

搜尋關鍵函數:

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

③.檔案上傳漏洞:

move_uploaded_file()

接着看調用這個函數的代碼是否存在為限制上傳格式或者可以繞過。

(1) 未過濾或本地過濾:

伺服器端未過濾,直接上傳PHP格式的檔案即可利用。

(2) 黑名單擴充名過濾:

限制不夠全面:IIS預設支援解析.asp,.cdx, .asa,.cer等。

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

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

④.檔案删除漏洞:

搜尋關鍵函數:

unlink()

利用回溯變量的方式

老版本下的session_destroy(),可以删除檔案,現已基本被修複。

2.代碼執行漏洞

①代碼執行函數:

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)call_user_func()函數

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

第一個參數為回調函數,第二個參數是回調函數的參數

(3)eval()和assert():

當assert()的參數為字元串時 可執行PHP代碼

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

②.動态函數執行:

動态函數後門:

<?php
$_GET['a']($_GET['b']);
?>
           
代碼審計入門總結

1.png

③.指令執行函數:

system(), exec(), shell_exec(), passthru() ,pcntl_exec(), popen(),proc_open()
           

(1) popen()和proc_open():

<?php 
popen( 'whoami >> 1.txt', 'r' ); 
?>
           

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

(2) 反引号指令執行:

<?php 
echo `whoami`;
?>                //直接就可以執行指令
           

雙引号和單引号的差別:

<?php 
$a = 1;
echo " $a " ; //1
echo ' $a ' ;//$a
?>                //雙引号時,可以直接解析變量,造成代碼執行漏洞。
           

3.變量覆寫漏洞

①.函數使用不當:

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 )
           

②.$$變量覆寫:

<?php
include "flag.php";
if ($_SERVER["REQUEST_METHOD"] != "POST")
    die("flag is here");
if (!isset($_POST["flag"]) )
    die($_403);
foreach ($_GET as $k => $v){
    $$k = $$v;
}
foreach ($_POST as $k => $v){
    $$k = $v;
}
if ( $_POST["flag"] !== $flag )
    die($_403);
echo "flag: ". $flag . "\n";
die($_200);
?>
           

使用了兩個foreach并且也使用了$$.兩個foreach中對 $$key的處理是不一樣的,滿足條件後會将$flag裡面的值列印出來。

但是由于

後兩個if語句及foreach

代碼會将$flag的值給覆寫掉了,是以需要先将$flag的值賦給$_200或$_403變量,然後利用die($_200)或 die($_403)将flag列印出來。

解題方法:

利用第一個foreach先将$flag的值賦給$_200,然後利用die($_200)将原本的flag值列印出來。

最終PAYLOAD:

GET DATA:?_200=flag 
POST DATA:flag=aaaaaaaaaaaaaaaaaaaaa
           

4.邏輯漏洞

需要思考的問題:

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

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

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

(1) 未

exit

/

return

die

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

           

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

(2) 支付漏洞:

  • 用戶端修改單價
  • 用戶端修改總價和購買數量
  • 服務端未校驗嚴格
  • 重複發包利用時間差:
    <?php
    if (check_money($price)){
      //Do something
      //花費幾秒
      $money = $money - $price;
    }
    ?>
               

可能導緻漏洞函數:

str_replace()

<?php
$a = addslashes($_GET['a']);
$b = addslashes($_GET['b']);
echo "$a<br>$b<br>";
$c = str_replace($a,'',$b);
echo trim($c);
?>
           
代碼審計入門總結

5.會話認證漏洞

  • COOKIE驗證:沒有使用SESSION驗證,将資訊直接儲存在COOKIE中
  • 找到傳入sql語句的參數的傳遞過程,回溯變量到最原始的函數,看它儲存在cookie的算法是否可逆
  • 審計代碼時,檢視登入處代碼