热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

CVE201814421——Seacms后台getshell分析

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

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

 

漏洞触发点、触发payload

触发条件以及payload作者给出了基本的说明,原博客地址
可以看到是在后台编辑video的时候,在图片pic处注入代码

{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,然后我们可以通过表单的提交地址,发现对应的控制器,从而跟踪代码的处理过程。
这里我们找到的输入变量名为:v_pic


2. 找到对应的逻辑代码

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

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

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


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

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


4. 代码分析

通过浏览代码,发现处理的数据比较多,我们只需要跟踪v_pic这个变量
我们跟进cn_substrR这个函数:
注释中讲的很明白,是按照中文单字节截取的方式,然后对数据进行了addslashes,这个函数会在入库的时候进行转义,很大程度上防止了sql注入。
然后我们继续进入二级代码处理acttype=edit
这里就开始数据入库了,可以看到:
到这里我们的数据,已经经过处理进入了数据库,我们可以梳理一下数据被过滤的流程:


5. 反向追踪

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

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

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

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

/details/index.php?1.html&m=admin&a=assert&b=phpinfo()
=>
1.html&m=admin&a=assert&b=phpinfo()
=>
1

所以我们得到的id为1.然后跟进echoContent函数:
在开头可以看到第一步是从数据库中按照id,取出有关数据,我们关注v_pic的处理:

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

$cOntent=str_replace("{playpage:pic}",'/'.$GLOBALS['cfg_cmspath'].ltrim($v_pic,'/'),$content);

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

/xxxx{if:1)$GLOBALS['_G'.'ET'][a]($GLOBALS['_G'.'ET'][b]);//}{end if}

这并不能造成代码执行,所以我们还是需要找到解析if语句的地方,继续往下翻:
在下面,所有数据拼接结束以后,我们看到了一个很关键的函数parseIf;
跟进查看具体实现:
为了测试方便,我们将这段代码单独拿出来,单独测试:
这里我们看到了整个流程中的关键过滤点,这里采用了黑名单,替换为特殊字符的过滤方式:

str_ireplace(array('unlink','opendir','mysqli_','mysql_','socket_','curl_','base64_','putenv','popen(','phpinfo','pfsockopen','proc_','preg_','_GET','_POST','_COOKIE','_REQUEST','_SESSION','_SERVER','assert','eval(','file_','passthru(','exec(','system(','shell_'), '@.@', $v)

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

$_GET[a]($_GET[b])

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


6. 总结测试

我们最后总结以下数据处理的流程:
我们把提取的有关代码,放到服务器上实际执行一下:

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

 

总结

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


推荐阅读
  • ShiftLeft:将静态防护与运行时防护结合的持续性安全防护解决方案
    ShiftLeft公司是一家致力于将应用的静态防护和运行时防护与应用开发自动化工作流相结合以提升软件开发生命周期中的安全性的公司。传统的安全防护方式存在误报率高、人工成本高、耗时长等问题,而ShiftLeft提供的持续性安全防护解决方案能够解决这些问题。通过将下一代静态代码分析与应用开发自动化工作流中涉及的安全工具相结合,ShiftLeft帮助企业实现DevSecOps的安全部分,提供高效、准确的安全能力。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • 本文介绍了使用readlink命令获取文件的完整路径的简单方法,并提供了一个示例命令来打印文件的完整路径。共有28种解决方案可供选择。 ... [详细]
author-avatar
新青年博宇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有