今天做了一道BUU上收录的2019强网杯upload,解题过程中拿到了题目源码,里面有个函数会对cookie进行反序列化,基本思路就是利用反序列化和源码中的魔术方法构造POP链进入upload_img函数绕过对上传文件的强制命名,从而拿到webshell
结果EXP都写好了,生成的字符串换到Cookie里面刷新却没能成功,找了别人的EXP过来对比自己也看不出哪里不一样,但是把别人的拿来用又行了,怎么会是呢?以下是我最开始写的EXP
1 |
|
擦亮眼睛仔细对比后,我发现了自己写的EXP和别人的不同之处,他们的EXP开头都有一行代码:
1 | namespace app\web\controller; |
namespace的作用是分配命名空间,可以起到防止变量、函数、类名重复的效果,runoob上有一篇专门讲PHP中的命名空间的文章很不错:
https://www.runoob.com/w3cnote/php-namespace-intro.html
其中提到了当调用其它命名空间(如test)下的类名(如Register)时,需要使用\test\Register :一种像文件路径的语法: \空间名\元素名
而当我们用echo输出对EXP添加命名空间前后的序列化字符串时,也能发现其中的不同(上面的结果是不添加Namespace的,下面的反之)
类名从Register变成了app\web\controller\Register,即\空间名\元素名的语法,所以说序列化后的字符串是会受到namespace影响的。
那么问题来了,为什么我们一定要添加这行代码声明命名空间才能执行成功呢?我翻了翻题目源码:
原来是题目源码中规定好了这样的命名空间,所以也只有声明了同样命名空间的EXP才能生成有效的序列化字符串,不然类名都不同了。
这种疏忽完全来源于基础的薄弱……但是边做边学效率才是最高的,嗯…我认错但还是不改。
事情到这里就算告一段落,我写下这篇博客后也心满意足地看比赛去了~