CVE-2018-14421 Seacms 后台getshell分析

2018-08-17 17:46:43 浏览数 (1)

前言

最近看到关注的博客里面,有一篇师傅拿cve的文章,是有关于海洋cms的后台getshell,只给出了exp,但是并没有详细的分析流程,好奇心的驱使下,开始了对这个cve的跟踪分析。

漏洞触发点、触发payload

触发条件以及payload作者给出了基本的说明,原博客地址:(http://hexo.imagemlt.xyz/post/seacms-backend-getshell/index.html)可以看到是在后台编辑video的时候,在图片pic处注入代码

代码语言:javascript复制
{if:1)$GLOBALS['_G'.'ET'][a]($GLOBALS['_G'.'ET'][b]);//}{end if}

利用是:/details/index.php?1.html&m=admin&a=assert&b=phpinfo()

初步观察

通过简单的观察,发现注入的代码是类似于渲染模板语法的代码,所以可以推测出来代码在最后执行的时候,一定经过了某种模板引擎的渲染,导致了任意代码执行。

追溯方法--污点追踪

还记得吴翰清在白帽子讲web安全里面讲过,如何追踪溯源一个漏洞,就是跟踪数据流。

我们现在已经知道了触发该漏洞的输入污点数据,下面我们开始一步步解析污点数据的执行过程:

1.确定输入参数

首先我们应该确定一下我们输入的变量名,这个时候我们可以使用phpstorm的全局搜索,搜索结果为:

通过和图片文字的对比我们发现了我们输入代码的模板文件 为/admin/template/admin_video_edit.htm ,然后我们可以通过表单的提交地址,发现对应的控制器,从而跟踪代码的处理过程。

2.找到对应的逻辑代码

这里我们首先可以通过模板文件,找到form表单执行的get参数 action=save&acttype=edit ,但是并不能直接找到该变量的处理流程,这个时候我们就再次需要phpstorm的全局搜索。

代码语言:javascript复制
这里首先要有一点开发技巧,htm文件在开发中就只是模板文件,需要有控制
器来渲染,渲染一般都有include,render,render_template等等代码关
键词,所以我们可以通过这个来确定控制器

通过全局搜索,发现只有一个地方引用了这个文件,所以我们就唯一确定了控制器的位置。

3.通过传入的get参数确定程序分支

上面我们在表单中找到了传入的get参数为action=save&acttype=edit,然后可以在代码中,找到相应的代码分支。

4.代码分析

通过浏览代码,发现处理的数据比较多,我们只需要跟踪v_pic这个变量

我们跟进cn_substrR这个函数:

在入库的时候进行转义,很大程度上防止了sql注入。 然后我们继续进入二级代码处理acttype=edit

这里就开始数据入库了,可以看到:

到这里我们的数据,已经经过处理进入了数据库,我们可以梳理一下数据被过滤的流程:

5.反向追踪

上面的数据,经过处理已经进入数据库,这个时候我们的分析流程就断了,这个时候我们可以通过利用的页面,来反向推理出代码执行的位置。

利用方法为:

代码语言:javascript复制
/details/index.php?1.html&m=admin&a=assert&b=phpinfo()

我们到details/index.php中查看处理代码:

我们可以看到这里有一点有关路由的处理,首先将query_string的最前面的文件名称去掉了,然后将字符串强转int,所以上面的路由经过的处理为:

代码语言:javascript复制
/details/index.php?1.html&m=admin&a=assert&b=phpinfo()
=>
1.html&m=admin&a=assert&b=phpinfo()
=> 1

所以我们得到的id为1.然后跟进echoContent函数:

根据if条件,我们进入的分支是:

代码语言:javascript复制
$content=str_replace("{playpage:pic}",'/'.$GLOBALS['cfg_cmspath'].ltrim ($v_pic,'/'),$content);

这里并没有对数据进行什么处理,只是对数据替换拼接进了content变量中。此时content变量中有一段污点数据为:

代码语言:javascript复制
/xxxx{if:1)$GLOBALS['_G'.'ET'][a]($GLOBALS['_G'.'ET'][b]);//}{end if}

这并不能造成代码执行,所以我们还是需要找到解析if语句的地方,继续往下翻:

这里我们看到了整个流程中的关键过滤点,这里采用了黑名单,替换为特殊字符的过滤方式:

代码语言:javascript复制
str_ireplace(array('unlink','opendir','mysqli_','mysql_','socket_','curl
_','base64_','putenv','popen(','phpinfo','pfsockopen','proc_','preg_','_G
ET','_POST','_COOKIE','_REQUEST','_SESSION','_SERVER','assert','eval(','f
ile_','passthru(','exec(','system(','shell_'), '@.@', $v)

这种过滤方式有很明显的问题,第一没有过滤$GLOBALS,第二字符串拼接就可以绕过黑名单。所以payload中为什么这么写,也就很清楚了,这里采用的是

代码语言:javascript复制
$_GET[a]($_GET[b])

这种代码执行方式,只要简单的采用global和字符串拼接就能绕过过滤代码,导致了eval代码执行。

6.总结 测试

我们最后总结以下数据处理的流程:

我们把提取的有关代码,放到服务器上实际执行一下:

可以看到代码经过处理以后,还是会执行,到这里我们的分析流程就结束了

总结

这个漏洞实际分析并不是很难,但是还是会用到一些开发的常识,还有追踪污点数据的小技巧,很适合新手学习。

0 人点赞