0x01 代码分析
后台地址:192.168.5.176/admin.php
admin admin
安装后的界面
在后台发布了一首新歌后,前台点进去到一个“下载LRC歌词”功能点的时候发现是使用readfile()函数的(readfile() 函数输出一个文件)
文件位置:\template\default\source\down.php
代码很短,这里下载文件漏洞我们重点关注readfile函数和传递给这个函数的参数,也就是$file,可以看到file这个变量是由geturl和getfield这两个函数得到的,跟进下这两个函数
首先geturl()函数路为/source/system/function_common.php。
这里file是我们传入的文件地址,这里首先通过正则来匹配判断,但是当file不符合正则规则而时候就直接复制给$url变量,即你上传什么,这里就读什么,读取下载的时候未作任何过滤操作. 那我们这里就是要控制传给geturl这个函数的参数即可,那我们继续来看看geturl函数里这个getfield函数是干什么的
文件位置:/source/system/function_common.php 和geturl在一个文件里
那么这里可以看到,getfield这个函数主要是查询下载文件的地址的。
$sql = "select ".$target." from ".tname($table)." where ".$object."='".$search."'";
这里就是查询in_lyic这个字段的值,而这个字段的值就是歌词文件的地址。
那么再回到我们最初的down文件理一下,这里我们要控制$file变量造成任意文件下载就必须对getfield函数里查询出来的文件下载地址进行控制,这样才可以达到任意文件下载而不是下载正常的歌词文件。
那么这个歌词地址是必须有后台权限,在管理页面添加音乐的时候指定歌词的地址
那么我们现在需要看看,后台这里新增音乐的文件,对填入的歌词文件的地址是否有过滤和替换之类的操作,这时候我们就转向上传的地方看看。
POST /admin.php?iframe=music&action=saveadd HTTP/1.1 Host: 192.168.5.176 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 186 Referer: http://192.168.5.176/admin.php?iframe=music&action=add Cookie: in_adminid=1; in_adminname=admin; in_adminpassword=c3284d0f94606de1fd2af172aba15bf3; in_permission=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9 Connection: close Upgrade-Insecure-Requests: 1 in_name=1&in_color=&in_classid=2&in_specialid=0&in_uname=admin&in_singerid=0&in_best=0&in_grade=3&in_points=0&in_tag=1&in_audio=1&in_cover=1&in_lyric=1&in_text=1&form2=%E6%8F%90%E4%BA%A4
请求的是admin.php文件 那我们看看这个admin.php
$iframe = !empty($_GET['iframe']) && in_array($_GET['iframe'], $frames) ? $_GET['iframe'] : 'login';
include_once 'source/admincp/module/'.$iframe.'.php';
随后这两行 通过get方式接受的iframe参数,来决定包含的文件的地址,
我们上面点击新增歌曲的数据包接受的参数是iframe=music&action=saveadd ,
那我们继续跟进,看看'source/admincp/module/music.php文件是否有我们上传代码
可以看到文件开头有个通过SafeRequest函数接收action参数的,看看这个函数
这个函数只是对接收的参数进行trim、addslashes和htmlspecialchars等字符转义、实体转义等过滤,这种过滤一般都是可绕过的。
接着回到music.php 寻找上传的相关代码
在music.php文件里往下翻可以到通过switch语句来选择执行的函数。我们提交的参数是
POST /admin.php?iframe=music&action=saveadd HTTP/1.1
就是调用saveadd这个函数 ,往下翻找到这个函数
$in_lyric = checkrename(SafeRequest("in_lyric","post"), 'attachment/music/lyric');
可以看到这行是对我们填写的歌词地址进行操作,然后通过下面数据库insert语句将歌词地址写入数据库。我们还需要看看这个checkrename做了什么
可以看到这里的cheackrename函数就是对传入的地址进行正则匹配然后替换成统一目录,并没有对传入的地址字符串本身进行任何过滤和限制,也就是说我们可以写任意的地址,配合网站首页的下载漏洞就造成了任意文件下载漏洞。
0x02漏洞利用
比如config.inc.php文件的物理路径为:
C:\phpStudy\PHPTutorial\WWW\source\system\config.inc.php
由于”\”会被过滤可使用”/”替换绕过
综合起来最终的payload为:
C:/phpStudy/PHPTutorial/WWW/source/system/config.inc.php