作者:H4lo
一道关于二次注入的和文件上传、文件重命名有关的题目,其中的一些bypass地方还是很值得学习的。
描述:这是一道源码审计,直接给了一套文件管理功能的php源码,结构如图
在upload.php页面以白名单方式检测了文件的后缀名,将上传的文件名和后缀分开,以insert语句插入后分别存放。因为代码经过了相关的过滤,单单看这段代码是没有什么问题的。
正常上传test.jpg后在的数据库是这样的
0x01 rename.php页面对文件重命名以后在数据库和文件系统都进行了改名
在rename.php中有两个变量,分别是$req['oldname'],$req['newname'],$req['oldname']是在数据库中查询到的没有包含后缀的文件名,$req['newname']是我们的输入文件名,两个变量都可控。
因为这里使用了updata语句来更新数据库,若我们在之前的upload页面插入的文件名包含单引号的话,即使经过了addslashes转义后,这里再次取出文件名就会直接闭合单引号。
关于二次注入的文章:https://www.cnblogs.com/ichunqiu/p/5852330.html
然后在rename.php页面将其重命名为test.jpg
此时数据库是这样的:
文件系统中是这样的:
因为在这里update语句中,取到的是数据库中的文件名,也就是',extension='',filename='test.jpg,那么拼接起来就是
0x03 然后我们将前面的文件名为test.jpg、后缀为空的文件在rename.php中再次将其命名为test.php
因为在下面的代码中,第二次从数据库中取出的$result["extension"]是空的,在下面的rename方法中直接在文件系统中把文件的名字改成了newname加上空的后缀,所以我们直接改成test.php,文件系统中自然就变成了这个名字。
在文件系统中我们可以看到成功更改为了php文件,然后就是getshell了。
同样无法在文件系统和数据库中统一
领取专属 10元无门槛券
私享最新 技术干货