前言
最近复现的漏洞都是以远程代码执行为主。但是基本都是JAVA
环境的,对java的也不怎么熟,就只能对PHP
的进行学习一下。
代码执行函数
通过搜索引擎了解到了PHP
的代码执行函数
1、eval()
定义和用法
eval() 函数把字符串按照 PHP 代码来计算。
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。
语法
1 | eval(phpcode) |
参数 | 描述 |
---|---|
phpcode | 必需。规定要计算的 PHP 代码。 |
代码
1 |
|
利用方式:
代码2
当采用POST
请求时,这就相当于PHP
一句话了。可以用菜刀连接。
1 |
|
2、assert()
assert
在PHP中叫断言,是用于在代码中捕捉假设的,可以将断言看作是异常处理的一种高级处理。
assert
这个函数在php
语言中是用来判断一个表达式是否成立。返回true or false;
断言在程序中的某个特定点该的表达式值为真。如果该表达式为假,就中断操作
assert()
会检查指定的assertion
并在结果为 FALSE 时采取适当的行动(视assert_options
而定):point_down:
1 | // 断言操作选项函数 |
assert_options
1 | 'ASSERT_ACTIVE=1' // Assert函数的开关 |
如果 assertion
是字符串,它将会被 assert()
当做 PHP 代码来执行。跟eval()
类似, 不过eval($assertion)
只是执行符合php编码规范的$code_str
。
代码
1 |
|
利用方式:
和eval
的就类似了。
3、preg_replace()
preg_replace
函数执行一个正则表达式的搜索和替换。
语法
1 | mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) |
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
- $pattern: 要搜索的模式,可以是字符串或一个字符串数组。
- $replacement: 用于替换的字符串或字符串数组。
- $subject: 要搜索替换的目标字符串或字符串数组。
- $limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
- $count: 可选,为替换执行的次数。
返回值
如果subject
是一个数组, preg_replace()
返回一个数组, 其他情况下返回一个字符串。
如果匹配被查找到,替换后的 subject
被返回,其他情况下 返回没有改变的 subject。如果发生错误,返回 NULL。
代码:
1 | #preg_replace('正则规则','替换字符','目标字符') |
该函数要利用时,需要使用/e(PHP版本<5.5.0)
修饰符使preg_replace()
将replacement
参数当作 PHP 代码
利用方式:
和以往的一样
4、call_user_func(),call_user_func_array()函数
call_user_func()
call_user_func
— 把第一个参数作为回调函数调用
语法
1 | call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed//可以有多个参数,第一个参数为被调用的回调函数,除了第一个参数外,其他参数均为被调用函数的参数 |
第一个参数 callback
是被调用的回调函数,其余参数是回调函数的参数。
参数
callback
将被调用的回调函数(callable
)。
parameter
0个或以上的参数,被传入回调函数。
Note:
请注意,传入call_user_func()的参数不能为引用传递。
例子
1 |
|
代码
1 |
|
利用方式:
直接打开就会是phpinfo();
页面
call_user_func_array()
call_user_func_array()
只有两个参数,第一个参数为被调用的回调函数,第二个参数是要被传入回调函数的数组,这个数组必须是索引数组。
语法
1 | call_user_func_array ( callable $callback , array $param_arr ) : mixed//把第一个参数作为回调函数(callback)调用,把参数数组作(`param_arr`)为回调函数的的参数传入。 |
参数
callback
被调用的回调函数。
param_arr
要被传入回调函数的数组,这个数组得是索引数组。
例子
1 |
|
代码
1 |
|
利用方式:
5、array_map()函数
语法
1 | array_map(myfunction,array1,array2,array3...) |
参数
参数 | 描述 |
---|---|
myfunction | 必需。用户自定义函数的名称,或者是 null。 |
array1 | 必需。规定数组。 |
array2 | 可选。规定数组。 |
array3 | 可选。规定数组。 |
例子
1 |
|
代码
1 |
|
利用方式:
6、array_filter()函数
语法
1 | array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) : array |
参数
array
要循环的数组
callback
使用的回调函数
如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。更多信息见转换为布尔值。
flag
决定callback
接收的参数形式:
ARRAY_FILTER_USE_KEY
-callback
接受键名作为的唯一参数ARRAY_FILTER_USE_BOTH
-callback
同时接受键名和键值
例子
1 |
|
$var &1
1 | (1) 判断int型变量var是奇数还是偶数 |
代码
1 | #用回调函数过滤数组中的元素:array_filter(数组,函数) |
利用方式:
代码注入的防治:
- 升级到PHP 7.1,该版本对大部分常见的执行动态代码的方法进行了封堵。
- php.ini中,关闭“
allow_url_fopen
”。在打开它的情况下,可以通过phar://
等协议丢给include
,让其执行动态代码。 - php.ini中,通过
disable_functions
关闭exec,passthru,shell_exec,system
等函数,禁止PHP调用外部程序。 - 永远不要在代码中使用
eval
。 - 设置好上传文件夹的权限,禁止从该文件夹执行代码。
- include 文件的时候,注意文件的来源;需要动态include时做好参数过滤。
- 对于
preg_replace()
函数,要放弃使用/e修饰符,也可以使用preg_replace_callback()
函数代替。如果一定要使用该函数,请保证第二个参数中,对于正则匹配出的对象用单引号包裹 因为mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) /e
修正符使preg_replace()
将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。
命令执行函数
本质:命令执行产生函数:exec
,shell_exec
,system
,passthru
等将参数以dos、shell执行
exec()、system()、popen()、passthru()、proc_open()、pcntl_exec()、shell_exec()
、反引号(`) 实际上是使用shell_exec()函数,此外还要小心mail()函数的安全
system()
输出并返回最后一行shell结果。exec()
不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。passthru()
只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
popen()、proc_open()
不会直接返回执行结果,而是返回一个文件指针
后面再学习一下关于命令执行绕过waf的方式才行。