1.代码执行漏洞原理
用户输入的数据被当作后端代码执行,当应用在调用一些能将字符串转化成代码的函数时,没有考虑用户是否能够控制这个字符串,将造成代码注入漏洞。
2.常见的代码执行漏洞的危险函数
eval() :
是将字符串当作php代码执行,例如常见的一句话木马:
<?php eval($_REQUEST['A']);?>
实际上eval不算是函数,应该是php的一种特殊写法。另外,eval允许多行执行并输出,而且,在php-ini文件中的disable_functions是无法禁用eval的!
assert():
类似JS中的事件型,assert — 检查断言是否为 false!
assert(mixed $assertion, string $description = ?)
assert() 会检查指定的 assertion 并在结果为 false 时采取适当的行动。使用assert也可以达到eval同样的效果:
<?php assert($_REQUEST['A']);?>
但是assert只能单行输出,但是可以使用别方法实现多行输出
(1)在文件中写入
<?php assert($_REQUEST['A']);?>
当在URL栏中传参时输入A=eval(‘echo 1;phpinfo()’)
(2)使用file-put-contents(),类似上面的方法,在传参时输入A=file-put-contents(‘1.php’,‘<?php echo 1;phpinfo();?>’)实现多行输出。
preg_replace():
正则替换函数
<?php
echo preg_repace('/a/e',$_GET[1],'acs');
?>
/e 修正符使 preg_replace() 将GET获得的参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。函数只有在发生替换时才触发;
其它修正符的用法可以参考:https://www.php.net/manual/zh/reference.pcre.pattern.modifiers.php
create_funtion() :
匿名函数(自定义函数)
具体使用方法可以参考https://www.cnblogs.com/zzjdbk/p/12980483.html(大佬讲的非常明了👍)
array_map ()
把数组里面的东西依次放入函数执行得到结果
array_map(要调用的函数名,对该函数的传参)
例如:
array_map(assert,array($_REQUEST['A']))
回调函数不能调用eval,PHP还有其它的回调函数可以构建一句话木马。
php双引号二次解析
在PHP中,单引号和双引号都可以表示一个字符串,但是对于双引号来说,可能会对引号内的内容进行二次解释,这就可能会出现安全问题。
"${你想执行的代码}"
例如:
"{phpinfo()}"
这么强大肯定有限制条件:
(1)PHP版本必须大于等于5.5在有效!
(2)网站源码中有写"{phpinfo()}",才能用,可以通过修改配置文件、修改配置、修改参数,安装文件,然后执行命令!
3.危害性
- 执行任意代码
- 向网站写WebShell
- 控制整个网站甚至服务器
4.防御方法
1.尽量少用执行命令的函数或者直接禁用
2. 参数值尽量使用引号包括
3.在使用动态函数之前,确保使用的函数是指定的函数之一
4.在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义
5.能使用脚本解决的工作,不要调用其他程序处理。
6.尽量少用执行命令的函数,并在disable_functions中禁用
7.对于可控点是程序参数的情况下,使用escapeshellcmd函数进行过滤
8.参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义
9.而针对由特定第三方组件引发的漏洞,我们要做的就是及时打补丁,修改安装时的默认配置。
10.对于eval( )函数一定要保证用户不能轻易接触eval的参数或者用正则严格判断输入的数据格式。
11.对于preg_replace放弃使用e修饰符。如果必须要用e修饰符,请保证第二个参数中,对于正则匹配出的对象,用单引号包裹 。