[PWNHUB 公开赛 2018]傻 fufu 的工作日

先扫下目录得到index.php.bak

这是份加密的源代码

网上找到解密方法

解密源码上有个UploadFile.class.php

访问打不开 尝试bak后缀的文件 得到备份文件

得到过滤的规则

漏洞问题在

if(!in_array(filename\[count(filename)-1], $this->allow_ext)) {

return $this->error('只允许上传图片文件');

}

// 用.分割文件名,只保留首尾两个字符串,防御Apache解析漏洞

origin_name = current(filename);

ext = end(filename);

new_name = (this->new_name ? this-\>new_name : origin_name) . '.' . $ext;

target_fullpath = this->dist_path . DIRECTORY_SEPARATOR . $new_name;

filenamecount($filename)-1

ext = end(filename)

count($filename) 计算的是元素个数,这里有两个元素,所以结果是 2。

2 - 1 = 1。

$filename1 是在按"键名"取值。因为这个数组里确实存在键名 1,对应的值就是 'jpg'。

结论:这种写法等价于 $filename1,它取的是键名为 1 的值,与元素是否排在最后毫无关系。

end() 函数忽略键名,只关注数组内部的"指针位置"。

PHP 数组会记住元素添加的先后顺序。你的数组是先塞入了 'jpg'(键1),后塞入了 'php'(键0)。

end() 将内部指针指向最后插入的那个元素,也就是后塞入的 'php'。

结论:end() 取的是插入顺序的最后一个,与键名数字大小无关

先传filename1=jpg

再传filename0=php

得到php为文件后缀

解密方法

PHPJiaMi 免扩展加密分析及解密 - vsalw