[网鼎杯 2020 半决赛]faka
未授权添加账号和提升权限
漏洞代码位于application/admin/controller/Index.php中的info方法:
1 | public function info() |
题目默认session都没有,因此后面的值为空,get和post不传id的话,$this->request->request('id')
也为空,因此可以进入if,跟进_form;
1 |
|
我们跟进下面的post处理,把post参数给$data
,然后把password给md5,再对$data
调用_form_filter这个回调方法:
1 | /** |
对$data
进行简单的处理,基本无太大影响,但要注意$data['authorize']
,是对权限的可知,如果这样添加账号的话,权限还是很低,很多功能用不了,所以post还需要加上authorize=3,因为数据表中admin就是3
从_form_filter方法出来后,就会执行$result=DataService::save($db,$data,$pk,$where);
,将data保存进数据库,成功未授权添加账号:
我们前往/admin进行登录
任意文件读取
漏洞代码位于/application/manage/controller/Backup.php的downloadBak方法:
1 | function downloadBak() { |
读取的文件的后半部分可控,即$_GET['file']
可控
我们可以通过这下载文件
1 | http://0c3a24d3-6960-480b-9d60-f986cd495e16.node3.buuoj.cn/manage/backup/downloadbak?file=../../../../../../../../../../etc/passwd |
但在buu环境中并没有/flag,因此还需要利用接下来的文件上传漏洞。(其实也可以猜到,是/flag.txt)
文件上传
拿到了后台,我们可以发现文件上传的点
正常上传发现上传不了,因此我们看一下文件上传的代码。代码位于application/admin/controller/Plugs.php
的upload方法
1 | /** |
他写了一个file类用来处理上传的文件,注意这个$md5 = str_split($this->request->post('md5'), 16);
,filename
是这样拼接而来的:$filename = join('/', $md5) . ".{$ext}";
然后检测后缀,不能是php,或者不是storage_local_exts
里面的,这个 是可以通过管理面板改配置来控制的
接下来是token验证:
1 | // 文件上传Token验证 |
默认session_id()是空,所以这里的token也很任意构造出来
接下来就是进入move()函数
1 | $file->move('static' . DS . 'upload' . DS . $md5[0], $md5[1], true) |
1 | /** |
前面是一些检测,在check()函数中又是否是图片的检测,利用图片头进行绕过
然后注意这里
1 | $path = rtrim($path, DS) . DS; |
$savename
是$md5[1]
,跟进$this->buildSaveName
函数:
1 | /** |
这些代码起作用:
1 | if (!strpos($savename, '.')) { |
最终相当于写入的文件是static/upload/$md5[0]/$md5[1].$ext
因此php文件写不了,虽然可写入的其他后缀可控,但是没法写入.htaccess之类的,因此也解析不了,正常
是没法写马的,我把这些代码看了一遍后也是这么想的,所以我还是太菜了。
仔细看了
1 | if (!strpos($savename, '.')) { |
如果$md5[1]
里面有后缀呢?就相当于直接return $savename
了,最后相当于是这里:
1 | static/upload/$md5[0]/$md5[1] |
因此可以考虑把php后缀写到$md5[1]
里面,想办法构造一下:
1 |
|
至少.php必须在16-32长度之间,生成一下token,是1d3eb018ca985d5fb7668cc8112f2cd3,md5是73058d518344b513098c51845768.php
,传入文件的后缀是png,然后上传:
虽然说文件上传失败,但其实还是成功了的:
转载